这不是只换 URL 的迁移。先改请求输入和输出读取,再单独适配流式事件、工具结果与会话状态。保留旧路径的功能开关,用同一组业务样例验证后再切流量;第三方“Chat 兼容”不等于支持 Responses。
适用前提
适用于已有 Chat Completions 应用、准备使用 OpenAI Responses 的开发者。应先确认目标模型和端点可用,固定 SDK 版本;迁移第三方服务时还需该服务自己的 Responses 文档。
先确定迁移边界
将原应用用到的功能列成清单:纯文本、工具、图片、结构化输出、流式、多轮状态。第一阶段只迁移已使用且有明确映射的部分,不同时更换模型、提示词和供应商,否则失败后难以定位是哪一项变化。官方迁移指南给出接口形状差异;本文的验收与发布顺序是编辑建议。
官方依据:来源 1
请求和响应需要一起改
下面的对照仅概括常见文本路径,不是所有参数的兼容承诺。不要盲目把旧请求展开为新请求,也不要继续按 choices[0] 读取 Responses。
| 项目 | Chat Completions | Responses |
|---|---|---|
| 输入 | messages | input;系统级指令可用 instructions |
| 文本读取 | choices 中的 message 内容 | 按 output 类型处理;SDK 提供 output_text helper |
| 结构化输出 | response_format | text.format |
| 函数结果 | tool 消息与调用标识 | function_call_output 与 call_id |
| 多轮状态 | 应用维护历史 | 手动传历史,或按文档使用 previous_response_id / Conversations |
官方依据:来源 1
先用本地数据检查解析适配
以下是自己编写的合成响应,不是模型返回或实测结果。保存为 response-shape.mjs,运行后应输出“示例文本”。真实 REST 输出不应被假定总有 output_text 顶层字段;SDK helper 与原始 JSON 要分清。
const response = {output:[
{type:'reasoning', summary:[]},
{type:'message', content:[{type:'output_text', text:'示例文本'}]}
]};
const text = response.output
.filter(item => item.type === 'message')
.flatMap(item => item.content ?? [])
.filter(part => part.type === 'output_text')
.map(part => part.text).join('');
console.assert(text === '示例文本');
console.log(text);
// 空文本可能是工具调用、拒绝或其他输出,不能一律当成接口故障。状态与存储不要依赖默认值
逐项确认是否保留响应、如何延续会话和如何传回工具上下文。若业务要求关闭响应存储,官方迁移文档提供 store:false;这并不等于承诺零日志或替代平台数据政策。使用 previous_response_id 前要确认所需响应可访问,不能同时把整段历史重复拼入而不检查上下文是否重复。流式路径另做事件解析测试。
官方依据:来源 1
怎样判断迁移成功,怎样退回
不要用两段自然语言是否逐字相同作为唯一标准。先比较任务是否完成、结构是否合法、工具结果是否闭环、取消是否生效,再观察真实账单口径。上线前准备小范围流量开关;若出现解析错误,切回旧适配器并保留脱敏失败样例。已经提交的外部动作不得因接口回退再次执行。
- 无工具的单轮文本、空文本分支和拒绝分支都有明确处理。
- 多轮指令与上下文不丢失、不重复;工具调用关联不串线。
- 流式中断不误标完成;使用量字段缺失时显示未知而非零。
- 目标服务没有 Responses 支持文档时,暂停该路径而不是更名包装成“兼容”。
2026-10-21 阅读下列官方资料。操作步骤为本站编辑归纳,代码与数字为本地合成示例;未调用付费模型,不是服务商实测报告,也不构成接口或性能承诺。