- 本文基于
openai(Python)3.26.1(commit9301e31,2026-10-08 发布)。文中代码已用 pyright 对照该版本做过类型检查;没有 API Key,因此没有实际运行。 - 示例模型名
gpt-6-astra取自 2026-10 的官方文档,使用时请以 Models 页面 为准。 - 资料截至 2026-10-09。本文不随官方更新而同步,请对照 Responses API 参考 和 openai-python CHANGELOG 使用。
1. 定位:它在哪一层#
分层模型里,openai 包属于 L1 客户端 SDK,Responses API 属于 L0/L2。它已经能做的事:
- 一次请求内,由 OpenAI 服务端执行内置工具(web search、code interpreter 等)2;
- 在服务端保存对话状态(
store、previous_response_id、Conversations)3。
它还不负责的事:本地函数工具的执行循环。这件事要你自己写(见 1.2 Tool Calling 与 Agent Loop 原理),或者交给 Agents SDK。
2. 安装与客户端配置#
pip install openaiexport OPENAI_API_KEY=sk-...from openai import OpenAI
# 默认值:从环境变量 OPENAI_API_KEY 读取密钥;超时 10 分钟;自动重试 2 次client = OpenAI(timeout=60.0, max_retries=3)
response = client.responses.create( model="gpt-6-astra", instructions="你是一个资深后端工程师,回答要简洁。", # 相当于系统提示词 input="用一句话解释什么是幂等性。",)print(response.output_text) # SDK 提供的便捷属性:把所有输出文本拼接起来print(response.id) # resp_...,可用于 previous_response_idprint(response.usage) # token 用量| 配置项 | 默认值 | 说明 |
|---|---|---|
api_key | 环境变量 OPENAI_API_KEY | 官方建议不要把 key 写死在代码里1 |
timeout | 10 分钟 | 可以传一个浮点数,或者 httpx2.Timeout。超时会抛出 APITimeoutError,并且默认会重试1 |
max_retries | 2 | 会自动重试的错误:连接错误、408、409、429、5xx。只有请求体可以安全重发时才会重试1 |
| 单次请求覆盖 | — | client.with_options(timeout=5.0).responses.create(...) |
| HTTP 底层 | HTTPX2 | 3.x 默认使用 HTTPX2;如果自定义了 HTTP 客户端,需要看迁移指南1 |
异步版本只需要把 OpenAI 换成 AsyncOpenAI,再加上 await1:
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI()
async def main() -> None: response = await client.responses.create(model="gpt-6-astra", input="你好") print(response.output_text)
asyncio.run(main())3. Responses 与 Chat Completions 的对比#
from openai import OpenAI
client = OpenAI()
# Chat Completions(上一代接口,仍然可用)completion = client.chat.completions.create( model="gpt-6-astra", messages=[{"role": "user", "content": "写一句关于独角兽的睡前故事。"}],)print(completion.choices[0].message.content)
# Responses(新项目推荐使用)response = client.responses.create( model="gpt-6-astra", input="写一句关于独角兽的睡前故事。",)print(response.output_text)| 维度 | Chat Completions | Responses |
|---|---|---|
| 返回结构 | choices[].message | output[],即一组 item |
一次生成多个候选(n) | 支持 | 不支持,只返回一个2 |
| 状态 | 需要手动管理 | 默认存储,可以用 previous_response_id 或 Conversations2 |
| 结构化输出参数 | response_format | text.format2 |
| 内置工具(web/file search、MCP 等) | — | 支持2 |
| 推理模型下的工具调用 | GPT-5.4 起,reasoning_effort 不为 none 时不支持2 | 支持;GPT-6 Astra 和 6.1 Sol 必须用 Responses 做工具调用4 |
官方给出的迁移收益有三点2:
- 使用推理模型时智能更好,内部 SWE-bench 测试提升约 3%;
- 缓存利用率更高,内部测试中成本降低 40% 到 80%;
- 默认就是 agentic loop:一次请求里可以调用多个内置工具。
4. Response 对象长什么样#
官方迁移指南中的一个返回示例(已节选)2:
{ "id": "resp_68af4030592c81938ec0a5fbab4a3e9f05438e46b5f69a3b", "object": "response", "model": "gpt-5.5", "output": [ { "id": "rs_...", "type": "reasoning", "content": [], "summary": [] }, { "id": "msg_...", "type": "message", "status": "completed", "role": "assistant", "content": [{ "type": "output_text", "annotations": [], "text": "Under a quilt of moonlight, ..." }] } ]}output_text是 SDK 提供的便捷属性,不是 API 原始字段。ResponseOutputMessage.content里装的是output_text或refusal。ResponseFunctionToolCall.arguments是一个 JSON 字符串,用之前要自己json.loads。
遍历 output 的典型写法:
from openai import OpenAI
client = OpenAI()response = client.responses.create(model="gpt-6-astra", input="1+1 等于几?")
for item in response.output: if item.type == "reasoning": print("[推理 item]", item.id) elif item.type == "message": for part in item.content: if part.type == "output_text": print("[文本]", part.text) elif part.type == "refusal": print("[拒绝]", part.refusal)5. 多轮对话的三种方式#
from typing import Any
from openai import OpenAI
client = OpenAI()MODEL = "gpt-6-astra"
# 方式 1:手动管理历史。配合 store=False 时,OpenAI 不保存这次 responsehistory: list[Any] = [{"role": "user", "content": "讲个笑话"}]r1 = client.responses.create(model=MODEL, input=history, store=False)history += r1.output # 包括加密的 reasoning item,必须原样保留history.append({"role": "user", "content": "再来一个"})r2 = client.responses.create(model=MODEL, input=history, store=False)
# 方式 2:previous_response_id 链式接续r1 = client.responses.create(model=MODEL, input="讲个笑话")r2 = client.responses.create( model=MODEL, previous_response_id=r1.id, input=[{"role": "user", "content": "解释一下笑点"}],)
# 方式 3:Conversations API,得到一个持久的会话 IDconv = client.conversations.create()r3 = client.responses.create( model=MODEL, conversation=conv.id, input=[{"role": "user", "content": "躲避球的 5 个 D 是什么?"}],)print(r2.output_text, r3.output_text)| 关键事实 | 出处 |
|---|---|
Response 对象默认保存 30 天,store: false 可以关闭 | 3 |
| Conversation 对象及其中的 item 不受 30 天 TTL 限制 | 3 |
使用 previous_response_id 时,链上所有历史输入仍然按输入 token 计费 | 3 |
无状态地调用推理模型时,必须保留 output 中的每一个 item;API 默认返回加密的 reasoning item | 3 |
previous_response_id 和 conversation 互斥 | Agents SDK 文档5 |
6. 函数调用(Function Calling)#
完整的手写循环见 1.2 Tool Calling 与 Agent Loop 原理 › 3. 手写一个最小 Agent Loop:OpenAI 版。这里补充几个常用参数:
| 参数 / 概念 | 作用 | 出处 |
|---|---|---|
strict: true | 保证模型生成的参数严格符合 JSON Schema。要求所有字段都是 required,并且 additionalProperties: false | 4 |
tool_choice | auto(默认)/ required / none / 指定某个函数 | 4 |
parallel_tool_calls=false | 限制每次最多调用一个函数 | 4 |
| Custom tools | 输入和输出都是自由文本,可以用上下文无关文法约束 | 4 |
defer_loading + tool_search | 函数太多时,按需加载工具定义(需要 gpt-5.4 及以上) | 46 |
async: true(GPT-6) | 异步工具调用:模型可以先去做别的事,等你稍后用原来的 call_id 回填结果 | 7 |
官方给出的判断标准8:
- 如果是把模型连接到你系统里的函数、数据或者 UI 操作,用函数调用;
- 如果只是希望模型回复用户时输出固定结构,用
text.format,也就是responses.parse。
7. 内置工具(Hosted Tools)#
内置工具在 OpenAI 服务端执行,你只需要在 tools 里声明:
from openai import OpenAI
client = OpenAI()
# 1) Web 搜索r = client.responses.create( model="gpt-6-astra", tools=[{"type": "web_search"}], input="今天有什么积极的科技新闻?",)print(r.output_text)
# 2) 远程 MCP 服务器:这里使用 OpenAI 官方的文档 MCP,只读,不需要鉴权r = client.responses.create( model="gpt-6-astra", tools=[ { "type": "mcp", "server_label": "openai_docs", "server_description": "Search and read the public OpenAI documentation.", "server_url": "https://developers.openai.com/mcp", "require_approval": "never", } ], input="在 OpenAI 文档中搜索 Responses API streaming,并返回相关链接。",)print(r.output_text)| 内置工具 | type | 说明 |
|---|---|---|
| Web 搜索 | web_search | 支持域名过滤、用户位置等参数6 |
| 文件搜索 | file_search | 在你的 Vector Store 里做检索6 |
| 代码解释器 | code_interpreter | 在沙箱中运行 Python2 |
| 远程 MCP | mcp | 模型先列出 server 上的工具(产生 mcp_list_tools item),然后再调用9 |
| 图像生成 | image_generation | 10 |
| Computer use | computer | 驱动浏览器或桌面2 |
| Shell(托管容器)+ Skills | shell | 在 OpenAI 托管容器中执行命令,可挂载 skills10 |
| 工具搜索 | tool_search | 按需加载延迟定义的工具6 |
官方特别强调:只连接你信任的远程 MCP 服务器。恶意的 server 可以把进入模型上下文的敏感数据外泄出去9。
8. 结构化输出:responses.parse#
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI()
class CalendarEvent(BaseModel): name: str date: str participants: list[str]
response = client.responses.parse( model="gpt-6-astra", input=[ {"role": "system", "content": "抽取事件信息。"}, {"role": "user", "content": "Alice 和 Bob 周五去参加科学展。"}, ], text_format=CalendarEvent, # SDK 自动把 Pydantic 模型转成 JSON Schema)event = response.output_parsed # 已经校验过的 CalendarEvent 实例(可能为 None)print(event)responses.parse和responses.stream都支持text_format。output_parsed返回第一个解析成功的结果11。- 模型拒绝作答时,不会把 commentary 当作结构化结果的兜底返回11。
9. 流式输出#
from openai import OpenAI
client = OpenAI()
stream = client.responses.create( model="gpt-6-astra", input="把 'double bubble bath' 快速说十遍。", stream=True,)for event in stream: if event.type == "response.output_text.delta": print(event.delta, end="", flush=True) elif event.type == "response.completed": print("\n[完成]", event.response.usage)- Responses 使用语义事件,每种事件都有固定的 schema。常见的有
response.created、response.output_text.delta、response.completed、error12。 - 函数调用的参数也会以流式到达,对应事件
response.function_call_arguments.delta和.done12。 - 流式消费过程中出现的错误不会自动重试,因为重放可能导致已经输出的内容重复出现1。
- 另有一种 WebSocket 模式:在一条持久连接上反复发送
response.create,可以降低多轮对话的延迟3。
10. 错误处理与排查#
import openaifrom openai import OpenAI
client = OpenAI()
try: response = client.responses.create(model="gpt-6-astra", input="hello") print(response._request_id) # 例如 req_123;以 _ 开头,但这是一个公开属性except openai.APIConnectionError as e: print("连不上服务器:", e.__cause__)except openai.RateLimitError: print("429:触发限流,需要退避重试")except openai.APIStatusError as e: print("其他非 2xx 状态码:", e.status_code, e.request_id)| 状态码 | 异常类 |
|---|---|
| 400 | BadRequestError |
| 401 | AuthenticationError |
| 403 | PermissionDeniedError |
| 404 | NotFoundError |
| 422 | UnprocessableEntityError |
| 429 | RateLimitError |
| ≥500 | InternalServerError |
| 网络问题 | APIConnectionError |
所有异常都继承自 openai.APIError。表格来自 openai-python README1。
11. 迁移清单#
从 Chat Completions 迁移,官方的建议是看成三件相关的改动2:
- 端点从
/v1/chat/completions改为/v1/responses; - 从 typed 的
output数组里读取结果; - 决定在轮次之间怎么保存状态。
另外,函数调用的请求和响应结构都变了(见 对照表),结构化输出参数从 response_format 改为 text.format。
从 Assistants 迁移:概念对应关系见 2.1 OpenAI 开发者生态全景 › 4.1 Assistants API 已下线。官方迁移指南明确说,没有现成的工具可以自动迁移已有的 Thread13。
小结#
- Responses API 是 OpenAI 一切 agent 能力的底座。 Agents SDK 默认调用它,Agents API 也复用了它的工具体系。
- 牢记三个概念:item(输入和输出的基本单元)、状态策略(手动回放、链式、会话三选一)、托管工具与本地函数的区别(谁来执行)。
- 下一步:用 2.3 OpenAI Agents SDK 去掉手写循环;或者用 2.4 OpenAI Agents API 把整个运行过程交给 OpenAI 托管。
相关笔记#
- 2.1 OpenAI 开发者生态全景 · 2.3 OpenAI Agents SDK · 2.4 OpenAI Agents API
- 对照:3.2 Anthropic 客户端 SDK 与 Messages API
参考资料#
注释与出处#
-
openai/openai-python,
README.md(Usage、Async usage、Streaming、Handling errors、Request IDs、Retries、Timeouts 等节),https://github.com/openai/openai-python/blob/9301e319ea33ef28fba380f39a289dedc14652c1/README.md ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 -
OpenAI,Migrate to the Responses API,https://developers.openai.com/api/docs/guides/migrate-to-responses ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12
-
OpenAI,Conversation state,https://developers.openai.com/api/docs/guides/conversation-state ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
OpenAI,Function calling,https://developers.openai.com/api/docs/guides/function-calling ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
openai/openai-agents-python,
docs/running_agents.md(“conversation_idandprevious_response_idare mutually exclusive”),https://github.com/openai/openai-agents-python/blob/26345c1e45ebede8e2fc9b0bc7341dedab5e01fc/docs/running_agents.md ↩ -
OpenAI,Using tools,https://developers.openai.com/api/docs/guides/tools ↩ ↩2 ↩3 ↩4
-
OpenAI,Using GPT-6(What's new 一节:Async tool calling),https://developers.openai.com/api/docs/guides/latest-model ↩
-
OpenAI,Structured model outputs,https://developers.openai.com/api/docs/guides/structured-outputs ↩
-
OpenAI,MCP servers(Quickstart 与 Risks and Safety 两节),https://developers.openai.com/api/docs/guides/tools-connectors-mcp ↩ ↩2
-
openai/openai-agents-python,
docs/tools.md(Hosted tools、Hosted container shell + skills 两节),https://github.com/openai/openai-agents-python/blob/26345c1e45ebede8e2fc9b0bc7341dedab5e01fc/docs/tools.md ↩ ↩2 -
openai/openai-python,
helpers.md(Parsing Responses API output 一节),https://github.com/openai/openai-python/blob/9301e319ea33ef28fba380f39a289dedc14652c1/helpers.md ↩ ↩2 -
OpenAI,Streaming API responses,https://developers.openai.com/api/docs/guides/streaming-responses ↩ ↩2
-
OpenAI,Assistants migration guide,https://developers.openai.com/api/docs/assistants/migration ↩