OpenAI 客户端接入 Anthropic 上游
AISIX 允许应用继续使用 OpenAI Chat Completions 请求格式,同时由网关调用 Anthropic 上游模型。当应用代码已经围绕兼容 OpenAI 的 SDK 构建,但平台团队希望把这类流量路由到 Claude 时,可以使用这一模式。
AISIX 会解析模型别名,将请求转换为 Anthropic Messages 格式,使用已保存的服务提供方凭证调用 Anthropic,并把响应转换回兼容 OpenAI 的 Chat Completions 格式。
准备工作
请先准备以下内容:
- 一个正在运行且应用可以访问的 AISIX 网关。
- 一个由 Anthropic 支持,且接受兼容 OpenAI 的 Chat Completions 请求的模型别名。
- 一个有权使用该模型别名的调用方 API Key。
- 如需运行 SDK 示例,请准备 Node.js 20 LTS 或更新版本以及
npm;如需运行 HTTP 示例,请准备curl。
如果尚未配置模型别名和调用方 API Key,请按照 Anthropic 文档为 AISIX Cloud 或开源 AISIX 网关完成配置。
请求流程
应用继续保持兼容 OpenAI 的客户端契约。服务提供方选择和协议转换都留在网关中完成。
应用将模型别名和调用方 API Key 发送到 AISIX。网关会解析上游模型、提供已保存的 Anthropic 凭证,并转换请求和响应。应用仍然发送和接收兼容 OpenAI 的数据。
调用模型别名
导出两个请求示例都会用到的调用方 API Key 和模型别名:
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export AISIX_MODEL="claude-sonnet-prod"
OpenAI SDK
安装 OpenAI SDK:
npm install openai
设置兼容 OpenAI 的基础 URL。OpenAI SDK 要求 URL 中包含 /v1 路径:
# 本地快速入门使用 http://127.0.0.1:3000/v1
export AISIX_BASE_URL="YOUR_AISIX_GATEWAY_URL/v1"
创建一个最小化 Chat Completions 客户端:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AISIX_API_KEY,
baseURL: process.env.AISIX_BASE_URL,
});
const completion = await client.chat.completions.create({
model: process.env.AISIX_MODEL,
messages: [{ role: "user", content: "Say hello from AISIX." }],
});
console.log(completion.choices[0]?.message.content);
console.log(completion.usage);
在已设置 AISIX 相关值的 Shell 中运行示例:
node anthropic-via-openai-sdk.mjs
HTTP
如需在不使用 SDK 的情况下查看响应,请导出网关源站地址,并使用 curl 发送相同的请求:
# 本地快速入门使用 http://127.0.0.1:3000
export AISIX_PROXY="YOUR_AISIX_GATEWAY_ORIGIN"
发送请求:
curl -sS -X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer $AISIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "'"$AISIX_MODEL"'",
"messages": [{"role":"user","content":"Say hello from AISIX."}]
}'
两个示例都会返回兼容 OpenAI 的 Chat Completions 结构。调用方不会收到 Anthropic 风格的内容块:
{
"object": "chat.completion",
"model": "claude-sonnet-prod",
"choices": [
{
"message": {
"role": "assistant",
"content": "Hello from AISIX."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 9,
"completion_tokens": 5,
"total_tokens": 14
}
}
转换行为
协议转换会保留常见聊天应用所依赖的兼容 OpenAI 契约:
| 行为 | AISIX 的处理方式 |
|---|---|
| 模型与身份验证 | 将模型别名解析到已配置的 Anthropic 模型,对调用方进行身份验证,并使用已保存的服务提供方凭证发送上游请求。 |
| 消息与工具 | 将开头的系统消息、用户和助手消息、函数工具、工具调用及工具结果映射为 Anthropic Messages 结构。 |
| 响应 | 将 Anthropic 文本和工具使用内容块、停止原因、Token 用量及流式事件转换回兼容 OpenAI 的字段。 |
| 输出长度限制 | 当兼容 OpenAI 的请求未指定输出长度限制时,自动提供 max_tokens: 4096,因为 Anthropic 要求必须设置这一字段。 |
| 推理力度 | 将 reasoning_effort 发送为 Anthropic 当前的深度控制字段 output_config.effort。minimal 映射为 Anthropic 的下限档位 low;none 则转为 thinking: {"type": "disabled"},因为 Anthropic 没有 none 这一档。其余情况下 AISIX 不会额外添加 thinking 块:请求要的是深度而不是思考模式,当前的 Anthropic 模型会采用自己的默认模式。取值不在上述集合内时该设置整体丢弃:它对应不到任何已知的 Anthropic 档位,而原字段本身也无法代为转发,因为 /v1/messages 会拒绝未知的顶层字段。请求自己携带的 output_config 或 thinking 保持原样,并优先于该转换。 |
当 OpenAI Chat Completions 消息使用带类型的内容部分时,Anthropic 转换会保留文本部分,但会丢弃图片和音频等非文本部分。如果必须将图片或文档内容发送到 Anthropic 上游,请使用 Anthropic 风格的 /v1/messages 路由。
如需了解完整的工具调用循环,请参阅工具调用。AISIX 还可以为符合条件的 Chat Completions 请求添加 Anthropic Prompt Cache 标记;请参阅 Anthropic Prompt Caching。
当应用必须保持 Anthropic 请求和响应格式,特别是使用服务提供方专属内容或 thinking blocks 时,请使用 Anthropic 风格的 /v1/messages 路由。有关原生客户端契约及其兼容性边界,请参阅 Anthropic 风格的 Messages API。
Token 用量
Anthropic 与 OpenAI 对 Prompt Cache Token 的计数方式不同,因此 AISIX 会转换这些计数,而不是原样透传。Anthropic 的 input_tokens 表示未命中缓存的输入,cache_creation_input_tokens 和 cache_read_input_tokens 是与之并列的独立计数器。OpenAI 的口径只有一个 prompt_tokens,它已经包含缓存命中的部分,并通过 prompt_tokens_details.cached_tokens 标明。OpenAI 完全没有缓存写入这一概念,因此 AISIX 把写入也折进 prompt_tokens(它属于计费输入),并与命中并列单独报告。
上游返回以下用量时:
{
"usage": {
"input_tokens": 40,
"output_tokens": 10,
"cache_creation_input_tokens": 30,
"cache_read_input_tokens": 70
}
}
兼容 OpenAI 的调用方会收到:
{
"usage": {
"prompt_tokens": 140,
"completion_tokens": 10,
"total_tokens": 150,
"prompt_tokens_details": {
"cached_tokens": 70,
"cache_creation_tokens": 30
}
}
}
调用方可以依赖以下规则:
prompt_tokens是模型读取的完整输入,包含缓存读取和缓存写入。total_tokens等于prompt_tokens + completion_tokens。cached_tokens是prompt_tokens的子集,只统计缓存读取。cache_creation_tokens是缓存写入,同样是prompt_tokens的子集。它属于计费输入但不是缓存命中,因此单独报告而不计入cached_tokens。OpenAI 没有缓存写入这一概念,所以该字段仅在上游报告了写入时出现——这一点很重要,因为服务提供方对写入的计费通常高于普通输入。在缓存会话的第一轮(只写不读)中,它是唯一能表明缓存参与了本次请求的信号。
流式响应,以及经由 Anthropic 上游的 Responses API,都适用同样的转换。
日志、指标和消费统计不做转换:它们保留 Anthropic 自身的计数器,因此同一次调用无论用哪种协议发起,成本都相同。记录侧的口径请参阅 Anthropic Prompt Caching。
下一步
你已经将兼容 OpenAI 的客户端路由到 Anthropic 上游。请参阅兼容 OpenAI 的 API了解面向调用方的路由行为。当你希望端到端使用 Anthropic 请求和响应结构时,请参阅 Anthropic Messages;如需了解端点与服务提供方支持边界,请查看服务提供方兼容性。