OpenAI 兼容 API 接入说明:请求、流式响应与排错

最后更新:

本页说明如何使用兼容 OpenAI 请求结构的接口完成一次对话请求。你可以先用 cURL 验证鉴权和返回格式,再将相同的请求迁移到 JavaScript 或其他 SDK。页面中的示例使用客户 API 的 Chat Completions 端点 https://sub.kejike.top/v1/chat/completions;具体模型名和账户权限以控制台当前可用列表为准。

接入前确认

先准备有效 API Key 和有权限调用的模型 ID,使用服务端环境发起请求。下方 cURL 示例采用 Bash 或 Git Bash 的换行语法;占位符需要自行替换。兼容请求结构不代表所有 SDK、端点和模型扩展都完全兼容。对于自动拼接 /chat/completions 的 SDK,基础地址(base URL)应设为 https://sub.kejike.top/v1;cURL 和原生 fetch 则使用完整端点 https://sub.kejike.top/v1/chat/completions。不要把完整端点填入 SDK 基础地址,也不要重复拼接 /v1;始终核对客户端最终生成的 URL。

如需接入现有 SDK,应核对它实际生成的 URL、鉴权方式和响应协议。先用最小 cURL 请求确认服务可用,再逐项迁移客户端设置,可以更快区分网络、参数和客户端配置问题。

快速开始

请求地址为 https://sub.kejike.top/v1/chat/completions。请求方法为 POST,请求头使用 Bearer Token,正文使用 JSON。不要把密钥放进浏览器公开代码、静态网页或提交到代码仓库。

curl https://sub.kejike.top/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "YOUR_MODEL_ID",
    "messages": [
      {"role": "user", "content": "请用一句话介绍 API 中转服务"}
    ],
    "stream": false
  }'

将 YOUR_API_KEY 和 YOUR_MODEL_ID 替换为你有权限使用的值。首次请求建议使用短消息和较小输出,便于区分鉴权、模型名和网络问题。

JavaScript 服务端调用

下面的示例使用 Node.js 20+ 内置的 fetch,保存为 request.mjs 后用 node request.mjs 运行。先在运行环境设置 KEJIKE_API_KEY 和 KEJIKE_MODEL_ID,具体步骤可参考环境变量与 Key 安全指南。示例输出仅用于本地验证;错误日志默认只记录 HTTP 状态码,响应正文可能包含敏感信息,如需排错应先脱敏再记录或分享,生产环境的成功响应也应脱敏。

if (!process.env.KEJIKE_API_KEY || !process.env.KEJIKE_MODEL_ID) {
  throw new Error('请先设置 KEJIKE_API_KEY 和 KEJIKE_MODEL_ID');
}

const response = await fetch('https://sub.kejike.top/v1/chat/completions', {
  signal: AbortSignal.timeout(60_000),
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KEJIKE_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model: process.env.KEJIKE_MODEL_ID,
    messages: [{ role: 'user', content: '你好' }],
    stream: false
  })
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}`);
}

const data = await response.json();
console.log(data);

多轮对话与示例上下文

需要模型理解上一轮时,由调用方按时间顺序传入相关历史;不要默认接口会保存先前请求。可先用 user 提问,再把实际返回的 assistant 内容与下一条 user 消息一起发送。根据任务保留必要历史,过长时摘要或裁剪,并为输出预留空间。不要伪造模型先前的回答来代替真实结果。

请求字段

字段类型说明
modelstring控制台中已开通的模型标识。不要直接把展示名称当成模型 ID,遇到 404 先核对当前列表。
messagesarray按顺序传入 system、user 和 assistant 消息;每项至少包含 role 与 content。
streamboolean设为 false 获取完整响应;设为 true 时按流式事件逐段读取,客户端要处理结束标记和中途错误。
temperaturenumber需要控制随机性时再传入。不同模型的支持范围可能不同,以实际返回结果和模型说明为准。
max_tokensnumber需要限制输出长度时传入。若模型不支持该参数,应根据返回的参数错误调整请求。

响应与流式处理

非流式请求通常返回 JSON 对象,客户端应先检查 HTTP 状态码,再读取正文。不同模型可能在字段细节上有所差异,生产代码不要只依赖固定的展示文本。

{
  "id": "response-id",
  "object": "chat.completion",
  "choices": [
    {
      "index": 0,
      "message": {"role": "assistant", "content": "响应内容"},
      "finish_reason": "stop"
    }
  ]
}

将 stream 设为 true 后,服务端可能以连续事件返回增量内容。客户端应按事件边界读取数据、累积增量文本,并在结束标记到达后关闭读取器;不要把整个流当成一次 JSON 解析。

上面的 JSON 仅演示常见返回结构,不代表固定响应;实际用量和结束状态应从真实响应中读取。如果响应使用 SSE,先确认 Content-Type,用文本解码器保留跨块字符与未完成事件,按空行分隔事件并处理 data: 内容;仅在实际协议使用时识别 [DONE]。网络读取块与事件边界并不一致,客户端需要检测异常结束,并支持主动取消读取。

常见错误排查

现象优先检查处理方式
401 UnauthorizedAuthorization 请求头确认使用 Bearer YOUR_API_KEY 格式,密钥未过期且属于当前账户。
404 Not Found路径和模型 ID确认向 https://sub.kejike.top 发送 POST /v1/chat/completions,没有重复拼接 /v1,并从控制台复制当前可用模型标识。
400 参数错误JSON 字段和类型先保留 model、messages、stream 三项,再逐项恢复可选参数。
403 Forbidden账户和模型权限确认当前 Key 有权访问目标模型,按响应正文检查权限或账户限制。
429 Too Many Requests频率、并发或额度先根据正文区分原因;频率限制可遵循 Retry-After(如有)并有限退避,额度不足需处理账户额度。
5xx 服务错误请求标识与服务状态记录时间、状态码和请求标识(如有),使用有限退避重试;持续失败时提供脱敏信息协助定位。
超时或连接中断超时、重试和请求体服务端设置合理超时,采用有限次数重试;超时后上游可能仍已执行,注意重复用量与重复操作。
流式内容不完整读取器和结束处理持续读取直到结束事件,保存已接收增量,并将网络中断与模型错误分开记录。

安全边界

从官方 SDK 迁移的核对清单

多数应用原本直连原厂端点,迁移时改动集中在三处:基础地址、鉴权头、模型标识。逐项核对可以避免“代码没改却报 404”这类最难定位的问题。

项目原厂直连接入 Kejike 时
基础地址原厂域名,通常以 /v1 结尾https://sub.kejike.top/v1,只写基础地址,不要拼完整端点
鉴权Bearer API Key同样使用 Authorization: Bearer,Key 从控制台创建
模型标识原厂模型名以控制台模型 ID 为准,不要沿用旧名称或展示名
组织 / 项目头可能使用组织头或项目头不需要传入,多余的表头可能被判定为无效请求
SDK 版本任意可用版本先用官方 SDK 默认参数跑通,再逐个打开自定义参数

核对顺序建议:环境变量 → 单条非流式请求 → 流式请求 → 多轮上下文 → 工具调用。每一步都保存原始响应(状态码、正文、用量),这样出现差异时可以直接对比,而不是反复猜测。

迁移期容易忽略的两点

多轮上下文组装与长度控制

对话类应用的质量很大程度取决于上下文如何拼装,而不是取哪个模型。一个可维护的做法是把“系统指令、历史消息、当前输入”分层管理,并在发送前统一裁剪。

  1. 系统指令固定化。把角色、输出格式、禁止事项写进 system 消息,不要每轮重新改写,便于复现问题。
  2. 历史消息按轮次裁剪。优先丢弃最早的成对问答,保留最近若干轮;不要只丢弃单条,否则会出现孤立的 assistant 或 tool 消息,导致 400。
  3. 预留输出空间。上下文上限同时包含输入和输出。若把输入填满,输出会被截断或直接报长度错误。
  4. 长文档先检索再拼接。把整篇文档塞进上下文既贵又易超限,先切块检索再拼接更稳定。
  5. 记录每次请求的实际用量。以便判断是裁剪策略问题还是模型额度问题。
// 按轮次裁剪的最小实现思路(服务端)
function trimHistory(messages, maxTurns) {
  const system = messages.filter(m => m.role === 'system');
  const rest = messages.filter(m => m.role !== 'system');
  const keep = rest.slice(-maxTurns * 2);           // 成对保留,避免孤立消息
  return [...system, ...keep];
}

裁剪后仍报长度错误,通常是单条消息过长(例如一整份日志或代码文件)。这类输入应先摘要或切分,而不是继续减少轮次。

结构化输出与函数调用的参数注意

需要程序消费输出时,应先确认目标模型是否支持结构化输出或函数调用,再决定实现方式;不同模型的参数名与支持范围存在差异,以控制台和当前文档为准。

用量、延迟与成本的观测方法

上线后真正需要盯的是“每次请求花了多少、慢在哪一段、失败率多高”。建议至少记录下列字段,并按模型和业务场景分组查看。

字段用途
请求 ID 或自建追踪 ID关联应用日志与接口响应,排障时能直接定位单次调用
模型 ID按模型比较质量、延迟与消耗,支撑选型决策
HTTP 状态码区分业务失败与链路失败;4xx 与 5xx 的处理策略不同
首字节时间与总耗时流式场景下首字延迟比总耗时更影响体验
响应中的用量字段核对实际消耗,发现异常放大或重试导致的重复用量
输入长度与裁剪后长度验证上下文裁剪是否生效,避免“以为裁了其实没裁”

日志里不要写完整密钥和完整用户正文;需要复盘时保留脱敏片段与哈希即可。若要核对账户额度与消耗明细,以控制台展示的数据为准。

集成阶段最常见的坑

继续阅读:API 错误码与排障手册列出 401/403/404/429/5xx 的分支处理,代码任务接入指南说明代码类请求的上下文准备方式。

相关文档

想先了解账户、Key 和调用流程,可阅读 AI API 中转站使用指南;需要代码任务接入建议,可查看 Codex API 中转接入指南;需要按任务选择模型,可查看 GPT、Claude、Gemini、DeepSeek、Grok 模型选择指南。