跳到正文

客户端接入与网关差异

本章讲两件事:各客户端怎么连上网关;连上之后,网关的行为和直连上游有什么不同。后者只讲你会观察到什么、怎么应对,不讲背后实现。

客户端接入

通用规则:把客户端的 base_url 指向网关,API key 填你在网关签发的访问密钥,模型名填你在网关配的名字。

OpenAI SDK(Python / Node)

text
base_url = http://<host>:7890/v1
api_key  = <你的访问密钥>

curl:

bash
curl http://localhost:7890/v1/chat/completions \
  -H "Authorization: Bearer <你的访问密钥>" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"hi"}]}'

Embeddings / Images / Audio / Rerank 同理,完整路径见 端点清单

Anthropic SDK

text
base_url = http://<host>:7890
api_key  = <你的访问密钥>   # 通过 x-api-key 头发送

curl:

bash
curl http://localhost:7890/v1/messages \
  -H "x-api-key: <你的访问密钥>" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet","max_tokens":1024,"messages":[{"role":"user","content":"hi"}]}'

Anthropic SDK 默认把路径拼成 /v1/messages,所以 base_url 填到根(不带 /v1)。

Google Gemini SDK

text
api_key  = <你的访问密钥>   # 通过 x-goog-api-key 头发送
base_url = http://<host>:7890

curl:

bash
curl "http://localhost:7890/v1beta/models/gemini-2.0-flash:generateContent" \
  -H "x-goog-api-key: <你的访问密钥>" \
  -H "Content-Type: application/json" \
  -d '{"contents":[{"parts":[{"text":"hi"}]}]}'

DashScope

两种接法:

  • 透传POST /v1/services/{*rest},请求体原样发给 DashScope 上游。
  • 翻译POST /v1/chat/completions,网关把 OpenAI 格式翻译成 DashScope 格式。

任意协议透传

当客户端协议与目标协议相同、你想完全绕过翻译时:

bash
curl http://localhost:7890/v3/<模型>/<任意后续路> \
  -H "Authorization: Bearer <你的访问密钥>" \
  -d '{ ...原样请求体... }'

/v3/{model}/{*rest} 把请求体原样转发到该模型配置的目标上游。

Cherry Studio 等第三方客户端

填法:

  • API 地址:http://<host>:7890/v1(OpenAI 兼容)
  • API Key:网关访问密钥
  • 模型:填网关里配的模型名

部分客户端按 model id 推断是否支持 function calling。若工具调用不生效,检查模型名是否落在客户端的能力识别规则内,或在客户端侧手动开启。

网关与原生 API 的差异

直连上游 vs 经网关,调用方会观察到这些不同。

长时间推理时收到 :keep-alive 注释行

流式请求中,如果上游推理时间较长,网关会周期性发送 SSE 注释行 :keep-alive 保持连接活跃,防止中间代理因空闲超时断开。

  • 这是 SSE 注释(以 : 开头),不是数据事件,SSE 客户端标准实现会自动忽略,无需特殊处理。
  • 如果你手写 SSE 解析,跳过以 : 开头的行即可。

上游流异常时收到 _gateway_warning 字段

当上游流在传输中途异常中断时,网关不会直接报错打断你的对话,而是:

  • 关闭尚未结束的内容块;

  • 在 SSE 流里插入一个 _gateway_warning 扩展字段,告诉你中断原因(含 reason / detail / last_finish_reason / timestamp);

  • 发送正常的终止序列,让客户端能正常收尾。

  • _gateway_warning 是网关的协议扩展字段(带下划线前缀)。解析流时如果看到它,说明这次响应中途出了问题,可据此记录或告警。

  • 设计目的是避免 Claude Code 这类客户端因流异常而中断整段对话。

错误码与重试

经网关时你会遇到这些状态码(完整速查见 错误码):

状态码含义你的处理
429被限流(每密钥/每 IP/上游)Retry-After 头等待后重试;无该头则按响应体提示
503服务过载/不可用/并发达上限退避后重试
504超时退避后重试
502上游故障网关通常已自动故障转移到其他节点;持续 502 检查上游配置

429 响应体有两种格式:每密钥限流返回纯文本Rate limit exceeded (N requests per Ns). Retry after Ns),每 IP 限流和上游限流返回 JSON。解析 429 时要兼容纯文本与 JSON 两种体。

上游故障时自动转移到其他节点

如果你的模型配了负载均衡(见 负载均衡字段),上游某节点故障时,网关会自动把请求重试到其他节点。你会观察到:

  • 响应可能来自不同于上一次的节点(正常现象)。
  • 如果所有节点都不可用,返回 503。

单上游(非负载均衡)不会跨节点转移,上游故障直接返回 502。

跨协议工具调用

当客户端协议和上游协议不同、且请求带工具调用时:

  • 网关自动翻译 tools / tool_choice / tool_calls 等字段。
  • tool_call_id 在跨协议往返中必须保留原值——你在多轮工具对话里回传的 tool_call_id 要和网关给你的完全一致,否则上游无法匹配。
  • Anthropic 面向客户端:响应里的 tool_use id 由网关合成为全局唯一的 toolu_ id(不透传上游原始 id),客户端原样回显即可。
  • Anthropic 面向客户端:请求历史里的 tool_use id 必须全局唯一,重复时网关回 400 invalid_request_errortool_use ids must be unique),与 Anthropic 官方 API 一致。
  • 流式工具调用期间,网关持续转发增量片段,保证长工具调用时始终有事件流动。

常见问题

Q:客户端报「stream 超时」或连接断开? 检查客户端和网关之间是否有反向代理,其空闲超时是否短于网关 keep-alive 间隔。调大反代超时,或调小 STREAMING_KEEPALIVE_SECONDS(默认 15 秒)。

Q:响应里混进了 _gateway_warning,是上游返回的吗? 不是,是网关加的。说明上游流中途断了。看里面的 reason/detail 判断是否需重试。

Q:流式请求被全局并发限制挡了,返回 503? 网关有全局并发上限。高峰期短暂 503 属正常,退避重试即可。如需调高上限联系管理员。

下一步:管理员从 控制台登录与角色 开始;查错误码看 错误码;查协议对支持看 协议互通矩阵