从 Chat Completions 迁到 Responses API,发布前至少做这 7 个验收

📅 2026/7/22 10:23:13 👁️ 阅读次数 📝 编程学习
从 Chat Completions 迁到 Responses API,发布前至少做这 7 个验收

从 Chat Completions 迁到 Responses API,发布前至少做这 7 个验收

很多项目迁移 OpenAI 接口时,会先改一行代码:

messages -> input

这一步只能说明你开始迁移了,不能说明你已经可以发布。Chat Completions 和 Responses API 的差异不只在字段名,还会影响资源路径、输出读取、流式事件、工具调用、会话状态、网关兼容和回滚方式。

如果你维护的是 SDK wrapper、内部 API 网关、AI 编程工具配置,或者给客户提供 OpenAI-compatible endpoint,发布前至少要做一张迁移验收表。否则很容易出现这种情况:最小文本请求能 200,真实业务一开流式、一接工具、一走中转,就开始 404、解析失败或前端不更新。

先明确:迁移目标是什么

不要把“迁移 Responses API”写成抽象目标。先选一个具体范围:

范围 A:只迁移非流式纯文本 范围 B:纯文本 + 流式 范围 C:加工具调用 范围 D:保留多轮状态 范围 E:通过内部中转网关暴露给多个客户端

如果今天只做范围 A,就不要在发布说明里写“已完整支持 Responses API”。读者、同事或客户会按你写的边界使用。

验收 1:资源路径不能混

Chat Completions 的典型资源是:

POST /v1/chat/completions

Responses API 的典型资源是:

POST /v1/responses

迁移时先记录最终请求路径。不要只看配置文件里的base_url,因为 SDK 会在基地址后面追加资源路径。如果你把资源路径也写进base_url,最终可能出现这种重复:

/v1/responses/responses

发布前验收标准:

chat path = /v1/chat/completions responses path = /v1/responses bad path = blocked or returns expected 404

验收 2:输入形状要分层

Chat Completions 常见输入是messages

{"model":"your-model","messages":[{"role":"user","content":"hello"}]}

Responses API 使用input,并且可以配合instructions、工具、状态等字段:

{"model":"your-model","input":"hello"}

如果你的业务代码里有统一 wrapper,不要在一个函数里偷偷兼容所有形状。更稳的方式是显式传入协议:

protocol=openai-chat protocol=openai-responses

然后进入各自的请求构造器。这样日志里能直接看出哪一层出了问题。

验收 3:输出读取不能继续读choices

旧代码经常读:

completion.choices[0].message.content

迁到 Responses 后,纯文本可以优先读 SDK 或响应对象提供的文本聚合字段;需要处理工具或 reasoning 时,则应遍历类型化输出项。发布前不要只测“HTTP 200”,还要测应用真正读取到文本。

验收标准:

HTTP_STATUS=200 TEXT_READ=ok WRONG_READER=blocked by test

如果错误读取仍然静默返回空字符串,前端就可能显示“生成中”或空结果,但日志里只有 200。这类问题比 404 更难排查。

验收 4:流式事件要单独测

Chat Completions 流式和 Responses 流式不是同一套事件形状。迁移前端或 SSE 解析器时,至少验证三件事:

  1. 首个事件到达后 UI 是否进入输出状态。
  2. 文本增量事件是否能追加到同一个消息。
  3. 完成事件是否能关闭 loading,并写入最终 usage / request id。

不要只用非流式请求证明流式已经可用。非流式 200 只能证明路由和基本请求体没坏。

验收 5:工具调用不是普通文本

如果你的业务用函数调用、文件检索、代码执行或自定义工具,迁移时要把工具调用当成独立输出类型处理,而不是拼进文本。

一个最小验收表可以这样写:

tool_call_detected=yes tool_name=get_weather tool_args_json_valid=yes tool_result_roundtrip=not_tested / passed

今天没有测工具结果回传,就不要写“工具调用完整支持”。最多写“已能识别 tool_call item,工具结果回传待测”。

验收 6:多轮状态要决定谁保存

旧的 Chat Completions 代码通常由应用自己累积messages。Responses API 的状态使用方式会让你重新选择:

  • 继续由应用保存完整上下文。
  • 使用响应 ID 或会话能力承接上一轮。
  • 混合方式:业务关键消息自己保存,临时推理状态交给 API。

这不是代码洁癖问题,而是数据边界问题。发布前要写清楚:用户隐私、审计日志、失败重试和回滚时,到底以哪份状态为准。

验收 7:中转网关要按能力矩阵放行

如果你通过中转服务暴露 OpenAI-compatible endpoint,不要因为/v1/chat/completions成功,就默认/v1/responses、工具调用、图像、流式和状态都成功。

建议维护一张能力矩阵:

能力验收状态证据
Chat Completions 非流式passed最小请求 200,文本读取成功
Responses 非流式passed / pending/v1/responses最小请求
Responses 流式pending事件解析截图或日志
工具调用pendingtool_call item 和结果回传
状态延续pendingprevious response / conversation 读写
计费与用量pendingusage readback
回滚到 Chatpassedfeature flag 或路由开关

这张表比一句“兼容 OpenAI”更有价值。它能告诉调用方今天能放心用什么,哪些只是下一阶段。

本地实测:用夹具跑一遍验收表

为了避免把线上服务能力写成未经验证的结论,我用标准库写了一个只监听127.0.0.1的本地夹具。它模拟 7 个检查项:Chat 路径、Responses 路径、错误路径、文本读取、流式事件、工具调用 item、状态字段。

执行:

python3 06-evidence/probe_responses_migration_checklist.py

本次输出:

PYTHON_VERSION=... CHAT_ENDPOINT=200 TEXT=chat fixture RESPONSES_ENDPOINT=200 TEXT=responses fixture BAD_RESPONSES_BASE=404 PATH=/v1/responses/responses STREAM_EVENTS=3 FINAL=completed TOOL_ITEM=present NAME=lookup_config STATEFUL_FIELD=previous_response_id ONLINE_PROVIDER_REQUEST=NO SUMMARY=pass checks=7/7

本地实测图:Responses 迁移验收夹具结果已生成,平台草稿保存后可按需要再上传正文图。

这组输出证明的是迁移验收思路:每一项都能被单独检查。它不证明任何线上中转服务已经完整支持 Responses API,也不证明某个模型在生产环境可用。

发布前建议保留一个回滚开关

迁移最容易忽略的是回滚。你可以在配置里显式保留:

OPENAI_PROTOCOL=chat OPENAI_PROTOCOL=responses

或者在网关路由里为不同客户端保留协议模式。上线后如果发现流式事件、工具结果或状态延续有问题,可以把部分客户端回到 Chat Completions,而不是在生产上临时改代码。

回滚不是退步,它是迁移验收的一部分。没有回滚路径的迁移,本质上还没准备好进入真实用户流量。

CodeLink 相关的正确写法

如果你使用 CODELINK API 中转服务测试这类迁移,建议把它放在能力矩阵里写清楚:今天测了哪个 endpoint、哪个模型、是否流式、是否有 usage readback、是否真实计费。没有这些证据时,就只写“可作为 OpenAI 兼容调用场景之一”,不要写“完整支持 Responses API”。

在 CSDN 文章里,CodeLink 更适合通过审核通过的官方网站卡承接下一步,而不是在正文里放注册链接或充值入口。读者读完这篇文章后,真正需要的是一份可复制的迁移验收脚本和技术落地页。

总结

从 Chat Completions 迁到 Responses API,不是把messages改成input就结束。发布前至少验收:

资源路径 输入形状 输出读取 流式事件 工具调用 状态延续 网关能力矩阵 回滚路径

每一项都要有自己的成功信号。这样你才能区分:到底是 SDK 配置错、端点没实现、前端解析错、工具调用没接上,还是中转网关还没有放行某个能力。

迁移最好的状态不是“全部一次性改完”,而是每一层都能独立证明、独立回滚、独立记录证据。