蓝色 = 商户可自助(INTEGRATION Key,限自有账户);橙色 = 仅平台(PLATFORM Key);绿色 = CALL Key 调用侧
call 行(主体快照 subAccountId/scopeId/storeScopeId + quotaMonth = 登记月 Asia/Shanghai)
→ 调上游(NewAPI/直连),调用预算 150 秒
quota 为权威计量:consumedPointUnits = max(quota,0) × 146
billingStatus=SUCCESS, settled=true,同事务写 consumption + point_record(扣快照桶)+ 余额SETTLE_PENDING → 补偿重试 1/5/15/60 分钟 ×24(≈21.35h)retryHint=QUERY_ORIGINAL_REQUEST,用原 requestId 查 GET /api/v1/calls/{requestId}data: {"error": …} 并结束,不发 [DONE],含 X-Should-Retry:falsedelta(role/content/reasoning_content)→ finish_reason → data: [DONE]GET /api/v1/calls/{requestId}。同号重放且原执行仍 PENDING/PROCESSING → JSON 409(reason=ORIGINAL_REQUEST_PENDING),绝不重新派发。| 类别 | 字段 / 行为 | 结果 |
|---|---|---|
| 支持(严格校验) | model(可省)、messages(system/user/assistant,developer 映射为 system;content 为字符串 1–1MiB,1–50 条)、stream(严格布尔)、stream_options.include_usage、temperature 0–2、top_p 0–1、max_tokens/max_completion_tokens 1–1e7、presence_penalty/frequency_penalty −2–2、seed 0–2³¹−1、stop(≤4 条,每条 1–64 字符) |
✔ 透传到上游 |
| 忽略(不报错) | n、tools/tool_choice、response_format、logit_bias、user、metadata 等一切白名单外字段 |
⚠ 静默丢弃,不会生效,也不会 400 |
| 拒绝(400) | messages[].content 数组形式(多模态)、stream 非布尔、stream_options 中出现 include_usage 以外的键、非流式请求带非 null 的 stream_options、stop 超 4 条或单条超 64 字符 |
✘ invalid_request_error |
| 响应形态 | id=chatcmpl-<requestId>、object=chat.completion/chat.completion.chunk、created、model、choices[{index, message|delta, finish_reason}]、usage{prompt_tokens, completion_tokens, total_tokens},另加扩展块 mei1{requestId, callId, billingStatus, consumedPoints}(官方 SDK 会忽略未知字段) |
✔ SDK 可直接解析 |
| 错误形态 | {error:{message, type, code, param}};余额不足与员工超额 → 429 insufficient_quota;限流 → 429 rate_limit_error;执行未出正文 → 500/503 api_error;/v1/* 的入参校验失败也走 OpenAI 形态 |
✔ 与 OpenAI 同构 |
| 必须知道的差异 |
1. 单模型白名单:model 必须等于服务端配置值,否则 400(不是「模型不存在」而是参数非法)2. 无幂等头的重试会重复计费:/v1 省略 X-Request-Id 时服务端每次生成新号,请自行带业务请求号并关闭自动重试 3. 仅字符串 content:多模态、工具调用、JSON mode 均不可用 4. 计费不看 usage:扣费以网关日志 quota 为准, usage 仅为展示;include_usage 的尾部用量事件可能缺失5. 429 insufficient_quota 有两种含义(账户/子账号余额不足 vs 员工月度额度超限),区分看 error.mei1.reason6. 错误 code 为自有错误码(如 ACCOUNT_BLOCKED),message 可能带 : reason 后缀
|
⚠ 兼容但非等价 |
| 入口 | POST /v1/chat/completions(非流式 + SSE)、GET /v1/models(单模型,仅供探活/枚举) |
迁移只需改 base_url 与 Key |
app/account_openai.py(请求模型、响应与错误构造)、app/account_main.py(路由与异常处理)、docs/external-api-reference.md §3.2 与 §7.2。未做真实网关联调的部分(上游 SSE 契约、目标环境反代)未包含在内。