---
title: "Anthropic 协议"
description: "pirouter 上接受 Anthropic 协议的模型（包括 Claude）可以直接用官方 Anthropic SDK 调用，只改 base URL、API key 和模型 ID；提示词缓存与思考参数原样转发，错误体与官方不同。"
canonical: "https://pirouter.ai/zh/docs/api/anthropic"
last-updated: "2026-10-17"
lang: "zh"
source: "content/docs/zh/api/anthropic.mdx"
---

# Anthropic 协议

pirouter 上接受 Anthropic 协议的模型（包括 Claude）可以直接用官方 Anthropic SDK 调用，只改 base URL、API key 和模型 ID；提示词缓存与思考参数原样转发，错误体与官方不同。

用官方 Anthropic SDK 调用 pirouter，改三项就够：base URL 填 `https://api.pirouter.ai`（不带 `/v1`），key 换成 pirouter 的 API key，模型 ID 写成 `vendor/model`。提示词缓存和思考参数的写法与 Anthropic 官方相同。

## 用官方 SDK 发请求

端点是 `POST /v1/messages`，SDK 会自己拼上 `/v1`。

cURL:

```bash
curl https://api.pirouter.ai/v1/messages \
  -H "x-api-key: $PIROUTER_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-opus-5.5",
    "max_tokens": 1024,
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'
```

Python:

```python
import os
import anthropic

client = anthropic.Anthropic(
    base_url="https://api.pirouter.ai",
    api_key=os.environ["PIROUTER_API_KEY"],
)

message = client.messages.create(
    model="anthropic/claude-opus-5.5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(message.content[0].text)
```

TypeScript:

```ts
import Anthropic from '@anthropic-ai/sdk'

const client = new Anthropic({
  baseURL: 'https://api.pirouter.ai',
  apiKey: process.env.PIROUTER_API_KEY,
})

const message = await client.messages.create({
  model: 'anthropic/claude-opus-5.5',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello!' }],
})
console.log(message.content[0].text)
```

成功时返回一段模型回复，控制台的 **日志** 里能找到这次请求。

要流式输出，在请求体里加 `"stream": true`，并给 curl 加 `-N`：

```bash
curl -N https://api.pirouter.ai/v1/messages \
  -H "x-api-key: $PIROUTER_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-opus-5.5",
    "stream": true,
    "max_tokens": 1024,
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'
```

SSE 事件成对到达：一行 `event: `，一行 `data: `。第一个事件是 `message_start`，最后一个是 `message_stop`，之后没有 `[DONE]`。

## 两种鉴权头

key 可以放在下面任一个请求头里，值都是 pirouter 的 API key：

| 请求头                     | SDK 里怎么写                                     |
| ----------------------- | -------------------------------------------- |
| `x-api-key`             | SDK 的默认写法，传 `api_key`（TypeScript 是 `apiKey`） |
| `Authorization: Bearer` | 改传 `auth_token`（TypeScript 是 `authToken`）    |

两个都带时以 `Authorization` 为准。读取规则见[在请求里带上 key](https://pirouter.ai/zh/docs/authentication.md#在请求里带上-key)。

`anthropic-version`、`anthropic-beta` 这类请求头原样转发给 provider。

## 哪些模型能用

Claude 系列接受 Anthropic 协议，部分其他厂商的模型也接受。要确认一个模型，看 `GET /v1/models/{vendor}/{model}/endpoints` 返回的 `protocols` 里有没有 `anthropic`，或者在[模型列表](https://pirouter.ai/zh/models)里看每个模型的协议。用不接受这个协议的模型调用，返回 `422`，见[协议不匹配](https://pirouter.ai/zh/docs/models.md#协议不匹配)。

Claude 模型也可以用别名调用，例如不带厂商前缀的名字。别名清单在同一个响应的 `aliases` 里。用哪个名字调用，日志和账单里记的都是完整 ID。

## 使用提示词缓存

在要缓存的内容块上加 `cache_control`，pirouter 原样转发。`ttl` 可以写 `"5m"` 或 `"1h"`：

```json
"system": [
  {
    "type": "text",
    "text": "一段很长、每次请求都不变的说明",
    "cache_control": { "type": "ephemeral", "ttl": "1h" }
  }
]
```

缓存用量在响应的 `usage` 里，每一项按不同的单价计费：

| 用量字段                                       | 含义           | 计价                                |
| ------------------------------------------ | ------------ | --------------------------------- |
| `input_tokens`                             | 没有命中缓存的输入    | 输入价（`prompt`）                     |
| `cache_read_input_tokens`                  | 从缓存读出的输入     | 缓存读取价（`input_cache_read`）         |
| `cache_creation.ephemeral_1h_input_tokens` | 写入 1 小时缓存的输入 | 1 小时缓存写入价（`input_cache_write_1h`） |
| `cache_creation.ephemeral_5m_input_tokens` | 写入 5 分钟缓存的输入 | 模型价格里的缓存写入价                       |

输入总量是 `input_tokens`、`cache_read_input_tokens`、`cache_creation_input_tokens` 三项之和。各项单价在模型的 `pricing` 里，说明见[价格](https://pirouter.ai/zh/docs/guides/billing.md#价格)。

## 控制思考

在 Claude 模型上，用 `thinking: {"type": "adaptive"}` 打开思考，用 `output_config.effort` 设档位：`low`、`medium`、`high`、`xhigh`、`max`。这两个参数原样转发；写了模型不接受的档位，返回 provider 的 `4xx`。

> **提示：** 要稳定地控制思考，用 `adaptive` 加 `output_config.effort`。部分 Claude 模型只接受 `adaptive`，部分不能关闭思考：在这些模型上写 `"type": "enabled"` 或 `"type": "disabled"`，请求不会被拒绝，但思考的方式不保证和你写的一致。

请求里既没写 `thinking`，也没写 `output_config.effort` 时，如果 provider 设有默认推理档位，pirouter 写入 `thinking: {"type": "adaptive"}` 和这一档；默认档位是 `none` 时写入 `thinking: {"type": "disabled"}`。

## 与 Anthropic 官方行为的差异

| 方面           | pirouter 的行为                                                                                                                                                                                        |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 错误体          | pirouter 自己的错误（`401`、`402`、`404`、`422`、`429`、`5xx`）是 `{"error": {"message", "type", "code"}}`，不是 Anthropic 的 `{"type": "error", "error": {…}}`。provider 返回的错误原样转发。SDK 照常按状态码抛出异常，`error.message` 可读 |
| 响应里的 `model` | 改写为 pirouter 的模型 ID（`vendor/model`）。provider 自己报的名字在响应头 `X-Pi-Upstream-Model` 里                                                                                                                     |
| 模型名          | 除完整 ID 外也接受别名，见[哪些模型能用](https://pirouter.ai/zh/docs/api/anthropic.md#哪些模型能用)                                                                                                                        |
| 思考预算         | 部分 provider 只按 token 预算限制思考。在这些 provider 上，你写的 `budget_tokens` 会被压到 `max_tokens` 以下，剩下的留给回复；没写时按 `output_config.effort` 换算（没写档位按 `medium`），预算不低于 1024                                               |
| 强制调用工具       | `tool_choice` 为 `any` 或指定某个工具时，部分模型不保证调用工具：请求照常返回 `200`，回复可能是普通文本                                                                                                                                   |
| 故障切换         | provider 在返回第一个字节之前失败时，pirouter 换到下一个 provider，见[故障切换](https://pirouter.ai/zh/docs/guides/routing.md#故障切换)                                                                                          |

## 出错时

按 `error.code` 处理，每个错误码的含义与要不要重试见[错误码](https://pirouter.ai/zh/docs/api/errors.md)。这个协议上的 `422` `validation_failed` 多半是模型不接受 Anthropic 协议：换一个模型，或改用它接受的协议。

## 目前没有的能力

下面这些 Anthropic 端点 pirouter 目前没有：

- `POST /v1/messages/count_tokens`。调用它返回 `400` `invalid_request`，`message` 是 `model is required`，意思是 pirouter 不提供这个端点，见 [`invalid_request`](https://pirouter.ai/zh/docs/api/errors.md#invalid_request)。
- Message Batches 端点。

## 下一步

- [创建 Message](https://pirouter.ai/zh/docs/api/messages.md): Messages 端点的全部参数与响应。
- [定价与计费](https://pirouter.ai/zh/docs/guides/billing.md): 每类 token 怎么计价。
