Anthropic 风格 Messages API
Anthropic 风格代理路由适合已经发送 Anthropic Messages 请求,并希望由 AISIX 管理网关侧认证、模型别名、路由和策略的应用。
客户端保持 Anthropic 风格请求和响应格式。AISIX 成为客户端调用的端点,上游服务提供方可以是 Anthropic,也可以是其它受支持的服务提供方协议族。
本指南说明代理 API 行为。可运行的客户端集成请参见 Anthropic SDK。
客户端发送的内容
客户端会发送三个由 AISIX 管理的值:
- base URL 是 AISIX 网关 Origin,末尾不包含斜杠或端点路径。
- API Key 是 AISIX 调用方 API Key。
- model 值是 AISIX 模型别名,例如
claude-prod。
请求体保持 Anthropic Messages 格式,包括 messages、max_tokens、tools 和 stream。调用方使用 AISIX 调用方 API Key,而不是上游 Anthropic 服务提供方密钥。
对于会发送这种形态的客户端,AISIX 也接受 messages[] 中的 system role。当上游路径需要 Anthropic 原生格式时,AISIX 会将开头的 system messages 映射到 Anthropic 顶层 system 字段。
Anthropic SDK 会以 x-api-key 发送调用方 API Key。对于直接 HTTP 客户端,AISIX 也接受 Bearer Token。
导出以下示例使用的网关连接和请求值:
# AISIX_PROXY 不含尾部斜杠或 /v1 等端点路径
# 本地快速入门使用 http://127.0.0.1:3000。
export AISIX_PROXY="YOUR_AISIX_GATEWAY_URL"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export AISIX_MODEL="claude-prod"
Messages 请求
通过 AISIX 发送 Messages 请求:
curl -sS -X POST "${AISIX_PROXY}/v1/messages" \
-H "x-api-key: ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"max_tokens": 128,
"messages": [
{
"role": "user",
"content": "Say hello from AISIX."
}
]
}'
成功响应使用 Anthropic Messages 格式。请求中的 model 值是 AISIX 模型别名,不一定是上游服务提供方模型 ID。
选择上游路径
与其它 AISIX 代理 API 一样,/v1/messages 让客户端请求格式在上游服务提供方变化时保持稳定。对于 Anthropic 风格请求,上游选择很重要,因为原生 Anthropic 协议路由会比转换后的上游保留更多 Anthropic 专属行为。
| 上游路径 | 能提供什么 | 适用场景 |
|---|---|---|
| 原生 Anthropic 协议路由 | 原生 Anthropic 请求和响应行为,同时由 AISIX 处理调用方 API Key、服务提供方密钥和模型别名。包括使用 anthropic 适配器的服务提供方密钥,以及声明了 apis.messages的密钥。 | 应用依赖思考块、图片块、缓存控制或精确工具使用语义等 Anthropic 专属行为。 |
| Amazon Bedrock 或 Vertex AI 上的 Claude | 携带调用方请求体访问平台自己的 Anthropic Messages API,只按平台接受的内容做调整。带签名的思考块、redacted_thinking、tool_result 中的图片、原生用量和上游消息 ID 都按平台返回的原样传回。 | 应用通过 Bedrock 或 Vertex AI 服务提供方密钥使用 Claude。AISIX 会自动为 Claude 模型选择此路径,Bedrock 参见 Messages API 上的 Claude,Vertex AI 参见 Vertex AI 上的 Claude。 |
| 转换后的上游 | 客户端侧保持 Anthropic 风格,AISIX 背后接入非 Anthropic 上游。 | 应用需要保持 Anthropic 风格客户端,同时由 AISIX 将流量路由到另一个受支持服务提供方协议族。 |
转换路径端到端支持文本、视觉和工具调用流程。text、image(base64 和 URL)以及 document 块会转换为上游线路上的多模态内容部分。assistant 的 tool_use 历史会变成上游工具调用,tool_result 块会变成上游期望的工具响应轮次,因此多轮工具循环能够跨服务提供方保留历史。
转换后的上游返回推理内容(例如兼容 OpenAI 的服务提供方返回的 reasoning_content)时,AISIX 会将其作为 signature: "" 的 thinking 内容块返回,排在文本块和 tool_use 块之前。上游不签发签名,因此该字段为空字符串。流式响应中,该块以 thinking 内容块的形式到达,带有 thinking_delta 事件,不带 signature_delta。只要上游返回了推理内容,AISIX 就会返回该块,与请求的 thinking 设置无关。同一响应中在 tool_use 块开始之后才到达的推理内容会被丢弃。上游是否返回推理内容取决于服务提供方和模型。
在请求历史中,助手轮次中 thinking 块的文本会作为该轮次的 reasoning_content 发送给上游,多个块以换行符连接。兼容 OpenAI 的上游(包括 Azure OpenAI)会收到该字段;Bedrock 和 Vertex AI 适配器没有对应字段,在走此转换的模型上会忽略它。redacted_thinking 块和签名会被丢弃,因为其他厂商无法重放 Anthropic 的签名推理。安全护栏从不改写 thinking 块,因此重放的思考内容中命中脱敏动作的部分会原样到达上游,详见推理与思考内容。当应用依赖签名推理块或其他服务提供方专属请求字段时,建议优先使用原生 Anthropic 协议路由。
Anthropic 自身的 API 会拒绝签名无法通过校验的 thinking 块,Amazon Bedrock 和 Vertex AI 上的 Claude 也是如此。因此,AISIX 向 Anthropic(即服务提供方为 anthropic 的模型,包括服务提供方密钥覆盖了 base URL 的情况)或 Bedrock、Vertex AI 上的 Claude 模型发送 /v1/messages 或 /v1/messages/count_tokens 请求前,会移除所有 signature 为空字符串的 thinking 块,并删除因此不再有内容的助手轮次。这样,在转换后的上游上开始的会话可以在 Anthropic 模型上继续,例如故障转移之后。其他 Anthropic 兼容端点,例如 adapter: anthropic 的 byo 密钥或声明了 apis.messages 的服务提供方密钥,会原样收到历史记录。
Anthropic 归属标识行
Anthropic 自家的客户端(包括 Claude Code)会在系统提示词最前面加上一行归属标识。它以 x-anthropic-billing-header: 开头,携带的是只有 Anthropic 自己的 API 才会读取的计费和遥测元数据。只要解析出的目标不是 Anthropic 自己的 API,AISIX 就会在构造上游请求之前移除这一行。
这一行位于系统提示词的最开头,而且在部分部署中它的取值会逐个请求变化。把它转发给其他服务提供方,就会改变每个提示词的前缀,从而让该服务提供方的提示词缓存在整段会话中全部失效:本应命中缓存并且命中量逐轮增长的会话,每一轮都只会报告 0 个缓存 Token。而这一行对该服务提供方毫无意义,因此 AISIX 会将其丢弃。
客户端发送:
{
"system": [
{ "type": "text", "text": "x-anthropic-billing-header: cc_entrypoint=cli; cch=7f3a91" },
{ "type": "text", "text": "你是一个乐于助人的助手。", "cache_control": { "type": "ephemeral" } }
]
}
AISIX 用剩下的内容构造上游请求:
{
"system": [
{ "type": "text", "text": "你是一个乐于助人的助手。", "cache_control": { "type": "ephemeral" } }
]
}
Anthropic 协议的上游会原样收到这个 system 字段。在转换路径上,AISIX 随后会把它转换成上游协议族自己使用的系统字段或系统消息,与转换其他请求内容的方式一致。
- 只移除这一行,而不是移除承载它的容器。同一个块中跟在它后面的文本会被保留,该块的
cache_control标记也会保留。被移空的块会被删除;system若因此 没有任何内容,则整个字段不会出现在上游请求中。system的纯字符串形态按同样规则处理。 - 匹配依据是开头的
x-anthropic-billing-header:标记,忽略前导空白并且不区分大小写。 messages永远不会被改动。如果调用方在会话内容中引用了这一行,它仍会照常发往上游——在那里移除它会改变提问本身的含义。- 豁免范围很窄:只有当目标模型的
provider为anthropic并且其服务提供方密钥以原生方式访问 Anthropic API 时,这一行才会被保留。其余情况一律适用:转换路径、通过byo+anthropic适配器或通过声明了apis.messages的服务提供方密钥接入的第三方 Anthropic 兼容服务提供方,以及 Bedrock、Vertex AI 和 Azure OpenAI 平台适配器——平台密钥即使配在provider: anthropic之下,同样会被移除这一行。指向 Anthropic 官方 API 的byo密钥也不在豁免之列,因为豁免判断读取的是模型的provider取值。 POST /v1/messages/count_tokens采用同样的移除逻辑,因此它返回的计数就是/v1/messages实际发送的请求体所对应的计数。
该行为没有任何配置项。
转换路径上的请求字段
当服务提供方密钥没有选择原生 Anthropic 协议路由时,AISIX 会将 Anthropic 请求字段改写为上游协议族期望的形态,而不是原样转发:
| Anthropic 字段 | 转换行为 |
|---|---|
tools, tool_choice | 转换为 OpenAI 工具调用形态。 |
stop_sequences | 作为 stop 发送。 |
metadata.user_id | 作为 user 发送。 |
thinking、output_config.effort | 映射为 reasoning_effort。解析顺序以及 AISIX 转发哪些档位,见推理力度。 |
output_format、output_config.format | json_schema 块会以 OpenAI 的 json_schema 形式作为 response_format 发送并启用严格模式,其中 schema 保持调用方书写的原样。其他形状一律丢弃。请求同时携带这两个字段时,以 output_format 为准。OpenAI 兼容上游会在自己这一侧闭合严格模式的 schema:在每一层对象上加入 additionalProperties: false,并把所有已声明的属性列入 required。非 OpenAI 上游则按各自的映射处理——反方向(OpenAI 的 response_format 发往 Anthropic、Gemini 或 Bedrock 上游)参见结构化输出。 |
context_management, top_k, mcp_servers, container, service_tier, betas 以及其他 Anthropic 专属字段 | 丢弃。直接转发会让兼容 OpenAI 的上游因未知参数失败;丢弃后,较新的 Anthropic SDK 增加字段时请求仍能继续工作。 |
原生 Anthropic 协议路由不会经过这层转换,因此每个 Anthropic 字段在该路径上都保持原生行为。AISIX 仍然会把 model 别名改写为上游模型 ID;在目标不是 Anthropic 自己的 API 时移除 Anthropic 归属标识行中描述的那一行;应用模型上配置的推理力度映射;以及应用服务提供方密钥上配置的 request 覆盖设置。其余字段都按客户端发送的原样发往上游。
推理力度
Anthropic 请求可以在两个位置携带推理深度。output_config.effort 是当前的控制字段,也是 Claude Opus 4.7 及以后的模型唯一接受的字段;thinking.budget_tokens 是更早的字段,在 Claude Opus 4.6 上已废弃。兼容 OpenAI 的上游只有 reasoning_effort 一个字段承载两者,因此 AISIX 按以下顺序解析:
thinking.type: disabled发送reasoning_effort: none。显式关闭推理是比深度档位更强的指令,同时出现的output_config.effort不会覆盖它。output_config.effort原档位发送为reasoning_effort。thinking.type: enabled按budget_tokens映射档位:0-1023为 minimal,1024-2047为 low,2048-4095为 medium,4096及以上为 high。thinking.type: adaptive且未指定output_config.effort时发送reasoning_effort: high,这也是请求省略 effort 时 Anthropic 自身采用的档位。
AISIX 按请求所要求的档位转发,不会拿它和上游模型的能力做校验。Anthropic 模型接受 max、xhigh 等档位,而许多兼容 OpenAI 的模型并不接受,上游不接受某个档位时会拒绝该请求。这个拒 绝是有意为之:替换成上游恰好能接受的档位,会悄悄改变应用所要求的推理深度,而这比一个报错难发现得多。请选择上游模型支持的档位,具体范围以该服务提供方自己的文档为准。
完全不支持推理的上游模型会拒绝 reasoning_effort 字段本身,因此 thinking 和 effort 字段只应发送给具备推理能力的模型。
流式与非流式请求使用同一套转换逻辑。
路由行为
/v1/messages 可以使用直接和路由模型别名。非流式请求在遇到可重试上游失败时,可以故障转移到下一个目标。
流式请求可以在 AISIX 向客户端发送响应字节之前执行故障转移。客户端可见的流开始后,AISIX 不会切换目标。通用流式行为请参见流式响应。
当能够拦截或脱敏的输出安全护栏覆盖流式请求时,AISIX 会保留整个响应,并在扫描完成后才交付,因此客户端在此之前收不到任何字节。请参阅 Messages 与 Responses 上的窗口模式。
POST /v1/messages/count_tokens 使用同一个 AISIX 调用方 API Key,并接受 Anthropic Token 计数请求格式。该路由只使用服务提供方密钥采用 anthropic 适配器或声明了 apis.messages 的目标,以及 Amazon Bedrock 或 Vertex AI 上的 Claude 模型(AISIX 使用平台自己的 Token 计数 API 计数)。平台拒绝为某个模型计数时,路由模型会转向下一个符合条件的目标。一项声明同时覆盖两条 Messages 路由,因此请确认上游也实现了 /v1/messages/count_tokens;否则,请为 /v1/messages 使用转换后的模型,或通过透传路由访问服务提供方的原生 Messages API。如果没有可用的原生 Anthropic 协议目标,AISIX 会拒绝请求。
处理错误
Messages 路由会以 Anthropic 风格信封返回错误。错误类型遵循与 Anthropic SDK 兼容的状态映射,因此 Anthropic 客户端可以用处理服务提供方错误的同一路径解析网关生成的错误。
原生 Anthropic 上游错误可能包含 request_id。AISIX 不会为网关生成的 Anthropic 风格错误添加该字段。
当输出安全护栏保留流式输出时,缓冲区中 AISIX 无法解析的帧会被丢弃,而不是未经扫描就放行。如果因此没有任何内容可返回,响应会以一个终止性 SSE error 事件结束。该事件和这条路由上的其他错误一样使用 Anthropic 信封。因此它携带 Anthropic 合法的 error.type,即 invalid_request_error;安全护栏拒绝还会加上 error.code:策略命中时为 content_filter,安全护栏无法评估内容时为 guardrail_unavailable。失败标记写在消息里。参见 AISIX 无法扫描的帧和安全护栏拒绝。
完整错误和响应头参考请参见响应头与错误码。服务提供方定义的错误类型请参见 Anthropic 的