核心 API
文本 API
本页列出 OpenAI Responses、Chat Completions 和 Anthropic Messages 的请求地址、认证方式与最小示例。
协议与地址
三种协议的请求体、响应结构和流式事件并不相同。SDK 配置填写 Base URL,直接发送 HTTP 请求则使用表中的完整 endpoint。
| API / 协议 | 完整 endpoint | 认证 | 读取文字 |
|---|---|---|---|
| OpenAI · Responses | POST https://api.khaix.net/v1/responses | Authorization: Bearer | output[].content[].text |
| OpenAI · Chat Completions | POST https://api.khaix.net/v1/chat/completions | Authorization: Bearer | choices[0].message.content |
| Anthropic Messages | POST https://api.khaix.net/v1/messages | x-api-key | content[].text |
模型 ID、可用分组和实时价格以模型广场为准。
多模态、用量与缓存边界
| 协议 | 多模态输入结构 | 用量与缓存 |
|---|---|---|
| Responses | input 内容项中的 input_text、input_image | 读取 usage.input_tokens、usage.output_tokens 及实际返回的明细字段 |
| Chat Completions | messages[].content 中的 text、image_url 内容块 | 读取 usage.prompt_tokens、usage.completion_tokens 及实际返回的明细字段 |
| Messages | content 中的 text、image 内容块 | 读取 usage.input_tokens、usage.output_tokens;缓存用量字段仅在上游返回时存在 |
上表说明协议字段位置,不代表每个模型或分组都开放视觉、缓存或全部内容类型。先确认目标模型与分组,再用最小请求验证;不要把一种协议的字段直接复制到另一种协议。重复发送相同提示词也不等于一定命中缓存,响应中的 usage 与控制台调用记录才是用量和计费依据。
Responses API
Responses 通过 input 提交文字,并提供流式事件、函数工具和结构化输出。Codex 等编码 Agent 也会使用该协议。
curl https://api.khaix.net/v1/responses \
-H "Authorization: Bearer sk-请替换为你的密钥" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"input": "用一句话说明 API 连接成功。"
}'
请求完成后会返回 status: "completed",文字位于类型为 message 的输出项中。SDK 的 output_text 是便捷属性,REST 响应顶层不一定包含这个字段。
Chat Completions
多数 OpenAI 兼容客户端通过 Chat Completions 接入。角色和对话内容放在 messages 数组中。
curl https://api.khaix.net/v1/chat/completions \
-H "Authorization: Bearer sk-请替换为你的密钥" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"messages": [
{"role": "user", "content": "用一句话说明 API 连接成功。"}
]
}'
响应文字通常位于 choices[0].message.content。Responses 使用的 input、text.format 和流式事件处理器不适用于本协议。
Anthropic Messages
Messages 采用 Anthropic 请求结构,其中 max_tokens 必填,API 版本通过请求头传递。
curl https://api.khaix.net/v1/messages \
-H "x-api-key: sk-请替换为你的密钥" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-5",
"max_tokens": 128,
"messages": [
{"role": "user", "content": "用一句话说明 API 连接成功。"}
]
}'
从响应的 content 数组读取文字。Claude Code 通过 ANTHROPIC_AUTH_TOKEN 连接网关时会发送授权头,持久配置方法见开发 SDK。
流式文本输出
在 Responses、Chat Completions 或 Messages 的请求体中加入 "stream": true 即可启用流式输出。下面是 Responses 的最小 SSE 请求:
curl -N https://api.khaix.net/v1/responses \
-H "Authorization: Bearer sk-请替换为你的密钥" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"input": "分三行输出一段简短文字。",
"stream": true
}'
| 协议 | 增量内容 | 成功结束 | 失败或非完整结束 |
|---|---|---|---|
| Responses | 累加 response.output_text.delta;工具参数另有增量事件 | 收到 response.completed | 处理 response.failed、response.incomplete 和 error |
| Chat Completions | 解析每个 data: JSON,累加 choices[].delta 中的文字或工具调用 | 处理 finish_reason,并读取 [DONE] | HTTP 200 后仍可能出现错误数据或在结束标记前断开 |
| Messages | 按 content_block_start、content_block_delta、content_block_stop 组装内容 | 收到 message_stop | 处理 error;允许 ping 和未知事件而不破坏解析器 |
先检查 HTTP 状态和 Content-Type: text/event-stream。非 2xx 错误通常在流开始前以 JSON 返回;连接建立后仍可能通过 SSE 错误事件失败。只有收到对应协议的成功结束事件才应提交结果,不能把 TCP 关闭、客户端取消或超时当作成功。
usage 通常出现在靠后的事件或附加分块中,连接提前结束时可能缺失。保留已接收内容用于诊断,但将其标记为不完整;重试前确认请求是否已在上游执行,避免自动重提造成重复调用或计费。
标准函数工具
模型只会返回函数名称和参数,实际执行仍由应用负责。校验参数并执行受控函数后,把结果连同原始 call_id 返回模型。普通 HTTP 转发按无状态方式续接:第二次请求必须包含原始输入、上一响应的完整 output、函数结果和同一份 tools,不要依赖 previous_response_id。
curl https://api.khaix.net/v1/responses \
-H "Authorization: Bearer sk-请替换为你的密钥" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"input": "查询上海现在的时间。",
"tools": [{
"type": "function",
"name": "get_city_time",
"description": "返回指定城市的当地时间",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
"additionalProperties": false
},
"strict": true
}]
}'
响应的 output 中会出现 type: "function_call"、name、arguments 和 call_id。执行函数后,把上一响应的全部 output 项按原顺序放在原始输入之后,再追加工具结果。下面假设上一响应只返回了一个函数调用;若还包含 reasoning 或 message 项,也必须原样保留。
curl https://api.khaix.net/v1/responses \
-H "Authorization: Bearer sk-请替换为你的密钥" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"input": [
{"role": "user", "content": "查询上海现在的时间。"},
{
"type": "function_call",
"call_id": "请替换为上一响应中的函数调用ID",
"name": "get_city_time",
"arguments": "{\"city\":\"上海\"}"
},
{
"type": "function_call_output",
"call_id": "请替换为同一个函数调用ID",
"output": "{\"city\":\"上海\",\"time\":\"10:30\"}"
}
],
"tools": [{
"type": "function",
"name": "get_city_time",
"description": "返回指定城市的当地时间",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
"additionalProperties": false
},
"strict": true
}]
}'
应用代码应直接展开上一响应的数组,避免手工重建时漏掉字段:
const nextInput = [
...originalInput,
...firstResponse.output,
...toolOutputs
];
const finalResponse = await client.responses.create({
model,
input: nextInput,
tools
});
| 协议 | 模型调用 | 回填工具结果 |
|---|---|---|
| Responses | output 中的 function_call | 保留原始输入和完整 output,追加带相同 call_id 的 function_call_output |
| Chat Completions | assistant message 中的 tool_calls | 先追加完整 assistant message,再为每个调用追加一条带 tool_call_id 的 role: "tool" message |
| Messages | assistant content 中的 tool_use | 保留完整 assistant 内容,再追加 user message,其中包含引用同一 tool_use_id 的 tool_result |
并行工具调用需要逐一按 ID 回填结果,后续请求继续携带工具定义。若模型再次返回工具调用,则按相同规则循环并设置应用侧最大轮数。不要在 Chat 或 Messages 中使用 Responses 的字段名。
结构化文本输出
需要固定 JSON 结构时可使用 JSON Schema。返回结果仍要经过解析、类型和业务规则校验;完整 Schema 的支持范围取决于模型。
curl https://api.khaix.net/v1/responses \
-H "Authorization: Bearer sk-请替换为你的密钥" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"input": "把这句话分类:服务器已恢复,问题解决。",
"text": {
"format": {
"type": "json_schema",
"name": "ticket_result",
"strict": true,
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "enum": ["open", "resolved"]},
"summary": {"type": "string"}
},
"required": ["status", "summary"],
"additionalProperties": false
}
}
}
}'
| 协议 | Schema 配置位置 | 注意事项 |
|---|---|---|
| Responses | text.format | 字段名与 Chat Completions 不同 |
| Chat Completions | response_format.json_schema | Schema 外层还需包含名称与严格模式 |
结构化结果仍通过文本内容返回。只有内容成功解析并包含所需字段后才算成功;拒答、输出中断、Schema 不受支持或 JSON 解析失败都需要单独处理。