文档总览 文档简介

文档简介#

云智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 用量、费用与状态审计记录,支持逐条对账与成本归因。

请求处理流程

  1. 协议接入:接收 OpenAI / Anthropic / Gemini 任一协议的请求,完成 CORS 预检与头部解析。
  2. 鉴权与风控:提取 API Key(支持五种传递方式),依次执行滑动窗口限流、密钥校验与余额预检。
  3. 协议规范化:将 Anthropic / Gemini / Responses 请求统一转换为内部 OpenAI 格式,执行参数校验与数值钳制。
  4. 幂等保护:基于 X-Idempotency-Key 等键值去重,命中缓存直接回放结果。
  5. 模型路由:按模型名匹配登记模型,解析出上游渠道与后端模型名,完成余额预扣。
  6. 上游转发:以熔断器保护的方式调用上游,支持自动重试与流式传输。
  7. 响应还原:按客户端协议还原响应格式(含 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 集成」分组。
  • 生产上线:务必阅读「幂等重试」「流式输出」「断点续传」三章,构建可靠的调用链路。

快速开始#

接入步骤

  1. 登录 用户中心,创建并复制以 sk- 开头的 API Key。
  2. 确认账户余额不低于最低预检额度 0.01,余额不足时请求会在预检阶段被拒绝并返回 HTTP 402。
  3. 选择一个接入协议(推荐 OpenAI 兼容),将 Base URL 指向本站点。
  4. 通过 GET https://yunzhiapi.cn/v1/models 拉取当前可用模型列表,选择模型名填入请求的 model 字段。
  5. 发送第一个聊天请求验证连通性。

第一个请求(cURL)

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)

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)

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 等)可直接跳转「应用配置」分组。
完成首次调用后,建议继续阅读「幂等重试」,为生产环境加上防重复扣费保护。

入口与鉴权#

统一入口

BASEhttps://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 浏览器直链等场景

同时携带多个鉴权头时,按上表优先级取第一个命中的值,其余忽略;为避免歧义,建议每个请求只携带一种鉴权信息。

各协议鉴权示例

OpenAI 协议
curl https://yunzhiapi.cn/v1/models \
-H "Authorization: Bearer sk-你的密钥"
Anthropic 协议
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"}]}'
Gemini 协议
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 已放行)。
  • 密钥仅在其所属账户范围内有效,无法跨账户访问其他用户的文件与任务资源。

密钥泄露应急流程

  1. 立即重置:在用户中心密钥管理页重置泄露密钥,旧密钥即时失效。
  2. 审计用量:查看用量明细中最近 24 小时的调用记录,确认是否存在异常模型或异常高频调用。
  3. 全量替换:更新所有部署位置(环境变量、配置文件、密钥管理服务),避免遗漏导致服务中断。
  4. 定期轮换:生产环境建议每 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 嗅探

追踪标识说明

HTTP
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, OPTIONSOPTIONS 预检请求返回 204 并附 Access-Control-Max-Age: 86400。放行的自定义头部包括 AuthorizationContent-TypeX-API-KeyX-Request-IdX-Idempotency-KeyX-Resume-TokenLast-Event-IDanthropic-versionanthropic-betaanthropic-dangerous-direct-browser-accessx-goog-api-keyopenai-organizationopenai-projectopenai-betax-stainless-* 系列、x-titlehttp-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:

  1. 前缀剥离匹配:自动去除 models/publishers/<厂商>/models/openai/anthropic/google/gemini/claude/ 等渠道前缀后,按小写精确匹配。
  2. 原名精确匹配:不剥离前缀的原始名称按小写精确匹配(大小写不敏感)。
  3. 后缀模糊匹配:请求名与登记名互为后缀时命中,例如登记名为 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_modeldid_you_mean 字段(最多 3 个相似模型名,按编辑距离与包含关系选出),可据此自动纠正或提示用户。

JSON
{
"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 做降级处理(自动切换到同能力备选模型)。
模型列表接口按请求特征自动返回 OpenAI / Anthropic / Gemini 三种格式,详见「模型列表 Models」。同一个模型名可用于全部三套协议,无需区分。

速率限制#

限制规则

网关对每个 API Key 实施滑动窗口限流:

  • 窗口大小:60 秒滚动窗口
  • 窗口内最大请求数:120 次
  • 超限响应:HTTP 429,错误码 YZ1003,错误类型 rate_limit_error,并携带 Retry-After: 60 响应头

滑动窗口按请求到达时刻动态计算:任意连续 60 秒内累计达到 120 次后,第 121 次被拒绝;随着最早的请求滑出窗口,额度逐步恢复,无需等待整分钟边界。限流按密钥维度统计,同一账户下多个密钥互不影响;GET /v1/modelscount_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 后原样重发同一请求即可(可命中幂等缓存直接回放结果,不会重复扣费)。
javascript
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 联系客服申请提额。
429 错误响应体中同样带有 request_idhint 字段,持续超限可凭 request_id 联系客服申请提高限额。

计费说明#

计费模式

每个模型按登记的价格配置自动归属两种计费模式之一,所有金额按 8 位小数精度计算:

按 Token 计费(per_token)

模型输入单价 input_price > 0 时生效。输入与输出分别计价:费用 = token 数 × 单价 ÷ 1,000,000(单价单位为元/百万 token),总费用为输入费用加输出费用之和。

按次计费(per_request)

模型输入单价 input_price = 0 时生效。每次成功请求固定收取 output_price 金额,与 token 数无关,常见于图像、语音、视频等生成类模型。

计费公式与示例

场景计算过程费用
按 token:输入 1,000 / 输出 500,单价 2 / 6 元每百万1000 × 2 ÷ 1M + 500 × 6 ÷ 1M = 0.002 + 0.0030.00500000 元
按次:图像生成 n=2,单价 0.5 元/次0.5 × 21.00000000 元
Embeddings:输入 800 token,单价 0.1 元每百万800 × 0.1 ÷ 1M0.00008000 元
失败请求(任意 4xx/5xx)预扣金额全额退还0 元

余额预检与预扣

请求在转发到上游之前会经过两道余额校验,确保余额真实可用:

  1. 最低余额预检:账户余额低于 0.01 元时直接拒绝,返回 402 + YZ2001
  2. 预估成本计算:按次计费模型预估成本 = 单次价格;按 token 计费模型预估成本 = 按请求文本估算的输入 token × 输入单价 ÷ 1,000,000 + 0.0001 元。预估成本与 0.01 元取较大者作为预扣金额
  3. 余额充足性校验:余额低于预扣金额时返回 402 + YZ2001,消息中包含当前余额与预估金额。
  4. 预扣:通过数据库行级锁(FOR UPDATE)从余额中预先扣减该金额;并发扣款冲突或失败时返回 402 + YZ2002,稍等几秒重试即可。

结算与失败退费

  • 多退:请求成功后按实际 token 用量(或单次价格)结算。预扣金额大于实际费用时,差额自动退还(差额小于 0.00000001 元的零头忽略)。
  • 少补:实际费用超过预扣金额时,超出部分从余额补扣;补扣不会把余额扣成负数,余额不足时最多扣到 0 为止。
  • 失败全退:上游超时、连接失败、返回错误、无内容等任何失败路径,预扣金额全额退还,不产生任何费用。
  • 结算可靠性:结算事务最多自动重试 3 次(退避 100/200/300 毫秒);仍失败时全额退还预扣并记录日志,不会多扣用户余额。
  • 审计:每次结算都会写入用量审计记录(模型、输入/输出 token、实际费用、预扣金额、差额),用于账单对账。
扣费保障:只有上游成功返回有效内容才会计费;所有失败请求(含 4xx/5xx 错误响应)均全额退费,重试不会重复扣费。

查询用量与余额

  • 单次请求用量:非流式响应的 usage 字段包含 prompt_tokenscompletion_tokens;流式响应的 usage 会随流末尾的 chunk 下发(服务端已强制开启 stream_options.include_usage)。
  • 账户余额与账单:登录本站后台可查看当前余额、充值记录与逐条用量明细(含每次请求的模型、token 数与扣费金额),用量明细与网关审计记录逐条对应,可据此对账。

计费与流式请求

流式请求(stream: true)与非流式请求采用完全相同的预扣-结算流程,费用不因流式而增加。需要注意两点:上游未返回 usage 时,输入 token 按请求文本估算、输出 token 按流式增量文本估算(至少按 1 计);客户端中途断开连接不视为失败,已产出的内容正常结算,因此主动中断流时请确认是否需要完整结果。

对账建议

  • 客户端持久化每次响应的 X-Request-IDmodelusage,作为与平台账单逐条比对的主键。
  • 命中幂等缓存的请求(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 格式)

JSON
{
"error": {
"message": "Insufficient balance.",
"type": "insufficient_quota_error",
"param": null,
"code": "YZ2001",
"request_id": "3f6b2f34-....",
"hint": "Recharge your account and retry."
}
}

错误响应结构(Anthropic 格式)

JSON
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "Insufficient balance. (code: YZ2001, request_id: 3f6b2f34-....)"
}
}

错误响应结构(Gemini 格式)

JSON
{
"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-Keyx-goog-api-keyanthropic-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 外)属于请求本身的问题,修正前重试没有意义;应解析 messagehint 自动修复或提示用户。
  • 429 必须按 Retry-After 等待,并叠加指数退避与随机抖动,重试时保持幂等键不变。
  • 5xx 与网络错误属于临时性故障,使用固定幂等键指数退避重试,最多 5 次后放弃并告警。
  • request_id、错误码与时间戳写入业务日志,便于与平台审计记录交叉定位。
所有 4xx/5xx 失败请求均已全额退还预扣金额,可放心按建议重试;YZ5xxxYZ9xxx 类错误多为临时性故障,建议采用指数退避策略重试。

聊天补全 Chat Completions#

聊天补全是本平台最核心的接口,与 OpenAI Chat Completions API 完全兼容,适用于对话助手、代码生成、文案写作、多模态理解(图片/音频输入)、函数调用(Function Calling)等场景。请求经统一入口处理:鉴权与限流、余额预检与预扣、参数规范化与钳制、幂等去重,然后转发至模型对应的上游端点,响应统一规整为 OpenAI 格式返回。

POST/v1/chat/completions

请求参数

参数类型必填说明
modelstring必填模型 ID。自动去除首尾空白,长度不超过 256 字符且不得含控制字符;模型不存在时返回 404,并附 did_you_mean 相似模型建议
messagesarray必填对话消息数组,最多 1000 条,超过返回 400。每条必须为对象且含 role;合法角色:systemuserassistanttoolfunctiondevelopermodel/bot/ai 自动转为 assistanthuman 转为 user,非法角色整条丢弃。content 支持字符串或多段数组(text、image_url、input_audio 等)
streamboolean可选是否流式输出,默认 false。非布尔值时字符串 "true"/"1"/"yes"/"on"(不区分大小写)视为开启
temperaturenumber可选采样温度,默认 1,取值会被钳制到 [0.0, 2.0]
top_pnumber可选核采样概率,默认 1,取值会被钳制到 [0.0, 1.0]
max_tokensinteger可选最大输出 token 数,小于 1 时按 1 处理
max_completion_tokensinteger可选新版最大输出 token 数(含推理 token),小于 1 时按 1 处理
ninteger可选每个请求生成的候选数,默认 1,钳制到 [1, 10]
stopstring | array可选停止序列。字符串自动转为单元素数组;数组形式会将各元素转为字符串并过滤空值
presence_penaltynumber可选存在惩罚,默认 0,钳制到 [-2.0, 2.0]
frequency_penaltynumber可选频率惩罚,默认 0,钳制到 [-2.0, 2.0]
seedinteger可选随机种子,强制转为整数,用于可复现采样
logprobsboolean可选是否返回对数概率,强制转为布尔值
top_logprobsinteger可选每个 token 返回的候选对数概率条数,钳制到 [0, 20],需配合 logprobs=true
toolsarray可选工具定义数组,上限 128 个。function 类型要求 function.name 为非空字符串,否则该工具被丢弃;缺省 description 补空串、缺省 parameters{"type":"object","properties":{}}、缺省 strictfalse
tool_choicestring | object可选工具调用策略:auto/none/required 或指定函数对象
response_formatobject可选输出格式:{"type":"text"}(默认)、{"type":"json_object"}{"type":"json_schema","json_schema":{...}};字符串形式自动包装为 {"type": 原值}
reasoning_effortstring可选推理强度(如 low/medium/high)。传入 reasoning.effort 对象形式时会自动提取为 reasoning_effort
userstring可选终端用户标识,原样透传上游

参数钳制规则

参数合法范围越界处理
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
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
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
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_reasontool_calls,参数位于 message.tool_calls[].function.arguments(JSON 字符串)。执行完函数后,将结果以 role: "tool" 消息(携带对应 tool_call_id)追加到 messages 再次请求,即可完成闭环。

结构化输出示例

JSON
"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 以兼容更多模型。

响应示例

JSON
{
"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
}
}
}

平台会自动补全 idobjectcreatedservice_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] 结束:

SSE
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]
请求体大小上限为 64 MB(超过返回 413);余额不足时返回 402;消息或工具中由客户端 SDK 注入的 cache_controlcitations 字段会在转发前递归剥离,避免上游报 400。
支持幂等:携带 X-Idempotency-Key 请求头可防止重复扣费;流式中断后可用 X-Resume-TokenLast-Event-ID 请求头断点续传。图像、语音、视频类模型也可经本接口调用,最后一条 user 文本将作为生成提示词。
temperature、top_p、presence_penalty、frequency_penalty、n、top_logprobs 超出范围时会被静默钳制而非报错;max_tokens 与 max_completion_tokens 小于 1 时按 1 处理。

传统补全 Completions#

传统补全接口用于兼容早期的 /v1/completions 调用方式(纯 prompt 续写)。平台内部会将 prompt 包装为一条 user 消息,委托给聊天补全统一流程处理,因此模型选择、计费、限流、幂等等行为与 Chat Completions 完全一致。

POST/v1/completions

请求参数

参数类型必填说明
modelstring必填模型 ID,校验规则与聊天补全一致
promptstring | array必填续写提示词。数组形式会将各元素转为字符串后拼接;最终作为一条 user 消息提交
suffixstring可选后缀文本,会被追加为第二条 user 消息一并提交
streamboolean可选是否流式输出,默认 false
max_tokensinteger可选最大输出 token 数,小于 1 时按 1 处理
temperaturenumber可选采样温度,钳制到 [0.0, 2.0]
top_pnumber可选核采样概率,钳制到 [0.0, 1.0]
ninteger可选候选数,默认 1,钳制到 [1, 10]
stopstring | array可选停止序列,处理规则与聊天补全一致
presence_penaltynumber可选存在惩罚,钳制到 [-2.0, 2.0]
frequency_penaltynumber可选频率惩罚,钳制到 [-2.0, 2.0]
seedinteger可选随机种子,强制转为整数
userstring可选终端用户标识,原样透传

请求示例

cURL
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 对象结构(objectchat.completion),生成文本位于 choices[0].message.content,而非旧式 text_completionchoices[0].text

JSON
{
"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:它支持系统指令、多轮上下文、工具调用与多模态输入,且所有新模型仅在对话管线上持续优化。

请求体为空或不是合法 JSON 时返回 400;仅 max_tokenstemperaturetop_pnstoppresence_penaltyfrequency_penaltyseeduser 这些字段会被带入转换后的请求,其余字段(如 logit_biasechobest_of)将被忽略。

响应接口 Responses API#

Responses API 兼容 OpenAI 新一代响应接口,适用于 Codex 等新版 SDK、结构化输出(JSON Schema)与工具编排场景。平台会将 Responses 入参标准化为内部 OpenAI 兼容结构后走统一处理流程,响应再转换回 Responses 格式(object: response)。

POST/v1/responses

请求参数

参数类型必填说明
modelstring必填模型 ID;缺失时返回 400
inputstring | array必填输入内容。字符串形式作为一条 user 消息;数组形式支持 message(含 input_text/input_image/output_text/refusal 等 part)、function_call(转为 assistant 的 tool_calls)、function_call_output/tool_result(转为 tool 消息);reasoningitem_referencecomputer_callweb_search_call 等条目会被忽略。inputmessages 同时提供时会合并,最终消息为空时返回 400
instructionsstring可选系统指令,非空时插入为一条 system 消息
systemstring可选等效于 instructions,且优先级更高(排在 messages 最前)
max_output_tokensinteger可选最大输出 token 数,内部映射为 max_tokens,小于 1 时按 1 处理;也接受直接传 max_tokens
temperaturenumber可选采样温度,钳制到 [0.0, 2.0],响应中默认回显 1.0
top_pnumber可选核采样概率,钳制到 [0.0, 1.0],响应中默认回显 1.0
textobject可选输出格式。text.format.typejson_schema 时转换为 response_format(缺省 nameresponse、缺省 strictfalse);为 json_object 时转换为 JSON 模式
toolsarray可选工具数组。function 类型的扁平定义(name/description/parameters 直接在工具对象上)会自动包装为 OpenAI 结构;web_search 类型会置位联网搜索标记而非加入 tools
tool_choicestring | object可选工具选择策略;{"type":"function","name":"..."} 扁平形式自动转换为嵌套结构
parallel_tool_callsboolean可选是否允许并行工具调用,默认 true;未提供 tools 时该字段不会转发上游
streamboolean可选是否流式输出,默认 false
storeboolean可选透传字段,响应骨架中默认回显 false
metadataobject可选透传字段,响应中默认回显空对象
reasoning_effortstring可选推理强度;reasoning.effort 对象形式也会被自动提取
seed / user / n / stop / presence_penalty / frequency_penalty / logit_bias / service_tiermixed可选原样映射透传,数值钳制规则与聊天补全一致

请求示例

cURL
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
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 即可续接对话。

响应示例

JSON
{
"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_reasonlength/max_tokenstool_callscontent_filter 时,incomplete_details.reason 分别回显 max_output_tokenstool_callscontent_filter;正常结束时为 null。工具调用会以 function_call 类型的 output 条目追加在 message 之后。

流式变体

设置 "stream": true 后返回 Responses API 语义化 SSE 事件流,事件顺序为:response.created(携带 status: in_progress 的响应骨架)→ 若干 response.output_text.deltaresponse.output_text.doneresponse.completed(携带完整响应对象)。

SSE
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}}

查询已有响应

GET/v1/responses/{response_id}

按响应 ID 读取已完成的响应(源自服务端幂等记录)。若存储的是 chat.completion 格式会自动转换为 Responses 格式返回;记录不存在或内容为空时返回 404,数据损坏时返回 500。

cURL
curl "https://yunzhiapi.cn/v1/responses/resp_9f8e7d6c5b4a3c2d1e0f" \
-H "Authorization: Bearer $API_KEY"

列出输入条目

GET/v1/responses/{response_id}/input_items

供 Codex 等 SDK 轮询使用的占位端点。平台不持久化 input_items,固定返回空列表以保证调用链完整:

JSON
{
"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,并通过限流检查。

列出全部模型

GET/v1/models

返回 OpenAI 格式的模型列表,每个条目包含 id(展示名)、created(创建时间戳)、owned_by(固定 yunzhi-api)等字段。

cURL
curl "https://yunzhiapi.cn/v1/models" \
-H "Authorization: Bearer $API_KEY"

响应示例:

JSON
{
"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保留字段,当前为空数组

获取单个模型

GET/v1/models/{model_id}

返回指定模型的详情。模型 ID 支持模糊匹配(与请求模型时相同的查找逻辑);未找到时返回 404 及 requested_model 字段。

cURL
curl "https://yunzhiapi.cn/v1/models/gpt-4o" \
-H "Authorization: Bearer $API_KEY"

响应示例:

JSON
{
"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-versionAnthropic 格式(含 has_more/first_id/last_id
显式访问 /anthropic/v1/models/v1beta/models 可强制获得对应协议格式,无需依赖请求头特征。
缺少 API Key 返回 401(Missing API key.),Key 无效返回 401(Invalid API key.);模型接口本身不计费,但计入限流。

向量嵌入 Embeddings

向量嵌入接口与 OpenAI Embeddings API 兼容,将文本转换为向量,适用于语义搜索、聚类、推荐与 RAG 检索增强等场景。请求经鉴权与余额检查后转发至模型对应的上游端点(默认 embeddings 端点),响应体原样透传。

POST/v1/embeddings

请求参数

参数类型必填说明
modelstring必填嵌入模型 ID;若模型在平台注册,会自动替换为其后端模型名(backend_name)后转发
inputstring | array必填待嵌入文本。数组形式最多 2048 条,超过返回 400(Too many embedding inputs.
encoding_formatstring可选向量编码格式(如 floatbase64),原样转发上游
dimensionsinteger可选输出向量维度(仅部分模型支持),原样转发上游
userstring可选终端用户标识,原样转发上游

请求示例

cURL
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
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 条,超大数据集请客户端分批提交。

响应示例

JSON
{
"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)。
modelinputencoding_formatdimensionsuser 五个字段会被转发至上游,其余字段将被丢弃;上游请求超时时间为 60 秒。
计费按 token 计:优先取上游返回的 usage.prompt_tokens,上游未返回时按输入文本本地估算;单价取模型配置的输入价,未配置时默认 0.1 / 百万 token。请求体为空或非法 JSON 返回 400,缺少 modelinput 返回 400,余额不足返回 402,上游不可达返回 502。

内容审核 Moderations#

内容审核接口与 OpenAI Moderations API 兼容,用于检测文本是否包含违规内容,适用于 UGC 社区、评论系统、对话产品的安全过滤场景。该接口不计费,但需要有效 API Key 并通过限流检查。

POST/v1/moderations

请求参数

参数类型必填说明
inputstring | array必填待审核文本(字符串或字符串数组)。缺失时返回 400(Missing required parameter: 'input'.
modelstring可选审核模型,默认 text-moderation-latest,原样转发上游

请求示例

cURL
curl "https://yunzhiapi.cn/v1/moderations" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "text-moderation-latest",
"input": "这是一段待审核的用户评论文本。"
}'

响应示例

上游正常时响应体原样透传:

JSON
{
"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
}
}
]
}

降级行为

  1. 审核端点未配置时,直接返回占位响应;
  2. 上游连接失败(超时 30 秒)时,返回占位响应;
  3. 上游返回 HTTP 错误(≥ 400)时,同样返回占位响应。

占位响应固定为 flagged: false、空的 categoriescategory_scores 对象,idmodr- 前缀生成,保证调用方链路不中断:

JSON
{
"id": "modr-9f8e7d6c5b4a",
"model": "text-moderation-latest",
"results": [
{
"flagged": false,
"categories": {},
"category_scores": {}
}
]
}

接入建议

  • 对安全强依赖的场景,请检查响应中 categories 是否为空对象来甄别降级响应,必要时走本地敏感词引擎二次复核。
  • 审核应与主对话链路并行调用(旁路审核),避免串行增加首字延迟。
  • 批量审核使用字符串数组一次提交,比逐条调用更节省限流额度。
降级响应意味着审核未真正执行,请勿将空 categories 误判为「内容安全」。
本接口固定走平台审核端点转发,请求体整体原样转发上游;缺少 API Key 返回 401,触发限流返回 429。

文件管理 Files#

文件管理接口与 OpenAI Files API 完全兼容,适用于上传微调/批处理数据文件、管理助手知识库附件、下载上游生成的文件内容等场景。所有请求(除查询参数外)均原样转发至上游文件服务,响应体与 Content-Type 原样透传。

列出文件

GET/v1/files

返回当前账户在上游文件服务中的全部文件列表,支持通过查询字符串(如 ?purpose=fine-tune)过滤,查询参数原样转发。

参数位置类型说明
purposequery 可选string按用途过滤,如 fine-tuneassistants,原样转发上游
cURL
curl "https://yunzhiapi.cn/v1/files" \
-H "Authorization: Bearer $API_KEY"

响应示例:

JSON
{
"object": "list",
"data": [
{
"id": "file-abc123",
"object": "file",
"bytes": 120000,
"created_at": 1710000000,
"filename": "train.jsonl",
"purpose": "fine-tune"
}
]
}

上传文件

POST/v1/files

multipart/form-data 上传文件,所有表单字段(含多文件数组字段)原样重建并转发至上游;若请求不含任何表单字段,则请求体与原始 Content-Type 直接透传。

字段位置类型说明
filemultipart 必填file要上传的文件内容,支持多文件数组形式(如 file[]
purposemultipart 必填string文件用途,如 fine-tuneassistantsbatch,由上游校验
cURL
curl "https://yunzhiapi.cn/v1/files" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@train.jsonl" \
-F "purpose=fine-tune"

响应示例:

JSON
{
"id": "file-abc123",
"object": "file",
"bytes": 120000,
"created_at": 1710000000,
"filename": "train.jsonl",
"purpose": "fine-tune"
}

用途与计费

purpose用途说明
fine-tune微调训练数据推荐 JSONL 格式,每行一个训练样本
assistants助手知识库附件供检索增强使用
batch批处理任务输入大批量离线任务

上传成功后每次扣费 0.005(账户余额单位),上传前请确保余额充足;列表、详情、下载与删除操作免费,但均计入限流窗口。

获取文件信息

GET/v1/files/{file_id}

获取单个文件的元数据。file_id 为路径段,允许除 / 以外的任意字符。

cURL
curl "https://yunzhiapi.cn/v1/files/file-abc123" \
-H "Authorization: Bearer $API_KEY"

响应示例:

JSON
{
"id": "file-abc123",
"object": "file",
"bytes": 120000,
"created_at": 1710000000,
"filename": "train.jsonl",
"purpose": "fine-tune"
}

下载文件内容

GET/v1/files/{file_id}/content

下载文件的原始二进制内容,响应体与 Content-Type 完全透传上游(可能为 application/octet-stream 等),不做 JSON 包装。

cURL
curl "https://yunzhiapi.cn/v1/files/file-abc123/content" \
-H "Authorization: Bearer $API_KEY" \
-o train.jsonl

删除文件

DELETE/v1/files/{file_id}

删除指定文件,结果由上游返回并透传。

cURL
curl -X DELETE "https://yunzhiapi.cn/v1/files/file-abc123" \
-H "Authorization: Bearer $API_KEY"

响应示例:

JSON
{
"id": "file-abc123",
"object": "file",
"deleted": true
}

生命周期说明

  • 文件存储于上游文件服务,保留策略由上游决定;长期不用的文件建议主动删除以避免配额占用。
  • 上传大文件时请保证网络稳定,中途失败需重新上传(本接口不支持断点续传)。
  • 文件内容不会经过网关的协议转换层,网关不解析也不留存文件正文。
Files 全系列端点上游超时为 300 秒;上游不可达时返回 502(Upstream files service unavailable.)。HTTP 状态码与响应头按上游结果原样返回。

图像生成 Images#

图像接口与 OpenAI Images API 兼容,覆盖文生图(generations)、图像编辑(edits)与图像变体(variations)三类场景。响应 data 数组会被规范化:每个条目保留上游原始字段(url / b64_json / revised_prompt 等),并自动补齐 media_typeimage)与 mime_type(默认 image/png)两个标准字段;裸 URL 或裸 base64 字符串条目会被提升为对象。

创建图像(文生图)

POST/v1/images/generations

根据文本提示词生成图像,请求体为 JSON。

参数位置类型说明
promptbody 必填string图像描述文本,不能为空,长度不超过 2,000,000 字节
modelbody 可选string图像模型名,用于路由与定价,未匹配时使用默认端点
nbody 可选integer生成数量,默认 1,自动钳制到 [1, 10]
sizebody 可选string图像尺寸,默认 1024x1024,必须匹配 宽x高 数字格式(如 1792x1024),否则返回 400
其他字段body 可选anyqualitystyleresponse_format 等,随请求体原样转发上游

尺寸与常用参数

参数合法取值默认值
size1024x1024 / 1792x1024 / 1024x1792(部分模型支持更多)1024x1024
n1 – 101
qualitystandard / hd(按模型支持情况)随上游默认
response_formaturl / b64_jsonurl
cURL
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"
}'

响应示例:

JSON
{
"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"
}
]
}

编辑图像

POST/v1/images/edits

以上传的原始图像(可选蒙版)为基础,按提示词进行局部编辑。请求为 multipart/form-data,原始请求体与 Content-Type 直接透传至上游。

字段位置类型说明
imagemultipart 必填file待编辑的原始图像文件
promptmultipart 必填string期望编辑结果的文本描述,由上游校验
maskmultipart 可选file蒙版图像,透明区域表示待编辑位置
modelmultipart 可选string模型名,缺省按 dall-e-2 计费路由
nmultipart 可选integer生成数量,默认 1,自动钳制到 [1, 10]
cURL
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"

响应示例:

JSON
{
"created": 1710000000,
"data": [
{
"url": "https://example.com/gen/edited-1.png",
"media_type": "image",
"mime_type": "image/png"
}
]
}

创建图像变体

POST/v1/images/variations

基于上传图像生成风格/构图相近的变体,无需提示词。请求为 multipart/form-data,原始请求体透传上游。

字段位置类型说明
imagemultipart 必填file源图像文件
modelmultipart 可选string模型名,缺省按 dall-e-2 计费路由
nmultipart 可选integer生成数量,默认 1,自动钳制到 [1, 10]
cURL
curl "https://yunzhiapi.cn/v1/images/variations" \
-H "Authorization: Bearer $API_KEY" \
-F "image=@photo.png" \
-F "n=2"

响应示例:

JSON
{
"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 的模型并在客户端后处理。
multipart 请求体大小上限为 64MB,超限返回 413;上游超时 120 秒。请求体为空的 JSON 请求返回 400(Request body is empty.)。
调用前需通过鉴权与余额检查;生成失败时预扣金额全额退还。

音频服务 Audio#

音频接口与 OpenAI Audio API 兼容,包含文本转语音(speech)、语音转文字(transcriptions)与语音翻译(translations)。三个端点共用统一代理:请求体原样转发上游,响应体与上游 Content-Type 原样透传(speech 直接返回二进制音频流,不做 JSON 包装)。

文本转语音

POST/v1/audio/speech

将文本合成为语音,请求体为 JSON,整体原样转发上游。

参数位置类型说明
modelbody 必填stringTTS 模型名(如 tts-1tts-1-hd),用于路由与定价
inputbody 必填string要合成的文本,由上游校验
voicebody 必填string发音人,如 alloyechofable 等,由上游校验
response_formatbody 可选string音频格式:mp3 / opus / aac / flac
speedbody 可选number语速倍率,随请求体原样转发
cURL
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
成功响应为二进制音频流,Content-Type 与上游一致(如 audio/mpeg),并携带准确的 Content-Length,可直接写入文件或流式播放。

语音转文字

POST/v1/audio/transcriptions

将音频文件转写为原始语言的文本。请求为 multipart/form-data,原始请求体与 Content-Type 直接透传至上游。

字段位置类型说明
filemultipart 必填file音频文件(mp3 / wav / m4a / flac 等,由上游支持)
modelmultipart 必填string识别模型名(如 whisper-1),用于路由与定价
languagemultipart 可选string音频语言代码(ISO-639-1,如 zh
promptmultipart 可选string提示文本,引导转写风格与专有名词
response_formatmultipart 可选stringjson / text / srt / verbose_json / vtt
temperaturemultipart 可选number采样温度,随表单原样转发
cURL
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"

响应示例:

JSON
{
"text": "大家好,今天我们讨论一下项目进度。"
}

语音翻译

POST/v1/audio/translations

将任意语言的音频翻译并转写为英文文本,参数与 transcriptions 基本一致,multipart 原样透传。

字段位置类型说明
filemultipart 必填file待翻译的音频文件
modelmultipart 必填string识别模型名(如 whisper-1),用于路由与定价
promptmultipart 可选string提示文本(英文),引导翻译风格
response_formatmultipart 可选stringjson / text / srt / verbose_json / vtt
temperaturemultipart 可选number采样温度
cURL
curl "https://yunzhiapi.cn/v1/audio/translations" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@speech.mp3" \
-F "model=whisper-1"

响应示例:

JSON
{
"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 注入专有名词表(产品名、人名),可减少术语误识别。
multipart 上传大小上限 64MB(超限 413);音频端点上游超时 300 秒。计费为每次调用固定 0.0001(或按模型 output_price),不按音频时长计费。

视频生成 Videos#

视频接口提供两种模式:/v1/videos/generations 同步生成(一次请求直接返回结果),以及 Sora 风格的 /v1/videos 异步任务(创建任务后轮询状态)。响应 data 数组会被规范化:保留上游原始字段并补齐 media_typevideo)与 mime_type(默认 video/mp4)。

同步与异步选型

模式端点特点适用场景
同步/v1/videos/generations一次请求等待结果返回,上游超时 300 秒短视频、可接受长等待的后端任务
异步/v1/videos + 轮询立即返回任务 ID,轮询查询状态长视频、需要任务管理与失败重试的场景

同步生成视频

POST/v1/videos/generations

提交提示词并等待上游同步返回生成结果,上游超时 300 秒。

参数位置类型说明
promptbody 必填string视频描述文本,不能为空,长度不超过 2,000,000 字节
modelbody 可选string视频模型名(如 sora-2veo-3.0-generate-001),用于路由与定价
nbody 可选integer生成数量,默认 1,自动钳制到 [1, 5]
其他字段body 可选anydurationaspect_ratiosize 等,随请求体原样转发上游
cURL
curl "https://yunzhiapi.cn/v1/videos/generations" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "海浪拍打礁石,慢镜头,电影质感",
"n": 1
}'

响应示例:

JSON
{
"created": 1710000000,
"data": [
{
"url": "https://example.com/gen/video-1.mp4",
"media_type": "video",
"mime_type": "video/mp4"
}
]
}
计费:未命中模型定价时按默认每个 10.0 × n 扣费;命中时按 prompt 估算 token × 模型 input_price / 1M × n 扣费。请求体为空或 JSON 非法返回 400。

创建异步视频任务

POST/v1/videos

创建 Sora 风格的异步生成任务,立即返回任务对象(含 id 与初始 status)。POST 创建成功后按模型 output_price 扣费(默认 10.0/次)。

参数位置类型说明
modelbody 必填string视频模型名,用于路由与定价
promptbody 必填string视频描述文本,由上游校验
其他字段body 可选anysizeseconds 等,随请求体原样转发上游
cURL
curl "https://yunzhiapi.cn/v1/videos" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "一只猫在窗边看雪,镜头缓慢推进"
}'

响应示例:

JSON
{
"id": "video_abc123",
"object": "video",
"model": "sora-2",
"status": "queued",
"created_at": 1710000000
}

查询任务状态

GET/v1/videos/{video_id}

查询单个任务状态,video_id 允许字母、数字、下划线与短横线;查询字符串(如展开参数)原样转发上游。GET 请求不计费。

cURL
curl "https://yunzhiapi.cn/v1/videos/video_abc123" \
-H "Authorization: Bearer $API_KEY"

响应示例(完成后):

JSON
{
"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"
}
]
}

列出任务

GET/v1/videos

列出全部视频任务,支持通过查询字符串分页/过滤(参数原样转发上游),不计费。

cURL
curl "https://yunzhiapi.cn/v1/videos?limit=20" \
-H "Authorization: Bearer $API_KEY"

删除任务

DELETE/v1/videos/{video_id}

删除指定任务及其产物,结果由上游返回并透传,不计费。

cURL
curl -X DELETE "https://yunzhiapi.cn/v1/videos/video_abc123" \
-H "Authorization: Bearer $API_KEY"

异步任务轮询流程

  1. 调用 POST /v1/videos 创建任务,从响应中保存 id 与初始 status(通常为 queuedin_progress)。
  2. 每隔 5~10 秒调用 GET /v1/videos/{video_id} 轮询任务状态,查询不计费。
  3. status 变为 completed 时,从响应的 data 数组中取出视频 URL(已补齐 media_type / mime_type)。
  4. status 变为 failed,检查响应中的错误信息并停止轮询。
  5. 可选:任务完成后调用 DELETE /v1/videos/{video_id} 清理任务记录。
仅 POST 创建任务计费(成功后按模型 output_price 扣费),GET / DELETE 均免费。上游不可达返回 502;上游 4xx/5xx 错误经映射后透传。同步与异步端点超时分别为 300 秒与 60 秒(查询/删除)。

消息对话 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

POSThttps://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

请求参数

参数类型必填默认值 / 范围说明
modelstring必填长度 ≤ 256模型名,需与本站模型列表展示名一致。
max_tokensinteger必填≥ 1最大输出 token 数,小于 1 时自动钳制为 1。
messagesarray必填对话消息数组,role 为 user / assistant,content 支持字符串或 text / image / document / tool_use / tool_result 等块。
systemstring | array可选系统提示;数组形式时仅提取其中的 text 块并合并为一条 system 消息。
temperaturenumber可选0.0 – 2.0采样温度,超出范围自动钳制。
top_pnumber可选0.0 – 1.0核采样概率,超出范围自动钳制。
top_kinteger可选Top-K 采样,原样透传上游。
stop_sequencesarray可选单条 ≤ 1024 字符停止序列,映射为 OpenAI 的 stop 字段。
streamboolean可选falsetrue 时以 SSE 流式返回 Anthropic 事件序列。
toolsarray可选工具定义,name / description / input_schema 会映射为 OpenAI function 工具;web_search_* 类型转换为联网搜索开关。
tool_choicestring | object可选autoauto→自动、any→强制调用、none→禁止调用、{"type":"tool","name":"..."}→指定工具。
thinkingobject可选{"type":"enabled","budget_tokens":N} 启用推理,内部映射为 reasoning_effort: highmax_completion_tokens = budget_tokens + max_tokens
metadata.user_idstring可选终端用户标识,映射为 OpenAI 的 user 字段。

请求示例

bash
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
}'

工具调用示例

bash
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 块(含 idinput 对象),stop_reasontool_use。执行完函数后,将结果以 tool_result 块(携带相同 tool_use_id)放入下一条 user 消息再次请求,即可完成闭环;失败结果设置 is_error: true,内容会自动加 [Error] 前缀。

扩展思考示例

JSON
"thinking": {
"type": "enabled",
"budget_tokens": 2048
}

启用后网关内部映射为 reasoning_effort: highmax_completion_tokens = budget_tokens + max_tokens;响应中思考内容以 thinking 类型块置于 content 首位,流式模式下以 thinking_delta 增量下发。signature 字段不参与校验,回传时可为 null

非流式响应示例

json
{
"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_startcontent_block_startping → 多个 content_block_deltacontent_block_stopmessage_deltamessage_stop

text
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 字段转换规则
systemmessages[0](role=system)字符串直接转换;数组形式提取全部 text 块以换行合并。
messages[].content(image 块)image_urlbase64 source 拼为 data:{media_type};base64,...,detail 固定为 auto
tool_usetool_calls转为 {"type":"function","function":{"name":...,"arguments": JSON 字符串}}
tool_resultrole=tool 消息tool_use_id 映射为 tool_call_idis_error 为真时内容前加 [Error] 前缀。
stop_sequencesstop原样映射。
tool_choicetool_choiceanyrequired{"type":"tool"}{"type":"function","function":{"name":...}}
thinking.budget_tokensthinking_budget + max_completion_tokens启用时 reasoning_effort=highmax_completion_tokens = budget_tokens + max_tokens(max_tokens 缺省按 4096 计)。
metadata.user_iduser原样映射。
响应 finish_reason响应 stop_reasonstopend_turnlength/max_tokensmax_tokenstool_callstool_use
响应 reasoning_content响应 thinking推理内容包裹为 {"type":"thinking","thinking":...,"signature":null} 置于 content 首位。
响应 usage.prompt_tokens / completion_tokens响应 usage.input_tokens / output_tokens一一对应,缓存相关字段固定为 0。
协议说明:请求中的 cache_controlcitations 等客户端注入字段会在转发前被递归剥离,以避免上游报 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

POSThttps://yunzhiapi.cn/v1/messages/count_tokens

请求头

请求头必填说明
x-api-key必填本站 sk- 开头的密钥;也支持 Authorization: Beareranthropic-api-key
anthropic-version必填固定填 2023-06-01
Content-Type必填application/json

请求参数

参数类型必填说明
modelstring必填模型名,与 Messages 端点一致。
messagesarray必填与 Messages 端点相同的消息结构,全部文本内容参与估算。
systemstring | array可选系统提示,转换为 system 消息后计入估算。
toolsarray可选工具定义,序列化为 JSON 文本后追加计入估算。

请求示例

bash
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": "用一句话介绍杭州。"}
]
}'

响应示例

json
{
"input_tokens": 21
}

使用场景

  • 上下文压缩:Claude Code 等客户端在历史接近窗口上限前调用本接口,决定是否触发自动压缩。
  • 成本预估:批量任务执行前估算总输入 token,预判费用与余额是否充足。
  • 窗口告警:长对话应用中实时监控占用比例,超过 80% 时提示用户或自动摘要。

与 OpenAI 协议的字段映射

Anthropic 字段内部处理说明
systemsystem 消息文本与 Messages 端点相同的转换规则,拼接进估算文本。
messages[].content消息文本各消息文本拼接后统一估算。
toolsJSON 文本整体序列化后追加到估算文本末尾。
响应 input_tokens估算结果由本地估算器(estimate_tokens_precise,chat 类别)计算得出。
估算性质:返回值为本地启发式估算结果,与上游真实分词器可能存在偏差,仅用于上下文窗口的占用预估,不代表实际计费数量。
注意事项:① 本端点仍需有效密钥与速率限制校验,但不会扣除任何额度;② 请求体为空或 JSON 非法时返回 Anthropic 风格的 400 错误;③ 不参与估算的参数(如 max_tokenstemperature)即使缺失也不会报错。

模型列表(Anthropic 格式)#

以 Anthropic 协议格式返回当前可用模型列表。适用于 Anthropic SDK 的模型枚举、Claude Code 启动时的模型探测等场景。除显式路径 /anthropic/v1/models 外,对标准 GET /v1/models 的请求,当携带 anthropic-version 请求头或 User-Agent 含 Anthropic 时,也会自动返回本格式。

GEThttps://yunzhiapi.cn/v1/models

请求头

请求头必填说明
x-api-key必填本站 sk- 开头的密钥;也支持 anthropic-api-keyAuthorization: Bearer
anthropic-version必填固定填 2023-06-01;同时作为 Anthropic 格式的识别信号。

请求示例

bash
curl https://yunzhiapi.cn/v1/models \
-H "x-api-key: sk-你的密钥" \
-H "anthropic-version: 2023-06-01"

响应示例

json
{
"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[].iddata[].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 格式。
注意事项:① 本接口同样需要鉴权与速率限制校验,密钥无效返回 401;② 暂不支持分页参数,has_more 固定为 false;③ 列表为空时 first_idlast_idnull

内容生成 generateContent#

Gemini 协议的核心对话端点,接收 contents 多轮对话并一次性返回完整生成结果。适用于 Google AI SDK(google-generativeai / @google/generative-ai)、支持 Gemini 原生协议的客户端,以及需要函数调用(functionCall)、JSON Schema 约束输出、思考预算(thinkingBudget)等 Gemini 特性的场景。网关会将请求转换为 OpenAI Chat Completions 格式转发上游,再把响应还原为 Gemini 格式。

POSThttps://yunzhiapi.cn/v1beta/models/{model}:generateContent

路径中的 {model} 替换为本站展示的模型名(如 gemini-2.5-pro),网关会自动剥离 models/ 等渠道前缀后匹配。/v1beta 前缀也可写作 /v1/v1alpha,三者等价。

鉴权方式

使用 x-goog-api-key 请求头传递本站 sk- 开头的密钥,或使用 ?key= 查询参数(浏览器直链场景),两种方式等价:

http
x-goog-api-key: sk-你的密钥

请求参数

参数 类型 必填 说明
contents array 必填 对话内容数组,每项含 roleusermodel)与 parts;parts 支持 textinlineData(base64 图片/音频)、fileData(文件 URI)、functionCallfunctionResponseexecutableCodecodeExecutionResult
systemInstruction string | object 可选 系统指令,支持纯字符串、{"parts":[{"text":"..."}]}{"text":"..."} 三种写法,多段 text 会以换行拼接后作为 system 消息
generationConfig object 可选 生成配置,见下方字段映射表
safetySettings array 可选 安全设置数组(category + threshold),网关原样透传给上游
tools array 可选 工具声明,支持 functionDeclarations 函数定义;声明 googleSearch / googleSearchRetrieval 会转换为联网搜索开关
toolConfig object 可选 工具调用控制,functionCallingConfig.modeAUTO / ANY / NONEANYallowedFunctionNames 仅一个函数时强制调用该函数

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

请求示例

bash
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
}
}'

函数调用示例

bash
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(含 nameresponse 结果对象)作为新 part 追加到 contents 再次请求,即可完成闭环。

JSON 模式示例

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 以兼容更多模型)。

响应示例

json
{
"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 映射:stopSTOPlength/max_tokensMAX_TOKENScontent_filterSAFETY
  • 上游的 reasoning_content 思考内容会作为独立 part 返回,带 "thought": true 标记。
  • 上游 tool_calls 会还原为 parts 中的 functionCallname + 对象形式的 args)。
  • usageMetadata 三项分别对应 OpenAI 的 prompt_tokenscompletion_tokenstotal_tokensmodelVersion 回填为你请求的展示模型名。
提示:/v1beta/models/{model}:generateContent 外,网关还兼容 /v1/gemini/{model}/generateContent 路径写法;模型名不区分大小写,未携带密钥返回 401 YZ1001,密钥无效返回 401 YZ1002

流式生成 streamGenerateContent#

generateContent 参数完全一致,但响应为 Server-Sent Events 事件流,模型每生成一个增量片段就推送一条 data: 行。适用于聊天界面打字机效果、长文本实时输出等低首字延迟场景。请求体参数、字段映射与约束均同上一节,不再重复。

POSThttps://yunzhiapi.cn/v1beta/models/{model}:streamGenerateContent

鉴权方式

使用 x-goog-api-key 请求头或 ?key= 查询参数,与 generateContent 相同。

触发流式的两种方式

  • 使用 :streamGenerateContent action(标准写法)。
  • :generateContent 上附加查询参数 ?alt=sse,网关同样按流式处理。

请求示例

bash
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:

text
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;若上游未提供则不会出现。
  • 函数调用在结束时一次性以 functionCall part 输出(参数聚合完整后随带 finishReason 的 chunk 下发)。

与 OpenAI 流式的差异

对比项OpenAI 协议Gemini 协议
结束标记data: [DONE]无结束标记,以连接关闭或末块 finishReason 判定
事件结构data:data:
usage 下发时机末尾 chunk(服务端强制开启)仅上游提供时附加在末块
思考内容载体reasoning_content 字段{"thought":true} part
注意:Gemini 流式不会发送 data: [DONE] 结束标记,客户端应以连接关闭或最后一个带 finishReason 的 chunk 判定结束;这与 OpenAI 协议的流式约定不同,混用 SDK 时需注意。

令牌计数 countTokens#

在正式发起生成请求前预估输入 token 数,用于成本预估与上下文长度控制。该端点在网关本地完成估算:将 Gemini 请求转换为内部消息格式后按文本估算,不转发上游、不消耗模型调用、不计费,仅做鉴权与限流检查。

POSThttps://yunzhiapi.cn/v1beta/models/{model}:countTokens

鉴权方式

使用 x-goog-api-key 请求头或 ?key= 查询参数。

请求参数

参数 类型 必填 说明
contents array 必填 generateContent 相同的对话内容数组;也可改为传 generateContentRequest 包裹的完整生成请求(网关会自动解包)
systemInstruction string | object 可选 系统指令,计入 token 估算
tools array 可选 工具声明,其 JSON 文本会一并计入估算

请求示例

bash
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": "用一句话介绍量子计算"}]}
]
}'

响应示例

json
{
"totalTokens": 24
}

使用建议

  • 批量任务执行前调用本接口预估总量,结合模型单价评估成本,避免余额不足中断。
  • 长上下文应用可在每轮对话后计数,超过窗口 80% 时触发摘要或截断策略。
  • 本接口不校验模型是否存在,拼写错误不会报错,仅影响估算的参考意义。
提示:返回值为网关本地估算结果,与上游真实 tokenizer 可能存在少量偏差,仅用于参考;该接口不检查模型是否真实存在,也不产生任何费用。

图像生成 predict(Imagen)#

Gemini 协议的图像生成端点(Vertex AI 风格),接收 instances 提示词数组并返回 predictions 图像数组。网关将每个 instance 的提示词转换为上游 OpenAI /v1/images/generations 请求,再把图像结果还原为 Gemini predictions 格式。适用于 Imagen 系列模型与 Vertex AI SDK 迁移场景。

POSThttps://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:161024x1792(竖版)
16:91792x1024(横版)
其他值 / 缺省1024x1024(方形)

请求示例

bash
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"
}
}'

响应示例

json
{
"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 数组中。
计费说明:按实际生成的图片张数计费(模型未配置按 token 计价时按张数乘以出图单价),多张 instance 与 sampleCount 会叠加计费,请留意账户余额。

视频生成 predictLongRunning(Veo)#

Gemini 协议的长任务视频生成端点(Veo 系列)。网关在内部将请求转换为上游 /v1/videos/generations同步调用,等待视频生成完成后,把结果包装为 Google 长运行操作(Long-Running Operation)对象返回,done 直接为 true,无需真实轮询。

POSThttps://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].promptprompt仅取第一项提示词
parameters.sampleCountn钳制到 [1, 5]
parameters.durationSecondsduration视频时长(秒)
parameters.aspectRatioaspect_ratio原样透传

请求示例

bash
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"
}
}'

响应示例

json
{
"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"
}
}
]
}
}
}

长任务处理流程

  1. :predictLongRunning 提交请求,网关同步等待上游视频生成完成(该过程可能耗时较长,请为客户端设置充足的超时时间)。
  2. 检查返回 operation 对象的 done 字段:本网关始终在完成后再响应,故直接为 truenameoperations/yz- + 请求 ID)仅作协议兼容标识。
  3. response.generateVideoResponse.generatedSamples 读取视频:上游返回 URL 时取 video.uri,返回 base64 时取 video.bytesBase64Encoded
  4. 若客户端实现了 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 可直接反序列化。
注意:该接口为同步阻塞实现,视频生成期间 HTTP 连接保持打开,网关侧上游超时为 300 秒;请避免在短超时网关或 serverless 环境中调用。任务按模型出图单价固定计费一次,与时长无关。

模型列表(Gemini 格式)#

以 Gemini 原生格式返回当前可用的模型列表,供 Google AI SDK 发现模型与能力。每个模型条目包含 models/ 前缀的资源名、token 上限与支持的生成方法。

GEThttps://yunzhiapi.cn/v1beta/models

鉴权方式

使用 x-goog-api-key 请求头或 ?key= 查询参数。此外,对 GET /v1/models 携带 x-goog-api-key 头或 ?key= 参数时,网关同样返回本 Gemini 格式列表(未携带时返回 OpenAI 格式)。

请求示例

bash
curl "https://yunzhiapi.cn/v1beta/models" \
-H "x-goog-api-key: sk-你的密钥"

响应示例

json
{
"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
}
]
}

字段说明

字段说明
namemodels/ + 展示名,可直接用于生成接口路径
displayName模型展示名,与 OpenAI 格式的 id 一致
inputTokenLimit / outputTokenLimit对外展示的窗口参考值,不代表实际上游限制
supportedGenerationMethods固定为 ["generateContent","countTokens"]
temperature / topP / topK默认采样参数参考值

与 OpenAI 模型列表的对应关系

  • namemodels/ + 对外展示名,displayName 即 OpenAI 格式中的 id,请求生成接口时两者均可使用。
  • supportedGenerationMethods 固定为 ["generateContent","countTokens"]inputTokenLimit / outputTokenLimit 为对外展示值,不代表实际上游限制。
  • 同一份模型清单也支持 OpenAI 格式({"object":"list","data":[...]})与 Anthropic 格式输出,由请求携带的鉴权头自动判定。
提示:模型清单由平台运营方在后台登记并实时生效(缓存约 30 秒);调用生成接口时填写 displayName 即可,网关转发上游时会自动替换为后端模型名。

流式输出 SSE#

在请求体中加入 "stream": true 后,网关将以 Server-Sent Events(SSE)方式实时推送生成内容。响应头如下:

http
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] 作为结束标记:

text
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 / Geminidata: 行(无 event: 行)OpenAI 透传 chat.completion.chunk;Gemini 逐块输出 candidates[].content.parts,思维链以 {"text":…,"thought":true} 表示,末块携带 finishReason(STOP / MAX_TOKENS / SAFETY)与 usageMetadatadata: [DONE]
Anthropicevent: + data: 成对出现message_startcontent_block_start → 若干 content_block_delta(text_delta / thinking_delta / input_json_delta)→ content_block_stopmessage_delta(含 stop_reason 与 usage)→ message_stopmessage_stop 事件
Responses APIevent: + data: 成对出现response.createdresponse.in_progressresponse.output_item.addedresponse.content_part.added → 若干 response.output_text.deltaresponse.output_text.doneresponse.output_item.doneresponse.completedresponse.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 手动解析:

javascript
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);
}
}
}
python
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_linesReadableStream),不要等待完整响应体。非流式请求网关侧超时为 600 秒,流式请求不限制总时长(仅受 120 秒低速检测约束),客户端超时应相应放宽。

断点续传 Resume#

流式响应期间网络中断时,网关支持从断点继续接收剩余的 SSE 数据,已生成的内容不会丢失,也不会重复扣费。

X-Resume-Token 响应头

每个流式响应的头部都会携带一个续传令牌,格式为 rst_ 前缀 + 32 位十六进制字符(由 random_bytes(16) 生成):

http
X-Resume-Token: rst_4f8a2c1e9b7d3f605a8e1c2b4d6f8093

网关在流式过程中会把每一条 SSE 帧按序号(chunk_index)写入续传缓冲表(mxgapi_stream_buffer),每积累 50 条批量落库一次,流结束时强制刷新剩余缓冲。

恢复方式

断线后,使用相同的请求体重新发起请求,并通过以下任一方式携带令牌:

  1. 请求头 X-Resume-Token: rst_…(推荐)
  2. 请求头 Last-Event-ID: rst_…(兼容 SSE 标准客户端自动重连)
  3. 查询参数 ?last_event_id=rst_…
bash
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 行为)。

完整恢复流程

  1. 发起流式请求后,从响应头读取并持久化 X-Resume-Token 与已接收的帧序号。
  2. 检测到连接中断(读超时、连接重置)后,保持原请求体不变,附加令牌重新发起请求。
  3. 网关回放缓冲帧时,客户端按帧序号与本地已渲染内容比对,跳过重复部分后继续拼接。
  4. 收到结束标记([DONE] / message_stop / response.completed)后清理本地令牌。
  5. 若令牌已过期(2 小时)或返回 404,降级为重新发起完整生成请求。

有效期与限制

项目数值 / 说明
缓冲保留时长2 小时(超过后由后台概率性清理删除,令牌失效)
单次回放上限最多回放 15000 条缓冲帧
单帧长度上限单条 SSE 帧超过 65000 字节时落库前会被截断
请求绑定令牌与 API Key 绑定,且需配合相同请求体(命中同一幂等键)才能恢复
处理中窗口仅当原请求处于 pending 且未超过 180 秒处理中锁定时可续传;否则按幂等冲突或已完成回放处理

客户端实现建议

  • 在每次收到事件后更新本地持久化的令牌与序号,确保任意时刻断开都能从最近点恢复。
  • 恢复请求与原请求使用同一个 X-Idempotency-Key,可复用幂等记录避免冲突。
  • 移动端弱网环境建议将读超时设为 30~60 秒并自动触发续传,用户无感知。
续传回放的是网关已转换为目标协议的 SSE 帧,因此 Anthropic / Responses 协议的流同样可以无缝恢复。断线后上游生成仍在继续(网关以 ignore_user_abort 运行),不会因为你断开而取消,费用按最终完整用量结算一次。

幂等重试 Idempotency#

网关为每个请求计算幂等键,保证网络重试、客户端超时重发不会造成重复扣费或重复执行。

幂等键来源优先级

  1. X-Idempotency-Key 请求头(最高优先级,推荐显式提供)
  2. X-Request-Id 请求头
  3. 请求体特征:对请求体原文计算 SHA-256 并取前 16 位十六进制作为指纹

最终幂等键由 API Key + 来源类型 + 客户端键 + 请求体指纹 拼接而成(最长 128 字符),因此同一个 X-Idempotency-Key 搭配不同的请求体会返回 409 与错误码 YZ3008,提示该键已被用于其他请求。

幂等键设计建议

  • 推荐为每个逻辑请求生成 UUID v4 作为幂等键,重试期间保持不变。
  • 业务系统可使用「业务ID + 时间窗口」组合键,天然防止同一业务重复提交。
  • 切勿对多个不同请求复用同一个键,也不要为同一请求的每次重试生成新键。
  • 请求体任何改动都会改变指纹,重试时请保持请求体逐字节一致。

命中回放

当幂等记录状态为 completed 且有缓存结果时,网关直接返回首次请求的响应(HTTP 200),并附带响应头:

http
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 秒),后续重复请求会被拒绝:

json
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,确保多次重试在服务端被识别为同一逻辑请求:

python
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 状态码映射表

上游状态码对外状态码网关错误码对外消息
400400YZ5005Request rejected by upstream(附上游消息)
401502YZ5005Upstream authentication failed, please contact support.
403502YZ5005Request rejected by upstream safety policy(附上游消息)
404404YZ4001Model not available on upstream(附上游消息)
422400YZ3007Parameter format unprocessable(附上游消息)
429429YZ1003Upstream rate limit exceeded, please retry later.
503503YZ5005Upstream under maintenance, please retry later.
504504YZ5001Upstream gateway timeout, please retry later.
其他 5xx(500/502/505…)502YZ5005Upstream service error (HTTP {code})(附上游消息)
其他未列出的状态码502YZ5005Upstream anomaly (HTTP {code})

传输层(curl)错误映射表

传输层错误对外状态码网关错误码对外消息
连接/读取超时502YZ5001AI service response timeout, please retry.
无法建立连接 / 收发中断502YZ5002Unable to connect to AI service, please retry later.
DNS 解析失败502YZ5003Unable to resolve AI service domain, please retry later.
TLS 握手失败502YZ5004SSL/TLS handshake error, please retry.
上游无数据返回502YZ5006Upstream returned no data, please retry.
上游返回非 JSON 响应502YZ5007Upstream returned non-JSON response.
熔断器打开503YZ5008Upstream circuit breaker open, please retry later.

所有上游失败场景网关都会全额退还预扣余额,并将幂等记录标记为 failed,客户端可安全重试。

流内错误事件

流式响应中若头部已下发后上游中断,HTTP 状态码不再改变,网关改为在流内发送错误事件,客户端解析器需处理这些事件:

OpenAI 协议
: error {"code":"YZ5001","message":"AI service response timeout, please retry.","request_id":"req_..."}
data: [DONE]
Anthropic 协议
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"}
Responses API
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,三者行为完全一致。

响应示例

json
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"status": "ok",
"timestamp": 1721000000
}
字段类型说明
statusstring固定为 "ok",表示网关进程可正常响应
timestampinteger服务器当前 Unix 时间戳(秒),可用于时钟偏移检测

探针配置示例(Kubernetes)

yaml
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 同步。

典型用途:负载均衡器 / Kubernetes liveness 与 readiness 探针、uptime 监控(如 UptimeRobot)、发布后的冒烟检查。注意该端点只验证网关进程存活,不检测数据库与上游 AI 服务的连通性;需要验证端到端链路时请改用一次低成本的 GET /v1/models 请求。

OpenAI SDK#

网关完整兼容 OpenAI Chat Completions 协议(POST https://yunzhiapi.cn/v1/chat/completions),官方 openai SDK 只需把 base_url 指向本网关即可使用,支持非流式、流式与异步调用。

安装

Bash
pip install openai
Bash
npm install openai

配置要点

配置项取值说明
base_url / baseURLhttps://yunzhiapi.cn/v1必须以 /v1 结尾
api_key / apiKeysk- 开头的密钥Authorization: Bearer 头发送
model模型名可先用 GET /v1/models 查询

Python 示例(非流式 + 流式)

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 异步示例

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 示例(非流式 + 流式)

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_urlapi_key 参数,SDK 会自动读取:

Bash
export OPENAI_BASE_URL="https://yunzhiapi.cn/v1"
export OPENAI_API_KEY="sk-your-key"

超时与内置重试

Python
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 指向本网关根地址即可,支持非流式与流式调用。

安装

Bash
pip install anthropic
Bash
npm install @anthropic-ai/sdk

配置要点

配置项取值说明
base_url / baseURLhttps://yunzhiapi.cn不带 /v1,SDK 自动追加 /v1/messages
api_key / apiKeysk- 开头的密钥x-api-key 头发送
auth_tokensk- 开头的密钥可选,改用 Authorization: Bearer 头发送
max_tokens必填Anthropic 协议强制要求

Python 示例(非流式 + 流式)

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 示例(非流式 + 流式)

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);
}
}

环境变量配置

Bash
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 秒。

常见坑:与 OpenAI SDK 相反,Anthropic SDK 的 base_url 不要/v1,SDK 会自行拼接 /v1/messages,手动带上会变成 /v1/v1/messages 导致 404;max_tokens 为必填参数,漏传会直接报参数错误;流式事件的文本在 content_block_deltatext_delta 里,需按事件类型过滤。

Gemini SDK#

网关兼容 Gemini generateContent 协议(POST https://yunzhiapi.cn/v1beta/models/模型名:generateContent),使用 Google 官方新版 SDK(Python 的 google-genai、Node.js 的 @google/genai),通过 httpOptionsbaseUrl 指向本网关即可。

安装

Bash
pip install google-genai
Bash
npm install @google/genai

配置要点

配置项取值说明
httpOptions.baseUrlhttps://yunzhiapi.cn网关根地址,SDK 自动追加 /v1beta/models/...
apiKeysk- 开头的密钥x-goog-api-key 头发送
model模型名gemini-2.5-flash

Python 示例(非流式 + 流式)

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 示例(非流式 + 流式)

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 ?? "");
}

环境变量配置

Bash
export GEMINI_API_KEY="sk-your-key"

SDK 按 GEMINI_API_KEYGOOGLE_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)不支持自定义 baseUrlbaseUrl 填网关根地址即可,不要手动拼 /v1beta;流式接口也可在 URL 上加 ?alt=sse 强制 SSE 输出。

原生 HTTP 调用#

不依赖任何 SDK,直接向 POST https://yunzhiapi.cn/v1/chat/completions 发送 JSON 即可。以下示例均包含错误处理,并读取响应头 X-Request-ID 用于问题追踪。

配置要点

  • 请求头 Authorization: Bearer sk-你的密钥(也可用 x-api-keyx-goog-api-key)。
  • 请求体为 OpenAI Chat Completions 格式 JSON,modelmessages 必填。
  • 非 2xx 状态码时响应体为 OpenAI 风格错误 JSON;务必读取并记录 X-Request-ID

Python requests

Python
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

Node.js
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
<?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

Go
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_urlhttps://yunzhiapi.cn/v1 并填入 sk- 密钥。

安装

Bash
pip install langchain-openai llama-index llama-index-llms-openai-like
npm install @langchain/openai ai @ai-sdk/openai

LangChain Python

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

Node.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

Python
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

Node.js
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

YAML
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 返回的名称一致。
常见坑:LangChain JS 的 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)。

配置步骤

  1. 在本站后台创建密钥,密钥以 sk- 开头,复制备用。
  2. 设置环境变量 ANTHROPIC_BASE_URLhttps://yunzhiapi.cn(注意:不带 /v1 后缀)。
  3. 设置环境变量 ANTHROPIC_AUTH_TOKEN 为你的密钥(部分版本使用 ANTHROPIC_API_KEY,两者任一即可)。
  4. 重新打开终端,使环境变量生效。

Windows PowerShell

powershell
[Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "https://yunzhiapi.cn", "User")
[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "sk-你的密钥", "User")

macOS / Linux

bash
export ANTHROPIC_BASE_URL="https://yunzhiapi.cn"
export ANTHROPIC_AUTH_TOKEN="sk-你的密钥"

settings.json 配置(可选)

也可以写入 ~/.claude/settings.json(Windows 为 %USERPROFILE%\.claude\settings.json):

json
{
"env": {
"ANTHROPIC_BASE_URL": "https://yunzhiapi.cn",
"ANTHROPIC_AUTH_TOKEN": "sk-你的密钥"
}
}

验证方法

  1. 执行 claude --version 确认客户端可用。
  2. 执行 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 兼容端点。

配置步骤

  1. 打开配置文件 ~/.codex/config.toml(Windows 为 %USERPROFILE%\.codex\config.toml)。
  2. 新增自定义 model_provider,将 base_url 设为 https://yunzhiapi.cn/v1(必须带 /v1 后缀)。
  3. 设置 env_key 指向存放密钥的环境变量名,例如 OPENAI_API_KEY
  4. 将环境变量 OPENAI_API_KEY 设为本站 sk- 开头的密钥。
  5. config.toml 顶部指定 model_providermodel(模型名通过 GET /v1/models 获取)。

config.toml 示例

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"

设置密钥环境变量

bash
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 提供商,可直接接入本站。

配置步骤

  1. 在 VS Code 扩展市场安装 Cline(或 Roo Code),安装后点击侧边栏插件图标。
  2. 打开插件设置,API Provider 选择 OpenAI Compatible
  3. Base URL 填写 https://yunzhiapi.cn/v1
  4. API Key 填写本站 sk- 开头的密钥。
  5. Model 填写本站展示的模型名(通过 GET /v1/models 获取完整列表),如 gpt-4o
  6. 保存配置。

验证方法

在插件对话框中发送任意问题,如「帮我写一个快速排序」,能正常流式返回代码即配置成功。

使用建议

Act 与 Chat 模式均通过同一 OpenAI 兼容端点发起请求;长任务建议在插件设置中开启流式输出并适当调高请求超时。Roo Code 的 Boomerang 任务分发同样适用本配置,多模型混用时请注意各模型单价差异,可在用量明细中按模型核对成本。

常见问题:① Base URL 必须以 /v1 结尾,不要带 /chat/completions;② 模型名必须与本站展示名完全一致,手误拼写会报模型不存在;③ 切换密钥后若仍用旧额度,重启 VS Code 让插件重新读取配置。

OpenClaw#

OpenClaw 支持自定义 OpenAI 兼容端点,按通用的「API 地址 + 密钥 + 模型名」三步即可完成接入。

配置步骤

  1. 打开 OpenClaw 的设置界面,找到模型 / API 提供方配置项。
  2. API 地址(Base URL / Endpoint)填写 https://yunzhiapi.cn/v1
  3. API 密钥(API Key)填写本站 sk- 开头的密钥。
  4. 模型名填写本站展示的模型名(通过 GET /v1/models 获取),保存配置。

验证方法

发起一次对话请求,能正常返回模型回复即接入成功。

参数透传

OpenClaw 侧设置的 temperature、max_tokens 等参数会原样透传至网关并参与统一钳制规则;对话历史由客户端维护,长会话请注意模型上下文窗口限制,必要时手动压缩历史或新建会话。

常见问题:① API 地址需以 /v1 结尾,这是 OpenAI 兼容协议的约定;② 密钥注意不要多复制空格或换行,否则鉴权失败返回 401;③ 模型名需与本站展示名完全一致。

WorkBuddy#

WorkBuddy 支持自定义 OpenAI 兼容端点,按通用的「API 地址 + 密钥 + 模型名」三步即可完成接入。

配置步骤

  1. 进入 WorkBuddy 的设置页面,找到模型服务 / API 配置入口。
  2. API 地址(Base URL / Endpoint)填写 https://yunzhiapi.cn/v1
  3. API 密钥(API Key)填写本站 sk- 开头的密钥。
  4. 模型名填写本站展示的模型名(通过 GET /v1/models 获取),保存配置。

验证方法

在对话窗口发送一条测试消息,能正常收到模型回复即接入成功。

团队协作建议

WorkBuddy 的温度、输出长度等设置以 OpenAI 兼容字段下发,网关按统一规则钳制;团队协作场景建议为不同项目创建独立密钥,便于用量归属统计与额度控制,密钥泄露时也可按项目粒度快速重置。

常见问题:① API 地址必须以 /v1 结尾;② 若提示密钥无效,请检查密钥是否完整复制(以 sk- 开头、无多余空格);③ 模型名拼写需与本站模型列表完全一致。

LobeHub / LobeChat#

LobeChat 支持为 OpenAI 提供商配置自定义代理地址,接入本站后即可在会话中选择本站模型。

配置步骤

  1. 打开 LobeChat,进入 设置 → 语言模型 → OpenAI
  2. 开启「使用自定义代理地址」,接口代理地址 填写 https://yunzhiapi.cn/v1
  3. API Key 填写本站 sk- 开头的密钥。
  4. 在模型列表区域点击「获取模型列表」,从 /v1/models 拉取可用模型并勾选需要使用的模型。
  5. 保存设置,回到会话页选择已启用的模型。

验证方法

新建会话发送任意消息,能正常流式回复即配置成功。

自部署环境变量

bash
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_URLOPENAI_API_KEY 配置;③ 模型列表拉取失败时先检查密钥是否正确。

Cherry Studio#

Cherry Studio 是桌面端 AI 客户端,支持添加 OpenAI 兼容的模型服务商。

配置步骤

  1. 打开 Cherry Studio,点击左下角 设置 图标。
  2. 进入 模型服务,点击 添加 新建服务商,类型选择 OpenAI 兼容(OpenAI Compatible)。
  3. API 地址 填写 https://yunzhiapi.cn/v1
  4. API 密钥 填写本站 sk- 开头的密钥。
  5. 点击 添加模型,填入本站展示的模型名(通过 GET /v1/models 获取),保存并开启该服务商开关。

验证方法

点击密钥旁的「检查」按钮测试连通性,或回到对话页选择刚添加的模型发送消息验证。

多服务商并存

Cherry Studio 允许同时添加多个 OpenAI 兼容服务商,本站可与其他渠道并存,按会话选择模型时以「服务商 + 模型名」区分;助手(Assistant)配置中引用的模型需先在对应服务商下启用,否则发送时会提示模型不可用。

常见问题:① API 地址填写到 /v1 即可,软件会自动拼接 /chat/completions;② 添加模型时模型 ID 必须与本站展示名一致;③ 检查失败时确认密钥无多余空格且服务商开关已打开。

NextChat / ChatGPT-Next-Web#

NextChat 支持通过环境变量或界面设置自定义 OpenAI 接口地址,两种方式任选其一。

方式一:环境变量(部署时)

bash
export BASE_URL="https://yunzhiapi.cn"
export OPENAI_API_KEY="sk-你的密钥"

方式二:界面设置

  1. 打开 NextChat,点击左下角 设置
  2. 找到 自定义接口 并开启。
  3. 接口地址 填写 https://yunzhiapi.cn
  4. API Key 填写本站 sk- 开头的密钥。
  5. 保存后回到对话页选择模型(模型名可在设置中自定义为 GET /v1/models 返回的名称)。

验证方法

新建对话发送任意消息,能正常收到回复即配置成功。

自定义模型名

在设置的「自定义模型」输入框中用英文逗号分隔多个模型名(如 gpt-4o,claude-sonnet-4-5,gemini-2.5-pro),即可全部加入模型下拉列表;需要强制所有模型可选时,可在列表末尾追加 -all 后缀的自定义项。

常见问题:① 界面接口地址填根路径即可,NextChat 会自行拼接 /v1/chat/completions;② 环境变量修改后需重启服务生效;③ 若模型下拉列表没有想要的模型,在设置中手动添加模型名。

Open WebUI#

Open WebUI 是流行的自托管 Web 聊天界面,可在管理后台添加 OpenAI API 连接。

配置步骤

  1. 登录 Open WebUI 管理员账号,点击左下角头像进入 Admin Panel(管理员面板)
  2. 进入 Settings → Connections(设置 → 连接)
  3. OpenAI API 区域点击 + 号添加连接。
  4. URL 填写 https://yunzhiapi.cn/v1API Key 填写本站 sk- 开头的密钥。
  5. 保存连接,系统会自动从 /v1/models 拉取模型列表。

Docker 环境变量方式(可选)

bash
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 出口),否则保存连接后看不到模型。

常见问题:① URL 必须以 /v1 结尾,末尾不要带斜杠或 /chat/completions;② 保存后看不到模型时,检查容器能否访问本站域名;③ 环境变量方式修改后需重启容器。

Dify#

Dify 是开源 LLM 应用开发平台,可通过 OpenAI-API-compatible 供应商接入本站模型。

配置步骤

  1. 登录 Dify,点击右上角头像进入 设置 → 模型供应商
  2. 在供应商列表中找到 OpenAI-API-compatible,点击「添加模型」。
  3. Name(模型名称) 填写本站展示的模型名(通过 GET /v1/models 获取)。
  4. API Endpoint URL 填写 https://yunzhiapi.cn/v1
  5. API Key 填写本站 sk- 开头的密钥。
  6. 选择模型类型(LLM / Text Embedding 等,按模型实际类型选择),保存。

验证方法

创建或打开一个应用,在模型选择器中选中刚添加的模型并发送消息,正常回复即接入成功。

工作流集成

在工作流编排中,LLM 节点选择已添加的本站模型即可;需要函数调用时选用支持 tool_calls 的模型并在节点中声明工具。Embedding 类模型需以 Text Embedding 类型单独添加,供知识库检索使用;Rerank 与语音类型同理,按实际能力分别登记。

常见问题:① 请使用 OpenAI-API-compatible 供应商而不是官方 OpenAI 供应商,后者不支持自定义 Endpoint;② API Endpoint 需以 /v1 结尾;③ 函数调用(Function Call)能力取决于模型本身,若工作流需要请确认模型支持。

沉浸式翻译#

沉浸式翻译浏览器插件支持自定义 OpenAI 兼容接口,可接入本站模型进行网页翻译。

配置步骤

  1. 点击浏览器工具栏中的沉浸式翻译图标,进入 设置
  2. 翻译服务 中选择 自定义 OpenAI(OpenAI 兼容接口)。
  3. API 接口地址 填写 https://yunzhiapi.cn/v1/chat/completions(注意需填写到完整的 chat completions 路径)。
  4. API Key 填写本站 sk- 开头的密钥。
  5. 模型名 填写本站展示的模型名(通过 GET /v1/models 获取),如 gpt-4o-mini
  6. 保存设置。

验证方法

打开任意外文网页触发翻译,页面正常出现双语对照译文即配置成功。

成本与体验

网页翻译按段落高频调用,建议选择低单价快速模型并开启插件的译文缓存以控制消耗;长文档可配合「术语表」统一专有名词译法。若整页翻译中断,检查是否触发限流(429),插件会自动按退避策略重试。

常见问题:① 与其他客户端不同,此处接口地址需要填写完整的 /v1/chat/completions 路径;② 翻译调用频繁,建议选用快速且价格低的模型以控制消耗;③ 若提示请求失败,检查地址中是否误加了末尾斜杠。

故障排查#

本章按「症状 → 原因 → 解决」组织常见问题的定位路径。遇到问题时请先完成下方的通用排查流程,再按症状查阅对应小节。

通用排查流程

  1. 记录响应头 X-Request-ID(与错误体中的 request_id 一致),这是全链路追踪的唯一标识。
  2. 对照「错误码总表」定位错误码与错误类型,确认问题发生在鉴权、计费、路由还是上游环节。
  3. 检查账户余额是否不低于 0.01,并通过 GET https://yunzhiapi.cn/v1/models 核对模型名拼写。
  4. 仍无法解决时联系客服,并提供 request_id、请求时间、模型名与完整错误响应。

401 未鉴权 / 密钥无效

症状 可能原因 解决办法
HTTP 401 / YZ1001 请求未携带任何鉴权头,或密钥格式不合法被视为未提供 补充 Authorization: Bearer sk-...x-api-keyx-goog-api-key 任一头部
HTTP 401 / YZ1002 密钥拼写错误、已被重置或删除 回用户中心重新复制完整密钥,替换所有配置位置
密钥前后混入空格或换行、Bearer 拼写错误、头部名大小写被中间代理改写,都会导致 401。错误体中的 hint 字段会给出针对性修复建议。

402 余额不足

症状 可能原因 解决办法
HTTP 402 / YZ2001 账户余额低于最低预检额度 0.01,请求在入口预检阶段被拒绝 前往用户中心充值,到账后无需重置密钥即可恢复
大请求中途失败 预扣额度超出账户余额 减小 max_tokens 或输入长度,或充值后重试
402 发生在鉴权通过之后、转发上游之前,不会产生任何计费,可安全重试。

404 模型不存在

症状 可能原因 解决办法
HTTP 404 / YZ4001,错误体含 requested_model 模型名拼写错误、大小写或渠道前缀异常、模型已下架 读取错误体中的 did_you_mean 字段(最多 3 个相似模型名)自动纠正,或用 GET /v1/models 拉取完整列表核对
所有请求都 404 Base URL 拼接错误,例如 OpenAI 协议少带了 /v1 按「入口与鉴权」一章核对各协议的完整路径
网关支持前缀剥离与后缀模糊匹配,但仍建议始终使用模型列表中的完整展示名,避免多候选时命中非预期模型。

429 限流与幂等处理中

症状 可能原因 解决办法
HTTP 429 / YZ1003Retry-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-Tokenrst_ + 32 位十六进制),用原请求参数加 X-Resume-TokenLast-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#

同时支持 OpenAI 兼容协议(含 Chat Completions、Responses、Images、Audio、Embeddings 等)、Anthropic 兼容协议(/v1/messages)与 Gemini 兼容协议(/v1beta/models/{model}:generateContent 等)。三套协议共用同一套密钥与余额,可任意混用。
登录用户中心,在密钥管理页面创建并复制以 sk- 开头的 API Key。请妥善保管,泄露后应立即在用户中心重置。
取决于协议:OpenAI SDK 与客户端填 https://yunzhiapi.cn/v1(SDK 会在其后拼接 /chat/completions 等路径);Anthropic SDK 填根地址 https://yunzhiapi.cn(SDK 自动拼接 /v1/messages);Gemini 协议路径前缀为 https://yunzhiapi.cn/v1beta。填错最常见的表现是所有请求 404。
支持。OpenAI 协议设置 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 格式),或访问站点模型广场页面。列表实时生效,请求时填写展示名即可。
可以。Anthropic SDK 设置 base_url 为本站根地址、api_key 为本站密钥即可;Gemini SDK 设置 base_urlhttps://yunzhiapi.cn/v1beta 并使用 x-goog-api-key 传密钥。无需修改任何请求体结构,详见「SDK 集成」分组。
按模型定价从账户余额扣费:文本模型按输入 / 输出 token 计费,图像、音频、视频按次数或时长计费。请求前先执行余额预检(低于 0.01 返回 402),转发前预扣、响应后按实际用量结算,多退少补。命中幂等缓存的请求不计费。
每个 API Key 60 秒滑动窗口内最多 120 次请求,超限返回 HTTP 429 与 Retry-After: 60。按提示等待后重试即可,批量任务建议控制并发并加入指数退避。
两种方式:一是调用专用端点(OpenAI /v1/images/generations/v1/videos,Gemini predict / predictLongRunning);二是直接在聊天端点中请求 image / video 分类的模型,网关会自动分流到生成管线并把结果包装成标准对话响应。
支持。OpenAI 协议通过 tools + tool_choice 声明,响应以 tool_calls 返回;Anthropic 协议映射为 tool_use / tool_result 块;Gemini 协议映射为 functionCall / functionResponse part。具体是否触发取决于所选模型本身的能力。
OpenAI 协议传 reasoning_effort(low/medium/high);Anthropic 协议传 thinking: {"type":"enabled","budget_tokens":N};Gemini 协议传 generationConfig.thinkingConfig.thinkingBudget。思考内容分别以 reasoning_contentthinking 块、thought:true part 返回,思考 token 计入输出费用。
不会。所有 4xx/5xx 失败路径(含上游超时、熔断、无内容返回)都会全额退还预扣金额,客户端可放心按指数退避重试;重试时保持幂等键不变即可确保不重复扣费。
默认限额为每密钥 60 秒 120 次。确有批量业务需求时,请提供业务场景说明、预期并发量与近期 request_id 联系客服申请提额;也可为不同业务线创建多个密钥天然隔离额度。
技术上可以:网关已完整支持 CORS,所有响应携带 Access-Control-Allow-Origin: *。但前端页面源码中的密钥任何人可见,生产环境建议通过自己的后端转发调用,浏览器直连仅用于内部工具或临时调试。
网关仅将请求内容实时转发至上游模型渠道,不用于任何模型训练。服务端仅保留必要的审计日志(request_id、时间、模型、token 用量与计费结果)用于对账与问题排查,可在用户中心查询自己的调用记录。