跳到主要内容
版本:1.4.0

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 专属行为。
转换后的上游客户端侧保持 Anthropic 风格,AISIX 背后接入非 Anthropic 上游。应用需要保持 Anthropic 风格客户端,同时由 AISIX 将流量路由到另一个受支持服务提供方协议族。

转换路径端到端支持文本、视觉和工具调用流程。text、image(base64 和 URL)以及 document 块会转换为上游线路上的多模态内容部分。assistant 的 tool_use 历史会变成上游工具调用,tool_result 块会变成上游期望的工具响应轮次,因此多轮工具循环能够跨服务提供方保留历史。

thinking 和 redacted_thinking 历史块在转换时会被丢弃,因为其他厂商无法重放 Anthropic 的签名推理块。当应用依赖这些推理块或其他服务提供方专属请求字段时,建议优先使用原生 Anthropic 协议路由。

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.formatjson_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 按以下顺序解析:

  1. thinking.type: disabled 发送 reasoning_effort: none。显式关闭推理是比深度档位更强的指令,同时出现的 output_config.effort 不会覆盖它。
  2. output_config.effort 原档位发送为 reasoning_effort。
  3. thinking.type: enabled 按 budget_tokens 映射档位:0-1023 为 minimal,1024-2047 为 low,2048-4095 为 medium,4096 及以上为 high。
  4. thinking.type: adaptive 且未指定 output_config.effort 时发送 reasoning_effort: high,这也是请求省略 effort 时 Anthropic 自身采用的档位。

AISIX 按请求所要求的档位转发,不会拿它和上游模型的能力做校验。Anthropic 模型接受 max、xhigh 等档位,而许多兼容 OpenAI 的模型并不接受,上游不接受某个档位时会拒绝该请求。这个拒绝是有意为之:替换成上游恰好能接受的档位,会悄悄改变应用所要求的推理深度,而这比一个报错难发现得多。请选择上游模型支持的档位,具体范围以该服务提供方自己的文档为准。

完全不支持推理的上游模型会拒绝 reasoning_effort 字段本身,因此 thinking 和 effort 字段只应发送给具备推理能力的模型。

流式与非流式请求使用同一套转换逻辑。

路由行为​

/v1/messages 可以使用直接和路由模型别名。非流式请求在遇到可重试上游失败时,可以故障转移到下一个目标。

流式请求可以在 AISIX 向客户端发送响应字节之前执行故障转移。客户端可见的流开始后,AISIX 不会切换目标。通用流式行为请参见流式响应。

POST /v1/messages/count_tokens 使用同一个 AISIX 调用方 API Key,并接受 Anthropic Token 计数请求格式。该路由只使用服务提供方密钥采用 anthropic 适配器或声明了 apis.messages 的目标。一项声明同时覆盖两条 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 且没有 code 字段,而不是 OpenAI 风格路由会返回的 content_filter。原因写在消息里。参见 AISIX 无法扫描的帧和安全护栏拒绝。

完整错误和响应头参考请参见响应头与错误码。服务提供方定义的错误类型请参见 Anthropic 的错误文档。

下一步​

你已经了解 Anthropic 风格客户端如何调用 AISIX。当应用依赖相关行为时,请继续阅读流式响应、工具调用或代理错误与重试。