Files
zend-token/docs/openai.md
T
2026-08-23 02:12:08 +08:00

226 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OpenAI API
> 来源:
> - OpenAPI 规范(权威):https://raw.githubusercontent.com/openai/openai-openapi/master/openapi.yaml
> - https://developers.openai.com/api/reference/resources/responses/methods/create
> - https://developers.openai.com/api/docs/guides/function-calling.md
> - https://developers.openai.com/api/docs/guides/structured-outputs.md
> - https://developers.openai.com/api/docs/guides/reasoning.md
> - https://developers.openai.com/api/docs/guides/migrate-to-responses.md
>
> 采集于 2026-08-12。注意:`platform.openai.com/docs/api-reference/*` 对爬虫返回 403,文档主站已迁移到 `developers.openai.com`;页面 URL 后加 `.md` 可直接取 Markdown 版本。
OpenAI 目前有**两套并存**的文本生成接口,中转站通常两套都要支持:
- `POST /v1/chat/completions` — 老接口,生态最广,几乎所有第三方"OpenAI 兼容"服务都实现它。
- `POST /v1/responses` — 新接口,OpenAI 主推,reasoning 模型的完整能力只在这里。
---
## 1. Chat Completions
### 1.1 请求参数
必填:`model``messages`
`messages[]` 的 role 取值:`system``developer``user``assistant``tool``function`(deprecated)。
来自 `CreateChatCompletionRequest`
| 参数 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `messages` | array | — | 必填,minItems 1 |
| `model` | string | — | 必填 |
| `max_completion_tokens` | int\|null | — | 输出上限,**含 reasoning tokens** |
| `max_tokens` | int\|null | — | **已 deprecated**,且与 o 系列/reasoning 模型不兼容 |
| `modalities` | array | — | 如 `["text"]` / `["text","audio"]` |
| `verbosity` | enum | — | 输出详略控制 |
| `reasoning_effort` | enum | — | 见 §3 |
| `frequency_penalty` | number | 0 | -2 ~ 2 |
| `presence_penalty` | number | 0 | -2 ~ 2 |
| `response_format` | object | `{type:"text"}` | `text` / `json_object` / `json_schema` |
| `stream` | bool | false | SSE |
| `stream_options` | object | — | `{include_usage: true}` |
| `stop` | string\|array | — | 停止序列 |
| `logit_bias` | map<int,int> | null | -100 ~ 100 |
| `logprobs` | bool | false | |
| `top_logprobs` | int | — | 0 ~ 20,需 `logprobs=true` |
| `n` | int | 1 | 1 ~ 128 |
| `seed` | int | — | **已 deprecated**Beta,不保证确定性 |
| `store` | bool | false | 是否存储用于 distillation/evals>8MB 图片会被丢弃 |
| `moderation` | object | — | 请求/输出审核配置 |
| `prediction` | object | — | Predicted Outputs |
| `audio` | object | — | `modalities:["audio"]` 时必填,含 `voice``format` |
| `web_search_options` | object | — | 内置 web 搜索 |
| `tools` | array | — | function tools 或 custom tools |
| `tool_choice` | string\|object | — | `none`/`auto`/`required`/指定函数/`allowed_tools` |
| `parallel_tool_calls` | bool | true | |
| `function_call` | — | — | **deprecated**,用 `tool_choice` |
| `functions` | array | — | **deprecated**,用 `tools`1~128 项 |
继承自 `ModelResponseProperties`Chat 与 Responses **共享**):
| 参数 | 类型 | 范围/默认 | 说明 |
| --- | --- | --- | --- |
| `temperature` | number | 0 ~ 2,默认 1 | |
| `top_p` | number | 0 ~ 1,默认 1 | 建议与 temperature 二选一 |
| `metadata` | map | — | |
| `user` | string | — | **deprecated**,被 `safety_identifier` + `prompt_cache_key` 取代 |
| `safety_identifier` | string | ≤64 字符 | 建议传用户名/邮箱的 hash |
| `prompt_cache_key` | string | — | 提升缓存命中率,取代 `user` |
| `service_tier` | enum | — | |
| `prompt_cache_retention` | enum | `in_memory` / `24h` | **deprecated**,改用 `prompt_cache_options.ttl``gpt-5.5` 及以后只支持 `24h` |
| `prompt_cache_options` | object | — | 含 `ttl` |
| `top_logprobs` | int | 0 ~ 20 | |
### 1.2 响应
```json
{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1741570283,
"model": "gpt-4o-2024-08-06",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "...", "refusal": null, "annotations": []},
"logprobs": null,
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 1117,
"completion_tokens": 46,
"total_tokens": 1163,
"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
}
},
"service_tier": "default",
"system_fingerprint": "fp_..."
}
```
`finish_reason` 枚举:`stop` | `length` | `tool_calls` | `content_filter` | `function_call`(deprecated)。
`system_fingerprint` 已标记 **deprecated**
`choices[].logprobs` 是 nullable 且在 schema 中被列为 **required**——即必须存在该 key,值可为 `null`。中转站生成响应时不要省略这个字段,严格的客户端会校验。
### 1.3 流式
`stream: true` 时返回 `object: "chat.completion.chunk"` 的 SSE,每个 chunk 的 `id` 相同,内容在 `choices[].delta`
关键点:
- 设置 `stream_options: {"include_usage": true}` 时,**最后一个 chunk 的 `choices` 为空数组**,只带 `usage`。这是很多客户端解析崩溃的来源。
- 流以 `data: [DONE]` 结束(非 JSON)。
- 工具调用的 `arguments` 以字符串分片下发,需按 `tool_calls[].index` 累加。
---
## 2. Responses API
`POST /v1/responses`
### 2.1 与 Chat Completions 的字段映射
| Chat Completions | Responses |
| --- | --- |
| `messages` | `input`(可为 string,也可为 Item 数组) |
| system / developer 消息 | `instructions`(顶层参数) |
| `max_completion_tokens` | `max_output_tokens` |
| `response_format` | `text.format` |
| `choices[0].message.content` | `output_text`SDK 便捷字段)/ `output[]` 里的 message item |
| `tool_calls[]`(含 `id` | `function_call` item(含 **`call_id`** |
| `tools[].function.{name,...}` | `tools[].{name,...}`(少一层嵌套) |
### 2.2 专有请求参数
| 参数 | 说明 |
| --- | --- |
| `background` | 后台执行 |
| `conversation` | 会话 ID 或 `{id}` 对象,自动把历史 item 拼到 input 前 |
| `previous_response_id` | 由 OpenAI 托管上下文;**注意仍需重发 `instructions`** |
| `store` | Responses **默认存储**Chat Completions 对新账户默认存储) |
| `include` | 请求额外输出,如 `web_search_call.action.sources``file_search_call.results` |
| `context_management` | `{type, compact_threshold}` 自动压缩上下文 |
| `reasoning` | `{effort, summary}` |
### 2.3 输出 item 类型
`output[]` 是异构数组,已知类型:
- `message``{id, role:"assistant", content:[text|refusal], status, phase?}``phase` 可为 `commentary` / `final_answer`
- `function_call``{arguments, call_id, name, status}`
- `file_search_call``{id, queries, status, results}`
- `web_search_call``{id, action, status}`
- `computer_call``{id, call_id, pending_safety_checks, action/actions, status}`
- `reasoning``{id, summary, content, encrypted_content, status}`
- `compaction``{id, encrypted_content}`
`status` 取值:`in_progress` | `completed` | `incomplete`
### 2.4 流式
事件是命名事件(如 `response.function_call_arguments.delta` / `.done`),与 Chat Completions 的匿名 chunk 完全不同结构。
未取到完整事件清单(`/api/reference/responses/streaming` 返回 404),实现前需补齐。
---
## 3. Reasoning 模型的怪癖
这是 OpenAI 侧最容易踩的一类坑:
1. **`max_tokens` 不可用**。Chat Completions 必须用 `max_completion_tokens`Responses 必须用 `max_output_tokens`。老代码直接透传 `max_tokens` 会报错。
2. **`temperature``top_p``presence_penalty` 不支持**(reasoning 模型上)。中转站若把这些参数无条件透传,请求会失败。
3. **`max_output_tokens` 包含 reasoning tokens**。官方建议实验时至少留 **25,000** tokens。给一个小的上限很可能只烧掉推理、输出为空。
4. **reasoning tokens 按 output token 计费**,占用上下文窗口,统计在 `output_tokens_details.reasoning_tokens`Chat 侧为 `completion_tokens_details.reasoning_tokens`)。
5. **`reasoning.effort` 取值随模型而变**`none` | `minimal` | `low` | `medium` | `high` | `xhigh` | `max``gpt-5.5` 默认 `medium`。不要假设所有模型接受全部取值。
6. **reasoning summary 需显式开启**`reasoning.summary`,设 `"auto"` 取最详细的可用摘要。默认不返回。
7. **无状态模式下必须回传 `encrypted_content`**。当 `store: false` 或组织启用 ZDR 时,reasoning item 携带 `encrypted_content`,多轮要把它传回去才能保留推理链。
8. **函数调用多轮时必须带回 reasoning item**:把最后一次 function call 返回的 reasoning items 与 function output 一起回传;连续多次函数调用时,需保留自上一条 user 消息以来的**所有** reasoning / function_call / function_call_output item。
---
## 4. Function calling 的怪癖
- **`strict: true` 的硬性要求**`additionalProperties` 必须为 `false`**所有** `properties` 都必须出现在 `required` 里。可选字段只能用 `"type": ["string", "null"]` 表达。
- **`strict` 在两套 API 下行为不同**Responses API 中 `strict` 默认尝试严格模式,**失败时自动回退到非严格**;Chat Completions 无此回退。
- **`tool_choice` 取值**`"auto"`(默认)| `"required"` | `"none"` | `{"type":"function","name":"x"}` | `allowed_tools`(限定子集)。
- **`parallel_tool_calls: false`** 保证一轮最多一次工具调用。
- **ID 字段名不一致**Chat Completions 是 `tool_calls[].id`Responses 是 `function_call.call_id`。跨 API 转换时这是最常见的 bug 点。
- **流式 arguments 是分片字符串**Responses 侧要累加 `response.function_call_arguments.delta` 直到 `.done`
---
## 5. Structured Outputs 的怪癖
`strict: true` 下 JSON Schema 只支持一个子集:
**支持**string、number、boolean、integer、object、array、enum、anyOf。
**不支持的关键字**`allOf``not``dependentRequired``dependentSchemas``if`/`then`/`else`
微调模型还额外不支持:字符串的 `minLength`/`maxLength`/`pattern`/`format`,数字的范围约束,数组的 `minItems`/`maxItems`
**结构上限**
- 最多 5000 个对象属性
- 最多 10 层嵌套
- 所有属性名 + 定义名 + 枚举值的总字符数 ≤ 120,000
- 枚举最多 1000 个值;超过 250 个时,单个属性的枚举值总长 ≤ 15,000 字符
- **根对象必须是 object,不能是 `anyOf`**
- 所有字段必须在 `required` 中;`additionalProperties` 必须为 `false`
**`refusal` 字段**:安全拒绝时,响应带一个**不遵守 schema** 的 `refusal` 字段。解析方必须先判断 `refusal` 再解析 JSON。
**与 `json_object` 的区别**`json_object` 只保证是合法 JSON**不保证符合 schema**。
---
## 6. 其他杂项怪癖
- `n > 1` 时按所有 choices 的生成 token 总量计费。多数第三方"OpenAI 兼容"实现只支持 `n=1`
- `seed` 已 deprecated 且从来不保证确定性。
- `store: true` 时超过 8MB 的图片输入会被静默丢弃。
- `prompt_cache_retention``prompt_cache_options.ttl` 是**两个独立且不交互**的字段:前者表达最大保留策略,后者表达最小缓存寿命。