Responses API 与 built-in tools#

前两节已经把结构化约束和 function calling parser 讲清楚了,但如果只停在这里,这一章仍然缺一块很重要的表面:当响应不再只是一次性文本,而是一个可以被追踪、检索、取消,甚至带着工具上下文继续推进的运行中实体时,系统怎样管理它。

这一节解决什么问题#

这一节主要回答三件事:

  1. Responses API 为什么不只是“另一种返回格式”;
  2. background request、retrieve、cancel 为什么会让 response 长成一个实体;
  3. built-in tools 为什么在这个 surface 里更显眼。

Responses API 改写的不是字段,而是工作流#

OpenAIServingResponses.create_responses 最值得注意的不是参数多,而是它把 response 变成了一个之后还能被继续操作的对象。

一旦进入 background 模式,请求就不再只是“一次 request-response”,而会长出:

  • background
  • request_id / response_id
  • response store
  • background task lifecycle
  • retrieve / cancel 语义

这说明 Responses API 改写的不是字段,而是工作流。

这条工作流如果先压成一张图,会更容易看清:

flowchart LR
    A["create_responses(...)"] --> B["foreground response"]
    A --> C["background task + response_store"]
    C --> D["retrieve_responses()"]
    C --> E["cancel_responses()"]

图里最重要的一点是:一旦进入 background 模式,response 就不再只是当前连接里的一次性结果,而会继续活在系统里。

为什么 background request 不是多一个布尔值#

如果 background 只是一个普通参数,它不应该带来额外状态管理。但在这里,background 路径会:

  1. 先把 response 写进 response_store
  2. 启动 _run_background_request(...)
  3. 把 task 记进 background_tasks
  4. 后续允许 retrieve_responses() / cancel_responses() 继续操作

所以 background 不是“生成方式的一个选项”,而是一套显式的响应生命周期。

这一点从代码骨架也能看出来:

if request.background:
    async with self.response_store_lock:
        self.response_store[response.id] = response
    task = asyncio.create_task(
        self._run_background_request(...)
    )
    self.background_tasks[response.id] = task

这说明 background 模式不是“生成后顺手多存一份”,而是会真正长出 response store 和 task lifecycle。

retrieve / cancel 为什么重要#

这两个动作共同说明:在 Responses API 里,response 不再只是当前 HTTP 连接里的一次性结果,而是一个可被追踪、可被取消、可被继续引用的运行中实体。

这对整本书的意义也很直接:它把结构化生成这一章从“输出怎样更可控”推进成了“结果怎样进入更长的工作流”。

也正因为这样,Responses API 不该被误看成只是“chat/completions 的另一个外壳”。它的重点已经从“结果长什么样”转到了“结果怎样继续被系统管理”。

built-in tools 为什么在这里更显眼#

Responses API 比普通 chat surface 更容易承载:

  • built-in tools
  • tool session
  • background continuation
  • previous response 关联

这意味着 built-in tools 在这里不是外围附加功能,而是更像工作流的一部分。也正因为如此,这一节必须放在结构化生成这一章里,而不是只放到后面“工具集成”里。

调试 Responses API 时先看哪里#

如果你看到的现象是:

  • background 请求已经发出,但后面查不到结果;
  • response 可以 retrieve,但 cancel 行为不一致;
  • built-in tools 看起来启用了,但响应工作流不对;

更稳的顺序通常是:

  1. 先确认 create_responses(...) 走的是 foreground 还是 background 路径;
  2. 再确认 response store 和 background task 是否真的建立了;
  3. 最后再看 retrieve / cancel 或 built-in tool 上下文是不是按预期继续推进。

小结#

这一节真正要稳定下来的,是一个简单判断:

  • Responses API 不是另一种 response schema;
  • background 会把 response 变成一个可持续操作的实体;
  • built-in tools 在这里更像工作流能力,而不是普通输出附件。

理解了这点,第七章就不再只是“怎样限制输出”,而会进一步回答“结构化结果怎样进入更长的运行时工作流”。