文档简介#
云智API 是统一的大模型中转网关,将 OpenAI、Anthropic(Claude)、Google(Gemini)三大主流协议收敛到同一入口。你只需一套 API Key 与一个 Base URL,即可调用平台内的全部文本、图像、音频、视频、向量模型,无需为每家厂商单独对接、单独维护密钥与计费体系。
网关对外暴露三套完全兼容的原生协议:OpenAI 兼容接口、Anthropic 兼容接口与 Gemini 兼容接口。任何支持自定义 Base URL 与 API Key 的客户端、SDK 或应用,都可以无缝接入;网关内部统一转换为 OpenAI 格式后转发至对应上游渠道,并按请求协议还原响应格式。
8.0,最近核对日期 2026-07-27。设计目标
- 统一入口:一个 Base URL、一套
sk-密钥覆盖三大协议族,消除多厂商密钥、账单与运维的碎片化。 - 原生兼容:请求与响应严格对齐官方协议字段,官方 SDK、CLI 工具与开源生态零改造接入。
- 资金安全:预扣—结算—失败全退的闭环计费,叠加幂等防重与断点续传,杜绝重复扣费。
- 链路可靠:熔断保护、指数退避重试、低速检测与全链路
request_id追踪,支撑生产级可用性。 - 可观测性:每次调用留存模型、token 用量、费用与状态审计记录,支持逐条对账与成本归因。
请求处理流程
- 协议接入:接收 OpenAI / Anthropic / Gemini 任一协议的请求,完成 CORS 预检与头部解析。
- 鉴权与风控:提取 API Key(支持五种传递方式),依次执行滑动窗口限流、密钥校验与余额预检。
- 协议规范化:将 Anthropic / Gemini / Responses 请求统一转换为内部 OpenAI 格式,执行参数校验与数值钳制。
- 幂等保护:基于
X-Idempotency-Key等键值去重,命中缓存直接回放结果。 - 模型路由:按模型名匹配登记模型,解析出上游渠道与后端模型名,完成余额预扣。
- 上游转发:以熔断器保护的方式调用上游,支持自动重试与流式传输。
- 响应还原:按客户端协议还原响应格式(含 SSE 事件序列),结算计费并写入审计日志。
协议族总览
| 协议族 | 代表端点 | 适用场景 |
|---|---|---|
| OpenAI 兼容 | /v1/chat/completions、/v1/responses、/v1/images/*、/v1/audio/* |
绝大多数客户端、SDK 与应用 |
| Anthropic 兼容 | /v1/messages、/v1/messages/count_tokens |
Claude Code 及 Anthropic 生态工具 |
| Gemini 兼容 | /v1beta/models/{model}:generateContent 等 |
Google 生态 SDK 与 Gemini 客户端 |
能力矩阵
Chat Completions、Responses、Messages、generateContent 四协议互通,支持流式、工具调用、结构化输出与推理模型。
文生图、图像编辑、图像变体与 Imagen predict,也可通过聊天接口以对话方式生成。
文本转语音、语音转文字、语音翻译,音频二进制与 JSON 响应原样透传。
同步生成、Sora 风格异步任务与 Veo predictLongRunning 三种接入方式。
Embeddings 文本向量化,支持批量输入与自定义维度,按输入 token 计费。
幂等防重、断点续传、熔断保护、token 预估计数、内容审核与全链路 request_id 追踪。
核心优势
| 能力 | 说明 | 对应章节 |
|---|---|---|
| 三协议互通 | 同一模型可同时被 OpenAI / Anthropic / Gemini 协议调用,响应自动还原为请求方格式 | 各协议端点章节 |
| 智能路由容错 | 前缀剥离、大小写不敏感、后缀模糊匹配,未命中时返回 did_you_mean 拼写建议 | 模型与路由 |
| 幂等防重扣费 | 基于 X-Idempotency-Key 的请求去重与结果回放,网络重试不产生新费用 | 幂等重试 |
| 流式断点续传 | 凭 X-Resume-Token 从断点恢复 SSE 事件流,已生成内容不丢失、不重复计费 | 断点续传 |
| 熔断与退避 | 上游连续失败自动熔断,辅助通道指数退避重试,保护整体可用性 | 错误映射 |
| 失败全额退费 | 任何 4xx/5xx 失败路径预扣金额原路退还,客户端重试零成本 | 计费说明 |
适用场景
- AI 应用统一后端:业务侧只对接一套协议,模型切换与扩容在网关侧完成,前端无感知。
- Agent 与编程助手:Claude Code、Codex CLI、Cline 等工具直接指向网关,按需切换底层模型。
- RAG 与知识库:Embeddings 批量向量化与聊天补全组合调用,按 token 精确计费。
- 内容生成流水线:图像、语音、视频多模态生成统一结算,异步任务轮询开箱即用。
- 多模型评测与灰度:同一请求体更换
model字段即可横向对比不同厂商模型的效果与成本。
环境与版本信息
| 项目 | 说明 |
|---|---|
| 网关版本 | 8.0(本文档最近核对日期 2026-07-27) |
| 传输协议 | HTTPS(TLS 1.2 及以上),明文 HTTP 请求将被拒绝 |
| 数据格式 | UTF-8 编码 JSON;文件与音频类接口使用 multipart/form-data 或二进制流 |
| 时区与时间戳 | 所有时间字段均为 UTC Unix 时间戳(秒) |
| 金额精度 | 8 位小数,单位为元 |
阅读指引
- 首次接入:按「快速开始」→「入口与鉴权」→「模型与路由」→ 对应协议端点的顺序阅读。
- 排障:先查「故障排查」与「错误码总表」,再对照「速率限制」与「计费说明」确认账户状态。
- 客户端配置:直接跳转「应用配置」分组,按软件名称查看步骤;SDK 开发查看「SDK 集成」分组。
- 生产上线:务必阅读「幂等重试」「流式输出」「断点续传」三章,构建可靠的调用链路。
快速开始#
接入步骤
- 登录 用户中心,创建并复制以
sk-开头的 API Key。 - 确认账户余额不低于最低预检额度
0.01,余额不足时请求会在预检阶段被拒绝并返回 HTTP 402。 - 选择一个接入协议(推荐 OpenAI 兼容),将 Base URL 指向本站点。
- 通过
GET https://yunzhiapi.cn/v1/models拉取当前可用模型列表,选择模型名填入请求的model字段。 - 发送第一个聊天请求验证连通性。
第一个请求(cURL)
curl https://yunzhiapi.cn/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-你的密钥" \
-d '{
"model": "你的模型名",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
],
"stream": false
}'
第一个请求(Python)
from openai import OpenAI
client = OpenAI(
base_url="https://yunzhiapi.cn/v1",
api_key="sk-你的密钥",
)
resp = client.chat.completions.create(
model="你的模型名",
messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)
第一个请求(Node.js)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://yunzhiapi.cn/v1",
apiKey: "sk-你的密钥",
});
const resp = await client.chat.completions.create({
model: "你的模型名",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(resp.choices[0].message.content);
验证连通性
返回 200 且包含 choices 数组即表示接入成功;响应头中的 X-Request-ID 是本次请求的追踪标识,排查问题时请一并提供。也可以先访问无需鉴权的 GET https://yunzhiapi.cn/health 确认网关在线。
响应关键字段解读
| 字段 | 位置 | 含义 |
|---|---|---|
choices[0].message.content | 响应体 | 模型回复正文 |
finish_reason | 响应体 | 结束原因:stop 正常结束、length 达到长度上限、tool_calls 需要调用工具 |
usage.prompt_tokens / completion_tokens | 响应体 | 输入 / 输出 token 数,是计费与对账的依据 |
model | 响应体 | 回填为你请求时使用的展示名,而非上游后端名 |
X-Request-ID | 响应头 | 全链路追踪标识,与审计日志一一对应 |
首次接入常见错误
| 现象 | 原因 | 处理 |
|---|---|---|
HTTP 401 / YZ1001 |
请求未携带任何鉴权头 | 补充 Authorization / x-api-key / x-goog-api-key 任一头部 |
HTTP 401 / YZ1002 |
密钥拼写错误或已重置 | 回用户中心重新复制完整密钥 |
HTTP 402 / YZ2001 |
余额低于最低预检额度 0.01 | 充值后立即恢复 |
HTTP 404 / YZ4001 |
模型名拼写错误或路径不对 | 用 GET /v1/models 核对模型名,检查 Base URL 是否少带 /v1 |
HTTP 429 / YZ1003 |
触发 60 秒 120 次限流 | 按 Retry-After 响应头退避重试 |
下一步建议
- 生产环境务必接入「幂等重试」,为每个逻辑请求携带唯一
X-Idempotency-Key,防止重复扣费。 - 对话类产品建议开启「流式输出」,并实现「断点续传」以应对网络抖动。
- 阅读「计费说明」了解预扣与结算规则,在用户中心定期核对用量明细。
- 使用现成客户端(Claude Code、NextChat、Dify 等)可直接跳转「应用配置」分组。
入口与鉴权#
统一入口
https://yunzhiapi.cn所有接口的统一入口三套协议共享同一个域名入口,仅路径与鉴权头不同:OpenAI 协议使用 /v1 前缀,Anthropic 协议使用 /v1/messages,Gemini 协议使用 /v1beta 前缀。路径写错最常见的表现是所有请求返回 404。
密钥格式规范
API Key 必须以 sk- 开头,后跟不少于 16 位字母、数字、下划线或短横线(完整匹配规则 sk-[a-zA-Z0-9_-]{16,}),不符合格式的密钥在网关入口即被视为未提供。
| 密钥形态 | 示例 | 校验结果 |
|---|---|---|
| 合法格式 | sk-Ab3xK9_mQ2pL7wRt | 通过格式校验,继续验证有效性 |
| 缺少 sk- 前缀 | Ab3xK9_mQ2pL7wRt | 视为未携带密钥,返回 401 YZ1001 |
| 前缀后长度不足 16 位 | sk-12345 | 视为未携带密钥,返回 401 YZ1001 |
| 混入空格或换行 | sk-Ab3xK9... (尾部空格) | 格式校验失败或密钥无效 |
| 格式合法但内容错误 | sk-xxxxxxxxxxxxxxxx | 返回 401 YZ1002(密钥无效) |
五种传递方式
网关支持以下五种鉴权传递方式,按表中顺序依次探测,任一方式命中即可:
| 优先级 | 传递方式 | 示例 | 适用协议 |
|---|---|---|---|
| 1 | Authorization: Bearer sk-...(也接受裸 sk-... 值) |
Authorization: Bearer sk-abc123... |
OpenAI / Responses / 通用 |
| 2 | x-goog-api-key 请求头 |
x-goog-api-key: sk-abc123... |
Gemini SDK 默认方式 |
| 3 | anthropic-api-key 请求头 |
anthropic-api-key: sk-abc123... |
Anthropic 生态部分客户端 |
| 4 | x-api-key / api-key 请求头 |
x-api-key: sk-abc123... |
Anthropic SDK 默认方式 |
| 5 | 查询参数 key |
?key=sk-abc123... |
Gemini 浏览器直链等场景 |
同时携带多个鉴权头时,按上表优先级取第一个命中的值,其余忽略;为避免歧义,建议每个请求只携带一种鉴权信息。
各协议鉴权示例
curl https://yunzhiapi.cn/v1/models \ -H "Authorization: Bearer sk-你的密钥"
curl https://yunzhiapi.cn/v1/messages \
-H "x-api-key: sk-你的密钥" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{"model":"你的模型名","max_tokens":64,"messages":[{"role":"user","content":"Hi"}]}'
curl "https://yunzhiapi.cn/v1beta/models/你的模型名:generateContent" \
-H "x-goog-api-key: sk-你的密钥" \
-H "Content-Type: application/json" \
-d '{"contents":[{"role":"user","parts":[{"text":"Hi"}]}]}'
鉴权失败与安全建议
- 未携带密钥返回
401 YZ1001;密钥不存在或已失效返回401 YZ1002,错误体附hint修复建议。 - 密钥通过校验后还会执行余额预检,余额低于
0.01返回402 YZ2001。 - 请勿将密钥提交到公共仓库或前端页面源码中;泄露后应立即在用户中心重置。
- 服务端到服务端调用优先使用
Authorization: Bearer;浏览器端 Gemini 直链场景可使用?key=查询参数(网关 CORS 已放行)。 - 密钥仅在其所属账户范围内有效,无法跨账户访问其他用户的文件与任务资源。
密钥泄露应急流程
- 立即重置:在用户中心密钥管理页重置泄露密钥,旧密钥即时失效。
- 审计用量:查看用量明细中最近 24 小时的调用记录,确认是否存在异常模型或异常高频调用。
- 全量替换:更新所有部署位置(环境变量、配置文件、密钥管理服务),避免遗漏导致服务中断。
- 定期轮换:生产环境建议每 90 天轮换一次密钥,轮换时先新增后删除,保证平滑过渡。
请求响应头#
请求头一览
| 请求头 | 必填 | 说明 |
|---|---|---|
Content-Type: application/json |
必填 | JSON 请求必须携带;文件上传类接口使用 multipart/form-data(边界由客户端自动生成) |
Authorization / x-api-key / x-goog-api-key / anthropic-api-key |
必填 | 任选一种鉴权方式,详见「入口与鉴权」 |
anthropic-version: 2023-06-01 |
建议 | Anthropic 协议请求建议附加,网关据此识别协议类型,CORS 已放行该头部及 anthropic-beta |
X-Idempotency-Key |
可选 | 幂等键,防止网络重试导致的重复扣费,详见「幂等重试」 |
X-Request-Id |
可选 | 请求追踪 ID,同时作为幂等键的第二优先级来源;未提供时由网关自动生成 UUID v4 |
X-Resume-Token / Last-Event-ID |
可选 | 流式断点续传令牌,二者等价,也可使用 ?last_event_id= 查询参数,详见「断点续传」 |
openai-organization / openai-project / openai-beta |
可选 | OpenAI SDK 自动附加的头部,网关 CORS 已放行,不参与业务逻辑 |
响应头一览
| 响应头 | 出现时机 | 说明 |
|---|---|---|
X-Request-ID |
所有响应(含错误) | 网关生成的 UUID v4 追踪标识,与错误体中的 request_id 一致,并会转发给上游 |
X-Idempotency-Hit: true |
命中幂等缓存时 | 表示本次响应为首次请求结果的回放,未产生新的计费 |
X-Resume-Token |
流式响应 | 断点续传令牌(rst_ + 32 位十六进制),断线后凭它恢复流 |
Retry-After |
HTTP 429 | 建议的等待秒数:限流时为 60;幂等请求处理中时为剩余锁定时长 |
X-Accel-Buffering: no |
流式响应 | 指示 Nginx 等反向代理不要缓冲事件流 |
X-Content-Type-Options: nosniff |
所有响应 | 安全加固头部,禁止 MIME 嗅探 |
追踪标识说明
X-Request-ID: 3f6b2f34-8a1c-4d2e-9f7b-6c5a4b3d2e1f
X-Request-ID 贯穿请求全生命周期:出现在所有响应头(含错误响应)、错误体的 request_id 字段、用量审计记录以及转发给上游的请求中。客户端未显式提供 X-Request-Id 请求头时由网关自动生成 UUID v4。排查任何问题时,请优先向客服提供该标识。
跨域支持
网关已完整支持浏览器跨域调用(CORS):所有响应携带 Access-Control-Allow-Origin: * 与 Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS;OPTIONS 预检请求返回 204 并附 Access-Control-Max-Age: 86400。放行的自定义头部包括 Authorization、Content-Type、X-API-Key、X-Request-Id、X-Idempotency-Key、X-Resume-Token、Last-Event-ID、anthropic-version、anthropic-beta、anthropic-dangerous-direct-browser-access、x-goog-api-key、openai-organization、openai-project、openai-beta、x-stainless-* 系列、x-title、http-referer 等,前端页面与官方 SDK 可直接发起请求。
代理与缓冲注意事项
- 自建 Nginx / Ingress 需透传
X-Accel-Buffering: no响应头,并对text/event-stream关闭proxy_buffering与 gzip 压缩,否则流式事件会被攒批延迟下发。 - CDN 与云负载均衡上,请对
/v1与/v1beta路径关闭响应缓存(POST 请求本身不缓存,但需避免错误响应被缓存)。 - 中间代理改写或丢弃鉴权头(尤其是
Authorization)是 401 问题的常见诱因,排查时可在网关侧日志确认实际收到的头部。
模型与路由#
模型名来源
可用模型由平台运营方在后台登记并实时生效(列表缓存 30 秒),每个模型包含对外展示名(display_name)与上游后端名(backend_name)。请求时填写展示名即可,网关转发上游时会自动替换为后端名,响应中的 model 字段始终回填为你请求的展示名。完整列表通过 GET /v1/models 或模型广场页面获取。
名称匹配规则
网关按以下顺序依次尝试匹配,全部不命中才返回 404:
- 前缀剥离匹配:自动去除
models/、publishers/<厂商>/models/、openai/、anthropic/、google/、gemini/、claude/等渠道前缀后,按小写精确匹配。 - 原名精确匹配:不剥离前缀的原始名称按小写精确匹配(大小写不敏感)。
- 后缀模糊匹配:请求名与登记名互为后缀时命中,例如登记名为
gpt-4o-2024-08-06时请求gpt-4o也可命中(存在多个候选时以先登记者为准,建议始终使用完整展示名)。
匹配示例
| 请求模型名 | 匹配结果 |
|---|---|
gpt-4o | 精确命中 gpt-4o |
models/gemini-2.5-pro | 剥离 models/ 前缀后命中 |
publishers/google/models/gemini-2.5-pro | 剥离渠道前缀后命中 |
GPT-4O | 大小写不敏感,命中 gpt-4o |
claude-sonnet-4 | 后缀模糊命中(多候选时取先登记者) |
gpt-4o-mini-x | 未命中,返回 404 并附 did_you_mean 建议 |
匹配失败与拼写建议
模型名未命中时返回 HTTP 404 与错误码 YZ4001,错误体附 requested_model 与 did_you_mean 字段(最多 3 个相似模型名,按编辑距离与包含关系选出),可据此自动纠正或提示用户。
{
"error": {
"message": "Model `gpt-4o-mini-x` not found.",
"type": "not_found_error",
"param": null,
"code": "YZ4001",
"request_id": "3f6b2f34-....",
"requested_model": "gpt-4o-mini-x",
"did_you_mean": ["gpt-4o-mini", "gpt-4o"],
"hint": "Check the model name spelling or GET /v1/models for the available list."
}
}
按能力分流
模型登记时带有能力分类:普通聊天与代码模型走标准对话管线;image(图像)、tts(语音合成)、video(视频)分类的模型即使通过 /v1/chat/completions 等对话端点调用,也会被自动分流到对应的生成管线——网关提取最后一条 user 消息文本作为 prompt,并把生成结果包装成所选协议的标准响应返回。模型未绑定上游渠道时返回 500 YZ4002,请凭 request_id 联系客服。
路由最佳实践
- 始终使用
GET /v1/models返回的完整展示名,避免依赖后缀模糊匹配命中非预期模型。 - 客户端启动时拉取一次模型列表并本地缓存 5~10 分钟,既降低延迟又避免高频调用触发限流。
- 收到
YZ4001时优先读取did_you_mean自动纠正,而不是直接向用户抛出原始错误。 - 模型下线或更名会在列表接口实时反映,建议对 404 做降级处理(自动切换到同能力备选模型)。
速率限制#
限制规则
网关对每个 API Key 实施滑动窗口限流:
- 窗口大小:60 秒滚动窗口
- 窗口内最大请求数:120 次
- 超限响应:HTTP
429,错误码YZ1003,错误类型rate_limit_error,并携带Retry-After: 60响应头
滑动窗口按请求到达时刻动态计算:任意连续 60 秒内累计达到 120 次后,第 121 次被拒绝;随着最早的请求滑出窗口,额度逐步恢复,无需等待整分钟边界。限流按密钥维度统计,同一账户下多个密钥互不影响;GET /v1/models、count_tokens 等免费接口同样计入限流窗口。
其他 429 场景
| 场景 | 错误码 | 说明 |
|---|---|---|
| 触发密钥限流 | YZ1003 |
60 秒窗口内超过 120 次,Retry-After: 60 |
| 幂等请求处理中 | YZ3008 |
相同幂等键的请求仍在处理,Retry-After 为锁定剩余秒数(最长 180 秒) |
| 上游限流 | YZ1003 |
上游渠道返回 429 时原样映射,消息为 Upstream rate limit exceeded, please retry later. |
超限处理
客户端收到 429 后,必须先读取 Retry-After 响应头,在该秒数之后再重试。不同场景的 Retry-After 含义不同:密钥限流(YZ1003)固定为 60 秒;幂等请求冲突(YZ3008)为幂等锁剩余秒数(幂等锁最长 180 秒,返回值为 180 - 已等待秒数,最小 1 秒);上游限流(YZ1003)建议同样按指数退避处理。
- 退避策略:以
Retry-After为下限,在此之上做指数退避(如 2s → 4s → 8s → 16s),单次等待封顶 60 秒。 - 抖动(Jitter):在每次退避时间上叠加 0~1 秒的随机抖动,避免多客户端同时重试造成惊群。
- 最大重试次数:建议最多重试 5 次,超过后放弃本次请求并上报失败,不要无限重试。
- 幂等冲突场景:
YZ3008表示同一请求正在处理中,等待Retry-After后原样重发同一请求即可(可命中幂等缓存直接回放结果,不会重复扣费)。
async function requestWithRetry(url, options, maxRetries = 5) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const resp = await fetch(url, options);
if (resp.status !== 429) return resp;
const retryAfter = Number(resp.headers.get('Retry-After') || 0);
const backoff = Math.min(Math.pow(2, attempt + 1), 60);
const jitter = Math.random();
await new Promise(r => setTimeout(r, Math.max(retryAfter, backoff) * 1000 + jitter * 1000));
}
throw new Error('max retries exceeded');
}
并发控制建议
- 批量任务(评测、数据标注、内容批量生成)请使用连接池并将并发控制在 10~20 之间,为交互式请求预留额度。
- 多业务线共用一个密钥时,建议按业务拆分子密钥,避免单一业务耗尽窗口额度。
- 长耗时请求(视频生成、长文本推理)占用窗口时间长,建议异步化并降低轮询频率。
- 确需更高限额时,凭业务场景说明与近期
request_id联系客服申请提额。
request_id 与 hint 字段,持续超限可凭 request_id 联系客服申请提高限额。
计费说明#
计费模式
每个模型按登记的价格配置自动归属两种计费模式之一,所有金额按 8 位小数精度计算:
模型输入单价 input_price > 0 时生效。输入与输出分别计价:费用 = token 数 × 单价 ÷ 1,000,000(单价单位为元/百万 token),总费用为输入费用加输出费用之和。
模型输入单价 input_price = 0 时生效。每次成功请求固定收取 output_price 金额,与 token 数无关,常见于图像、语音、视频等生成类模型。
计费公式与示例
| 场景 | 计算过程 | 费用 |
|---|---|---|
| 按 token:输入 1,000 / 输出 500,单价 2 / 6 元每百万 | 1000 × 2 ÷ 1M + 500 × 6 ÷ 1M = 0.002 + 0.003 | 0.00500000 元 |
按次:图像生成 n=2,单价 0.5 元/次 | 0.5 × 2 | 1.00000000 元 |
| Embeddings:输入 800 token,单价 0.1 元每百万 | 800 × 0.1 ÷ 1M | 0.00008000 元 |
| 失败请求(任意 4xx/5xx) | 预扣金额全额退还 | 0 元 |
余额预检与预扣
请求在转发到上游之前会经过两道余额校验,确保余额真实可用:
- 最低余额预检:账户余额低于
0.01元时直接拒绝,返回402+YZ2001。 - 预估成本计算:按次计费模型预估成本 = 单次价格;按 token 计费模型预估成本 = 按请求文本估算的输入 token × 输入单价 ÷ 1,000,000 +
0.0001元。预估成本与0.01元取较大者作为预扣金额。 - 余额充足性校验:余额低于预扣金额时返回
402+YZ2001,消息中包含当前余额与预估金额。 - 预扣:通过数据库行级锁(
FOR UPDATE)从余额中预先扣减该金额;并发扣款冲突或失败时返回402+YZ2002,稍等几秒重试即可。
结算与失败退费
- 多退:请求成功后按实际 token 用量(或单次价格)结算。预扣金额大于实际费用时,差额自动退还(差额小于
0.00000001元的零头忽略)。 - 少补:实际费用超过预扣金额时,超出部分从余额补扣;补扣不会把余额扣成负数,余额不足时最多扣到 0 为止。
- 失败全退:上游超时、连接失败、返回错误、无内容等任何失败路径,预扣金额全额退还,不产生任何费用。
- 结算可靠性:结算事务最多自动重试 3 次(退避 100/200/300 毫秒);仍失败时全额退还预扣并记录日志,不会多扣用户余额。
- 审计:每次结算都会写入用量审计记录(模型、输入/输出 token、实际费用、预扣金额、差额),用于账单对账。
查询用量与余额
- 单次请求用量:非流式响应的
usage字段包含prompt_tokens与completion_tokens;流式响应的 usage 会随流末尾的 chunk 下发(服务端已强制开启stream_options.include_usage)。 - 账户余额与账单:登录本站后台可查看当前余额、充值记录与逐条用量明细(含每次请求的模型、token 数与扣费金额),用量明细与网关审计记录逐条对应,可据此对账。
计费与流式请求
流式请求(stream: true)与非流式请求采用完全相同的预扣-结算流程,费用不因流式而增加。需要注意两点:上游未返回 usage 时,输入 token 按请求文本估算、输出 token 按流式增量文本估算(至少按 1 计);客户端中途断开连接不视为失败,已产出的内容正常结算,因此主动中断流时请确认是否需要完整结果。
对账建议
- 客户端持久化每次响应的
X-Request-ID、model与usage,作为与平台账单逐条比对的主键。 - 命中幂等缓存的请求(
X-Idempotency-Hit: true)不产生新计费,对账时应与首次请求合并看待。 - 发现金额异常时,请提供对应
request_id与账单时间段,客服可在审计日志中还原完整计费过程。
0.01 元时所有生成类请求都会被拒绝(402 + YZ2001),请及时充值;预扣失败(YZ2002)多为高并发下的扣款冲突,稍后重试即可,不会造成重复扣费。
错误码总表#
所有错误响应均为 JSON 格式,包含 message(错误描述)、type(错误类型)、code(YZ 错误码)、request_id(请求追踪 ID),多数错误附带 hint 修复建议。错误响应结构会按协议自动适配 OpenAI / Anthropic / Gemini 三种格式。排查问题时请优先提供 request_id。
错误响应结构(OpenAI 格式)
{
"error": {
"message": "Insufficient balance.",
"type": "insufficient_quota_error",
"param": null,
"code": "YZ2001",
"request_id": "3f6b2f34-....",
"hint": "Recharge your account and retry."
}
}
错误响应结构(Anthropic 格式)
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "Insufficient balance. (code: YZ2001, request_id: 3f6b2f34-....)"
}
}
错误响应结构(Gemini 格式)
{
"error": {
"code": 402,
"message": "Insufficient balance. (code: YZ2001, request_id: 3f6b2f34-....)",
"status": "RESOURCE_EXHAUSTED"
}
}
错误码明细
| 错误码 | HTTP 状态 | 类型 | 含义 | 处理建议 |
|---|---|---|---|---|
YZ1001 |
401 | authentication_error |
缺少 API Key | 在 Authorization: Bearer sk-...、X-API-Key、x-goog-api-key 或 anthropic-api-key 头中携带密钥 |
YZ1002 |
401 | authentication_error |
API Key 无效或已停用 | 核对密钥是否正确且处于启用状态,疑似泄露请重新生成 |
YZ1003 |
429 | rate_limit_error |
触发限流(密钥限流或上游限流) | 按 Retry-After 降低请求频率后重试,或联系客服提升限额 |
YZ1004 |
403 | authentication_error |
密钥被禁用或无权访问该资源 | 确认账户与密钥状态,必要时联系客服 |
YZ2001 |
402 | insufficient_quota_error |
余额不足(低于 0.01 元预检线或不足以覆盖预估成本) | 充值后重试,错误消息中含当前余额与预估金额 |
YZ2002 |
402 | insufficient_quota_error |
余额预扣失败(并发扣款冲突) | 稍等几秒后重试,不会重复扣费 |
YZ2003 |
500 | api_error |
计费结算失败(内部错误) | 系统会自动全额退还预扣金额,仍异常请凭 request_id 联系客服 |
YZ3001 |
400 | invalid_request_error |
请求体为空 | 提供非空的 JSON 请求体 |
YZ3002 |
400 | invalid_request_error |
请求体不是合法 JSON | 检查 JSON 语法与 Content-Type: application/json 头 |
YZ3003 |
413 | invalid_request_error |
请求体超过大小限制 | 减小请求负载或拆分为多个请求 |
YZ3004 |
400 | invalid_request_error |
缺少 model 字段 |
指定模型名(如 gpt-4o、claude-3-5-sonnet、gemini-1.5-pro) |
YZ3005 |
400 | invalid_request_error |
缺少 messages 数组 |
提供非空的 messages 数组(含 role/content 对象) |
YZ3006 |
400 | invalid_request_error |
缺少其他必填参数 | 按响应 param 字段指明的参数名补齐 |
YZ3007 |
400 | invalid_request_error |
参数超出合法范围(含上游 422 映射) | 按文档将参数调整到合法范围 |
YZ3008 |
409 / 429 | invalid_request_error / rate_limit_error |
幂等键冲突:同一 X-Idempotency-Key 用于不同请求,或相同请求仍在处理中 |
为每个不同请求使用唯一幂等键;请求处理中时按 Retry-After 等待后原样重发 |
YZ4001 |
404 | not_found_error |
模型不存在(含上游 404 映射) | 核对模型名拼写,或调用 GET /v1/models 获取可用列表;响应可能附带 did_you_mean 建议 |
YZ4002 |
500 | api_error |
模型未绑定上游端点 | 凭 request_id 联系客服处理 |
YZ5001 |
502 / 504 | api_error |
上游响应超时(含上游网关超时) | 缩短 prompt 或 max_tokens 后重试,持续出现请联系客服 |
YZ5002 |
502 | api_error |
无法连接上游服务 | 指数退避重试,上游可能暂时不可达 |
YZ5003 |
502 | api_error |
上游域名解析失败 | 稍后重试 |
YZ5004 |
502 | api_error |
上游 TLS 握手失败 | 重试,持续出现请联系客服 |
YZ5005 |
400 / 502 / 503 | api_error |
上游返回 HTTP 错误(消息中附带上游错误描述) | 稍等片刻后重试 |
YZ5006 |
502 | api_error |
上游未返回任何数据 | 重试或联系客服 |
YZ5007 |
502 | api_error |
上游返回非 JSON 响应 | 重试或联系客服 |
YZ5008 |
503 | api_error |
上游熔断器开启(连续失败触发保护) | 稍作延迟后重试 |
YZ9001 |
500 | api_error |
网关内部错误 | 重试请求,持续出现请凭 request_id 联系客服 |
YZ9002 |
500 | api_error |
数据库暂时不可用 | 稍后重试 |
YZ9003 |
500 | api_error |
响应序列化失败 | 简化请求内容后重试 |
错误处理最佳实践
- 4xx 错误(除 429 外)属于请求本身的问题,修正前重试没有意义;应解析
message与hint自动修复或提示用户。 - 429 必须按
Retry-After等待,并叠加指数退避与随机抖动,重试时保持幂等键不变。 - 5xx 与网络错误属于临时性故障,使用固定幂等键指数退避重试,最多 5 次后放弃并告警。
- 将
request_id、错误码与时间戳写入业务日志,便于与平台审计记录交叉定位。
YZ5xxx 与 YZ9xxx 类错误多为临时性故障,建议采用指数退避策略重试。
聊天补全 Chat Completions#
聊天补全是本平台最核心的接口,与 OpenAI Chat Completions API 完全兼容,适用于对话助手、代码生成、文案写作、多模态理解(图片/音频输入)、函数调用(Function Calling)等场景。请求经统一入口处理:鉴权与限流、余额预检与预扣、参数规范化与钳制、幂等去重,然后转发至模型对应的上游端点,响应统一规整为 OpenAI 格式返回。
/v1/chat/completions请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 必填 | 模型 ID。自动去除首尾空白,长度不超过 256 字符且不得含控制字符;模型不存在时返回 404,并附 did_you_mean 相似模型建议 |
messages | array | 必填 | 对话消息数组,最多 1000 条,超过返回 400。每条必须为对象且含 role;合法角色:system、user、assistant、tool、function、developer;model/bot/ai 自动转为 assistant,human 转为 user,非法角色整条丢弃。content 支持字符串或多段数组(text、image_url、input_audio 等) |
stream | boolean | 可选 | 是否流式输出,默认 false。非布尔值时字符串 "true"/"1"/"yes"/"on"(不区分大小写)视为开启 |
temperature | number | 可选 | 采样温度,默认 1,取值会被钳制到 [0.0, 2.0] |
top_p | number | 可选 | 核采样概率,默认 1,取值会被钳制到 [0.0, 1.0] |
max_tokens | integer | 可选 | 最大输出 token 数,小于 1 时按 1 处理 |
max_completion_tokens | integer | 可选 | 新版最大输出 token 数(含推理 token),小于 1 时按 1 处理 |
n | integer | 可选 | 每个请求生成的候选数,默认 1,钳制到 [1, 10] |
stop | string | array | 可选 | 停止序列。字符串自动转为单元素数组;数组形式会将各元素转为字符串并过滤空值 |
presence_penalty | number | 可选 | 存在惩罚,默认 0,钳制到 [-2.0, 2.0] |
frequency_penalty | number | 可选 | 频率惩罚,默认 0,钳制到 [-2.0, 2.0] |
seed | integer | 可选 | 随机种子,强制转为整数,用于可复现采样 |
logprobs | boolean | 可选 | 是否返回对数概率,强制转为布尔值 |
top_logprobs | integer | 可选 | 每个 token 返回的候选对数概率条数,钳制到 [0, 20],需配合 logprobs=true |
tools | array | 可选 | 工具定义数组,上限 128 个。function 类型要求 function.name 为非空字符串,否则该工具被丢弃;缺省 description 补空串、缺省 parameters 补 {"type":"object","properties":{}}、缺省 strict 补 false |
tool_choice | string | object | 可选 | 工具调用策略:auto/none/required 或指定函数对象 |
response_format | object | 可选 | 输出格式:{"type":"text"}(默认)、{"type":"json_object"} 或 {"type":"json_schema","json_schema":{...}};字符串形式自动包装为 {"type": 原值} |
reasoning_effort | string | 可选 | 推理强度(如 low/medium/high)。传入 reasoning.effort 对象形式时会自动提取为 reasoning_effort |
user | string | 可选 | 终端用户标识,原样透传上游 |
参数钳制规则
| 参数 | 合法范围 | 越界处理 |
|---|---|---|
temperature | [0.0, 2.0] | 静默钳制到边界值,不报错 |
top_p | [0.0, 1.0] | 静默钳制 |
presence_penalty / frequency_penalty | [-2.0, 2.0] | 静默钳制 |
n | [1, 10] | 静默钳制 |
top_logprobs | [0, 20] | 静默钳制 |
max_tokens / max_completion_tokens | ≥ 1 | 小于 1 按 1 处理 |
messages 条数 | ≤ 1000 | 超出返回 400 |
tools 数量 | ≤ 128 | 超出部分丢弃 |
请求示例
curl "https://yunzhiapi.cn/v1/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "system", "content": "你是一个乐于助人的助手。"},
{"role": "user", "content": "你好,请介绍一下你自己。"}
],
"temperature": 0.7,
"max_tokens": 1024,
"stream": false
}'
多模态输入示例
curl "https://yunzhiapi.cn/v1/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "描述这张图片的内容"},
{"type": "image_url", "image_url": {"url": "https://example.com/photo.png", "detail": "auto"}}
]
}
]
}'
图片支持公网 URL 与 data:image/png;base64,... 两种写法,detail 可选 auto/low/high;音频输入使用 input_audio 块(data + format)。多模态内容按 base64 解码后的原文估算 token 并计费。
函数调用示例
curl "https://yunzhiapi.cn/v1/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "北京今天天气怎么样?"}],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市的实时天气",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
],
"tool_choice": "auto"
}'
模型决定调用工具时,finish_reason 为 tool_calls,参数位于 message.tool_calls[].function.arguments(JSON 字符串)。执行完函数后,将结果以 role: "tool" 消息(携带对应 tool_call_id)追加到 messages 再次请求,即可完成闭环。
结构化输出示例
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "user_profile",
"strict": false,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"]
}
}
}
轻量场景可使用 {"type":"json_object"}(需在提示词中明确要求 JSON 输出);强约束场景使用 json_schema,网关缺省补 strict: false 以兼容更多模型。
响应示例
{
"id": "chatcmpl-9f8e7d6c5b4a",
"object": "chat.completion",
"created": 1710000000,
"model": "gpt-4o",
"service_tier": "default",
"system_fingerprint": "fp_3a2b1c9d",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "你好!我是一个 AI 助手,可以回答问题、协助写作和编程等。",
"refusal": null
},
"finish_reason": "stop",
"logprobs": null
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 18,
"total_tokens": 42,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
}
}
平台会自动补全 id、object、created、service_tier(默认 default)、system_fingerprint 字段;finish_reason 缺失时补 stop;上游未返回 usage 时按本地估算补全。
流式变体
设置 "stream": true 后以 SSE(text/event-stream)返回 chat.completion.chunk 增量块,每个 chunk 同样补全 model/id/created/service_tier/system_fingerprint 字段,且不含 usage,最后以 data: [DONE] 结束:
data: {"id":"chatcmpl-9f8e7d6c5b4a","object":"chat.completion.chunk","created":1710000000,"model":"gpt-4o","service_tier":"default","system_fingerprint":"fp_3a2b1c9d","choices":[{"index":0,"delta":{"role":"assistant","content":"你好","refusal":null},"finish_reason":null,"logprobs":null}]}
data: {"id":"chatcmpl-9f8e7d6c5b4a","object":"chat.completion.chunk","created":1710000000,"model":"gpt-4o","service_tier":"default","system_fingerprint":"fp_3a2b1c9d","choices":[{"index":0,"delta":{"content":"!","refusal":null},"finish_reason":null,"logprobs":null}]}
data: {"id":"chatcmpl-9f8e7d6c5b4a","object":"chat.completion.chunk","created":1710000000,"model":"gpt-4o","service_tier":"default","system_fingerprint":"fp_3a2b1c9d","choices":[{"index":0,"delta":{},"finish_reason":"stop","logprobs":null}]}
data: [DONE]
cache_control、citations 字段会在转发前递归剥离,避免上游报 400。X-Idempotency-Key 请求头可防止重复扣费;流式中断后可用 X-Resume-Token 或 Last-Event-ID 请求头断点续传。图像、语音、视频类模型也可经本接口调用,最后一条 user 文本将作为生成提示词。传统补全 Completions#
传统补全接口用于兼容早期的 /v1/completions 调用方式(纯 prompt 续写)。平台内部会将 prompt 包装为一条 user 消息,委托给聊天补全统一流程处理,因此模型选择、计费、限流、幂等等行为与 Chat Completions 完全一致。
/v1/completions请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 必填 | 模型 ID,校验规则与聊天补全一致 |
prompt | string | array | 必填 | 续写提示词。数组形式会将各元素转为字符串后拼接;最终作为一条 user 消息提交 |
suffix | string | 可选 | 后缀文本,会被追加为第二条 user 消息一并提交 |
stream | boolean | 可选 | 是否流式输出,默认 false |
max_tokens | integer | 可选 | 最大输出 token 数,小于 1 时按 1 处理 |
temperature | number | 可选 | 采样温度,钳制到 [0.0, 2.0] |
top_p | number | 可选 | 核采样概率,钳制到 [0.0, 1.0] |
n | integer | 可选 | 候选数,默认 1,钳制到 [1, 10] |
stop | string | array | 可选 | 停止序列,处理规则与聊天补全一致 |
presence_penalty | number | 可选 | 存在惩罚,钳制到 [-2.0, 2.0] |
frequency_penalty | number | 可选 | 频率惩罚,钳制到 [-2.0, 2.0] |
seed | integer | 可选 | 随机种子,强制转为整数 |
user | string | 可选 | 终端用户标识,原样透传 |
请求示例
curl "https://yunzhiapi.cn/v1/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"prompt": "从前有座山,山里有座庙,",
"max_tokens": 256,
"temperature": 0.8
}'
响应示例
注意:本接口的响应沿用 Chat Completion 对象结构(object 为 chat.completion),生成文本位于 choices[0].message.content,而非旧式 text_completion 的 choices[0].text。
{
"id": "chatcmpl-1a2b3c4d5e6f",
"object": "chat.completion",
"created": 1710000000,
"model": "gpt-4o",
"service_tier": "default",
"system_fingerprint": "fp_3a2b1c9d",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "庙里有个老和尚在讲故事,讲的是:从前有座山……",
"refusal": null
},
"finish_reason": "stop",
"logprobs": null
}
],
"usage": {
"prompt_tokens": 16,
"completion_tokens": 22,
"total_tokens": 38,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
}
}
流式变体
设置 "stream": true 时同样返回 chat.completion.chunk 增量块并以 data: [DONE] 结束,事件格式与聊天补全的流式输出完全一致。
迁移到 Chat Completions
| Completions 概念 | Chat 等价处理 |
|---|---|
prompt | 包装为单条 role: user 消息 |
suffix | 追加为第二条 user 消息 |
响应 choices[0].text | 位于 choices[0].message.content |
logit_bias / echo / best_of | 不支持,静默忽略 |
新项目建议直接使用 /v1/chat/completions:它支持系统指令、多轮上下文、工具调用与多模态输入,且所有新模型仅在对话管线上持续优化。
max_tokens、temperature、top_p、n、stop、presence_penalty、frequency_penalty、seed、user 这些字段会被带入转换后的请求,其余字段(如 logit_bias、echo、best_of)将被忽略。响应接口 Responses API#
Responses API 兼容 OpenAI 新一代响应接口,适用于 Codex 等新版 SDK、结构化输出(JSON Schema)与工具编排场景。平台会将 Responses 入参标准化为内部 OpenAI 兼容结构后走统一处理流程,响应再转换回 Responses 格式(object: response)。
/v1/responses请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 必填 | 模型 ID;缺失时返回 400 |
input | string | array | 必填 | 输入内容。字符串形式作为一条 user 消息;数组形式支持 message(含 input_text/input_image/output_text/refusal 等 part)、function_call(转为 assistant 的 tool_calls)、function_call_output/tool_result(转为 tool 消息);reasoning、item_reference、computer_call、web_search_call 等条目会被忽略。input 与 messages 同时提供时会合并,最终消息为空时返回 400 |
instructions | string | 可选 | 系统指令,非空时插入为一条 system 消息 |
system | string | 可选 | 等效于 instructions,且优先级更高(排在 messages 最前) |
max_output_tokens | integer | 可选 | 最大输出 token 数,内部映射为 max_tokens,小于 1 时按 1 处理;也接受直接传 max_tokens |
temperature | number | 可选 | 采样温度,钳制到 [0.0, 2.0],响应中默认回显 1.0 |
top_p | number | 可选 | 核采样概率,钳制到 [0.0, 1.0],响应中默认回显 1.0 |
text | object | 可选 | 输出格式。text.format.type 为 json_schema 时转换为 response_format(缺省 name 补 response、缺省 strict 补 false);为 json_object 时转换为 JSON 模式 |
tools | array | 可选 | 工具数组。function 类型的扁平定义(name/description/parameters 直接在工具对象上)会自动包装为 OpenAI 结构;web_search 类型会置位联网搜索标记而非加入 tools |
tool_choice | string | object | 可选 | 工具选择策略;{"type":"function","name":"..."} 扁平形式自动转换为嵌套结构 |
parallel_tool_calls | boolean | 可选 | 是否允许并行工具调用,默认 true;未提供 tools 时该字段不会转发上游 |
stream | boolean | 可选 | 是否流式输出,默认 false |
store | boolean | 可选 | 透传字段,响应骨架中默认回显 false |
metadata | object | 可选 | 透传字段,响应中默认回显空对象 |
reasoning_effort | string | 可选 | 推理强度;reasoning.effort 对象形式也会被自动提取 |
seed / user / n / stop / presence_penalty / frequency_penalty / logit_bias / service_tier | mixed | 可选 | 原样映射透传,数值钳制规则与聊天补全一致 |
请求示例
curl "https://yunzhiapi.cn/v1/responses" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"instructions": "你是一个乐于助人的助手。",
"input": "你好,请介绍一下你自己。",
"max_output_tokens": 1024,
"temperature": 0.7
}'
工具编排示例
curl "https://yunzhiapi.cn/v1/responses" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"input": "北京今天天气怎么样?",
"tools": [
{
"type": "function",
"name": "get_weather",
"description": "查询指定城市的实时天气",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
]
}'
模型决定调用工具时,output 数组中会追加 function_call 类型条目(含 call_id 与 JSON 字符串形式的 arguments)。执行完函数后,将结果以 function_call_output 条目(携带相同 call_id)放入下一次请求的 input 即可续接对话。
响应示例
{
"id": "resp_9f8e7d6c5b4a3c2d1e0f",
"object": "response",
"created_at": 1710000000,
"status": "completed",
"model": "gpt-4o",
"output": [
{
"id": "msg_1a2b3c4d5e6f7a8b",
"type": "message",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "你好!我是一个 AI 助手,可以回答问题、协助写作和编程等。",
"annotations": []
}
]
}
],
"usage": {
"input_tokens": 24,
"output_tokens": 18,
"total_tokens": 42,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens_details": {
"reasoning_tokens": 0
}
},
"metadata": {},
"error": null,
"incomplete_details": null,
"instructions": null,
"parallel_tool_calls": true,
"previous_response_id": null,
"reasoning": null,
"store": false,
"temperature": 1.0,
"tool_choice": "auto",
"tools": [],
"top_p": 1.0,
"truncation": "disabled",
"text": {
"format": {
"type": "text"
}
},
"max_output_tokens": null
}
当 finish_reason 为 length/max_tokens、tool_calls、content_filter 时,incomplete_details.reason 分别回显 max_output_tokens、tool_calls、content_filter;正常结束时为 null。工具调用会以 function_call 类型的 output 条目追加在 message 之后。
流式变体
设置 "stream": true 后返回 Responses API 语义化 SSE 事件流,事件顺序为:response.created(携带 status: in_progress 的响应骨架)→ 若干 response.output_text.delta → response.output_text.done → response.completed(携带完整响应对象)。
event: response.created
data: {"type":"response.created","response":{"id":"resp_9f8e7d6c5b4a3c2d1e0f","object":"response","created_at":1710000000,"status":"in_progress","model":"gpt-4o","output":[],"usage":null,"metadata":{},"error":null,"incomplete_details":null,"instructions":null,"parallel_tool_calls":true,"previous_response_id":null,"reasoning":null,"store":false,"temperature":1.0,"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","text":{"format":{"type":"text"}},"max_output_tokens":null}}
event: response.output_text.delta
data: {"type":"response.output_text.delta","item_id":"msg_1a2b3c4d5e6f7a8b","output_index":0,"content_index":0,"delta":"你好"}
event: response.output_text.done
data: {"type":"response.output_text.done","item_id":"msg_1a2b3c4d5e6f7a8b","output_index":0,"content_index":0,"text":"你好!"}
event: response.completed
data: {"type":"response.completed","response":{"id":"resp_9f8e7d6c5b4a3c2d1e0f","object":"response","created_at":1710000000,"status":"completed","model":"gpt-4o","output":[{"id":"msg_1a2b3c4d5e6f7a8b","type":"message","role":"assistant","status":"completed","content":[{"type":"output_text","text":"你好!","annotations":[]}]}],"usage":{"input_tokens":24,"output_tokens":18,"total_tokens":42,"input_tokens_details":{"cached_tokens":0},"output_tokens_details":{"reasoning_tokens":0}},"metadata":{},"error":null,"incomplete_details":null,"instructions":null,"parallel_tool_calls":true,"previous_response_id":null,"reasoning":null,"store":false,"temperature":1.0,"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","text":{"format":{"type":"text"}},"max_output_tokens":null}}
查询已有响应
/v1/responses/{response_id}按响应 ID 读取已完成的响应(源自服务端幂等记录)。若存储的是 chat.completion 格式会自动转换为 Responses 格式返回;记录不存在或内容为空时返回 404,数据损坏时返回 500。
curl "https://yunzhiapi.cn/v1/responses/resp_9f8e7d6c5b4a3c2d1e0f" \ -H "Authorization: Bearer $API_KEY"
列出输入条目
/v1/responses/{response_id}/input_items供 Codex 等 SDK 轮询使用的占位端点。平台不持久化 input_items,固定返回空列表以保证调用链完整:
{
"object": "list",
"data": [],
"first_id": null,
"last_id": null,
"has_more": false
}
接口选型建议
| 场景 | 推荐接口 |
|---|---|
| 通用对话、既有 OpenAI 生态 | /v1/chat/completions |
| Codex 等新版 SDK、语义化事件流、工具编排 | /v1/responses |
| 纯文本续写、兼容旧系统 | /v1/completions |
DELETE /v1/responses/{id}(路由未注册,请求会命中全局 404);previous_response_id 不会参与上下文拼接,仅在响应骨架中回显 null,多轮对话请自行携带完整 input。response_id 路径段仅允许字母、数字、下划线与短横线;GET 查询同样需要有效 API Key 并通过限流检查。模型列表 Models#
模型接口用于发现当前账户可调用的全部模型及其元信息,适用于客户端启动时拉取模型清单、校验模型 ID 是否存在等场景。两个接口均要求携带有效 API Key,并通过限流检查。
列出全部模型
/v1/models返回 OpenAI 格式的模型列表,每个条目包含 id(展示名)、created(创建时间戳)、owned_by(固定 yunzhi-api)等字段。
curl "https://yunzhiapi.cn/v1/models" \ -H "Authorization: Bearer $API_KEY"
响应示例:
{
"object": "list",
"data": [
{
"id": "gpt-4o",
"object": "model",
"created": 1710000000,
"owned_by": "yunzhi-api",
"permission": [],
"root": "gpt-4o",
"parent": null,
"capabilities": []
},
{
"id": "claude-sonnet-4",
"object": "model",
"created": 1710000100,
"owned_by": "yunzhi-api",
"permission": [],
"root": "claude-sonnet-4",
"parent": null,
"capabilities": []
}
]
}
字段说明
| 字段 | 说明 |
|---|---|
id | 模型对外展示名,请求生成接口时填入此值 |
created | 模型登记时间(UTC Unix 时间戳,秒) |
owned_by | 固定为 yunzhi-api,表示由本网关托管 |
root / parent | 兼容字段,分别回填展示名与 null |
capabilities | 保留字段,当前为空数组 |
获取单个模型
/v1/models/{model_id}返回指定模型的详情。模型 ID 支持模糊匹配(与请求模型时相同的查找逻辑);未找到时返回 404 及 requested_model 字段。
curl "https://yunzhiapi.cn/v1/models/gpt-4o" \ -H "Authorization: Bearer $API_KEY"
响应示例:
{
"id": "gpt-4o",
"object": "model",
"created": 1710000000,
"owned_by": "yunzhi-api"
}
协议自适应返回
| 请求特征 | 返回格式 |
|---|---|
Authorization: Bearer(默认) | OpenAI 格式(object: list + data 数组) |
携带 x-goog-api-key 头或 ?key= 参数 | Gemini 格式(models 数组) |
携带 anthropic-api-key,或 x-api-key + anthropic-version | Anthropic 格式(含 has_more/first_id/last_id) |
/anthropic/v1/models 或 /v1beta/models 可强制获得对应协议格式,无需依赖请求头特征。Missing API key.),Key 无效返回 401(Invalid API key.);模型接口本身不计费,但计入限流。向量嵌入 Embeddings
向量嵌入接口与 OpenAI Embeddings API 兼容,将文本转换为向量,适用于语义搜索、聚类、推荐与 RAG 检索增强等场景。请求经鉴权与余额检查后转发至模型对应的上游端点(默认 embeddings 端点),响应体原样透传。
/v1/embeddings请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 必填 | 嵌入模型 ID;若模型在平台注册,会自动替换为其后端模型名(backend_name)后转发 |
input | string | array | 必填 | 待嵌入文本。数组形式最多 2048 条,超过返回 400(Too many embedding inputs.) |
encoding_format | string | 可选 | 向量编码格式(如 float、base64),原样转发上游 |
dimensions | integer | 可选 | 输出向量维度(仅部分模型支持),原样转发上游 |
user | string | 可选 | 终端用户标识,原样转发上游 |
请求示例
curl "https://yunzhiapi.cn/v1/embeddings" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "text-embedding-3-small",
"input": "今天天气真好,适合出去散步。",
"encoding_format": "float"
}'
批量请求示例
curl "https://yunzhiapi.cn/v1/embeddings" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "text-embedding-3-small",
"input": ["第一段文本", "第二段文本", "第三段文本"],
"dimensions": 512
}'
批量请求中每条文本独立生成一个向量,按 index 升序排列;单次最多 2048 条,超大数据集请客户端分批提交。
响应示例
{
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [
0.0023064255,
-0.009327292,
0.015783105,
-0.021884446,
0.0068145283
]
}
],
"model": "text-embedding-3-small",
"usage": {
"prompt_tokens": 8,
"total_tokens": 8
}
}
响应体由上游原样透传(HTTP 状态码 ≥ 400 时按上游错误映射返回)。上例仅为示意,真实向量维度以所选模型为准。
最佳实践
- 向量维度需与下游向量数据库的索引维度一致;使用
dimensions降维会损失部分精度,请按需权衡。 - 对同一语料重复嵌入会产生重复费用,建议在业务侧对文本做哈希缓存。
- 长文本超过模型上下文窗口时会被上游截断,入库前建议按语义分段(chunk)。
model、input、encoding_format、dimensions、user 五个字段会被转发至上游,其余字段将被丢弃;上游请求超时时间为 60 秒。usage.prompt_tokens,上游未返回时按输入文本本地估算;单价取模型配置的输入价,未配置时默认 0.1 / 百万 token。请求体为空或非法 JSON 返回 400,缺少 model 或 input 返回 400,余额不足返回 402,上游不可达返回 502。内容审核 Moderations#
内容审核接口与 OpenAI Moderations API 兼容,用于检测文本是否包含违规内容,适用于 UGC 社区、评论系统、对话产品的安全过滤场景。该接口不计费,但需要有效 API Key 并通过限流检查。
/v1/moderations请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
input | string | array | 必填 | 待审核文本(字符串或字符串数组)。缺失时返回 400(Missing required parameter: 'input'.) |
model | string | 可选 | 审核模型,默认 text-moderation-latest,原样转发上游 |
请求示例
curl "https://yunzhiapi.cn/v1/moderations" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "text-moderation-latest",
"input": "这是一段待审核的用户评论文本。"
}'
响应示例
上游正常时响应体原样透传:
{
"id": "modr-0abc123def456",
"model": "text-moderation-latest",
"results": [
{
"flagged": false,
"categories": {
"hate": false,
"hate/threatening": false,
"harassment": false,
"harassment/threatening": false,
"self-harm": false,
"self-harm/intent": false,
"self-harm/instructions": false,
"sexual": false,
"sexual/minors": false,
"violence": false,
"violence/graphic": false
},
"category_scores": {
"hate": 0.0001,
"hate/threatening": 0.00001,
"harassment": 0.0002,
"harassment/threatening": 0.00001,
"self-harm": 0.00001,
"self-harm/intent": 0.00001,
"self-harm/instructions": 0.00001,
"sexual": 0.0001,
"sexual/minors": 0.00001,
"violence": 0.0002,
"violence/graphic": 0.00001
}
}
]
}
降级行为
- 审核端点未配置时,直接返回占位响应;
- 上游连接失败(超时 30 秒)时,返回占位响应;
- 上游返回 HTTP 错误(≥ 400)时,同样返回占位响应。
占位响应固定为 flagged: false、空的 categories 与 category_scores 对象,id 以 modr- 前缀生成,保证调用方链路不中断:
{
"id": "modr-9f8e7d6c5b4a",
"model": "text-moderation-latest",
"results": [
{
"flagged": false,
"categories": {},
"category_scores": {}
}
]
}
接入建议
- 对安全强依赖的场景,请检查响应中
categories是否为空对象来甄别降级响应,必要时走本地敏感词引擎二次复核。 - 审核应与主对话链路并行调用(旁路审核),避免串行增加首字延迟。
- 批量审核使用字符串数组一次提交,比逐条调用更节省限流额度。
categories 误判为「内容安全」。文件管理 Files#
文件管理接口与 OpenAI Files API 完全兼容,适用于上传微调/批处理数据文件、管理助手知识库附件、下载上游生成的文件内容等场景。所有请求(除查询参数外)均原样转发至上游文件服务,响应体与 Content-Type 原样透传。
列出文件
/v1/files返回当前账户在上游文件服务中的全部文件列表,支持通过查询字符串(如 ?purpose=fine-tune)过滤,查询参数原样转发。
| 参数 | 位置 | 类型 | 说明 |
|---|---|---|---|
purpose | query 可选 | string | 按用途过滤,如 fine-tune、assistants,原样转发上游 |
curl "https://yunzhiapi.cn/v1/files" \ -H "Authorization: Bearer $API_KEY"
响应示例:
{
"object": "list",
"data": [
{
"id": "file-abc123",
"object": "file",
"bytes": 120000,
"created_at": 1710000000,
"filename": "train.jsonl",
"purpose": "fine-tune"
}
]
}
上传文件
/v1/files以 multipart/form-data 上传文件,所有表单字段(含多文件数组字段)原样重建并转发至上游;若请求不含任何表单字段,则请求体与原始 Content-Type 直接透传。
| 字段 | 位置 | 类型 | 说明 |
|---|---|---|---|
file | multipart 必填 | file | 要上传的文件内容,支持多文件数组形式(如 file[]) |
purpose | multipart 必填 | string | 文件用途,如 fine-tune、assistants、batch,由上游校验 |
curl "https://yunzhiapi.cn/v1/files" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@train.jsonl" \ -F "purpose=fine-tune"
响应示例:
{
"id": "file-abc123",
"object": "file",
"bytes": 120000,
"created_at": 1710000000,
"filename": "train.jsonl",
"purpose": "fine-tune"
}
用途与计费
| purpose | 用途 | 说明 |
|---|---|---|
fine-tune | 微调训练数据 | 推荐 JSONL 格式,每行一个训练样本 |
assistants | 助手知识库附件 | 供检索增强使用 |
batch | 批处理任务输入 | 大批量离线任务 |
上传成功后每次扣费 0.005(账户余额单位),上传前请确保余额充足;列表、详情、下载与删除操作免费,但均计入限流窗口。
获取文件信息
/v1/files/{file_id}获取单个文件的元数据。file_id 为路径段,允许除 / 以外的任意字符。
curl "https://yunzhiapi.cn/v1/files/file-abc123" \ -H "Authorization: Bearer $API_KEY"
响应示例:
{
"id": "file-abc123",
"object": "file",
"bytes": 120000,
"created_at": 1710000000,
"filename": "train.jsonl",
"purpose": "fine-tune"
}
下载文件内容
/v1/files/{file_id}/content下载文件的原始二进制内容,响应体与 Content-Type 完全透传上游(可能为 application/octet-stream 等),不做 JSON 包装。
curl "https://yunzhiapi.cn/v1/files/file-abc123/content" \ -H "Authorization: Bearer $API_KEY" \ -o train.jsonl
删除文件
/v1/files/{file_id}删除指定文件,结果由上游返回并透传。
curl -X DELETE "https://yunzhiapi.cn/v1/files/file-abc123" \ -H "Authorization: Bearer $API_KEY"
响应示例:
{
"id": "file-abc123",
"object": "file",
"deleted": true
}
生命周期说明
- 文件存储于上游文件服务,保留策略由上游决定;长期不用的文件建议主动删除以避免配额占用。
- 上传大文件时请保证网络稳定,中途失败需重新上传(本接口不支持断点续传)。
- 文件内容不会经过网关的协议转换层,网关不解析也不留存文件正文。
Upstream files service unavailable.)。HTTP 状态码与响应头按上游结果原样返回。图像生成 Images#
图像接口与 OpenAI Images API 兼容,覆盖文生图(generations)、图像编辑(edits)与图像变体(variations)三类场景。响应 data 数组会被规范化:每个条目保留上游原始字段(url / b64_json / revised_prompt 等),并自动补齐 media_type(image)与 mime_type(默认 image/png)两个标准字段;裸 URL 或裸 base64 字符串条目会被提升为对象。
创建图像(文生图)
/v1/images/generations根据文本提示词生成图像,请求体为 JSON。
| 参数 | 位置 | 类型 | 说明 |
|---|---|---|---|
prompt | body 必填 | string | 图像描述文本,不能为空,长度不超过 2,000,000 字节 |
model | body 可选 | string | 图像模型名,用于路由与定价,未匹配时使用默认端点 |
n | body 可选 | integer | 生成数量,默认 1,自动钳制到 [1, 10] |
size | body 可选 | string | 图像尺寸,默认 1024x1024,必须匹配 宽x高 数字格式(如 1792x1024),否则返回 400 |
| 其他字段 | body 可选 | any | 如 quality、style、response_format 等,随请求体原样转发上游 |
尺寸与常用参数
| 参数 | 合法取值 | 默认值 |
|---|---|---|
size | 1024x1024 / 1792x1024 / 1024x1792(部分模型支持更多) | 1024x1024 |
n | 1 – 10 | 1 |
quality | standard / hd(按模型支持情况) | 随上游默认 |
response_format | url / b64_json | url |
curl "https://yunzhiapi.cn/v1/images/generations" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "dall-e-3",
"prompt": "一只在月光下奔跑的柴犬,水彩风格",
"n": 1,
"size": "1024x1024"
}'
响应示例:
{
"created": 1710000000,
"data": [
{
"url": "https://example.com/gen/image-1.png",
"revised_prompt": "A Shiba Inu running under moonlight, watercolor style",
"media_type": "image",
"mime_type": "image/png"
}
]
}
编辑图像
/v1/images/edits以上传的原始图像(可选蒙版)为基础,按提示词进行局部编辑。请求为 multipart/form-data,原始请求体与 Content-Type 直接透传至上游。
| 字段 | 位置 | 类型 | 说明 |
|---|---|---|---|
image | multipart 必填 | file | 待编辑的原始图像文件 |
prompt | multipart 必填 | string | 期望编辑结果的文本描述,由上游校验 |
mask | multipart 可选 | file | 蒙版图像,透明区域表示待编辑位置 |
model | multipart 可选 | string | 模型名,缺省按 dall-e-2 计费路由 |
n | multipart 可选 | integer | 生成数量,默认 1,自动钳制到 [1, 10] |
curl "https://yunzhiapi.cn/v1/images/edits" \ -H "Authorization: Bearer $API_KEY" \ -F "image=@photo.png" \ -F "mask=@mask.png" \ -F "prompt=把天空替换为星空" \ -F "n=1" \ -F "size=1024x1024"
响应示例:
{
"created": 1710000000,
"data": [
{
"url": "https://example.com/gen/edited-1.png",
"media_type": "image",
"mime_type": "image/png"
}
]
}
创建图像变体
/v1/images/variations基于上传图像生成风格/构图相近的变体,无需提示词。请求为 multipart/form-data,原始请求体透传上游。
| 字段 | 位置 | 类型 | 说明 |
|---|---|---|---|
image | multipart 必填 | file | 源图像文件 |
model | multipart 可选 | string | 模型名,缺省按 dall-e-2 计费路由 |
n | multipart 可选 | integer | 生成数量,默认 1,自动钳制到 [1, 10] |
curl "https://yunzhiapi.cn/v1/images/variations" \ -H "Authorization: Bearer $API_KEY" \ -F "image=@photo.png" \ -F "n=2"
响应示例:
{
"created": 1710000000,
"data": [
{
"url": "https://example.com/gen/variation-1.png",
"media_type": "image",
"mime_type": "image/png"
},
{
"url": "https://example.com/gen/variation-2.png",
"media_type": "image",
"mime_type": "image/png"
}
]
}
计费与最佳实践
- 未命中模型定价时按默认每张
2.0×n扣费;命中定价时按 prompt 估算 token × 模型input_price÷ 1M ×n扣费。 - 提示词建议包含主体、风格、光影、构图四要素;dall-e-3 会自动改写提示词,可通过响应中的
revised_prompt查看改写结果。 - 需要透明背景或精确控制时,优先选择支持
b64_json的模型并在客户端后处理。
Request body is empty.)。音频服务 Audio#
音频接口与 OpenAI Audio API 兼容,包含文本转语音(speech)、语音转文字(transcriptions)与语音翻译(translations)。三个端点共用统一代理:请求体原样转发上游,响应体与上游 Content-Type 原样透传(speech 直接返回二进制音频流,不做 JSON 包装)。
文本转语音
/v1/audio/speech将文本合成为语音,请求体为 JSON,整体原样转发上游。
| 参数 | 位置 | 类型 | 说明 |
|---|---|---|---|
model | body 必填 | string | TTS 模型名(如 tts-1、tts-1-hd),用于路由与定价 |
input | body 必填 | string | 要合成的文本,由上游校验 |
voice | body 必填 | string | 发音人,如 alloy、echo、fable 等,由上游校验 |
response_format | body 可选 | string | 音频格式:mp3 / opus / aac / flac 等 |
speed | body 可选 | number | 语速倍率,随请求体原样转发 |
curl "https://yunzhiapi.cn/v1/audio/speech" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "tts-1",
"input": "你好,这是一段语音合成测试。",
"voice": "alloy",
"response_format": "mp3"
}' \
-o speech.mp3
audio/mpeg),并携带准确的 Content-Length,可直接写入文件或流式播放。语音转文字
/v1/audio/transcriptions将音频文件转写为原始语言的文本。请求为 multipart/form-data,原始请求体与 Content-Type 直接透传至上游。
| 字段 | 位置 | 类型 | 说明 |
|---|---|---|---|
file | multipart 必填 | file | 音频文件(mp3 / wav / m4a / flac 等,由上游支持) |
model | multipart 必填 | string | 识别模型名(如 whisper-1),用于路由与定价 |
language | multipart 可选 | string | 音频语言代码(ISO-639-1,如 zh) |
prompt | multipart 可选 | string | 提示文本,引导转写风格与专有名词 |
response_format | multipart 可选 | string | json / text / srt / verbose_json / vtt |
temperature | multipart 可选 | number | 采样温度,随表单原样转发 |
curl "https://yunzhiapi.cn/v1/audio/transcriptions" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@meeting.mp3" \ -F "model=whisper-1" \ -F "language=zh" \ -F "response_format=json"
响应示例:
{
"text": "大家好,今天我们讨论一下项目进度。"
}
语音翻译
/v1/audio/translations将任意语言的音频翻译并转写为英文文本,参数与 transcriptions 基本一致,multipart 原样透传。
| 字段 | 位置 | 类型 | 说明 |
|---|---|---|---|
file | multipart 必填 | file | 待翻译的音频文件 |
model | multipart 必填 | string | 识别模型名(如 whisper-1),用于路由与定价 |
prompt | multipart 可选 | string | 提示文本(英文),引导翻译风格 |
response_format | multipart 可选 | string | json / text / srt / verbose_json / vtt |
temperature | multipart 可选 | number | 采样温度 |
curl "https://yunzhiapi.cn/v1/audio/translations" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@speech.mp3" \ -F "model=whisper-1"
响应示例:
{
"text": "Hello everyone, today we will discuss the project progress."
}
格式与限制
| 端点 | 输入 / 输出 | 限制 |
|---|---|---|
/v1/audio/speech | 输出 mp3 / opus / aac / flac 等 | 二进制流返回,非 JSON |
/v1/audio/transcriptions | 输入 mp3 / wav / m4a / flac 等 | 文件 ≤ 64MB |
/v1/audio/translations | 输入同上,输出固定英文 | 文件 ≤ 64MB |
最佳实践
- 显式指定
language可显著提升中英混说场景的转写准确率。 - 长音频建议按静音段切分为 5~10 分钟片段分别转写,降低单次失败的影响面。
- 通过
prompt注入专有名词表(产品名、人名),可减少术语误识别。
视频生成 Videos#
视频接口提供两种模式:/v1/videos/generations 同步生成(一次请求直接返回结果),以及 Sora 风格的 /v1/videos 异步任务(创建任务后轮询状态)。响应 data 数组会被规范化:保留上游原始字段并补齐 media_type(video)与 mime_type(默认 video/mp4)。
同步与异步选型
| 模式 | 端点 | 特点 | 适用场景 |
|---|---|---|---|
| 同步 | /v1/videos/generations | 一次请求等待结果返回,上游超时 300 秒 | 短视频、可接受长等待的后端任务 |
| 异步 | /v1/videos + 轮询 | 立即返回任务 ID,轮询查询状态 | 长视频、需要任务管理与失败重试的场景 |
同步生成视频
/v1/videos/generations提交提示词并等待上游同步返回生成结果,上游超时 300 秒。
| 参数 | 位置 | 类型 | 说明 |
|---|---|---|---|
prompt | body 必填 | string | 视频描述文本,不能为空,长度不超过 2,000,000 字节 |
model | body 可选 | string | 视频模型名(如 sora-2、veo-3.0-generate-001),用于路由与定价 |
n | body 可选 | integer | 生成数量,默认 1,自动钳制到 [1, 5] |
| 其他字段 | body 可选 | any | 如 duration、aspect_ratio、size 等,随请求体原样转发上游 |
curl "https://yunzhiapi.cn/v1/videos/generations" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "海浪拍打礁石,慢镜头,电影质感",
"n": 1
}'
响应示例:
{
"created": 1710000000,
"data": [
{
"url": "https://example.com/gen/video-1.mp4",
"media_type": "video",
"mime_type": "video/mp4"
}
]
}
创建异步视频任务
/v1/videos创建 Sora 风格的异步生成任务,立即返回任务对象(含 id 与初始 status)。POST 创建成功后按模型 output_price 扣费(默认 10.0/次)。
| 参数 | 位置 | 类型 | 说明 |
|---|---|---|---|
model | body 必填 | string | 视频模型名,用于路由与定价 |
prompt | body 必填 | string | 视频描述文本,由上游校验 |
| 其他字段 | body 可选 | any | 如 size、seconds 等,随请求体原样转发上游 |
curl "https://yunzhiapi.cn/v1/videos" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "一只猫在窗边看雪,镜头缓慢推进"
}'
响应示例:
{
"id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "queued",
"created_at": 1710000000
}
查询任务状态
/v1/videos/{video_id}查询单个任务状态,video_id 允许字母、数字、下划线与短横线;查询字符串(如展开参数)原样转发上游。GET 请求不计费。
curl "https://yunzhiapi.cn/v1/videos/video_abc123" \ -H "Authorization: Bearer $API_KEY"
响应示例(完成后):
{
"id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "completed",
"created_at": 1710000000,
"completed_at": 1710000060,
"data": [
{
"url": "https://example.com/gen/video-abc123.mp4",
"media_type": "video",
"mime_type": "video/mp4"
}
]
}
列出任务
/v1/videos列出全部视频任务,支持通过查询字符串分页/过滤(参数原样转发上游),不计费。
curl "https://yunzhiapi.cn/v1/videos?limit=20" \ -H "Authorization: Bearer $API_KEY"
删除任务
/v1/videos/{video_id}删除指定任务及其产物,结果由上游返回并透传,不计费。
curl -X DELETE "https://yunzhiapi.cn/v1/videos/video_abc123" \ -H "Authorization: Bearer $API_KEY"
异步任务轮询流程
- 调用
POST /v1/videos创建任务,从响应中保存id与初始status(通常为queued或in_progress)。 - 每隔 5~10 秒调用
GET /v1/videos/{video_id}轮询任务状态,查询不计费。 - 当
status变为completed时,从响应的data数组中取出视频 URL(已补齐media_type/mime_type)。 - 若
status变为failed,检查响应中的错误信息并停止轮询。 - 可选:任务完成后调用
DELETE /v1/videos/{video_id}清理任务记录。
消息对话 Messages#
Anthropic Messages 协议端点,与官方 POST /v1/messages 完全兼容。本站接收 Anthropic 格式请求后,在内部转换为 OpenAI Chat Completions 格式转发上游,再将响应还原为 Anthropic message 结构返回。适用于 Claude Code、Cherry Studio 以及任何使用 Anthropic SDK 的客户端。同时支持别名路径 /anthropic/v1/messages 与 /v1/anthropic/v1/messages。
https://yunzhiapi.cn/v1/messages请求头
| 请求头 | 必填 | 说明 |
|---|---|---|
x-api-key | 必填 | 本站 sk- 开头的密钥;也可使用 Authorization: Bearer sk-... 或 anthropic-api-key。 |
anthropic-version | 必填 | Anthropic 协议版本号,固定填 2023-06-01;Anthropic SDK 会自动携带。 |
Content-Type | 必填 | application/json |
请求参数
| 参数 | 类型 | 必填 | 默认值 / 范围 | 说明 |
|---|---|---|---|---|
model | string | 必填 | 长度 ≤ 256 | 模型名,需与本站模型列表展示名一致。 |
max_tokens | integer | 必填 | ≥ 1 | 最大输出 token 数,小于 1 时自动钳制为 1。 |
messages | array | 必填 | — | 对话消息数组,role 为 user / assistant,content 支持字符串或 text / image / document / tool_use / tool_result 等块。 |
system | string | array | 可选 | — | 系统提示;数组形式时仅提取其中的 text 块并合并为一条 system 消息。 |
temperature | number | 可选 | 0.0 – 2.0 | 采样温度,超出范围自动钳制。 |
top_p | number | 可选 | 0.0 – 1.0 | 核采样概率,超出范围自动钳制。 |
top_k | integer | 可选 | — | Top-K 采样,原样透传上游。 |
stop_sequences | array | 可选 | 单条 ≤ 1024 字符 | 停止序列,映射为 OpenAI 的 stop 字段。 |
stream | boolean | 可选 | false | 为 true 时以 SSE 流式返回 Anthropic 事件序列。 |
tools | array | 可选 | — | 工具定义,name / description / input_schema 会映射为 OpenAI function 工具;web_search_* 类型转换为联网搜索开关。 |
tool_choice | string | object | 可选 | auto | auto→自动、any→强制调用、none→禁止调用、{"type":"tool","name":"..."}→指定工具。 |
thinking | object | 可选 | — | {"type":"enabled","budget_tokens":N} 启用推理,内部映射为 reasoning_effort: high 与 max_completion_tokens = budget_tokens + max_tokens。 |
metadata.user_id | string | 可选 | — | 终端用户标识,映射为 OpenAI 的 user 字段。 |
请求示例
curl https://yunzhiapi.cn/v1/messages \
-H "x-api-key: sk-你的密钥" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"system": "你是一名严谨的助理。",
"messages": [
{"role": "user", "content": "用一句话介绍杭州。"}
],
"temperature": 0.7,
"stream": false
}'
工具调用示例
curl https://yunzhiapi.cn/v1/messages \
-H "x-api-key: sk-你的密钥" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"tools": [
{
"name": "get_weather",
"description": "查询城市实时天气",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
],
"messages": [{"role": "user", "content": "北京天气如何?"}]
}'
模型决定调用工具时,响应 content 中出现 tool_use 块(含 id 与 input 对象),stop_reason 为 tool_use。执行完函数后,将结果以 tool_result 块(携带相同 tool_use_id)放入下一条 user 消息再次请求,即可完成闭环;失败结果设置 is_error: true,内容会自动加 [Error] 前缀。
扩展思考示例
"thinking": {
"type": "enabled",
"budget_tokens": 2048
}
启用后网关内部映射为 reasoning_effort: high 与 max_completion_tokens = budget_tokens + max_tokens;响应中思考内容以 thinking 类型块置于 content 首位,流式模式下以 thinking_delta 增量下发。signature 字段不参与校验,回传时可为 null。
非流式响应示例
{
"id": "msg_9f3a1c2e7b4d8f0a1b2c3d4e",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "杭州是浙江省省会,以西湖、龙井茶和数字经济闻名的历史文化名城。"
}
],
"model": "claude-sonnet-4-5",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 28,
"output_tokens": 35,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}
流式响应示例("stream": true)
流式模式返回 text/event-stream,事件序列为 message_start → content_block_start → ping → 多个 content_block_delta → content_block_stop → message_delta → message_stop:
event: message_start
data: {"type":"message_start","message":{"id":"msg_9f3a1c2e7b4d8f0a1b2c3d4e","type":"message","role":"assistant","content":[],"model":"claude-sonnet-4-5","stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0}}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: ping
data: {"type":"ping"}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"杭州是浙江省省会,"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"以西湖和数字经济闻名。"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":28,"output_tokens":35}}
event: message_stop
data: {"type":"message_stop"}
当上游返回推理内容时,会先输出 thinking 类型的 content block(thinking_delta 增量);当触发工具调用时,对应 block 为 tool_use 类型,参数以 input_json_delta 增量下发。
与 OpenAI 协议的字段映射
| Anthropic 字段 | OpenAI 字段 | 转换规则 |
|---|---|---|
system | messages[0](role=system) | 字符串直接转换;数组形式提取全部 text 块以换行合并。 |
messages[].content(image 块) | image_url 块 | base64 source 拼为 data:{media_type};base64,...,detail 固定为 auto。 |
tool_use 块 | tool_calls | 转为 {"type":"function","function":{"name":...,"arguments": JSON 字符串}}。 |
tool_result 块 | role=tool 消息 | tool_use_id 映射为 tool_call_id;is_error 为真时内容前加 [Error] 前缀。 |
stop_sequences | stop | 原样映射。 |
tool_choice | tool_choice | any→required;{"type":"tool"}→{"type":"function","function":{"name":...}}。 |
thinking.budget_tokens | thinking_budget + max_completion_tokens | 启用时 reasoning_effort=high,max_completion_tokens = budget_tokens + max_tokens(max_tokens 缺省按 4096 计)。 |
metadata.user_id | user | 原样映射。 |
响应 finish_reason | 响应 stop_reason | stop→end_turn;length/max_tokens→max_tokens;tool_calls→tool_use。 |
响应 reasoning_content | 响应 thinking 块 | 推理内容包裹为 {"type":"thinking","thinking":...,"signature":null} 置于 content 首位。 |
响应 usage.prompt_tokens / completion_tokens | 响应 usage.input_tokens / output_tokens | 一一对应,缓存相关字段固定为 0。 |
cache_control、citations 等客户端注入字段会在转发前被递归剥离,以避免上游报 400;因此提示词缓存不生效,响应中缓存 token 计数恒为 0。
document 类型的附件会被转换为占位文本(如 [Document: url]),不会真正解析文件内容;② tool_result 中的图片内容会被省略并替换为提示文本;③ 消息 role 为 model / bot 时自动归一化为 assistant;④ thinking 块的 signature 字段不参与校验,回传时可为 null。
令牌计数 Count Tokens#
Anthropic token 预估端点。将请求体按 Messages 端点相同的规则转换为内部消息后,在本地估算输入 token 数,不转发上游模型、不消耗额度、不计费。Claude Code 等客户端在压缩上下文前会调用此接口判断窗口占用。同时支持别名路径 /anthropic/v1/messages/count_tokens 与 /v1/anthropic/v1/messages/count_tokens。
https://yunzhiapi.cn/v1/messages/count_tokens请求头
| 请求头 | 必填 | 说明 |
|---|---|---|
x-api-key | 必填 | 本站 sk- 开头的密钥;也支持 Authorization: Bearer 与 anthropic-api-key。 |
anthropic-version | 必填 | 固定填 2023-06-01。 |
Content-Type | 必填 | application/json |
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 必填 | 模型名,与 Messages 端点一致。 |
messages | array | 必填 | 与 Messages 端点相同的消息结构,全部文本内容参与估算。 |
system | string | array | 可选 | 系统提示,转换为 system 消息后计入估算。 |
tools | array | 可选 | 工具定义,序列化为 JSON 文本后追加计入估算。 |
请求示例
curl https://yunzhiapi.cn/v1/messages/count_tokens \
-H "x-api-key: sk-你的密钥" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"system": "你是一名严谨的助理。",
"messages": [
{"role": "user", "content": "用一句话介绍杭州。"}
]
}'
响应示例
{
"input_tokens": 21
}
使用场景
- 上下文压缩:Claude Code 等客户端在历史接近窗口上限前调用本接口,决定是否触发自动压缩。
- 成本预估:批量任务执行前估算总输入 token,预判费用与余额是否充足。
- 窗口告警:长对话应用中实时监控占用比例,超过 80% 时提示用户或自动摘要。
与 OpenAI 协议的字段映射
| Anthropic 字段 | 内部处理 | 说明 |
|---|---|---|
system | system 消息文本 | 与 Messages 端点相同的转换规则,拼接进估算文本。 |
messages[].content | 消息文本 | 各消息文本拼接后统一估算。 |
tools | JSON 文本 | 整体序列化后追加到估算文本末尾。 |
响应 input_tokens | 估算结果 | 由本地估算器(estimate_tokens_precise,chat 类别)计算得出。 |
max_tokens、temperature)即使缺失也不会报错。
模型列表(Anthropic 格式)#
以 Anthropic 协议格式返回当前可用模型列表。适用于 Anthropic SDK 的模型枚举、Claude Code 启动时的模型探测等场景。除显式路径 /anthropic/v1/models 外,对标准 GET /v1/models 的请求,当携带 anthropic-version 请求头或 User-Agent 含 Anthropic 时,也会自动返回本格式。
https://yunzhiapi.cn/v1/models请求头
| 请求头 | 必填 | 说明 |
|---|---|---|
x-api-key | 必填 | 本站 sk- 开头的密钥;也支持 anthropic-api-key 与 Authorization: Bearer。 |
anthropic-version | 必填 | 固定填 2023-06-01;同时作为 Anthropic 格式的识别信号。 |
请求示例
curl https://yunzhiapi.cn/v1/models \ -H "x-api-key: sk-你的密钥" \ -H "anthropic-version: 2023-06-01"
响应示例
{
"data": [
{
"type": "model",
"id": "claude-sonnet-4-5",
"display_name": "claude-sonnet-4-5",
"created_at": "2025-03-01T00:00:00Z"
},
{
"type": "model",
"id": "gpt-4o",
"display_name": "gpt-4o",
"created_at": "2025-03-01T00:00:00Z"
}
],
"has_more": false,
"first_id": "claude-sonnet-4-5",
"last_id": "gpt-4o"
}
字段说明
| 字段 | 说明 |
|---|---|
data[].id / display_name | 均为本站模型展示名,请求 Messages 端点时填入此值 |
data[].created_at | 模型登记时间,ISO 8601 UTC 格式 |
has_more | 分页标记,当前全量返回,恒为 false |
first_id / last_id | 首尾模型 ID,列表为空时为 null |
与 OpenAI 协议的字段映射
| OpenAI 格式字段 | Anthropic 格式字段 | 转换规则 |
|---|---|---|
object: "list" | (无) | Anthropic 格式不输出顶层 object 字段。 |
data[].object: "model" | data[].type: "model" | 字段名由 object 改为 type。 |
data[].id | data[].id / data[].display_name | 均为本站模型的展示名。 |
data[].created(Unix 时间戳) | data[].created_at(ISO 8601) | 格式化为 Y-m-d\TH:i:s\Z 的 UTC 时间。 |
data[].owned_by 等 | (无) | owned_by / permission / root / parent 等字段不输出。 |
| (无) | has_more / first_id / last_id | 分页元信息;当前全量返回,has_more 恒为 false。 |
GET /v1/models,服务端按请求头判断返回格式——携带 x-goog-api-key 返回 Gemini 格式;携带 anthropic-api-key,或 x-api-key 且(User-Agent 含 Anthropic 或携带 anthropic-version)时返回 Anthropic 格式;其余情况返回 OpenAI 格式。显式访问 /anthropic/v1/models 可强制获得 Anthropic 格式。
has_more 固定为 false;③ 列表为空时 first_id 与 last_id 为 null。
内容生成 generateContent#
Gemini 协议的核心对话端点,接收 contents 多轮对话并一次性返回完整生成结果。适用于 Google AI SDK(google-generativeai / @google/generative-ai)、支持 Gemini 原生协议的客户端,以及需要函数调用(functionCall)、JSON Schema 约束输出、思考预算(thinkingBudget)等 Gemini 特性的场景。网关会将请求转换为 OpenAI Chat Completions 格式转发上游,再把响应还原为 Gemini 格式。
https://yunzhiapi.cn/v1beta/models/{model}:generateContent路径中的 {model} 替换为本站展示的模型名(如 gemini-2.5-pro),网关会自动剥离 models/ 等渠道前缀后匹配。/v1beta 前缀也可写作 /v1 或 /v1alpha,三者等价。
鉴权方式
使用 x-goog-api-key 请求头传递本站 sk- 开头的密钥,或使用 ?key= 查询参数(浏览器直链场景),两种方式等价:
x-goog-api-key: sk-你的密钥
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
contents |
array | 必填 | 对话内容数组,每项含 role(user 或 model)与 parts;parts 支持 text、inlineData(base64 图片/音频)、fileData(文件 URI)、functionCall、functionResponse、executableCode、codeExecutionResult |
systemInstruction |
string | object | 可选 | 系统指令,支持纯字符串、{"parts":[{"text":"..."}]} 或 {"text":"..."} 三种写法,多段 text 会以换行拼接后作为 system 消息 |
generationConfig |
object | 可选 | 生成配置,见下方字段映射表 |
safetySettings |
array | 可选 | 安全设置数组(category + threshold),网关原样透传给上游 |
tools |
array | 可选 | 工具声明,支持 functionDeclarations 函数定义;声明 googleSearch / googleSearchRetrieval 会转换为联网搜索开关 |
toolConfig |
object | 可选 | 工具调用控制,functionCallingConfig.mode 取 AUTO / ANY / NONE;ANY 且 allowedFunctionNames 仅一个函数时强制调用该函数 |
generationConfig 与 OpenAI 字段映射
| Gemini 字段 | 转换后 OpenAI 字段 | 约束 |
|---|---|---|
temperature |
temperature |
钳制到 [0, 2] |
topP |
top_p |
钳制到 [0, 1] |
topK |
top_k |
正整数 |
maxOutputTokens |
max_tokens |
最小为 1 |
stopSequences |
stop |
字符串数组,单条最长 1024 字符 |
candidateCount |
n |
钳制到 [1, 10] |
seed |
seed |
整数 |
responseMimeType: application/json |
response_format: {"type":"json_object"} |
强制 JSON 输出 |
responseSchema |
response_format: {"type":"json_schema"} |
按 Schema 约束输出,strict 固定为 false |
thinkingConfig.thinkingBudget |
reasoning_effort + thinking_budget |
大于 0 时 reasoning_effort=high;等于 0 时 reasoning_effort=minimal |
请求示例
curl "https://yunzhiapi.cn/v1beta/models/gemini-2.5-pro:generateContent" \
-H "x-goog-api-key: sk-你的密钥" \
-H "Content-Type: application/json" \
-d '{
"systemInstruction": {"parts": [{"text": "你是一名简洁的中文助手"}]},
"contents": [
{"role": "user", "parts": [{"text": "用一句话介绍量子计算"}]}
],
"generationConfig": {
"temperature": 0.7,
"topP": 0.95,
"maxOutputTokens": 1024
}
}'
函数调用示例
curl "https://yunzhiapi.cn/v1beta/models/gemini-2.5-pro:generateContent" \
-H "x-goog-api-key: sk-你的密钥" \
-H "Content-Type: application/json" \
-d '{
"contents": [{"role": "user", "parts": [{"text": "北京天气如何?"}]}],
"tools": [
{
"functionDeclarations": [
{
"name": "get_weather",
"description": "查询城市实时天气",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}}
}
}
]
}
]
}'
模型决定调用工具时,响应 parts 中出现 functionCall(含 name 与对象形式的 args)。执行完函数后,将 functionResponse(含 name 与 response 结果对象)作为新 part 追加到 contents 再次请求,即可完成闭环。
JSON 模式示例
"generationConfig": {
"responseMimeType": "application/json",
"responseSchema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"]
}
}
仅设置 responseMimeType: application/json 时为宽松 JSON 模式;同时提供 responseSchema 时按 Schema 强约束输出(网关内部 strict 固定为 false 以兼容更多模型)。
响应示例
{
"candidates": [
{
"content": {
"parts": [
{"text": "量子计算利用量子比特的叠加与纠缠特性,对特定问题实现远超经典计算机的并行求解能力。"}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0,
"safetyRatings": []
}
],
"usageMetadata": {
"promptTokenCount": 24,
"candidatesTokenCount": 38,
"totalTokenCount": 62
},
"modelVersion": "gemini-2.5-pro"
}
响应字段与 OpenAI 的对应关系
finishReason由上游finish_reason映射:stop→STOP、length/max_tokens→MAX_TOKENS、content_filter→SAFETY。- 上游的
reasoning_content思考内容会作为独立 part 返回,带"thought": true标记。 - 上游
tool_calls会还原为 parts 中的functionCall(name+ 对象形式的args)。 usageMetadata三项分别对应 OpenAI 的prompt_tokens、completion_tokens、total_tokens;modelVersion回填为你请求的展示模型名。
/v1beta/models/{model}:generateContent 外,网关还兼容 /v1/gemini/{model}/generateContent 路径写法;模型名不区分大小写,未携带密钥返回 401 YZ1001,密钥无效返回 401 YZ1002。
流式生成 streamGenerateContent#
与 generateContent 参数完全一致,但响应为 Server-Sent Events 事件流,模型每生成一个增量片段就推送一条 data: 行。适用于聊天界面打字机效果、长文本实时输出等低首字延迟场景。请求体参数、字段映射与约束均同上一节,不再重复。
https://yunzhiapi.cn/v1beta/models/{model}:streamGenerateContent鉴权方式
使用 x-goog-api-key 请求头或 ?key= 查询参数,与 generateContent 相同。
触发流式的两种方式
- 使用
:streamGenerateContentaction(标准写法)。 - 在
:generateContent上附加查询参数?alt=sse,网关同样按流式处理。
请求示例
curl "https://yunzhiapi.cn/v1beta/models/gemini-2.5-pro:streamGenerateContent" \
-H "x-goog-api-key: sk-你的密钥" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{"role": "user", "parts": [{"text": "写一首关于春天的短诗"}]}
]
}'
响应示例(SSE 事件流)
响应头为 Content-Type: text/event-stream,每条事件是一个完整的 Gemini 响应片段 JSON:
data: {"candidates":[{"content":{"parts":[{"text":"春风"}],"role":"model"},"index":0,"safetyRatings":[]}]}
data: {"candidates":[{"content":{"parts":[{"text":"拂过柳梢,"}],"role":"model"},"index":0,"safetyRatings":[]}]}
data: {"candidates":[{"content":{"parts":[{"text":"唤醒一城新绿。"}],"role":"model"},"index":0,"safetyRatings":[]}]}
data: {"candidates":[{"content":{"parts":[{"text":""}],"role":"model"},"finishReason":"STOP","index":0,"safetyRatings":[]}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":18,"totalTokenCount":30}}
流式事件还原规则
- 每个 chunk 都包装为
{"candidates":[{"content":{"parts":[...],"role":"model"},"index":0,"safetyRatings":[]}]}结构。 - 思考增量以
{"text":"...","thought":true}part 推送;正文增量为普通{"text":"..."}part。 finishReason只在结束 chunk 出现,映射规则与非流式一致(STOP/MAX_TOKENS/SAFETY)。usageMetadata仅当上游在流中回传了真实用量时附加在末尾 chunk;若上游未提供则不会出现。- 函数调用在结束时一次性以
functionCallpart 输出(参数聚合完整后随带finishReason的 chunk 下发)。
与 OpenAI 流式的差异
| 对比项 | OpenAI 协议 | Gemini 协议 |
|---|---|---|
| 结束标记 | data: [DONE] | 无结束标记,以连接关闭或末块 finishReason 判定 |
| 事件结构 | 仅 data: 行 | 仅 data: 行 |
| usage 下发时机 | 末尾 chunk(服务端强制开启) | 仅上游提供时附加在末块 |
| 思考内容载体 | reasoning_content 字段 | {"thought":true} part |
data: [DONE] 结束标记,客户端应以连接关闭或最后一个带 finishReason 的 chunk 判定结束;这与 OpenAI 协议的流式约定不同,混用 SDK 时需注意。
令牌计数 countTokens#
在正式发起生成请求前预估输入 token 数,用于成本预估与上下文长度控制。该端点在网关本地完成估算:将 Gemini 请求转换为内部消息格式后按文本估算,不转发上游、不消耗模型调用、不计费,仅做鉴权与限流检查。
https://yunzhiapi.cn/v1beta/models/{model}:countTokens鉴权方式
使用 x-goog-api-key 请求头或 ?key= 查询参数。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
contents |
array | 必填 | 与 generateContent 相同的对话内容数组;也可改为传 generateContentRequest 包裹的完整生成请求(网关会自动解包) |
systemInstruction |
string | object | 可选 | 系统指令,计入 token 估算 |
tools |
array | 可选 | 工具声明,其 JSON 文本会一并计入估算 |
请求示例
curl "https://yunzhiapi.cn/v1beta/models/gemini-2.5-pro:countTokens" \
-H "x-goog-api-key: sk-你的密钥" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{"role": "user", "parts": [{"text": "用一句话介绍量子计算"}]}
]
}'
响应示例
{
"totalTokens": 24
}
使用建议
- 批量任务执行前调用本接口预估总量,结合模型单价评估成本,避免余额不足中断。
- 长上下文应用可在每轮对话后计数,超过窗口 80% 时触发摘要或截断策略。
- 本接口不校验模型是否存在,拼写错误不会报错,仅影响估算的参考意义。
图像生成 predict(Imagen)#
Gemini 协议的图像生成端点(Vertex AI 风格),接收 instances 提示词数组并返回 predictions 图像数组。网关将每个 instance 的提示词转换为上游 OpenAI /v1/images/generations 请求,再把图像结果还原为 Gemini predictions 格式。适用于 Imagen 系列模型与 Vertex AI SDK 迁移场景。
https://yunzhiapi.cn/v1beta/models/{model}:predict鉴权方式
使用 x-goog-api-key 请求头或 ?key= 查询参数。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
instances |
array | 必填 | 生成实例数组,每项为 {"prompt":"..."} 对象或纯字符串;空数组或缺失返回 400,空提示词的项会被跳过 |
parameters.sampleCount |
integer | 可选 | 每个提示词生成的图片数量,默认 1,超限时自动钳制到平台允许的最大值 |
parameters.aspectRatio |
string | 可选 | 宽高比,映射为上游尺寸,见下表 |
aspectRatio 映射
| aspectRatio | 映射上游尺寸 |
|---|---|
9:16 | 1024x1792(竖版) |
16:9 | 1792x1024(横版) |
| 其他值 / 缺省 | 1024x1024(方形) |
请求示例
curl "https://yunzhiapi.cn/v1beta/models/imagen-3.0-generate-002:predict" \
-H "x-goog-api-key: sk-你的密钥" \
-H "Content-Type: application/json" \
-d '{
"instances": [
{"prompt": "一只在樱花树下打盹的橘猫,水彩风格"}
],
"parameters": {
"sampleCount": 1,
"aspectRatio": "16:9"
}
}'
响应示例
{
"predictions": [
{
"bytesBase64Encoded": "iVBORw0KGgoAAAANSUhEUgAA...",
"mimeType": "image/png"
}
]
}
与 OpenAI 图像接口的对应关系
- 每个 instance 独立调用一次上游
/v1/images/generations,请求体为{"model":后端模型名,"prompt":提示词,"n":sampleCount,"size":映射尺寸}。 - 上游返回
b64_json时还原为bytesBase64Encoded;返回url时还原为url字段,mimeType均标记为image/png。 - 多个 instance 的图像结果按顺序合并到同一个
predictions数组中。
视频生成 predictLongRunning(Veo)#
Gemini 协议的长任务视频生成端点(Veo 系列)。网关在内部将请求转换为上游 /v1/videos/generations 的同步调用,等待视频生成完成后,把结果包装为 Google 长运行操作(Long-Running Operation)对象返回,done 直接为 true,无需真实轮询。
https://yunzhiapi.cn/v1beta/models/{model}:predictLongRunning鉴权方式
使用 x-goog-api-key 请求头或 ?key= 查询参数。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
instances |
array | 必填 | 生成实例数组,仅取第一项的 prompt(对象或纯字符串)作为视频提示词 |
parameters.sampleCount |
integer | 可选 | 生成视频数量,映射为上游 n,超限时自动钳制 |
parameters.durationSeconds |
integer | 可选 | 视频时长(秒),映射为上游 duration |
parameters.aspectRatio |
string | 可选 | 宽高比(如 16:9),映射为上游 aspect_ratio,原样透传 |
参数映射关系
| Gemini 参数 | 上游字段 | 说明 |
|---|---|---|
instances[0].prompt | prompt | 仅取第一项提示词 |
parameters.sampleCount | n | 钳制到 [1, 5] |
parameters.durationSeconds | duration | 视频时长(秒) |
parameters.aspectRatio | aspect_ratio | 原样透传 |
请求示例
curl "https://yunzhiapi.cn/v1beta/models/veo-3.0-generate-001:predictLongRunning" \
-H "x-goog-api-key: sk-你的密钥" \
-H "Content-Type: application/json" \
-d '{
"instances": [
{"prompt": "夕阳下海浪拍打礁石,电影感慢镜头"}
],
"parameters": {
"sampleCount": 1,
"durationSeconds": 8,
"aspectRatio": "16:9"
}
}'
响应示例
{
"name": "operations/yz-550e8400-e29b-41d4-a716-446655440000",
"done": true,
"response": {
"@type": "type.googleapis.com/google.ai.generativelanguage.v1beta.PredictLongRunningResponse",
"generateVideoResponse": {
"generatedSamples": [
{
"video": {
"uri": "https://cdn.example.com/videos/abc123.mp4"
}
}
]
}
}
}
长任务处理流程
- 向
:predictLongRunning提交请求,网关同步等待上游视频生成完成(该过程可能耗时较长,请为客户端设置充足的超时时间)。 - 检查返回 operation 对象的
done字段:本网关始终在完成后再响应,故直接为true,name(operations/yz-+ 请求 ID)仅作协议兼容标识。 - 从
response.generateVideoResponse.generatedSamples读取视频:上游返回 URL 时取video.uri,返回 base64 时取video.bytesBase64Encoded。 - 若客户端实现了 Google 标准的 operation 轮询逻辑,可直接跳过轮询分支——网关不单独提供 operation 查询端点,收到响应即代表任务已结束。
与 OpenAI 视频接口的对应关系
- 请求体被转换为
{"model":后端模型名,"prompt":提示词,"n":sampleCount,"duration":时长,"aspect_ratio":宽高比}后调用上游/v1/videos/generations。 - 上游
data数组中的url/b64_json分别还原为video.uri/video.bytesBase64Encoded。 @type固定为PredictLongRunningResponse,与 Google 官方 Veo 响应结构一致,官方 SDK 可直接反序列化。
模型列表(Gemini 格式)#
以 Gemini 原生格式返回当前可用的模型列表,供 Google AI SDK 发现模型与能力。每个模型条目包含 models/ 前缀的资源名、token 上限与支持的生成方法。
https://yunzhiapi.cn/v1beta/models鉴权方式
使用 x-goog-api-key 请求头或 ?key= 查询参数。此外,对 GET /v1/models 携带 x-goog-api-key 头或 ?key= 参数时,网关同样返回本 Gemini 格式列表(未携带时返回 OpenAI 格式)。
请求示例
curl "https://yunzhiapi.cn/v1beta/models" \ -H "x-goog-api-key: sk-你的密钥"
响应示例
{
"models": [
{
"name": "models/gemini-2.5-pro",
"version": "1.0",
"displayName": "gemini-2.5-pro",
"description": "Proxy model hosted by Yunzhi API",
"inputTokenLimit": 1048576,
"outputTokenLimit": 8192,
"supportedGenerationMethods": ["generateContent", "countTokens"],
"temperature": 1.0,
"topP": 0.95,
"topK": 40
}
]
}
字段说明
| 字段 | 说明 |
|---|---|
name | models/ + 展示名,可直接用于生成接口路径 |
displayName | 模型展示名,与 OpenAI 格式的 id 一致 |
inputTokenLimit / outputTokenLimit | 对外展示的窗口参考值,不代表实际上游限制 |
supportedGenerationMethods | 固定为 ["generateContent","countTokens"] |
temperature / topP / topK | 默认采样参数参考值 |
与 OpenAI 模型列表的对应关系
name为models/+ 对外展示名,displayName即 OpenAI 格式中的id,请求生成接口时两者均可使用。supportedGenerationMethods固定为["generateContent","countTokens"],inputTokenLimit/outputTokenLimit为对外展示值,不代表实际上游限制。- 同一份模型清单也支持 OpenAI 格式(
{"object":"list","data":[...]})与 Anthropic 格式输出,由请求携带的鉴权头自动判定。
displayName 即可,网关转发上游时会自动替换为后端模型名。
流式输出 SSE#
在请求体中加入 "stream": true 后,网关将以 Server-Sent Events(SSE)方式实时推送生成内容。响应头如下:
HTTP/1.1 200 OK Content-Type: text/event-stream; charset=utf-8 Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: 0 X-Accel-Buffering: no Connection: keep-alive Transfer-Encoding: chunked X-Resume-Token: rst_9f2c…(32 位十六进制)
网关在下发头部时会清空 PHP 全部输出缓冲区,并显式发送 X-Accel-Buffering: no,确保 Nginx 等反向代理不做响应缓冲、逐块直发。
帧结构
每个 SSE 事件以空行结尾。OpenAI 协议下每个事件只有一行 data:,流末尾发送 data: [DONE] 作为结束标记:
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","created":1721000000,"model":"gpt-4o","choices":[{"index":0,"delta":{"role":"assistant","content":"你好"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","created":1721000000,"model":"gpt-4o","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
三种协议的流式事件差异
| 协议 | 事件形式 | 关键事件序列 | 结束标记 |
|---|---|---|---|
| OpenAI / Gemini | 仅 data: 行(无 event: 行) | OpenAI 透传 chat.completion.chunk;Gemini 逐块输出 candidates[].content.parts,思维链以 {"text":…,"thought":true} 表示,末块携带 finishReason(STOP / MAX_TOKENS / SAFETY)与 usageMetadata | data: [DONE] |
| Anthropic | event: + data: 成对出现 | message_start → content_block_start → 若干 content_block_delta(text_delta / thinking_delta / input_json_delta)→ content_block_stop → message_delta(含 stop_reason 与 usage)→ message_stop | message_stop 事件 |
| Responses API | event: + data: 成对出现 | response.created → response.in_progress → response.output_item.added → response.content_part.added → 若干 response.output_text.delta → response.output_text.done → response.output_item.done → response.completed | response.completed 事件 |
流式工具调用在各协议下分别映射为:OpenAI 的 delta.tool_calls 增量、Anthropic 的 tool_use content block(参数经 input_json_delta 下发)、Responses 的 response.function_call_arguments.delta/done。
心跳机制
头部下发后,若超过 5 秒没有新数据,网关会自动发送心跳防止连接被中间链路断开:
- Anthropic 协议:
event: ping+data: {"type":"ping"} - 其他协议:SSE 注释行
: keep-alive
客户端解析器应忽略以 : 开头的注释行。网关同时启用了低速检测:上游连续 120 秒传输速率低于 1 字节/秒会判定连接失效并终止。
客户端解析示例
由于浏览器原生 EventSource 只支持 GET 且无法自定义请求头,POST 流式请求需使用 fetch 手动解析:
const resp = await fetch("https://api.example.com/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": "Bearer sk-xxx",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "gpt-4o",
stream: true,
messages: [{ role: "user", content: "你好" }]
})
});
const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buf = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buf += decoder.decode(value, { stream: true });
const events = buf.split("\n\n");
buf = events.pop();
for (const ev of events) {
for (const line of ev.split("\n")) {
if (!line.startsWith("data:")) continue;
const payload = line.slice(5).trim();
if (payload === "[DONE]") return;
const chunk = JSON.parse(payload);
const text = chunk.choices?.[0]?.delta?.content;
if (text) process.stdout.write(text);
}
}
}
import json
import requests
resp = requests.post(
"https://api.example.com/v1/chat/completions",
headers={"Authorization": "Bearer sk-xxx"},
json={
"model": "gpt-4o",
"stream": True,
"messages": [{"role": "user", "content": "你好"}],
},
stream=True,
timeout=600,
)
for line in resp.iter_lines(decode_unicode=True):
if not line or line.startswith(":"):
continue
if line.startswith("data:"):
payload = line[5:].strip()
if payload == "[DONE]":
break
chunk = json.loads(payload)
text = chunk["choices"][0]["delta"].get("content")
if text:
print(text, end="", flush=True)
性能与体验建议
- 首 token 到达即开始渲染,不要等待完整响应;打字机效果可按 20~30ms 节流合并增量,避免高频 DOM 更新。
- 客户端读超时应按「事件空闲间隔」设置(如 60 秒无事件再断开),而非请求总时长;网关流式不限制总时长。
- 解析器必须容忍注释行(
:开头)与ping事件,它们是保活心跳而非内容。 - 断线后优先走「断点续传」恢复,而不是重新发起生成,可避免重复计费与内容跳变。
X-Accel-Buffering: no,但如果你前面还有自建 Nginx / CDN / 网关层,请确认它们未开启 proxy_buffering 或响应压缩缓冲,否则 SSE 会被攒批延迟下发。客户端请使用流式读取(如 iter_lines、ReadableStream),不要等待完整响应体。非流式请求网关侧超时为 600 秒,流式请求不限制总时长(仅受 120 秒低速检测约束),客户端超时应相应放宽。断点续传 Resume#
流式响应期间网络中断时,网关支持从断点继续接收剩余的 SSE 数据,已生成的内容不会丢失,也不会重复扣费。
X-Resume-Token 响应头
每个流式响应的头部都会携带一个续传令牌,格式为 rst_ 前缀 + 32 位十六进制字符(由 random_bytes(16) 生成):
X-Resume-Token: rst_4f8a2c1e9b7d3f605a8e1c2b4d6f8093
网关在流式过程中会把每一条 SSE 帧按序号(chunk_index)写入续传缓冲表(mxgapi_stream_buffer),每积累 50 条批量落库一次,流结束时强制刷新剩余缓冲。
恢复方式
断线后,使用相同的请求体重新发起请求,并通过以下任一方式携带令牌:
- 请求头
X-Resume-Token: rst_…(推荐) - 请求头
Last-Event-ID: rst_…(兼容 SSE 标准客户端自动重连) - 查询参数
?last_event_id=rst_…
curl -N https://api.example.com/v1/chat/completions \
-H "Authorization: Bearer sk-xxx" \
-H "Content-Type: application/json" \
-H "X-Resume-Token: rst_4f8a2c1e9b7d3f605a8e1c2b4d6f8093" \
-d '{"model":"gpt-4o","stream":true,"messages":[{"role":"user","content":"你好"}]}'
恢复时的行为分三种情况:
- 原请求已完成:网关按序回放缓冲中已保存的 SSE 帧,直到
[DONE]/message_stop/response.completed,随后关闭连接。 - 原请求仍在进行中:网关先回放已有缓冲,然后每 0.5 秒轮询一次数据库增量回放新产生的帧,最长等待 300 秒,直到原请求终结或客户端断开。
- 无缓冲数据:视为普通重复请求处理(见幂等章节的 429 行为)。
完整恢复流程
- 发起流式请求后,从响应头读取并持久化
X-Resume-Token与已接收的帧序号。 - 检测到连接中断(读超时、连接重置)后,保持原请求体不变,附加令牌重新发起请求。
- 网关回放缓冲帧时,客户端按帧序号与本地已渲染内容比对,跳过重复部分后继续拼接。
- 收到结束标记(
[DONE]/message_stop/response.completed)后清理本地令牌。 - 若令牌已过期(2 小时)或返回 404,降级为重新发起完整生成请求。
有效期与限制
| 项目 | 数值 / 说明 |
|---|---|
| 缓冲保留时长 | 2 小时(超过后由后台概率性清理删除,令牌失效) |
| 单次回放上限 | 最多回放 15000 条缓冲帧 |
| 单帧长度上限 | 单条 SSE 帧超过 65000 字节时落库前会被截断 |
| 请求绑定 | 令牌与 API Key 绑定,且需配合相同请求体(命中同一幂等键)才能恢复 |
| 处理中窗口 | 仅当原请求处于 pending 且未超过 180 秒处理中锁定时可续传;否则按幂等冲突或已完成回放处理 |
客户端实现建议
- 在每次收到事件后更新本地持久化的令牌与序号,确保任意时刻断开都能从最近点恢复。
- 恢复请求与原请求使用同一个
X-Idempotency-Key,可复用幂等记录避免冲突。 - 移动端弱网环境建议将读超时设为 30~60 秒并自动触发续传,用户无感知。
ignore_user_abort 运行),不会因为你断开而取消,费用按最终完整用量结算一次。幂等重试 Idempotency#
网关为每个请求计算幂等键,保证网络重试、客户端超时重发不会造成重复扣费或重复执行。
幂等键来源优先级
X-Idempotency-Key请求头(最高优先级,推荐显式提供)X-Request-Id请求头- 请求体特征:对请求体原文计算 SHA-256 并取前 16 位十六进制作为指纹
最终幂等键由 API Key + 来源类型 + 客户端键 + 请求体指纹 拼接而成(最长 128 字符),因此同一个 X-Idempotency-Key 搭配不同的请求体会返回 409 与错误码 YZ3008,提示该键已被用于其他请求。
幂等键设计建议
- 推荐为每个逻辑请求生成 UUID v4 作为幂等键,重试期间保持不变。
- 业务系统可使用「业务ID + 时间窗口」组合键,天然防止同一业务重复提交。
- 切勿对多个不同请求复用同一个键,也不要为同一请求的每次重试生成新键。
- 请求体任何改动都会改变指纹,重试时请保持请求体逐字节一致。
命中回放
当幂等记录状态为 completed 且有缓存结果时,网关直接返回首次请求的响应(HTTP 200),并附带响应头:
HTTP/1.1 200 OK X-Idempotency-Hit: true Content-Type: application/json; charset=utf-8
命中回放的响应不会再次扣费。缓存结果会按当前请求的协议(OpenAI / Anthropic / Gemini / Responses)重新转换格式后返回。仅非流式且响应体不超过 65535 字节的结果会被缓存;流式请求的"回放"请使用断点续传机制。
记录状态机
| 记录状态 | 含义 | 重复请求行为 |
|---|---|---|
pending(≤ 180 秒) | 首次请求处理中 | 返回 429 YZ3008 + Retry-After |
completed(已缓存) | 处理完成且结果已缓存 | 200 直接回放,附 X-Idempotency-Hit: true,不计费 |
completed(未缓存) | 处理完成但结果过大或为流式 | 作为新请求重新执行并正常计费 |
failed | 首次请求失败 | 作为新请求重新执行(失败请求本就不计费) |
pending 超过 180 秒 | 陈旧锁 | 原记录标记为 failed,允许新请求重新执行 |
处理中锁定(429 YZ3008)
若相同幂等键的请求仍在处理中(pending 状态未超过 180 秒),后续重复请求会被拒绝:
HTTP/1.1 429 Too Many Requests
Retry-After: 87
{
"error": {
"message": "Duplicate request is being processed.",
"type": "rate_limit_error",
"param": null,
"code": "YZ3008",
"request_id": "req_…",
"hint": "Use a unique X-Idempotency-Key for each distinct request."
}
}
Retry-After 的值为 180 - 已处理秒数(最小 1 秒)。已完成 / 已失败的幂等记录保留 24 小时后由后台概率性清理。
客户端重试最佳实践
对 429 / 5xx / 网络错误,建议使用指数退避加随机抖动重试,并固定同一个 X-Idempotency-Key,确保多次重试在服务端被识别为同一逻辑请求:
import random
import time
import uuid
import requests
IDEMPOTENCY_KEY = str(uuid.uuid4())
def chat_with_retry(payload, max_retries=5):
url = "https://api.example.com/v1/chat/completions"
headers = {
"Authorization": "Bearer sk-xxx",
"Content-Type": "application/json",
"X-Idempotency-Key": IDEMPOTENCY_KEY,
}
for attempt in range(max_retries + 1):
try:
resp = requests.post(url, headers=headers, json=payload, timeout=600)
except requests.RequestException:
resp = None
if resp is not None and resp.status_code < 500 and resp.status_code != 429:
return resp
if attempt == max_retries:
break
if resp is not None and resp.headers.get("Retry-After"):
delay = float(resp.headers["Retry-After"])
else:
delay = min(0.5 * (2 ** attempt), 30) + random.uniform(0, 0.5)
time.sleep(delay)
return resp
X-Idempotency-Key,也不要修改请求体;优先遵守响应头 Retry-After;退避间隔按 0.5s × 2^n 增长并封顶 30 秒,叠加随机抖动避免惊群。命中 X-Idempotency-Hit: true 的响应可直接使用,代表这是首次结果的回放。错误映射 Mapping#
当上游 AI 服务返回错误时,网关会将其统一映射为对外的 HTTP 状态码与 YZ 前缀错误码。若上游响应体中包含 error.message,会截取前 200 字符附加在网关消息之后。
上游 HTTP 状态码映射表
| 上游状态码 | 对外状态码 | 网关错误码 | 对外消息 |
|---|---|---|---|
| 400 | 400 | YZ5005 | Request rejected by upstream(附上游消息) |
| 401 | 502 | YZ5005 | Upstream authentication failed, please contact support. |
| 403 | 502 | YZ5005 | Request rejected by upstream safety policy(附上游消息) |
| 404 | 404 | YZ4001 | Model not available on upstream(附上游消息) |
| 422 | 400 | YZ3007 | Parameter format unprocessable(附上游消息) |
| 429 | 429 | YZ1003 | Upstream rate limit exceeded, please retry later. |
| 503 | 503 | YZ5005 | Upstream under maintenance, please retry later. |
| 504 | 504 | YZ5001 | Upstream gateway timeout, please retry later. |
| 其他 5xx(500/502/505…) | 502 | YZ5005 | Upstream service error (HTTP {code})(附上游消息) |
| 其他未列出的状态码 | 502 | YZ5005 | Upstream anomaly (HTTP {code}) |
传输层(curl)错误映射表
| 传输层错误 | 对外状态码 | 网关错误码 | 对外消息 |
|---|---|---|---|
| 连接/读取超时 | 502 | YZ5001 | AI service response timeout, please retry. |
| 无法建立连接 / 收发中断 | 502 | YZ5002 | Unable to connect to AI service, please retry later. |
| DNS 解析失败 | 502 | YZ5003 | Unable to resolve AI service domain, please retry later. |
| TLS 握手失败 | 502 | YZ5004 | SSL/TLS handshake error, please retry. |
| 上游无数据返回 | 502 | YZ5006 | Upstream returned no data, please retry. |
| 上游返回非 JSON 响应 | 502 | YZ5007 | Upstream returned non-JSON response. |
| 熔断器打开 | 503 | YZ5008 | Upstream circuit breaker open, please retry later. |
所有上游失败场景网关都会全额退还预扣余额,并将幂等记录标记为 failed,客户端可安全重试。
流内错误事件
流式响应中若头部已下发后上游中断,HTTP 状态码不再改变,网关改为在流内发送错误事件,客户端解析器需处理这些事件:
: error {"code":"YZ5001","message":"AI service response timeout, please retry.","request_id":"req_..."}
data: [DONE]
event: error
data: {"type":"error","error":{"type":"api_error","message":"AI service response timeout, please retry. (code: YZ5001)"}}
event: message_stop
data: {"type":"message_stop"}
event: response.failed
data: {"type":"response.failed","response":{"id":"resp_...","status":"failed","error":{"code":"YZ5001","message":"AI service response timeout, please retry."}}}
重试与熔断行为
- 网关侧重试:对同步上游请求(图像 / 语音等辅助通道)内置指数退避重试,最多重试 2 次(共 3 次尝试),仅对
408 / 429 / 500 / 502 / 503 / 504重试;退避间隔为150ms × 2^attempt(即 300ms、600ms)。主聊天通道不做自动重试,错误直接映射返回,由客户端按幂等章节策略重试。 - 熔断器:按上游 host 维度统计,连续失败达到 5 次即打开熔断,期间所有请求直接返回
503 YZ5008不再穿透上游;60 秒后进入半开状态,放行 1 个探测请求,成功则闭合,失败则重新打开。熔断状态跨请求持久化于服务端临时目录。 - 超时:上游连接超时 30 秒;非流式总超时 600 秒;流式不限制总时长,但连续 120 秒速率低于 1 字节/秒即判定失效。
健康检查 Health#
健康检查端点用于探活与监控,无需鉴权,不消耗配额,也不触发限流之外的任何业务逻辑。
GET /health
等效路径还有 /v1/health 与 /ping,三者行为完全一致。
响应示例
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"status": "ok",
"timestamp": 1721000000
}
| 字段 | 类型 | 说明 |
|---|---|---|
status | string | 固定为 "ok",表示网关进程可正常响应 |
timestamp | integer | 服务器当前 Unix 时间戳(秒),可用于时钟偏移检测 |
探针配置示例(Kubernetes)
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 3
periodSeconds: 10
UptimeRobot 等第三方监控直接填入 https://yunzhiapi.cn/health 即可,期望状态码 200;timestamp 与本地时钟偏差持续超过 30 秒时,建议检查服务器 NTP 同步。
GET /v1/models 请求。OpenAI SDK#
网关完整兼容 OpenAI Chat Completions 协议(POST https://yunzhiapi.cn/v1/chat/completions),官方 openai SDK 只需把 base_url 指向本网关即可使用,支持非流式、流式与异步调用。
安装
pip install openai
npm install openai
配置要点
| 配置项 | 取值 | 说明 |
|---|---|---|
base_url / baseURL | https://yunzhiapi.cn/v1 | 必须以 /v1 结尾 |
api_key / apiKey | sk- 开头的密钥 | 以 Authorization: Bearer 头发送 |
model | 模型名 | 可先用 GET /v1/models 查询 |
Python 示例(非流式 + 流式)
from openai import OpenAI
client = OpenAI(
base_url="https://yunzhiapi.cn/v1",
api_key="sk-your-key",
)
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "你好"}],
)
print(resp.choices[0].message.content)
stream = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "写一首短诗"}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
Python 异步示例
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI(
base_url="https://yunzhiapi.cn/v1",
api_key="sk-your-key",
)
async def main():
resp = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "你好"}],
)
print(resp.choices[0].message.content)
asyncio.run(main())
Node.js 示例(非流式 + 流式)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://yunzhiapi.cn/v1",
apiKey: "sk-your-key",
});
const resp = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "你好" }],
});
console.log(resp.choices[0].message.content);
const stream = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "写一首短诗" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
环境变量配置
设置以下环境变量后,可省略构造函数中的 base_url 与 api_key 参数,SDK 会自动读取:
export OPENAI_BASE_URL="https://yunzhiapi.cn/v1" export OPENAI_API_KEY="sk-your-key"
超时与内置重试
client = OpenAI( base_url="https://yunzhiapi.cn/v1", api_key="sk-your-key", timeout=600.0, max_retries=2, )
SDK 内置重试仅对网络层与部分 5xx 错误生效;涉及扣费的生成请求请同时携带 X-Idempotency-Key(通过 extra_headers 传入),确保重试不重复计费。
base_url 必须以 /v1 结尾,写成根地址会得到 404;流式响应必须传 stream=True 并逐 chunk 读取 delta.content,不要直接取 choices[0].message;环境变量名是 OPENAI_BASE_URL,不是 OPENAI_API_BASE(后者是旧版 SDK 的变量名)。Anthropic SDK#
网关兼容 Anthropic Messages 协议(POST https://yunzhiapi.cn/v1/messages),官方 anthropic SDK 把 base_url 指向本网关根地址即可,支持非流式与流式调用。
安装
pip install anthropic
npm install @anthropic-ai/sdk
配置要点
| 配置项 | 取值 | 说明 |
|---|---|---|
base_url / baseURL | https://yunzhiapi.cn | 不带 /v1,SDK 自动追加 /v1/messages |
api_key / apiKey | sk- 开头的密钥 | 以 x-api-key 头发送 |
auth_token | sk- 开头的密钥 | 可选,改用 Authorization: Bearer 头发送 |
max_tokens | 必填 | Anthropic 协议强制要求 |
Python 示例(非流式 + 流式)
import anthropic
client = anthropic.Anthropic(
base_url="https://yunzhiapi.cn",
api_key="sk-your-key",
)
msg = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": "你好"}],
)
print(msg.content[0].text)
with client.messages.stream(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": "写一首短诗"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Node.js 示例(非流式 + 流式)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://yunzhiapi.cn",
apiKey: "sk-your-key",
});
const msg = await client.messages.create({
model: "claude-sonnet-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: "你好" }],
});
console.log(msg.content[0].text);
const stream = client.messages.stream({
model: "claude-sonnet-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: "写一首短诗" }],
});
for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
process.stdout.write(event.delta.text);
}
}
环境变量配置
export ANTHROPIC_BASE_URL="https://yunzhiapi.cn" export ANTHROPIC_API_KEY="sk-your-key"
也可以改用 ANTHROPIC_AUTH_TOKEN 代替 ANTHROPIC_API_KEY,此时密钥以 Authorization: Bearer 头发送,网关两种鉴权头均支持,二选一即可。
超时配置
Python SDK 通过 anthropic.Anthropic(..., timeout=600.0) 设置总超时;Node.js SDK 通过构造参数 timeout: 600 * 1000 设置。长文本与推理模型建议不低于 600 秒。
base_url 不要带 /v1,SDK 会自行拼接 /v1/messages,手动带上会变成 /v1/v1/messages 导致 404;max_tokens 为必填参数,漏传会直接报参数错误;流式事件的文本在 content_block_delta 的 text_delta 里,需按事件类型过滤。Gemini SDK#
网关兼容 Gemini generateContent 协议(POST https://yunzhiapi.cn/v1beta/models/模型名:generateContent),使用 Google 官方新版 SDK(Python 的 google-genai、Node.js 的 @google/genai),通过 httpOptions 把 baseUrl 指向本网关即可。
安装
pip install google-genai
npm install @google/genai
配置要点
| 配置项 | 取值 | 说明 |
|---|---|---|
httpOptions.baseUrl | https://yunzhiapi.cn | 网关根地址,SDK 自动追加 /v1beta/models/... |
apiKey | sk- 开头的密钥 | 以 x-goog-api-key 头发送 |
model | 模型名 | 如 gemini-2.5-flash |
Python 示例(非流式 + 流式)
from google import genai from google.genai import types client = genai.Client( api_key="sk-your-key", http_options=types.HttpOptions(base_url="https://yunzhiapi.cn"), ) resp = client.models.generate_content( model="gemini-2.5-flash", contents="你好", ) print(resp.text) for chunk in client.models.generate_content_stream( model="gemini-2.5-flash", contents="写一首短诗", ): print(chunk.text, end="", flush=True)
Node.js 示例(非流式 + 流式)
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({
apiKey: "sk-your-key",
httpOptions: { baseUrl: "https://yunzhiapi.cn" },
});
const resp = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: "你好",
});
console.log(resp.text);
const stream = await ai.models.generateContentStream({
model: "gemini-2.5-flash",
contents: "写一首短诗",
});
for await (const chunk of stream) {
process.stdout.write(chunk.text ?? "");
}
环境变量配置
export GEMINI_API_KEY="sk-your-key"
SDK 按 GEMINI_API_KEY → GOOGLE_API_KEY 的顺序读取密钥,设置其中一个即可省略构造函数里的 api_key;两者同时设置时以 GEMINI_API_KEY 为准。注意环境变量只覆盖密钥,baseUrl 仍需在代码中显式指定。
超时与版本
Python SDK 可在 HttpOptions 中追加 timeout=600(秒);Node.js SDK 通过 httpOptions: { baseUrl, timeout: 600000 }(毫秒)设置。SDK 默认使用 v1beta 前缀,与网关完全兼容,无需手动指定 api_version。
google-genai / @google/genai 包,旧版 google-generativeai(@google/generative-ai)不支持自定义 baseUrl;baseUrl 填网关根地址即可,不要手动拼 /v1beta;流式接口也可在 URL 上加 ?alt=sse 强制 SSE 输出。原生 HTTP 调用#
不依赖任何 SDK,直接向 POST https://yunzhiapi.cn/v1/chat/completions 发送 JSON 即可。以下示例均包含错误处理,并读取响应头 X-Request-ID 用于问题追踪。
配置要点
- 请求头
Authorization: Bearer sk-你的密钥(也可用x-api-key或x-goog-api-key)。 - 请求体为 OpenAI Chat Completions 格式 JSON,
model与messages必填。 - 非 2xx 状态码时响应体为 OpenAI 风格错误 JSON;务必读取并记录
X-Request-ID。
Python requests
import requests
url = "https://yunzhiapi.cn/v1/chat/completions"
headers = {
"Authorization": "Bearer sk-your-key",
"Content-Type": "application/json",
}
payload = {
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "你好"}],
}
try:
resp = requests.post(url, headers=headers, json=payload, timeout=60)
resp.raise_for_status()
print("X-Request-ID:", resp.headers.get("X-Request-ID", ""))
print(resp.json()["choices"][0]["message"]["content"])
except requests.HTTPError as e:
print("HTTP", e.response.status_code, e.response.text)
except requests.RequestException as e:
print("请求失败:", e)
Node.js fetch
const url = "https://yunzhiapi.cn/v1/chat/completions";
try {
const resp = await fetch(url, {
method: "POST",
headers: {
"Authorization": "Bearer sk-your-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "你好" }],
}),
});
console.log("X-Request-ID:", resp.headers.get("x-request-id") ?? "");
if (!resp.ok) {
throw new Error("HTTP " + resp.status + " " + (await resp.text()));
}
const data = await resp.json();
console.log(data.choices[0].message.content);
} catch (err) {
console.error("请求失败:", err.message);
}
PHP cURL
<?php
$url = 'https://yunzhiapi.cn/v1/chat/completions';
$payload = json_encode([
'model' => 'gpt-4o-mini',
'messages' => [['role' => 'user', 'content' => '你好']],
]);
$requestId = '';
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer sk-your-key',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HEADERFUNCTION => function ($ch, $line) use (&$requestId) {
if (stripos($line, 'X-Request-ID:') === 0) {
$requestId = trim(substr($line, 13));
}
return strlen($line);
},
]);
$body = curl_exec($ch);
if ($body === false) {
fwrite(STDERR, '请求失败: ' . curl_error($ch) . PHP_EOL);
curl_close($ch);
exit(1);
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo 'X-Request-ID: ' . $requestId . PHP_EOL;
if ($status !== 200) {
fwrite(STDERR, 'HTTP ' . $status . ': ' . $body . PHP_EOL);
exit(1);
}
$data = json_decode($body, true);
echo $data['choices'][0]['message']['content'] . PHP_EOL;
Go net/http
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
func main() {
url := "https://yunzhiapi.cn/v1/chat/completions"
payload := map[string]interface{}{
"model": "gpt-4o-mini",
"messages": []map[string]string{
{"role": "user", "content": "你好"},
},
}
body, err := json.Marshal(payload)
if err != nil {
fmt.Println("序列化失败:", err)
return
}
req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body))
if err != nil {
fmt.Println("构造请求失败:", err)
return
}
req.Header.Set("Authorization", "Bearer sk-your-key")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 60 * time.Second}
resp, err := client.Do(req)
if err != nil {
fmt.Println("请求失败:", err)
return
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("读取响应失败:", err)
return
}
fmt.Println("X-Request-ID:", resp.Header.Get("X-Request-ID"))
if resp.StatusCode != http.StatusOK {
fmt.Printf("HTTP %d: %s\n", resp.StatusCode, string(respBody))
return
}
fmt.Println(string(respBody))
}
X-Request-ID;建议所有客户端都设置超时(示例中为 60 秒)并对非 2xx 响应读取错误体中的 error.message 字段,而不是只看状态码。框架集成 LangChain#
凡支持自定义 OpenAI 端点的框架均可接入本网关,核心都是在 ChatOpenAI(或等价类)上覆盖 base_url 为 https://yunzhiapi.cn/v1 并填入 sk- 密钥。
安装
pip install langchain-openai llama-index llama-index-llms-openai-like npm install @langchain/openai ai @ai-sdk/openai
LangChain Python
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-4o-mini",
api_key="sk-your-key",
base_url="https://yunzhiapi.cn/v1",
)
print(llm.invoke("你好").content)
LangChain JS
import { ChatOpenAI } from "@langchain/openai";
const llm = new ChatOpenAI({
model: "gpt-4o-mini",
apiKey: "sk-your-key",
configuration: { baseURL: "https://yunzhiapi.cn/v1" },
});
const resp = await llm.invoke("你好");
console.log(resp.content);
LlamaIndex
from llama_index.core.llms import ChatMessage from llama_index.llms.openai_like import OpenAILike llm = OpenAILike( model="gpt-4o-mini", api_key="sk-your-key", api_base="https://yunzhiapi.cn/v1", is_chat_model=True, ) resp = llm.chat([ChatMessage(role="user", content="你好")]) print(resp.message.content)
Vercel AI SDK
import { createOpenAI } from "@ai-sdk/openai";
import { generateText } from "ai";
const gateway = createOpenAI({
baseURL: "https://yunzhiapi.cn/v1",
apiKey: "sk-your-key",
});
const { text } = await generateText({
model: gateway("gpt-4o-mini"),
prompt: "你好",
});
console.log(text);
Spring AI
spring: ai: openai: api-key: sk-your-key base-url: https://yunzhiapi.cnchat: options: model: gpt-4o-mini
Dify / Flowise(自定义 OpenAI Provider)
- Dify:设置 → 模型供应商 → 添加「OpenAI-API-compatible」,API Endpoint 填
https://yunzhiapi.cn/v1,API Key 填sk-密钥,模型类型选 LLM,补全模型名后保存。 - Flowise:使用 ChatOpenAI 节点,Credential 中填
sk-密钥,Additional Parameters 里的 BasePath 填https://yunzhiapi.cn/v1,Model Name 填网关可用模型名。 - 两者都要求地址带
/v1,且模型名必须与GET /v1/models返回的名称一致。
baseURL 必须放在 configuration 对象内,直接放顶层不生效;LlamaIndex 需用 OpenAILike 并设 is_chat_model=True,用 OpenAI 类会做模型名校验;Spring AI 的 base-url 不带 /v1(框架自动拼接 /v1/chat/completions),与其它框架正好相反。Claude Code#
Claude Code 是 Anthropic 官方的命令行编程助手,通过设置环境变量即可将请求转发到本站 Anthropic 协议端点(/v1/messages)。
配置步骤
- 在本站后台创建密钥,密钥以
sk-开头,复制备用。 - 设置环境变量
ANTHROPIC_BASE_URL为https://yunzhiapi.cn(注意:不带 /v1 后缀)。 - 设置环境变量
ANTHROPIC_AUTH_TOKEN为你的密钥(部分版本使用ANTHROPIC_API_KEY,两者任一即可)。 - 重新打开终端,使环境变量生效。
Windows PowerShell
[Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "https://yunzhiapi.cn", "User")
[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "sk-你的密钥", "User")
macOS / Linux
export ANTHROPIC_BASE_URL="https://yunzhiapi.cn" export ANTHROPIC_AUTH_TOKEN="sk-你的密钥"
settings.json 配置(可选)
也可以写入 ~/.claude/settings.json(Windows 为 %USERPROFILE%\.claude\settings.json):
{
"env": {
"ANTHROPIC_BASE_URL": "https://yunzhiapi.cn",
"ANTHROPIC_AUTH_TOKEN": "sk-你的密钥"
}
}
验证方法
- 执行
claude --version确认客户端可用。 - 执行
claude "你好,请用一句话介绍你自己",能正常返回回复即配置成功。
模型切换与计数
会话中执行 /model 命令可在本站可用模型间切换,模型名与 GET /v1/models 返回的展示名一致;也可以在启动时用 claude --model 模型名 直接指定。客户端自动调用的 count_tokens 计数接口本站已完整支持且不计费,可放心使用上下文压缩功能。
ANTHROPIC_BASE_URL 末尾不要带 /v1,Claude Code 会自行拼接 /v1/messages,多写一层路径会 404;② 若之前执行过 claude login 登录了官方账号,官方凭证可能与自定义端点冲突,先执行 claude logout 再试;③ 修改环境变量后必须重开终端或 IDE,否则不生效。
Codex CLI#
Codex CLI 是 OpenAI 官方的命令行编程助手,支持通过 config.toml 自定义 model_provider,接入任意 OpenAI 兼容端点。
配置步骤
- 打开配置文件
~/.codex/config.toml(Windows 为%USERPROFILE%\.codex\config.toml)。 - 新增自定义
model_provider,将base_url设为https://yunzhiapi.cn/v1(必须带/v1后缀)。 - 设置
env_key指向存放密钥的环境变量名,例如OPENAI_API_KEY。 - 将环境变量
OPENAI_API_KEY设为本站sk-开头的密钥。 - 在
config.toml顶部指定model_provider与model(模型名通过GET /v1/models获取)。
config.toml 示例
model = "gpt-4o" model_provider = "custom" [model_providers.custom] name = "Custom" base_url = "https://yunzhiapi.cn/v1" env_key = "OPENAI_API_KEY" wire_api = "responses"
设置密钥环境变量
export OPENAI_API_KEY="sk-你的密钥"
验证方法
执行 codex "用一句话解释什么是递归",能正常输出回答即接入成功。
参数与模式
追加 --model 模型名 可临时覆盖配置文件中的模型;wire_api = "responses" 走本站 /v1/responses 端点,"chat" 走 /v1/chat/completions,两者计费与限流规则完全一致。沙箱模式下工具调用频繁,建议为高消耗任务配置审批策略并关注用量明细。
base_url 必须以 /v1 结尾,漏掉会报 404;② 若所用模型不支持 Responses API,请将 wire_api 改为 "chat";③ 环境变量未生效时检查是否重开了终端。
Cline / Roo Code#
Cline 与 Roo Code 是 VS Code 中的 AI 编程插件,均支持 OpenAI Compatible 提供商,可直接接入本站。
配置步骤
- 在 VS Code 扩展市场安装 Cline(或 Roo Code),安装后点击侧边栏插件图标。
- 打开插件设置,API Provider 选择
OpenAI Compatible。 - Base URL 填写
https://yunzhiapi.cn/v1。 - API Key 填写本站
sk-开头的密钥。 - Model 填写本站展示的模型名(通过
GET /v1/models获取完整列表),如gpt-4o。 - 保存配置。
验证方法
在插件对话框中发送任意问题,如「帮我写一个快速排序」,能正常流式返回代码即配置成功。
使用建议
Act 与 Chat 模式均通过同一 OpenAI 兼容端点发起请求;长任务建议在插件设置中开启流式输出并适当调高请求超时。Roo Code 的 Boomerang 任务分发同样适用本配置,多模型混用时请注意各模型单价差异,可在用量明细中按模型核对成本。
/v1 结尾,不要带 /chat/completions;② 模型名必须与本站展示名完全一致,手误拼写会报模型不存在;③ 切换密钥后若仍用旧额度,重启 VS Code 让插件重新读取配置。
OpenClaw#
OpenClaw 支持自定义 OpenAI 兼容端点,按通用的「API 地址 + 密钥 + 模型名」三步即可完成接入。
配置步骤
- 打开 OpenClaw 的设置界面,找到模型 / API 提供方配置项。
- API 地址(Base URL / Endpoint)填写
https://yunzhiapi.cn/v1。 - API 密钥(API Key)填写本站
sk-开头的密钥。 - 模型名填写本站展示的模型名(通过
GET /v1/models获取),保存配置。
验证方法
发起一次对话请求,能正常返回模型回复即接入成功。
参数透传
OpenClaw 侧设置的 temperature、max_tokens 等参数会原样透传至网关并参与统一钳制规则;对话历史由客户端维护,长会话请注意模型上下文窗口限制,必要时手动压缩历史或新建会话。
/v1 结尾,这是 OpenAI 兼容协议的约定;② 密钥注意不要多复制空格或换行,否则鉴权失败返回 401;③ 模型名需与本站展示名完全一致。
WorkBuddy#
WorkBuddy 支持自定义 OpenAI 兼容端点,按通用的「API 地址 + 密钥 + 模型名」三步即可完成接入。
配置步骤
- 进入 WorkBuddy 的设置页面,找到模型服务 / API 配置入口。
- API 地址(Base URL / Endpoint)填写
https://yunzhiapi.cn/v1。 - API 密钥(API Key)填写本站
sk-开头的密钥。 - 模型名填写本站展示的模型名(通过
GET /v1/models获取),保存配置。
验证方法
在对话窗口发送一条测试消息,能正常收到模型回复即接入成功。
团队协作建议
WorkBuddy 的温度、输出长度等设置以 OpenAI 兼容字段下发,网关按统一规则钳制;团队协作场景建议为不同项目创建独立密钥,便于用量归属统计与额度控制,密钥泄露时也可按项目粒度快速重置。
/v1 结尾;② 若提示密钥无效,请检查密钥是否完整复制(以 sk- 开头、无多余空格);③ 模型名拼写需与本站模型列表完全一致。
LobeHub / LobeChat#
LobeChat 支持为 OpenAI 提供商配置自定义代理地址,接入本站后即可在会话中选择本站模型。
配置步骤
- 打开 LobeChat,进入 设置 → 语言模型 → OpenAI。
- 开启「使用自定义代理地址」,接口代理地址 填写
https://yunzhiapi.cn/v1。 - API Key 填写本站
sk-开头的密钥。 - 在模型列表区域点击「获取模型列表」,从
/v1/models拉取可用模型并勾选需要使用的模型。 - 保存设置,回到会话页选择已启用的模型。
验证方法
新建会话发送任意消息,能正常流式回复即配置成功。
自部署环境变量
docker run -d -p 3210:3210 \ -e OPENAI_API_KEY="sk-你的密钥" \ -e OPENAI_PROXY_URL="https://yunzhiapi.cn/v1" \ lobehub/lobe-chat
服务端渲染模式下密钥保存在服务端,可避免浏览器端泄露;代理地址必须以 /v1 结尾,修改环境变量后需重建或重启容器生效。
/v1 结尾;② 若使用自部署版 LobeChat,也可通过环境变量 OPENAI_PROXY_URL 与 OPENAI_API_KEY 配置;③ 模型列表拉取失败时先检查密钥是否正确。
Cherry Studio#
Cherry Studio 是桌面端 AI 客户端,支持添加 OpenAI 兼容的模型服务商。
配置步骤
- 打开 Cherry Studio,点击左下角 设置 图标。
- 进入 模型服务,点击 添加 新建服务商,类型选择
OpenAI 兼容(OpenAI Compatible)。 - API 地址 填写
https://yunzhiapi.cn/v1。 - API 密钥 填写本站
sk-开头的密钥。 - 点击 添加模型,填入本站展示的模型名(通过
GET /v1/models获取),保存并开启该服务商开关。
验证方法
点击密钥旁的「检查」按钮测试连通性,或回到对话页选择刚添加的模型发送消息验证。
多服务商并存
Cherry Studio 允许同时添加多个 OpenAI 兼容服务商,本站可与其他渠道并存,按会话选择模型时以「服务商 + 模型名」区分;助手(Assistant)配置中引用的模型需先在对应服务商下启用,否则发送时会提示模型不可用。
/v1 即可,软件会自动拼接 /chat/completions;② 添加模型时模型 ID 必须与本站展示名一致;③ 检查失败时确认密钥无多余空格且服务商开关已打开。
NextChat / ChatGPT-Next-Web#
NextChat 支持通过环境变量或界面设置自定义 OpenAI 接口地址,两种方式任选其一。
方式一:环境变量(部署时)
export BASE_URL="https://yunzhiapi.cn" export OPENAI_API_KEY="sk-你的密钥"
方式二:界面设置
- 打开 NextChat,点击左下角 设置。
- 找到 自定义接口 并开启。
- 接口地址 填写
https://yunzhiapi.cn。 - API Key 填写本站
sk-开头的密钥。 - 保存后回到对话页选择模型(模型名可在设置中自定义为
GET /v1/models返回的名称)。
验证方法
新建对话发送任意消息,能正常收到回复即配置成功。
自定义模型名
在设置的「自定义模型」输入框中用英文逗号分隔多个模型名(如 gpt-4o,claude-sonnet-4-5,gemini-2.5-pro),即可全部加入模型下拉列表;需要强制所有模型可选时,可在列表末尾追加 -all 后缀的自定义项。
/v1/chat/completions;② 环境变量修改后需重启服务生效;③ 若模型下拉列表没有想要的模型,在设置中手动添加模型名。
Open WebUI#
Open WebUI 是流行的自托管 Web 聊天界面,可在管理后台添加 OpenAI API 连接。
配置步骤
- 登录 Open WebUI 管理员账号,点击左下角头像进入 Admin Panel(管理员面板)。
- 进入 Settings → Connections(设置 → 连接)。
- 在 OpenAI API 区域点击 + 号添加连接。
- URL 填写
https://yunzhiapi.cn/v1,API Key 填写本站sk-开头的密钥。 - 保存连接,系统会自动从
/v1/models拉取模型列表。
Docker 环境变量方式(可选)
docker run -d -p 3000:8080 \ -e OPENAI_API_BASE_URL="https://yunzhiapi.cn/v1" \ -e OPENAI_API_KEY="sk-你的密钥" \ ghcr.io/open-webui/open-webui:main
验证方法
回到主界面新建聊天,模型下拉框出现本站模型且能正常回复即配置成功。
多连接管理
可添加多条 OpenAI API 连接(如按模型系列或用途拆分),每条连接独立拉取模型列表;模型名冲突时 Open WebUI 会自动加前缀区分。企业内网部署时请确保容器能直连本站域名(放行 443 出口),否则保存连接后看不到模型。
/v1 结尾,末尾不要带斜杠或 /chat/completions;② 保存后看不到模型时,检查容器能否访问本站域名;③ 环境变量方式修改后需重启容器。
Dify#
Dify 是开源 LLM 应用开发平台,可通过 OpenAI-API-compatible 供应商接入本站模型。
配置步骤
- 登录 Dify,点击右上角头像进入 设置 → 模型供应商。
- 在供应商列表中找到 OpenAI-API-compatible,点击「添加模型」。
- Name(模型名称) 填写本站展示的模型名(通过
GET /v1/models获取)。 - API Endpoint URL 填写
https://yunzhiapi.cn/v1。 - API Key 填写本站
sk-开头的密钥。 - 选择模型类型(LLM / Text Embedding 等,按模型实际类型选择),保存。
验证方法
创建或打开一个应用,在模型选择器中选中刚添加的模型并发送消息,正常回复即接入成功。
工作流集成
在工作流编排中,LLM 节点选择已添加的本站模型即可;需要函数调用时选用支持 tool_calls 的模型并在节点中声明工具。Embedding 类模型需以 Text Embedding 类型单独添加,供知识库检索使用;Rerank 与语音类型同理,按实际能力分别登记。
OpenAI-API-compatible 供应商而不是官方 OpenAI 供应商,后者不支持自定义 Endpoint;② API Endpoint 需以 /v1 结尾;③ 函数调用(Function Call)能力取决于模型本身,若工作流需要请确认模型支持。
沉浸式翻译#
沉浸式翻译浏览器插件支持自定义 OpenAI 兼容接口,可接入本站模型进行网页翻译。
配置步骤
- 点击浏览器工具栏中的沉浸式翻译图标,进入 设置。
- 在 翻译服务 中选择 自定义 OpenAI(OpenAI 兼容接口)。
- API 接口地址 填写
https://yunzhiapi.cn/v1/chat/completions(注意需填写到完整的 chat completions 路径)。 - API Key 填写本站
sk-开头的密钥。 - 模型名 填写本站展示的模型名(通过
GET /v1/models获取),如gpt-4o-mini。 - 保存设置。
验证方法
打开任意外文网页触发翻译,页面正常出现双语对照译文即配置成功。
成本与体验
网页翻译按段落高频调用,建议选择低单价快速模型并开启插件的译文缓存以控制消耗;长文档可配合「术语表」统一专有名词译法。若整页翻译中断,检查是否触发限流(429),插件会自动按退避策略重试。
/v1/chat/completions 路径;② 翻译调用频繁,建议选用快速且价格低的模型以控制消耗;③ 若提示请求失败,检查地址中是否误加了末尾斜杠。
故障排查#
本章按「症状 → 原因 → 解决」组织常见问题的定位路径。遇到问题时请先完成下方的通用排查流程,再按症状查阅对应小节。
通用排查流程
- 记录响应头
X-Request-ID(与错误体中的request_id一致),这是全链路追踪的唯一标识。 - 对照「错误码总表」定位错误码与错误类型,确认问题发生在鉴权、计费、路由还是上游环节。
- 检查账户余额是否不低于
0.01,并通过GET https://yunzhiapi.cn/v1/models核对模型名拼写。 - 仍无法解决时联系客服,并提供
request_id、请求时间、模型名与完整错误响应。
401 未鉴权 / 密钥无效
| 症状 | 可能原因 | 解决办法 |
|---|---|---|
HTTP 401 / YZ1001 |
请求未携带任何鉴权头,或密钥格式不合法被视为未提供 | 补充 Authorization: Bearer sk-...、x-api-key 或 x-goog-api-key 任一头部 |
HTTP 401 / YZ1002 |
密钥拼写错误、已被重置或删除 | 回用户中心重新复制完整密钥,替换所有配置位置 |
Bearer 拼写错误、头部名大小写被中间代理改写,都会导致 401。错误体中的 hint 字段会给出针对性修复建议。402 余额不足
| 症状 | 可能原因 | 解决办法 |
|---|---|---|
HTTP 402 / YZ2001 |
账户余额低于最低预检额度 0.01,请求在入口预检阶段被拒绝 |
前往用户中心充值,到账后无需重置密钥即可恢复 |
| 大请求中途失败 | 预扣额度超出账户余额 | 减小 max_tokens 或输入长度,或充值后重试 |
404 模型不存在
| 症状 | 可能原因 | 解决办法 |
|---|---|---|
HTTP 404 / YZ4001,错误体含 requested_model |
模型名拼写错误、大小写或渠道前缀异常、模型已下架 | 读取错误体中的 did_you_mean 字段(最多 3 个相似模型名)自动纠正,或用 GET /v1/models 拉取完整列表核对 |
| 所有请求都 404 | Base URL 拼接错误,例如 OpenAI 协议少带了 /v1 |
按「入口与鉴权」一章核对各协议的完整路径 |
429 限流与幂等处理中
| 症状 | 可能原因 | 解决办法 |
|---|---|---|
HTTP 429 / YZ1003,Retry-After: 60 |
单个密钥 60 秒滑动窗口内超过 120 次请求 | 按 Retry-After 等待后重试,客户端实现指数退避加随机抖动 |
HTTP 429 / YZ3008 |
相同幂等键的请求仍在处理中(最长锁定 180 秒) | 按 Retry-After 提示的剩余秒数等待,再用原幂等键重放,结果会直接回放且不再计费 |
429,消息为 Upstream rate limit exceeded |
上游渠道限流,由网关原样映射 | 稍后重试;持续出现可更换模型或凭 request_id 反馈客服 |
5xx 上游错误与熔断
| 症状 | 可能原因 | 解决办法 |
|---|---|---|
HTTP 500 / YZ4002 |
模型未绑定上游渠道(配置缺失) | 凭 request_id 联系客服修复渠道配置 |
| HTTP 502 / 503 | 上游渠道故障或触发熔断保护 | 网关已自动重试与切换渠道,客户端可有限次重试;持续失败请凭 request_id 反馈 |
流式中断与 X-Resume-Token 恢复
- 症状:SSE 事件流中途断开,连接被重置或客户端超时。
- 原因:网络波动、客户端空闲超时过短、中间代理主动断连。
- 解决:保存流式响应头中的
X-Resume-Token(rst_+ 32 位十六进制),用原请求参数加X-Resume-Token或Last-Event-ID头(也可用?last_event_id=查询参数)重新发起请求,网关将从中断点继续推送,已生成内容不重复计费。
CORS 预检失败
- 症状:浏览器控制台报 CORS 错误,
OPTIONS预检未返回 204,或提示某头部不被允许。 - 原因:请求携带了未在放行清单中的自定义头部,或中间代理、浏览器插件拦截改写了预检响应。
- 解决:对照「请求响应头」中的放行清单核减自定义头;确认
OPTIONS请求返回204且含Access-Control-Allow-Origin: *;无痕窗口排除插件干扰。
Access-Control-Max-Age: 86400,同一域名 24 小时内不会重复预检。网关自身已完整放行,预检失败大多发生在浏览器到网关之间的中间环节。响应慢 / 超时
| 症状 | 可能原因 | 解决办法 |
|---|---|---|
| 非流式请求长时间无响应 | 输出 token 多,需等待全部生成完毕才返回 | 改用 stream: true,首 token 到达即开始渲染 |
| 客户端主动断开 | 客户端超时设置过短 | 非流式建议总超时 120 秒以上;流式按事件空闲间隔设置超时(如 60 秒无事件再断开并续传) |
| 偶发变慢 | 上游渠道排队或负载波动 | 有限次重试,或更换同能力模型分流 |
GET https://yunzhiapi.cn/health 区分是网关慢还是上游慢:健康检查秒回而业务请求慢,说明瓶颈在上游生成阶段。SSE 被代理缓冲
- 症状:请求了
stream: true,但客户端长时间收不到事件,最后一次性收到全部内容,流式体验丢失。 - 原因:客户端与网关之间的反向代理(如自建 Nginx、CDN)对响应做了缓冲,攒满缓冲区才下发。
- 解决:网关流式响应已携带
X-Accel-Buffering: no,请确认链路中的代理透传该头;自建 Nginx 需配置proxy_buffering off;并禁用 gzip 对text/event-stream的压缩;CDN 需将接口路径配置为不缓存、不缓冲。
curl -N 直连网关若流式正常而经过代理后不正常,即可确认缓冲发生在代理层。密钥格式校验
- 症状:确认已填写密钥,但仍返回 401
YZ1001(未提供密钥)。 - 原因:密钥不符合格式要求,网关在入口处即视为未提供。
- 解决:密钥必须以
sk-开头,后跟不少于 16 位字母、数字、下划线或短横线,完整匹配规则sk-[a-zA-Z0-9_-]{16,}。复制时注意不要带入首尾空格、换行或引号。
YZ1002(密钥无效)。一分钟检查清单
- 密钥以
sk-开头、无多余空格,且未被重置; - 余额不低于
0.01,大额请求已覆盖预估成本; - 模型名与
GET /v1/models返回的展示名完全一致; - Base URL 按协议携带正确前缀(OpenAI 带
/v1、Anthropic 不带、Gemini 为/v1beta); - 未触发 60 秒 120 次限流,重试已按
Retry-After退避; - 自建代理未缓冲 SSE(透传
X-Accel-Buffering: no); - 已保存
X-Request-ID,必要时凭它联系客服。
常见问题 FAQ#
/v1/messages)与 Gemini 兼容协议(/v1beta/models/{model}:generateContent 等)。三套协议共用同一套密钥与余额,可任意混用。sk- 开头的 API Key。请妥善保管,泄露后应立即在用户中心重置。https://yunzhiapi.cn/v1(SDK 会在其后拼接 /chat/completions 等路径);Anthropic SDK 填根地址 https://yunzhiapi.cn(SDK 自动拼接 /v1/messages);Gemini 协议路径前缀为 https://yunzhiapi.cn/v1beta。填错最常见的表现是所有请求 404。stream: true,Anthropic 协议设置 "stream": true,Gemini 使用 streamGenerateContent,三套协议均以 SSE 推送,且支持断点续传。X-Idempotency-Key 请求头。命中幂等缓存时网关直接回放首次结果,响应头带 X-Idempotency-Hit: true,不产生新的计费;相同键的请求处理中会返回 429 与 Retry-After。GET https://yunzhiapi.cn/v1/models(按请求特征自动返回 OpenAI / Anthropic / Gemini 格式),或访问站点模型广场页面。列表实时生效,请求时填写展示名即可。base_url 为本站根地址、api_key 为本站密钥即可;Gemini SDK 设置 base_url 为 https://yunzhiapi.cn/v1beta 并使用 x-goog-api-key 传密钥。无需修改任何请求体结构,详见「SDK 集成」分组。0.01 返回 402),转发前预扣、响应后按实际用量结算,多退少补。命中幂等缓存的请求不计费。Retry-After: 60。按提示等待后重试即可,批量任务建议控制并发并加入指数退避。/v1/images/generations、/v1/videos,Gemini predict / predictLongRunning);二是直接在聊天端点中请求 image / video 分类的模型,网关会自动分流到生成管线并把结果包装成标准对话响应。tools + tool_choice 声明,响应以 tool_calls 返回;Anthropic 协议映射为 tool_use / tool_result 块;Gemini 协议映射为 functionCall / functionResponse part。具体是否触发取决于所选模型本身的能力。reasoning_effort(low/medium/high);Anthropic 协议传 thinking: {"type":"enabled","budget_tokens":N};Gemini 协议传 generationConfig.thinkingConfig.thinkingBudget。思考内容分别以 reasoning_content、thinking 块、thought:true part 返回,思考 token 计入输出费用。request_id 联系客服申请提额;也可为不同业务线创建多个密钥天然隔离额度。Access-Control-Allow-Origin: *。但前端页面源码中的密钥任何人可见,生产环境建议通过自己的后端转发调用,浏览器直连仅用于内部工具或临时调试。request_id、时间、模型、token 用量与计费结果)用于对账与问题排查,可在用户中心查询自己的调用记录。