跳到主要内容
黯羽轻扬每天积累一点点

Responses API 是怎么工作的?我用一条真实链路把它讲清楚

免费2026-07-02#AI#AI

Responses API 是 OpenAI 最新接口规范,但它究竟怎么工作?本文用一个真实用户上下文链路,逐步拆解请求-响应周期,并给出迁移时最容易错的三个坑。

为什么现在必须理解 Responses API

Responses API 是 OpenAI 2025 年主推的新接口形态,它把原来分散的 Chat Completions、Function Calling 和 Tool Use 合并成一个统一的请求-响应协议。这意味着如果你还在用旧 API 拼接对话历史、手动管理工具调用状态,那么往下半年你会越来越难维护——新 SDK 和 Agent SDK 都默认只支持 Responses API,旧版本已经进入倒计时。

但这不表示你只需要简单替换 endpoint URL 就行。我见过太多团队在迁移后出现“对话上下文丢失”“工具调用顺序错乱”“超时响应被吞掉”等问题。本质上,Responses API 把一部分“显式状态管理”从开发者手里抽走了,如果你不理解它的数据流,就很容易掉坑。

一条真实用户链路:从提问到完整响应

为了更好地说明,我们以一个实际场景来走通整个流程:用户问“帮我查一下昨天的服务器日志,然后汇总错误类型”。

第一步:构造请求,发送用户上下文

你只需要提供一个“输入”字符串和可用的工具列表(如果有)。Responses API 会自动把这段输入放入一个内部状态上下文,不需要你手动拼接多轮 message 数组。例如:

POST /v1/responses
{
  "model": "gpt-4o",
  "input": "帮我查一下昨天的服务器日志,然后汇总错误类型",
  "tools": [{
    "type": "function",
    "name": "query_logs",
    "description": "查询指定日期的服务器日志",
    "parameters": { ... }
  }]
}

这里的关键区别:旧 API 需要你把“我”的历史消息都放在 messages 数组里,而 Responses API 只关心当前轮的输入,以及你是否开启 previous_response_id 来延续上下文。

第二步:模型决定调用工具

模型会返回一个 response 对象,其中 output 字段不再是简单的“assistant 消息”,而是一个数组,可能包含多个 function_callcontent 块。例如:

{
  "id": "resp_abc123",
  "output": [
    { "type": "function_call", "name": "query_logs", "arguments": "{\"date\":\"2025-02-10\"}" },
    { "type": "function_call", "name": "query_logs", "arguments": "{\"date\":\"2025-02-11\"}" }
  ]
}

请注意,这里一口气发起了两个工具调用(因为“昨天”可能跨日)。你需要并行执行这两个调用,然后把结果作为下一次请求的一部分返回。容易出错的地方是:很多开发者会像旧 API 那样只处理第一个 function_call,导致日志查询不完整。

第三步:把工具结果送回上下文

这是最容易失败的一步。你需要把工具的结果拼接成 status: completed 的 tool_call,然后通过 previous_response_id 关联到上一个响应,再次发出请求:

POST /v1/responses
{
  "model": "gpt-4o",
  "previous_response_id": "resp_abc123",
  "input": [
    { "type": "function_call_output", "call_id": "call_001", "output": "[...日志行...]" },
    { "type": "function_call_output", "call_id": "call_002", "output": "[...日志行...]" }
  ]
}

如果你忘记设置 previous_response_id,模型就会认为这是一个全新的对话,完全不知道前面发生了什么。这是返回“上下文丢失”错误的根本原因。

第四步:模型生成最终回答

在得到工具结果后,模型会综合所有信息,返回一个 type: "message" 的 output,内容就是汇总后的错误类型。

代码编辑器中展示 Responses API 的请求 JSON 体,突出 input 和 tools 字段

最容易失败的地方与错误理解

误区一:认为 Responses API 不需要管理上下文

这个误解最大。虽然 API 内部保留了一个上下文状态,但你仍然需要显式传递 previous_response_id。如果你在多轮对话中不维护这个 ID,模型每次都是“第一次见面”。

误区二:并行工具调用时只处理第一个

如第二步所示,output 数组可能包含多个 function_call。你必须对所有调用都做出响应;否则模型会卡住,或者返回一个不完整的回答。

失败场景:超时导致响应丢失

Responses API 的默认超时是 30 秒。如果你的工具执行时间超过 30 秒,API 会返回超时错误,且已经调用的工具结果不会保留。这时你需要重试整个请求,并让模型知道“前一步超时了”。

备用方案:回退到 Chat Completions + 手动状态管理

如果你的工具调用逻辑特别复杂(多轮嵌套),或者延迟要求极高(<500ms),那么继续使用 Chat Completions API 手动管理消息数组可能是更稳定的选择。Responses API 的设计主要是为了简化常规 agent 场景,不是所有场景都适用。

如果你现在就要落地,第一步应该怎么做

  1. 读一遍 OpenAI 官方 Responses API 文档(2025 年 2 月版),重点看 previous_response_idoutput 结构。
  2. 在你的开发环境里,把最常用的一个单轮工具调用(比如“查询天气”)从 Chat Completions 迁移到 Responses API,走通完整流程。
  3. 记录迁移前后的 Latency 和 Token 消耗。Responses API 更容易预测 token 用量,因为 input 不再包含历史消息(但上下文内部消耗 tokens)。
  4. 针对多工具并行场景,编写一个简单的循环,确保所有 function_call 都被收集并回传。
  5. 设置错误重试逻辑:当超时或“context lost”错误出现时,最多重试 2 次,并考虑回退方案。

下一步去哪里继续系统化学习

以上只是 Responses API 的基础用法。如果你想把这条链路变成生产级别的 agent 服务——比如涉及长对话记忆、多工具编排、条件分支和错误恢复——那还需要更系统的方法论和实战案例。

评论

暂无评论,快来发表你的见解吧

提交评论