第1章 Responses API¶
学习目标¶
- 理解 OpenAI Responses API 的设计理念与核心能力
- 掌握 system / user / assistant 三类消息的结构与作用
- 区分 Chat Completions API 与 Responses API 的差异及选型依据
- 能够使用 OpenAI Python SDK v1.x 完成 API 调用与错误处理
- 构建支持多轮对话的最小可用原型
问题导入¶
当你第一次拿到 OpenAI API Key 时,最迫切的问题是:"我该用哪个接口把大模型接进我的应用?" 过去几年里,chat.completions.create() 几乎是所有开发者的入口,但它把上下文管理、工具调度、推理过程等都推给了开发者自行编排。随着 Agent 场景的复杂化,OpenAI 在 2025 年推出了统一的 Responses API,把"对话"升级为"任务执行":一次调用既能产出文本,也能触发工具、维护状态、返回结构化结果。
Responses API 并不是简单更名,而是把以往散落在 Chat Completions、Assistants、Tools 中的能力收敛到一个端点。它内置了对多轮上下文、函数调用、文件引用、推理模型(如 o1 / o3 系列)的支持,开发者无需再手动拼接 messages 数组中的 tool_call_id 与 tool 角色消息。对于 Agent 工程师而言,掌握 Responses API 是后续学习流式响应、函数调用、微调的前置条件。本章将从最基础的请求结构出发,逐步带你看懂一次完整调用的全貌。
核心概念¶
1. Responses API 与 Chat Completions API 的区别¶
Chat Completions API 是面向"聊天补全"设计的端点,开发者需要自己维护 messages 数组,处理工具调用结果回填。Responses API 则是面向"任务"设计的统一端点,主要差异如下:
| 维度 | Chat Completions | Responses API |
|---|---|---|
| 入口 | client.chat.completions.create() |
client.responses.create() |
| 上下文 | 手动维护 messages | 可用 previous_response_id 链式续接 |
| 工具调用 | 需手动回填 tool 消息 | 内置工具调度与状态管理 |
| 推理模型 | 支持有限 | 原生支持 reasoning 模型 |
| 内置工具 | 需自行实现 | 提供文件检索、代码解释器等 |
简单迁移场景仍可继续使用 Chat Completions;新项目、特别是 Agent 类应用,建议直接采用 Responses API。
2. 消息结构:system / user / assistant¶
Responses API 的输入核心是 input 字段,它接受字符串或消息列表。消息角色分为三种:
- system:设定模型的人设、约束、输出格式,整段对话中通常只出现一次且位于开头。
- user:用户输入,可包含文本、图片、文件引用。
- assistant:模型历史回复,用于多轮上下文重建。
合理使用 system 消息是控制模型行为最经济的手段,远比在 user 消息中反复强调规则有效。
3. 模型选择与参数¶
model 字段决定使用哪个模型,常见取值包括 gpt-4.1、gpt-4o、o3-mini 等。关键参数:
temperature:0~2,越高越发散,越低越确定。max_output_tokens:限制输出长度,注意推理模型会消耗部分 token 用于内部思考。instructions:等价于 system 消息的快捷写法,适合短指令。previous_response_id:传入上一次响应的 ID,服务端自动续接上下文,避免重复传输。
4. 分段返回与结构化输出¶
Responses API 返回的是 Response 对象,其 output 是一个列表,每项是 output_item,可能是 message、function_call、reasoning 等类型。这种分段结构让 Agent 可以精确判断"模型这次到底产出了什么",而不是从一段文本里费力解析。
5. 错误处理¶
OpenAI SDK 会针对不同故障抛出对应异常:
AuthenticationError:API Key 无效。RateLimitError:触发限流,应退避重试。APIConnectionError:网络问题。BadRequestError:请求参数错误,通常是 model 名称或参数拼写错误。
生产代码应至少捕获以上四类,配合指数退避重试。
原理图¶
sequenceDiagram
participant App as 应用代码
participant SDK as OpenAI SDK
participant API as Responses API
participant Model as 模型
App->>SDK: client.responses.create(input, model, tools)
SDK->>API: POST /v1/responses
API->>Model: 调度模型推理
Model-->>API: 返回 output_items
API-->>SDK: Response 对象
SDK-->>App: 解析 output_text / output
Note over App: 若有 function_call<br/>执行后调用 responses.create<br/>并传入 function_call_output
图:Responses API 调用流程,包含工具调用的回填闭环
示例代码¶
import os
from openai import OpenAI, AuthenticationError, RateLimitError, APIConnectionError, BadRequestError
# 1. 初始化客户端,建议从环境变量读取 Key
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# 2. 单轮调用:使用 instructions 设定人设
response = client.responses.create(
model="gpt-4.1",
instructions="你是一位严谨的技术翻译,只输出译文,不解释。",
input="Translate 'function calling' to Chinese.",
)
print(response.output_text)
# 3. 多轮对话:使用 previous_response_id 续接上下文
first = client.responses.create(
model="gpt-4.1",
input="我叫张三,是一名 Python 后端工程师。",
)
print("第一轮:", first.output_text)
second = client.responses.create(
model="gpt-4.1",
previous_response_id=first.id,
input="我刚才说我的名字和职业是什么?",
)
print("第二轮:", second.output_text)
# 4. 手动维护消息列表(兼容 Chat Completions 风格)
messages = [
{"role": "system", "content": "你是一位耐心的编程导师。"},
{"role": "user", "content": "用一句话解释什么是闭包。"},
]
resp = client.responses.create(
model="gpt-4.1",
input=messages,
)
print(resp.output_text)
# 5. 带错误处理的封装
def safe_complete(prompt: str, model: str = "gpt-4.1") -> str:
try:
resp = client.responses.create(model=model, input=prompt)
return resp.output_text
except AuthenticationError:
raise RuntimeError("API Key 无效,请检查环境变量 OPENAI_API_KEY")
except RateLimitError:
raise RuntimeError("触发限流,请稍后重试或升级配额")
except APIConnectionError:
raise RuntimeError("网络异常,无法连接 OpenAI 服务")
except BadRequestError as e:
raise RuntimeError(f"请求参数错误: {e.message}")
if __name__ == "__main__":
print(safe_complete("用 30 字概括 RAG 的核心思想。"))
企业案例¶
案例 1:智能客服的多轮对话管理¶
某 SaaS 公司将 Responses API 用于客服后台,借助 previous_response_id 在 30 分钟会话窗口内续接上下文,无需在本地缓存全量 messages,单次请求体积下降约 60%。system 消息中注入产品 FAQ 摘要与禁止承诺清单,约束模型行为。
案例 2:代码评审助手¶
研发团队将 PR 的 diff 作为 user 输入,instructions 中要求模型按"风险等级 / 改进建议 / 通过结论"三段式输出。利用 max_output_tokens 控制评审篇幅,避免长 PR 触发截断。
案例 3:结构化数据抽取¶
金融团队用 Responses API 从非结构化新闻中抽取事件,配合 response_format 指定 JSON Schema,直接得到可入库的结构化结果,省去正则解析与人工校对。
常见问题¶
Q1:Responses API 是否会替代 Chat Completions? OpenAI 官方表示两者会长期并存。Chat Completions 适合简单文本补全与已有系统迁移;Responses API 是面向 Agent 与推理模型的新一代入口,新项目建议优先使用。
Q2:previous_response_id 能保存多久?
默认保留 30 天,具体以官方文档为准。超出窗口后需要改为手动维护 input 列表重建上下文。
Q3:为什么我的 output_text 是空的?
当模型选择调用工具而非直接回答时,output 列表中只会出现 function_call 项,output_text 自然为空。应遍历 response.output 判断类型。
Q4:system 消息和 instructions 有什么区别?
功能上等价,instructions 是便捷写法。同时使用时,instructions 会拼接到 system 之前,建议二选一避免混淆。
Q5:如何控制成本?
优先使用 max_output_tokens 限制输出;推理模型按"思考 token + 输出 token"计费,简单任务不必用 o 系列;缓存 previous_response_id 可减少重复传输但不会降低 token 计费。
面试题¶
1. Responses API 与 Chat Completions API 的核心区别是什么?
答:Responses API 是面向任务的统一端点,内置上下文续接(previous_response_id)、工具调度、推理模型支持与内置工具;Chat Completions 是面向聊天补全的传统端点,需要开发者手动维护 messages 与工具回填。
2. 如何在 Responses API 中实现多轮对话?
答:两种方式——一是手动维护 input 消息列表(system/user/assistant 交替);二是使用 previous_response_id 传入上一次响应 ID,由服务端续接上下文,后者更省带宽。
3. output 与 output_text 的区别?
答:output 是分段返回的 output_item 列表,可能包含 message、function_call、reasoning 等多种类型;output_text 是便捷属性,仅拼接 message 类型项的文本,工具调用场景下可能为空。
4. 列举三类常见 API 异常及处理策略。
答:AuthenticationError(检查 Key)、RateLimitError(指数退避重试)、APIConnectionError(重试 + 降级到本地兜底响应)。
5. system 消息为什么比在 user 消息中强调规则更有效? 答:system 消息在训练时被赋予了更高权重,模型会将其作为全局约束作用于整段对话;user 消息中的规则容易被后续输入稀释或覆盖。
练习题¶
- 使用 Responses API 实现一个"英译中"函数,要求 system 消息约束模型只输出译文,并对空输入和限流做异常处理。
- 分别用"手动维护 messages"与"
previous_response_id"两种方式实现三轮对话,对比请求体大小差异。 - 给定一段产品评论,使用 Responses API 输出 JSON 格式的情感分析结果(包含 sentiment 与 score 字段)。
小结¶
本章介绍了 Responses API 的定位、消息结构、关键参数、分段返回与错误处理。Responses API 是 OpenAI 面向 Agent 时代统一入口,掌握它是后续流式响应与函数调用的基础。建议先用单轮调用跑通环境,再逐步引入多轮上下文与结构化输出,最后在生产代码中补全异常处理与重试策略。下一章我们将进入流式响应,让模型"边想边说"。