Skip to content

Chat Completions API 与 Responses API 详细对照 ​

核对日期:2026-10-16。适用对象:正在学习模型调用、OpenAI Python SDK 和 LangChain 的开发者。

范围:以 OpenAI 官方接口为基准,重点解释请求设置、返回字段、流式事件、工具调用、会话管理,以及 LangChain 的参数映射。第三方“OpenAI 兼容接口”必须另外核实,不能直接套用全部结论。

本文是本章的独立补充材料,不修改原课件。示例是教学代码与结构示意,不是实际模型执行记录。已检查 Python/JSON 语法,未调用付费模型验证账户权限、模型可用性及实际生成结果。

目录 ​

1 核心概念与选型 ​

1.1 先分清模型、接口、SDK 和框架 ​

层次例子决定什么
模型gpt-4.1-mini、某个推理模型能力、上下文窗口、支持哪些参数和模态
API 协议Chat Completions、Responses请求和返回如何组织、会话与工具如何表达
SDKPython 的 openai 包把 HTTP 请求包装成 Python 方法和类型对象
应用框架LangChain 的 ChatOpenAI统一消息、工具、流式处理,转换不同协议的字段
服务提供方OpenAI 官方、兼容平台、自托管服务实际实现的端点、认证、模型及扩展字段

同一个模型可能支持两种 API,但某些能力只在其中一种 API 上开放;同一个 SDK 可以调用不同服务方,但服务方不一定完整实现两种 API。

特别注意三个容易混淆的名称:

  • 本文的 Chat Completions 是 /v1/chat/completions。
  • 旧的 Completions 是 /v1/completions,与本文讨论的 Chat Completions 不同。
  • ChatGPT 网页产品也不等同于 OpenAI API,订阅、工具和计费不能直接互相推断。

1.2 两种 API 的设计中心 ​

Chat Completions 以“对话消息”作为主要单位:应用提交 messages,服务端返回 choices,每个候选中有一条 assistant 消息。模型请求函数时,函数调用挂在这条消息的 tool_calls 上。

Responses 以“带类型的条目 Item”表达输入和输出:message、reasoning、function_call、function_call_output 等各有自己的类型。一次响应可以包含多个异质条目,用来描述回答、推理摘要和工具活动。

图 1:两种结果结构的文字示意,不表示真实响应内容。

text
Chat Completions
请求 messages[]
  └─ 返回 choices[]
       └─ message
            ├─ content
            └─ tool_calls[]

Responses
请求 input / input[] + instructions
  └─ 返回 output[]
       ├─ reasoning
       ├─ function_call / web_search_call / ...
       └─ message
            └─ content[]
                 ├─ output_text
                 └─ refusal

output[] 有多个条目,不代表生成了多个候选答案。Chat Completions 的 n 表示多个候选生成,Responses 没有对应的 n 请求参数。官方迁移指南

1.3 选型建议 ​

场景建议原因
新建 OpenAI 官方应用,需要后续扩展工具或推理能力优先 Responses官方推荐新项目使用;提供更完整的类型化输出、内置工具和状态管理
现有 Chat Completions 应用运行稳定按能力需求逐步迁移Chat Completions 仍受支持,不需要仅因“新接口”立即全量替换
接入只声明支持 /chat/completions 的第三方平台使用 Chat Completions,按其文档配置兼容一个端点,不代表兼容另一个端点
需要 n 一次生成多个候选核实模型后使用 Chat CompletionsResponses 没有直接对应参数,可由应用发起多次请求
需要音频输入输出或实时交互按具体模型及专用音频/Realtime 文档选型不要把 Responses 的“多模态”解释成对所有模态、模型和传输方式的完整替代

“Responses 一定更便宜、更快、答案一定更好”不应作为通用保证。成本受模型、输入输出 token、缓存、推理预算、工具费用影响;性能应在相同任务和配置下测试。

2 共同点与能力边界 ​

两者都能在受支持模型上完成文本生成、视觉理解、JSON/结构化输出、函数调用以及流式返回。它们都需要认证,都受限流、模型权限和上下文窗口约束,调用也都可能产生费用。

维度Chat CompletionsResponses
HTTP 创建端点POST https://api.openai.com/v1/chat/completionsPOST https://api.openai.com/v1/responses
Python SDKclient.chat.completions.create(...)client.responses.create(...)
主要输入messages 数组input 字符串或 Item 数组
主要输出choices[] 中的消息output[] 中的类型化 Item
多轮聊天应用重传必要历史重传历史、响应 ID 续接、Conversations
自定义函数执行应用执行、回传结果应用执行、回传结果
平台内置工具有限、依赖具体模型/专用能力更丰富,如搜索、文件检索、代码解释器、远程 MCP
存储可配置;当前官方指南提到新账户默认存储默认存储,可用 store=False 关闭响应存储
流式传输SSE,主要是 completion chunkSSE,按语义区分事件类型
后台任务没有 Responses 同款 background 生命周期可用 background,按支持情况轮询/取消

必须同时满足“API 有字段”“模型支持该字段”“服务提供方实现字段”三个条件。SDK 接受参数并不能证明模型接受参数;JSON 能正常序列化也不代表请求符合服务端约束。

3 最小调用与消息结构 ​

3.1 示例约定 ​

以下 Python 示例依赖 openai 包;LangChain 示例另依赖 langchain-openai。代码从环境变量读取 OPENAI_API_KEY,不把密钥写进笔记。OPENAI_MODEL 可覆盖教学示例的模型名;实际使用前确认模型仍可用、账户有权限且支持相应能力。

示例采用 logging 展示结果;生产环境应避免把用户原文、完整模型结果、密钥或工具敏感数据直接写入日志。这里不构建后端 HTTP 服务,因此没有 Controller、DTO、统一返回信封或数据库变更。

3.2 Chat Completions 最小调用 ​

示例逻辑路径:/tmp/openai-api-comparison-examples/chat_basic.py,仅作为代码标识,不另建文件。

python
import logging
import os

from openai import OpenAI

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
client = OpenAI()

result = client.chat.completions.create(
    model=os.getenv("OPENAI_MODEL", "gpt-4.1-mini"),
    messages=[
        {"role": "developer", "content": "使用中文,回答简洁。"},
        {"role": "user", "content": "用一句话解释 LangChain。"},
    ],
    max_completion_tokens=300,
    store=False,
)

logger.info("回答:%s", result.choices[0].message.content)

messages 里每个元素是一条消息,至少包含角色和相应内容。developer 适用于支持该角色的现代模型;较老模型或第三方接口可能要求 system,应以其文档为准。

3.3 Responses 最小调用 ​

示例逻辑路径:/tmp/openai-api-comparison-examples/responses_basic.py。

python
import logging
import os

from openai import OpenAI

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
client = OpenAI()

result = client.responses.create(
    model=os.getenv("OPENAI_MODEL", "gpt-4.1-mini"),
    instructions="使用中文,回答简洁。",
    input="用一句话解释 LangChain。",
    max_output_tokens=300,
    store=False,
)

logger.info("状态:%s", result.status)
logger.info("回答:%s", result.output_text)

input="..." 相当于一条 user 输入。需要明确角色或历史时,也可传入 [{"role": "user", "content": "..."}]。Responses 仍然有角色概念,并非“取消了 messages,所以没有 system/user/assistant”。

instructions 提供 system/developer 级别指令;也可以在 input 消息中表达这些角色。避免在两处放入相互冲突的要求。使用 previous_response_id 时,上一轮的顶层 instructions 不自动沿用,需要继续生效的指令应在新请求中重新提供。

3.4 content 的类型差异 ​

内容Chat Completions 常见写法Responses 常见写法
简单用户文本{"role":"user","content":"你好"}同样可用简写消息;也可直接 input="你好"
显式输入文本块{"type":"text","text":"你好"}{"type":"input_text","text":"你好"}
输入图片块{"type":"image_url","image_url":{"url":"..."}}{"type":"input_image","image_url":"...","detail":"auto"}
文件输入块type="file",内容位于 file 对象type="input_file",使用 file_id 等字段
输出文本message.content,普通文本场景通常是字符串type="message" 的 content[] 中,type="output_text" 的 text

纯文本简写消息有一定可复用性,多模态块和工具消息不能只把外层 messages 改为 input 就直接迁移。

4 请求设置与字段映射 ​

4.1 高频字段总表 ​

表中的“无直接对应”表示没有等价的同名/改名迁移方案,不表示无法在应用层实现类似业务效果。

设置目的Chat Completions 原生字段Responses 原生字段迁移要点
模型modelmodel同名,但模型/快照可用能力不一定相同
用户输入与历史messagesinput简单文本消息可以复用;复杂 Item 需转换
高优先级指令messages 中的 developer/systeminstructions,或 input 中的相应角色不应把用户输入提升到指令角色
输出 token 上限max_completion_tokensmax_output_tokens两者均包含可见输出和推理 token
旧输出上限max_tokens,已弃用无该原生字段旧字段并非所有推理模型都兼容
温度temperaturetemperature通用定义为 0~2,受模型限制
核采样top_ptop_p概率质量阈值;通常不要与温度一起大幅调节
候选数量n无直接对应不要把 output[] 的条目数当成 n
停止序列stop无直接对应的顶层 stopChat 自身也不是所有模型都支持
重复惩罚frequency_penalty、presence_penalty无通用直接对应不要把 Chat 的参数包整体透传
token 偏置logit_bias无通用直接对应依赖具体接口和模型
随机种子seed,受支持情况限制且已被标记弃用无通用直接对应不能依赖它保证严格复现
文本输出格式response_formattext.formatJSON Schema 嵌套结构不同
输出详细程度支持模型上的 verbosity支持模型上的 text.verbosity与推理 effort、token 上限分开理解
推理强度reasoning_effortreasoning.effort可用枚举和默认值由模型决定
推理摘要无通用等价字段reasoning.summary返回摘要,不保证开放原始思维链
工具定义toolstools函数结构从嵌套变为扁平,内置工具各有类型
工具选择tool_choicetool_choice字符串常见值相似,指定函数的对象结构不同
并行工具调用parallel_tool_callsparallel_tool_calls是否可用还取决于模型和工具类型
流式streamstream解析协议不同
流式配置stream_optionsstream_options子字段不同,不能直接照搬 include_usage
存储响应storestore显式指定,勿依赖跨账户一致的默认行为
业务标签metadatametadata用于关联/管理,不等同于给模型的业务上下文
安全用户标识safety_identifiersafety_identifier建议稳定且不包含明文个人敏感信息
旧用户标识user,已弃用user,已弃用根据用途迁移到安全标识/缓存键等字段
缓存路由键prompt_cache_keyprompt_cache_key不代表会话、记忆或强制命中缓存
服务等级service_tierservice_tier额度、计费及模型支持需另查
响应续接无直接对应previous_response_id引用服务端保存的响应上下文
会话容器无直接对应conversation与 previous_response_id 不能同时使用
上下文截断应用管理truncation默认为 disabled,auto 可丢弃较早条目
后台运行无同款字段background适合较长任务,不等同于 Python 的 async
附加结果展开无统一等价机制include例如检索细节、logprobs 或加密推理内容
内置工具调用上限无同款字段max_tool_calls对内置工具总调用次数的限制,不是整个 Agent 的迭代上限

字段依据:Chat 创建接口、Responses 创建接口。服务端字段会演进;本文关注常用设置,不承诺覆盖全部实验或专用访问计划字段。

4.2 temperature 和 top_p ​

temperature 调整采样随机性,top_p 限制参与采样的累计概率范围。两者有相近的控制目标,但不是数值可互换的同一个参数。

常见默认值在传统文本模型上是 temperature=1、top_p=1,但模型支持范围与有效默认值优先于通用经验。部分推理模型不接受非默认温度,或仅在特定推理模式下支持采样设置。遇到 Unsupported parameter,应查模型说明,而不是认定另一种 API 一定能接收。

temperature=0 倾向于稳定输出,但不保证每次逐字相同;后端更新、数值差异、模型快照和工具结果都可能影响结果。原课件中“温度为 0 最确定性”的表述适合帮助理解,工程上不能等同于严格确定性保证。

4.3 三个 max 字段怎么区分 ​

字段所属接口含义和限制
max_tokensChat 的旧字段;也常见于框架和第三方接口已弃用的旧输出限制;不能认为与所有推理模型兼容
max_completion_tokensChat 的现代字段限制生成 token 总量,包含可见输出与推理 token
max_output_tokensResponses同样限制生成预算,包含可见输出与推理 token

这里的 token 上限不等于“最多多少汉字”,也不等于模型上下文窗口。上下文还需要容纳输入历史、工具结果及相关内容。

假设教学设置的生成预算为 1000 token,模型内部推理消耗了一部分,则可见回答能使用的预算会减少。这个数字只用于说明预算关系,不是实测记录。过低的预算可能让推理模型在没有完整可见答案时就结束。

达到生成上限时,Chat 通常通过 finish_reason="length" 表达;Responses 检查 status="incomplete" 和 incomplete_details.reason,例如 max_output_tokens。不要仅凭 HTTP 200 判断回答完整。

4.4 reasoning、verbosity 与文本格式是三件事 ​

配置影响对象不应误解为
reasoning_effort / reasoning.effort模型投入的推理强度最终答案必然更长、一定正确或固定耗时
verbosity / text.verbosity可见输出的详细程度固定字数上限或推理预算
response_format / text.format输出的表示格式、JSON Schema回答内容的事实正确性
max_completion_tokens / max_output_tokens可生成 token 的硬预算完整回答的最低保证

旧教程常列出推理强度 low、medium、high;当前接口还可出现 none、minimal、xhigh、max 等。不是每个模型都支持全部取值,默认值也不能跨模型套用。 推理摘要可用值同样需要核实模型支持。

Responses 推理配置形状示意如下,不是对任意模型的可运行保证。

json
{
  "reasoning": {
    "effort": "medium",
    "summary": "auto"
  },
  "text": {
    "format": {"type": "text"},
    "verbosity": "low"
  }
}

推理摘要位于 type="reasoning" Item 的 summary 中。reasoning.encrypted_content 是加密数据,不能将它当成可直接展示的原始思维链。

4.5 logprobs 的设置与位置 ​

目的Chat CompletionsResponses
请求文本 token 概率信息logprobs=Trueinclude=["message.output_text.logprobs"]
每个位置返回候选 token 数top_logprobs,通常需开启 logprobstop_logprobs,结合相应 include
常见返回位置choices[i].logprobsoutput 中 output_text 内容块的 logprobs

top_logprobs 当前参考范围为 0~20,实际返回数量可能更少,且有模型限制。token 概率不是“整句话的事实置信度”,也不是业务分类准确率。

4.6 超时、重试与 extra_body 不属于模型生成参数 ​

配置属于哪一层注意事项
api_key客户端认证不应放入生成请求正文或提交到仓库
base_urlSDK/框架的服务地址通常设置到 /v1,SDK 再拼接具体资源路径
timeoutSDK/框架网络等待策略不等于输出 token、后台任务持续时间或必然取消服务端任务
max_retriesSDK/框架重试策略重试不保证外部写入动作幂等,工具执行需单独保护
extra_headersHTTP 请求头扩展不等同于模型参数,不泄露认证信息
extra_bodySDK 合并到请求 JSON 的扩展入口只能传服务方真实支持的参数,不会自动创造能力
model_kwargsLangChain 参数封装入口通常用于有效的模型参数,不应乱塞非标准供应商字段

background=True 是服务端任务执行模式,AsyncOpenAI / ainvoke() 是客户端异步等待方式,stream=True 是增量交付方式。三者可以解决不同问题,不能互相替代。

4.7 存储、隐私、缓存和会话的区别 ​

当前 Responses 创建参考明确 store 省略时默认 true;迁移指南还明确提到 Chat Completions 对新账户默认存储。因此不能继续把“Chat 默认 false、Responses 默认 true”写成跨账户的永久规律。

有隐私要求时显式设置 store=False,但仍需分别理解:

  1. store 管理生成响应的存储与后续检索;它不自动代表所有平台日志归零。
  2. 滥用监控日志、上传文件、向量库、Conversations、工具容器及第三方 MCP 各有自己的保留政策。
  3. Zero Data Retention 需要组织/项目满足相应条件,不能靠一个请求参数自行获得。
  4. store=False 与“API 数据是否用于训练”是不同问题;官方默认不使用 API 数据训练模型,除非主动选择分享。
  5. prompt_cache_key 和缓存命中不等同于服务端会话状态;缓存也不是永久记忆。

当前缓存设置还在演进:旧 prompt_cache_retention 已被标记弃用,新的 prompt_cache_options 面向特定较新模型,包含 ttl、mode 等选项。二者保留语义不同,不要仅把旧字段改名就沿用全部取值;调用前查对应模型的缓存指南。

依据:数据控制、缓存指南。

5 返回字段与结果解析 ​

5.1 主要字段对照 ​

含义Chat CompletionsResponses注意事项
整体响应 IDid,常见 chatcmpl_ 或 chatcmpl- 前缀id,常见 resp_ 前缀不应解析前缀来替代接口类型判断
对象类型object="chat.completion"object="response"Chat 流式对象通常是 chat.completion.chunk
创建时间createdcreated_atUnix 时间戳;不是请求耗时
模型modelmodel可能体现实际模型/快照
生成结果choices[]output[]前者是候选,后者是不同类型条目
文本路径choices[i].message.contentmessage Item 的 content[] 内 output_text.textResponses 不应固定取 output[0]
SDK 文本快捷读取读取 messageresponse.output_textSDK 聚合辅助属性,不是通用 HTTP 原始字段承诺
拒绝信息message.refusaltype="refusal" 的内容块拒绝不一定是 HTTP 错误
函数调用message.tool_calls[]type="function_call" Item工具请求不等于最终答案
推理结果部分模型返回用量细节,第三方可能有扩展type="reasoning" Item,含摘要/加密内容等不应将供应商扩展当成官方统一字段
结束/生命周期choices[i].finish_reason顶层 status语义不同,不能做简单枚举重命名
不完整原因常见 length、content_filter 等结束原因incomplete_details.reason结果可能存在但不完整
生成失败信息HTTP/SDK 异常,或特定结束状态HTTP/SDK 异常,也可能是 status="failed"、error尤其后台、流式场景要检查生命周期
引用标注某些模型消息的 annotationsoutput_text.annotations 等搜索答案要保留引用信息
响应用量usageusage子字段名称不同
请求追踪HTTP x-request-id;SDK 常见 _request_id同左不等于业务 traceId,也不等于生成响应的 id

Responses 顶层 text 是输出配置,不是最终回答内容;input 是输入,output 才是输出条目。response.output_text 只聚合文本,不包含全部工具活动、图片、拒绝说明或推理内容。

5.2 Chat finish_reason 与 Responses status ​

情况Chat 常见表现Responses 常见表现
正常结束文本生成finish_reason="stop"status="completed",检查是否有可见消息
达到生成预算finish_reason="length"status="incomplete",原因可能是 max_output_tokens
请求应用执行工具finish_reason="tool_calls"返回 function_call Item;整体也可能是 completed
内容过滤导致未完成可能为 content_filter可能为 incomplete,检查具体原因和拒绝块
排队/执行中普通同步创建不提供同款生命周期queued / in_progress,常见于后台/流式
取消/失败网络或 API 错误等cancelled / failed,结合 error

completed 表示这次响应生成完成,不表示整个业务流程完成。例如模型已经成功产生一个函数调用,仍然需要应用执行函数并发起下一轮。

5.3 usage 对照 ​

用量含义Chat 字段Responses 字段
输入 tokenusage.prompt_tokensusage.input_tokens
输出 tokenusage.completion_tokensusage.output_tokens
总 tokenusage.total_tokensusage.total_tokens
命中缓存的输入 tokenusage.prompt_tokens_details.cached_tokensusage.input_tokens_details.cached_tokens
推理 tokenusage.completion_tokens_details.reasoning_tokensusage.output_tokens_details.reasoning_tokens

细分 token 是父级用量的组成部分,不要再次相加造成重复统计。某些模型还有音频、预测等细分字段,不能假设所有模型都返回同一组 details。

usage 也不是一张完整费用账单:内置工具、存储、服务等级和不同模态可能有额外计价规则。previous_response_id 减少历史传输体积,但不会自动免除参与推理的历史输入计费。

5.4 不使用 SDK 时怎样提取 Responses 文本 ​

示例逻辑路径:/tmp/openai-api-comparison-examples/extract_response_text.py。函数接收 HTTP JSON 解码得到的字典,不发起网络请求。

python
def extract_response_text(payload: dict) -> str:
    fragments = []
    for item in payload.get("output") or []:
        if item.get("type") != "message":
            continue
        for part in item.get("content") or []:
            if part.get("type") == "output_text":
                fragments.append(part["text"])
    return "".join(fragments)

这个函数只演示文本聚合。实际应用还应另外识别 refusal、函数调用、状态及错误;空文本不能直接认定调用失败。如果模型存在中间说明与最终答案的 phase,还要按需要区分,回传历史时保留相应字段。

6 结构化输出与 JSON Schema ​

6.1 三种方式不能混为一谈 ​

方式目标能保证什么仍需处理什么
提示词要求“只输出 JSON”文本习惯约束不提供协议级格式保证格式错误、缺字段、拒绝、截断
JSON mode,type="json_object"输出有效 JSON通常保证 JSON 语法,仍有边界情况不保证业务 Schema;应明确提示生成 JSON
Structured Outputs,type="json_schema"输出符合受支持 Schema正常完整输出时按 Schema 约束拒绝、截断、请求错误,以及内容事实和业务规则

Schema 约束保证形状,不保证提取结果真实;生成一个符合结构的错误价格,仍然是业务错误。

6.2 最重要的嵌套差异 ​

Chat 的结构是 response_format.json_schema,Schema 名称、严格模式、Schema 本体在其中。

json
{
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "answer",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {"answer": {"type": "string"}},
        "required": ["answer"],
        "additionalProperties": false
      }
    }
  }
}

Responses 的结构是 text.format,不再有第二层 json_schema 包装。

json
{
  "text": {
    "format": {
      "type": "json_schema",
      "name": "answer",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {"answer": {"type": "string"}},
        "required": ["answer"],
        "additionalProperties": false
      }
    }
  }
}

因此不能只把 response_format 重命名为 text.format,却把其内部原样塞进去。

6.3 两种 API 的 Python 对照 ​

示例逻辑路径:/tmp/openai-api-comparison-examples/structured_outputs.py。执行该示例会发起两次请求。

python
import json
import logging
import os

from openai import OpenAI

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
client = OpenAI()
model = os.getenv("OPENAI_MODEL", "gpt-4.1-mini")
schema = {
    "type": "object",
    "properties": {"answer": {"type": "string"}},
    "required": ["answer"],
    "additionalProperties": False,
}

chat = client.chat.completions.create(
    model=model,
    messages=[{"role": "user", "content": "用一句话解释 API。"}],
    response_format={
        "type": "json_schema",
        "json_schema": {"name": "answer", "strict": True, "schema": schema},
    },
    max_completion_tokens=500,
    store=False,
)
choice = chat.choices[0]
if choice.message.refusal:
    logger.warning("Chat 返回拒绝,未解析 JSON")
elif choice.finish_reason != "stop" or not choice.message.content:
    logger.warning("Chat 未返回完整 JSON,结束原因为 %s", choice.finish_reason)
else:
    chat_data = json.loads(choice.message.content)
    logger.info("Chat 解析字段:%s", list(chat_data))

response = client.responses.create(
    model=model,
    input="用一句话解释 API。",
    text={
        "format": {
            "type": "json_schema",
            "name": "answer",
            "strict": True,
            "schema": schema,
        }
    },
    max_output_tokens=500,
    store=False,
)
refused = any(
    part.type == "refusal"
    for item in response.output
    if item.type == "message"
    for part in item.content
)
if refused:
    logger.warning("Responses 返回拒绝,未解析 JSON")
elif response.status != "completed" or not response.output_text:
    logger.warning("Responses 未返回完整 JSON,状态为 %s", response.status)
else:
    response_data = json.loads(response.output_text)
    logger.info("Responses 解析字段:%s", list(response_data))

严格模式只支持 JSON Schema 的子集,通常要求对象 additionalProperties=False,所有属性列入 required;允许空值时使用可含 null 的类型。无效或不受支持的 Schema 会直接报请求错误。原生 SDK 还有 .parse() 等辅助方法,可结合 Pydantic 返回解析对象;它们与这里演示的 .create() 加 json.loads() 是不同层次的功能。

依据:Structured Outputs 官方指南。

7 函数调用与工具执行 ​

7.1 函数定义的差异 ​

Chat Completions 的 function 是嵌套对象。

json
{
  "type": "function",
  "function": {
    "name": "lookup_term",
    "description": "查询课程术语定义",
    "parameters": {
      "type": "object",
      "properties": {"term": {"type": "string"}},
      "required": ["term"],
      "additionalProperties": false
    },
    "strict": true
  }
}

Responses 将函数字段放在工具对象本身。

json
{
  "type": "function",
  "name": "lookup_term",
  "description": "查询课程术语定义",
  "parameters": {
    "type": "object",
    "properties": {"term": {"type": "string"}},
    "required": ["term"],
    "additionalProperties": false
  },
  "strict": true
}

strict 约束函数参数结构,不代表模型会自动执行函数,也不代表权限、金额、资源归属等业务规则已经校验。为避免不同接口或版本的默认严格化行为差异,教学与迁移时建议显式设置严格模式及 Schema。

7.2 tool_choice 的差异 ​

目的Chat CompletionsResponses
由模型决定"auto""auto"
不调用工具"none""none"
要求调用工具"required""required"
指定函数{"type":"function","function":{"name":"lookup_term"}}{"type":"function","name":"lookup_term"}

required 表示需要工具调用,不等于某个指定函数必然执行;需要指定函数时使用相应对象结构。设 parallel_tool_calls=False 可用于限制受支持场景下的并行函数调用,但不应推断它能限制内置工具总次数或整个多轮 Agent 的循环次数。

7.3 工具调用返回和结果回传 ​

环节Chat CompletionsResponses
模型请求执行函数message.tool_calls[i]output 中 type="function_call"
函数名tool_call.function.nameitem.name
参数tool_call.function.arguments,JSON 字符串item.arguments,JSON 字符串
用来匹配执行结果的 IDtool_call.iditem.call_id
回传形式{"role":"tool","tool_call_id":"...","content":"..."}{"type":"function_call_output","call_id":"...","output":"..."}

Responses 的 Item id 和 call_id 不要混用。回传函数结果通常用 call_id 对应调用,不是拿 fc_... Item ID 或 resp_... 响应 ID 填进去。

7.4 成对的函数调用示例 ​

示例逻辑路径:/tmp/openai-api-comparison-examples/function_calling.py。使用本地课程术语表,不连接数据库或外部系统;该术语表是教学输入,不是联网检索结果。示例分别展示一次“请求函数 → 执行 → 回传”流程,执行时最多发起四次模型请求。

python
import json
import logging
import os

from openai import OpenAI

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
client = OpenAI()
model = os.getenv("OPENAI_MODEL", "gpt-4.1-mini")
definition = {
    "name": "lookup_term",
    "description": "查询课程术语定义",
    "parameters": {
        "type": "object",
        "properties": {"term": {"type": "string"}},
        "required": ["term"],
        "additionalProperties": False,
    },
    "strict": True,
}


def execute_lookup(name: str, arguments: str) -> str:
    if name != "lookup_term":
        raise ValueError("不允许调用该函数")
    args = json.loads(arguments)
    if not isinstance(args, dict) or set(args) != {"term"}:
        raise ValueError("函数参数结构不合法")
    term = args["term"]
    if not isinstance(term, str) or not 1 <= len(term) <= 100:
        raise ValueError("术语参数不合法")
    glossary = {"LangChain": "用于构建大模型应用的框架"}
    return json.dumps({"definition": glossary.get(term)}, ensure_ascii=False)


chat_tools = [{"type": "function", "function": definition}]
messages = [{"role": "user", "content": "查询 LangChain 的课程定义。"}]
chat_first = client.chat.completions.create(
    model=model,
    messages=messages,
    tools=chat_tools,
    tool_choice={"type": "function", "function": {"name": "lookup_term"}},
    parallel_tool_calls=False,
    store=False,
)
assistant = chat_first.choices[0].message
messages.append(assistant)
if not assistant.tool_calls:
    raise RuntimeError("Chat 未返回预期函数调用")
for call in assistant.tool_calls:
    if call.type != "function":
        raise ValueError("不支持此工具类型")
    tool_result = execute_lookup(call.function.name, call.function.arguments)
    messages.append({"role": "tool", "tool_call_id": call.id, "content": tool_result})
chat_final = client.chat.completions.create(
    model=model,
    messages=messages,
    tools=chat_tools,
    tool_choice="none",
    store=False,
)
logger.info("Chat 回答:%s", chat_final.choices[0].message.content)

response_tools = [{"type": "function", **definition}]
history = [{"role": "user", "content": "查询 LangChain 的课程定义。"}]
response_first = client.responses.create(
    model=model,
    input=history,
    tools=response_tools,
    tool_choice={"type": "function", "name": "lookup_term"},
    parallel_tool_calls=False,
    store=False,
)
history.extend(response_first.output)
calls = [item for item in response_first.output if item.type == "function_call"]
if not calls:
    raise RuntimeError("Responses 未返回预期函数调用")
for call in calls:
    tool_result = execute_lookup(call.name, call.arguments)
    history.append({
        "type": "function_call_output",
        "call_id": call.call_id,
        "output": tool_result,
    })
response_final = client.responses.create(
    model=model,
    input=history,
    tools=response_tools,
    tool_choice="none",
    store=False,
)
logger.info("Responses 回答:%s", response_final.output_text)

第二次请求设 tool_choice="none" 是为了让单轮示例收尾;真实 Agent 可能允许更多工具轮次,应由应用设定迭代、耗时、费用和权限上限。推理模型手工管理历史时,应完整保留可回传的 reasoning Item,而非只追加文本或函数调用。

函数调用的安全边界位于应用:只允许白名单工具,校验参数与用户权限,对退款、删除、发消息等动作增加确认和幂等保护,不使用 eval() 执行模型文本。严格 Schema 不替代这些保护。

较新的模型可能收紧 Chat Completions 中“推理 + 工具”的支持范围;当前迁移指南对 GPT-5.4 起的相关限制有专门说明。示例选择非推理教学模型,不能简单更换为任意新模型并照搬所有设置。

依据:Function calling、迁移指南。

8 多轮会话与状态管理 ​

8.1 Chat Completions 手工维护历史 ​

每次请求带上本轮需要的历史消息。只发第二个问题而没有历史,模型不会因为同一个 Python client 对象就自动知道上一轮内容。

示例逻辑路径:/tmp/openai-api-comparison-examples/chat_history.py。

python
import logging
import os

from openai import OpenAI

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
client = OpenAI()
model = os.getenv("OPENAI_MODEL", "gpt-4.1-mini")
messages = [
    {"role": "developer", "content": "使用中文回答。"},
    {"role": "user", "content": "我正在学习 LangChain。"},
]
first = client.chat.completions.create(model=model, messages=messages, store=False)
messages.append(first.choices[0].message)
messages.append({"role": "user", "content": "根据我刚说的内容,建议一个练习。"})
second = client.chat.completions.create(model=model, messages=messages, store=False)
logger.info("第二轮:%s", second.choices[0].message.content)

设置 Chat 的 store=True 也不等于自动获得 Responses 式的 previous_response_id 续接能力。

8.2 Responses 的三种组织方式 ​

方式怎么传适合场景注意
应用手工维护历史 input + 上轮完整 output + 新消息自己控制历史、使用无状态调用不要只保留 output_text;模型相关 Item 需要保留
响应 ID 续接previous_response_id=上一轮.id同一上下文连续追问、少传历史依赖服务端能续接该响应;历史仍可能参与计费
Conversationsconversation=会话ID需要持久会话容器、跨请求管理会话 Item 自动追加;不能与 previous ID 同用

示例逻辑路径:/tmp/openai-api-comparison-examples/responses_previous_id.py。该例明确存储响应,以演示服务端续接;不适合直接套用到禁止存储的业务。

python
import logging
import os

from openai import OpenAI

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
client = OpenAI()
model = os.getenv("OPENAI_MODEL", "gpt-4.1-mini")
instructions = "使用中文,回答不超过三句话。"
first = client.responses.create(
    model=model,
    instructions=instructions,
    input="我正在学习 LangChain。",
    store=True,
)
second = client.responses.create(
    model=model,
    instructions=instructions,
    previous_response_id=first.id,
    input="根据我刚说的内容,建议一个练习。",
    store=True,
)
logger.info("第二轮:%s", second.output_text)

这里第二轮仍然传 instructions。不要假设前一轮顶层指令、工具定义、Schema、温度等全部请求配置会自动继承;续接主要管理上下文,本轮需要的设置应明确提供。

若改成手工历史模式,保留全部可回传输出条目,并按模型需要使用 include=["reasoning.encrypted_content"]。该设置便于无状态续传推理上下文,不代表本地可解密或查看原始推理。

8.3 truncation 与上下文压缩 ​

Responses 的 truncation="disabled" 默认在输入超出上下文窗口时返回错误;"auto" 可丢弃较早对话条目以适配窗口。自动截断可能丢失最初的业务约束、事实或工具结果,不能把它当成“无限记忆”。

当前接口另提供面向支持模型的 context_management 等上下文管理配置,例如 compaction。压缩与截断语义不同:前者用压缩表示延续上下文,后者会丢弃内容。两者都不能假定完全无损;重要业务状态应保存在应用自己的数据结构中。

同一会话有并发请求时,还需由应用处理顺序和分支,避免两个请求同时基于不同历史继续写入造成业务上下文混乱。

依据:Conversation state、Responses 创建接口。

9 流式调用与事件字段 ​

9.1 开启方式相同,事件语义不同 ​

两者都使用 stream=True,但 Chat 的 chunk 解析器不能原样用于 Responses。

环节Chat CompletionsResponses
文本增量chunk.choices[i].delta.contentevent.type="response.output_text.delta",文本在 event.delta
工具参数增量delta.tool_calls 中的 function.argumentsresponse.function_call_arguments.delta
响应开始首个 chunk 等response.created、response.in_progress
条目生命周期在消息/工具的 chunk 中聚合response.output_item.added、response.output_item.done
文本结束结合 finish_reason 等response.output_text.done,只表示该文本段结束
整体生成结束最终 finish_reason;HTTP SSE 常见 [DONE]response.completed,或失败/不完整事件
用量可请求 stream_options={"include_usage":True}通常从最终 response 生命周期事件取得 usage
标识不同内容位置choice/tool 的 indexitem_id、output_index、content_index,某些事件有 sequence_number

Chat 请求流式 usage 时,额外用量 chunk 的 choices 可能为空;因此 chunk.choices[0] 前应先判空。网络中断时,最终 usage 或完成事件也可能收不到。

Responses 当前 stream_options 中有 include_obfuscation 等配置,它不等于 Chat 的 include_usage。混淆这些子字段可能导致请求错误。

9.2 Chat 流式读取 ​

示例逻辑路径:/tmp/openai-api-comparison-examples/chat_stream.py。

python
import logging
import os

from openai import OpenAI

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
client = OpenAI()
stream = client.chat.completions.create(
    model=os.getenv("OPENAI_MODEL", "gpt-4.1-mini"),
    messages=[{"role": "user", "content": "简述 API 的作用。"}],
    stream=True,
    stream_options={"include_usage": True},
    store=False,
)
fragments = []
finish_reason = None
usage = None
for chunk in stream:
    if chunk.usage is not None:
        usage = chunk.usage
    for choice in chunk.choices:
        if choice.delta.content:
            fragments.append(choice.delta.content)
        if choice.finish_reason is not None:
            finish_reason = choice.finish_reason
logger.info("结束原因:%s;是否取得用量:%s", finish_reason, usage is not None)
logger.info("回答:%s", "".join(fragments))

9.3 Responses 流式读取 ​

示例逻辑路径:/tmp/openai-api-comparison-examples/responses_stream.py。

python
import logging
import os

from openai import OpenAI

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
client = OpenAI()
stream = client.responses.create(
    model=os.getenv("OPENAI_MODEL", "gpt-4.1-mini"),
    input="简述 API 的作用。",
    stream=True,
    store=False,
)
fragments = []
final_response = None
for event in stream:
    if event.type == "response.output_text.delta":
        fragments.append(event.delta)
    elif event.type in {"response.completed", "response.failed", "response.incomplete"}:
        final_response = event.response
    elif event.type == "error":
        logger.error("流式接口错误,错误码:%s", event.code)
if final_response is None:
    logger.warning("未收到最终响应,不能认定生成成功")
else:
    logger.info("最终状态:%s", final_response.status)
logger.info("已收到的文本:%s", "".join(fragments))

示例聚合文本以便阅读;前端实时展示应把每个文本增量送往界面,而非在生产循环中高频写日志。若要流式执行函数,须按调用 ID 聚合参数,收到完整参数后再解析和校验,不能对半截 JSON 执行业务动作。

依据:Streaming API responses。

10 多模态与内置工具 ​

10.1 图片输入的字段差异 ​

Chat 图片块的 image_url 是对象;Responses 的 input_image.image_url 是字符串,detail 位于块上。

json
{
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "描述这张图。"},
        {
          "type": "image_url",
          "image_url": {
            "url": "data:image/png;base64,BASE64_DATA",
            "detail": "auto"
          }
        }
      ]
    }
  ]
}
json
{
  "input": [
    {
      "role": "user",
      "content": [
        {"type": "input_text", "text": "描述这张图。"},
        {
          "type": "input_image",
          "image_url": "data:image/png;base64,BASE64_DATA",
          "detail": "auto"
        }
      ]
    }
  ]
}

这里 BASE64_DATA 是需替换的示意占位,不是合法图片数据,以上两个 JSON 只说明结构。图片内容、分辨率、detail 和模型规则可能影响 token 和费用。

10.2 内置工具与自定义函数的区别 ​

工具类型谁执行常见配置/结果
自定义 function应用自己的代码返回 function_call 后,由应用执行并回传
Web search平台内置工具tools 中 type="web_search";可返回 web_search_call、文本引用
File search平台检索能力type="file_search",关联 vector_store_ids,可用 include 展开结果
Code interpreter平台托管执行环境type="code_interpreter",配置容器;不是执行在用户本机
Image generation对应平台图像工具返回图像生成条目,不应只读取 output_text
Remote MCP远程 MCP 服务type="mcp",配置服务地址、工具范围和审批策略
Computer use按具体工具配置的执行环境可能需要应用执行动作并回传截图,不能笼统理解为平台自动操作本机

Responses 可在一次请求内完成某些内置工具的调用与继续生成,但它不会因为你定义了一个本地函数名,就自动访问应用数据库。工具是否支持、谁来执行、是否需要人工审批,应查对应工具指南。

Chat Completions 也存在特定搜索模型/搜索能力,因此“Chat 完全不能联网”过于绝对;准确结论是,它不提供与 Responses 相同的通用内置工具协议和完整工具组合能力。

11 LangChain 参数与输出映射 ​

11.1 ChatOpenAI 不等于固定使用 Chat Completions ​

ChatOpenAI 是 LangChain 的聊天模型适配类,可以根据参数和版本调用 Chat Completions 或 Responses。类名中的 Chat 不能用来判断最终 HTTP 路径。

同样,init_chat_model(..., model_provider="openai") 选择的是 OpenAI 集成,不是“强制使用某个 API 端点”。最终路由仍由适配类配置决定。

LangChain 设置作用常见误区
use_responses_api=True明确选择 Responses不是开启所有第三方兼容能力
use_responses_api=False明确选择 Chat Completions 路径不保证第三方接受其余 OpenAI 参数
use_responses_api=None / 未显式设置按当前版本规则推断不可当成永远固定 False
output_version="responses/v1"LangChain 的 Responses 消息内容表示不是请求 /v1 的版本号,不是模型版本
output_version="v1"LangChain 标准内容块表示,依版本支持不等于 OpenAI Responses v1
use_previous_response_id=True从传入消息历史中提取上一响应 ID,减少重发历史不代表模型对象自动保存所有聊天记忆
stream_usage=True让框架请求/汇总流式 token 使用情况第三方可能不支持对应流式扩展
with_structured_output(...)封装结构化输出,具体方法依配置和版本不能只看方法名判断最终请求结构

内置工具、reasoning、previous_response_id 等设置可能让框架自动路由到 Responses;当前实现中显式的 output_version="responses/v1" 也可能参与路由判断。默认输出格式与默认路由是两个问题,不能根据看到某种消息内容格式就反推所有请求都走了 Responses。

11.2 max_tokens 的两次转换 ​

当前官方集成文档和实现保留 max_tokens 以兼容旧代码,但可能转换后才发出请求:

text
LangChain 调用参数 max_tokens
  ├─ Chat Completions 路径 → max_completion_tokens
  └─ Responses 路径        → max_output_tokens

这解释了一个常见现象:代码里写 max_tokens=1000,第三方却报 max_completion_tokens 不支持。关闭 Responses 只能改变 API 路径,未必能阻止 Chat 路径上的字段转换。应核对实际安装版本和服务方支持;需要供应商扩展时优先考虑专用集成,不能保证简单换 base_url 足够。

11.3 两种显式配置的示例 ​

示例逻辑路径:/tmp/openai-api-comparison-examples/langchain_routes.py。依赖支持相应参数的 langchain-openai,执行时会请求两个接口。

python
import logging
import os

from langchain_openai import ChatOpenAI

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
model_name = os.getenv("OPENAI_MODEL", "gpt-4.1-mini")

chat_model = ChatOpenAI(
    model=model_name,
    use_responses_api=False,
    max_tokens=500,
    timeout=60,
    max_retries=2,
)
chat_message = chat_model.invoke("用一句话解释 LangChain。", store=False)
logger.info("Chat 消息内容:%s", chat_message.content)
logger.info("Chat 用量:%s", chat_message.usage_metadata)

responses_model = ChatOpenAI(
    model=model_name,
    use_responses_api=True,
    output_version="responses/v1",
    max_tokens=500,
    timeout=60,
    max_retries=2,
)
responses_message = responses_model.invoke("用一句话解释 LangChain。", store=False)
logger.info("Responses 消息内容:%s", responses_message.content)
logger.info("Responses 用量:%s", responses_message.usage_metadata)

LangChain 接收的是统一消息接口,示例没有手动传入原生 Responses 的 input。框架负责转换;不能把原生 SDK 的整个请求字典直接当成 ChatOpenAI 的构造参数。

11.4 AIMessage 字段与原生字段不是同一层 ​

LangChain 字段一般含义与原生 API 的关系
AIMessage.content字符串或内容块列表不保证始终是普通字符串;受 output_version 影响
AIMessage.tool_calls标准化工具调用列表通常把函数参数解析成 args 字典,与原生 arguments 字符串不同
AIMessage.invalid_tool_calls无法正常解析的工具调用需要处理,不能默认 tools 全部合法
AIMessage.response_metadata供应商及响应相关元数据ID、结束原因、模型等组织方式受版本/路径影响
AIMessage.usage_metadata框架标准化输入/输出/总 token 等不应再按 Chat 的 prompt_tokens 路径硬读
AIMessage.additional_kwargs额外原生信息新格式可能把部分内容移入 content,不是永久固定位置
AIMessage.id框架消息 ID某些路径与响应 ID 相关,不能在所有场景都视为可续接 ID

原生 OpenAI 返回整个 response,LangChain invoke() 通常返回标准化 AIMessage。看到一个 AIMessage 不代表底层是 Chat Completions,也不能要求它具备原生 response.output_text 属性。

11.5 自动续接不等于自动记忆 ​

使用 use_previous_response_id=True 时,仍然需要传入包含之前 AIMessage 的历史,框架才有材料寻找上次响应信息;只调用两次 invoke("新问题") 不会自动构成同一聊天。

官方示例与源码版本对 ID 的读取位置可能不同。当前实现会从消息响应元数据中寻找可用 resp_ ID;手工构造消息或持久化恢复时,应保留完整响应元数据。生产依赖需固定版本并测试,不能把主分支实现细节当成永不变化的公开契约。

store=False 下不能默认用任意历史 ID 实现服务端续接;若希望由应用管理状态,可保留并回传完整历史,按模型需要保留加密推理 Item。

11.6 本章“OpenAI 兼容”应如何理解 ​

原课件中通过 ChatOpenAI 配置不同 base_url 的方式,适合说明基础协议兼容,但兼容性至少分成以下几层:

层次应核实内容
端点兼容/chat/completions、/responses 分别是否实现
参数兼容接受 max_tokens 还是 max_completion_tokens;是否支持 store、严格 Schema
响应兼容消息、usage、工具参数、ID 是否符合对应规范
流式兼容SSE 结构、最终事件、stream usage 是否支持
状态兼容previous_response_id 是否可续接,响应保存多久
模型扩展reasoning_content 等供应商字段是否会被框架提取

OpenAI 官方 ChatOpenAI 集成不保证保存所有供应商非标准扩展字段。需要 DeepSeek、OpenRouter 等特定扩展时,应优先核实 ChatDeepSeek、ChatOpenRouter 等专用集成。

版本提示:官方资料标注 Responses 支持从 langchain-openai 0.3.9 引入,自动响应续接与较新内容格式相关能力从 0.3.26 引入;1.x 又有输出格式演进。本文不锁定当前工作区依赖,也不修改环境,实际行为以安装版本为准。

依据:LangChain OpenAI 集成、ChatOpenAI Reference、官方实现源码。

12 迁移与排错 ​

12.1 迁移时需要改变哪些层 ​

层次原有依赖迁移时的变化
地址与客户端方法/chat/completions、chat.completions.create/responses、responses.create
输入转换messages、多模态块、工具消息input Item、instructions、函数输出 Item
生成设置max、reasoning、format 等改名与嵌套转换;去掉无等价参数
输出解析choices/message/finish_reasontyped output/status/incomplete_details
流式前端协议content delta、tool_calls delta语义事件、多个 Item 和内容索引
会话保存文本消息历史保留所有必要 Item 或选用服务端状态
用量报表prompt/completion tokensinput/output tokens,避免重复细分计数
日志与错误HTTP 错误、结束原因另考虑响应生命周期失败、拒绝和不完整

迁移应先以相同模型与任务验证文本、工具、Schema、流式和异常分支,再扩展到新的内置能力。若原应用必须兼容只支持 Chat 的服务方,建议把两种协议适配隔离;回退需要重建合适的请求和历史,不能在某次失败后仅替换 URL 并重发同一个 JSON。

对可能造成外部写入的工具,不应在未确认执行结果时自动回退重跑,以免重复退款、重复创建记录或重复发送消息。保留旧适配路径、配置开关与必要历史格式,有助于回滚,但不能保证不同 API 之间的 Item 可无损互转。

12.2 常见现象与诊断方向 ​

现象优先核实处理方向
/responses 返回 404服务方是否实现该路径、base_url 是否重复拼接按其支持选择路径;不要假定所有兼容平台都支持
Unsupported parameter: max_tokens当前调用是否为 Responses 或不支持旧参数的模型原生 Responses 用 max_output_tokens,Chat 按模型用现代字段
代码写 max_tokens,报错却是 max_completion_tokens框架是否转换字段查当前 LangChain 实现、服务方协议或专用集成
非默认 temperature 报错模型/推理模式是否支持采样参数删除不支持设置,按模型文档配置
Responses 找不到 choices仍按 Chat 解析改为解析 output,或用 SDK output_text
output[0].content 不存在第一个 Item 是 reasoning 或工具调用按 type 分支遍历
HTTP 200 但回答没生成完整是否 length、incomplete、拒绝、工具请求检查结束状态和输出类型,调整预算/流程
流式 choices[0] 越界是否收到空 choices 的 usage chunk判空并分开读取 usage
Responses 流式没有 delta.content沿用 Chat 解析器使用语义事件类型及 event.delta
JSON Schema 参数错误是否多包了一层 json_schema、Schema 子集是否合法按两种接口各自结构设置
函数执行结果关联不上混淆 item.id、call_id、tool_call_id使用对应协议的调用关联字段
第二轮忘记上一轮内容没传历史、没有有效响应 ID、指令未重发明确选择状态管理方式
previous_response_id 不存在是否禁存、过期、跨项目/服务、未实现状态能力手工回传历史或按实际状态策略重建
LangChain content 变成列表输出版本、Responses 内容块结构发生变化使用相应内容块解析,不强制假设字符串
推理信息“消失”第三方非标准字段未被适配器保留核实供应商专用集成及版本

12.3 错误与限流不是业务返回信封 ​

OpenAI 原始 HTTP 接口可能返回 400、401、403、404、429、5xx 等错误状态;Python SDK 会据此抛出相应异常。429 需要区分请求速率限制与额度问题,重试策略不能解决所有额度错误。

如果应用后端要求统一 code/message/data/traceId 信封,应由自己的全局异常处理层转换第三方错误,不能要求 OpenAI 自身也按应用约定返回 HTTP 200。日志中记录脱敏上下文和供应商 request ID,不把密钥、用户敏感数据或完整内部错误直接返回前端。

13 官方核对入口与版本边界 ​

以下链接用于追溯字段来源。OpenAI 的迁移指南、API Reference、模型说明和数据政策关注点不同;出现文档默认值或历史教程差异时,优先查具体模型与当前创建端点,并显式设置关键配置。

主题官方入口本文采用的用途
API 迁移总览Migrate to Responses官方推荐方向、消息与 Item、n、函数与输出格式差异
Chat 请求字段Create chat completionmessages、max_completion_tokens、finish_reason 等
Responses 请求字段Create a model responseinput、reasoning、text、store、include、状态及工具 Item
函数调用Function calling嵌套/扁平工具、call_id、执行回传、严格模式
结构化输出Structured OutputsJSON Schema 位置、JSON mode、拒绝及 Schema 限制
会话状态Conversation state手工历史、响应续接、Conversations、保留 reasoning Item
流式Streaming API responsesSSE、语义事件、Chat delta 与 Responses delta
推理Reasoning models推理预算、摘要、模型相关限制
数据政策Data controlsstore、日志、ZDR、会话和第三方数据边界
缓存Prompt caching缓存设置及新旧字段语义
LangChain 集成ChatOpenAI integration路由、max token 映射、输出格式、第三方扩展限制
LangChain 参数ChatOpenAI Reference参数定义与版本提示
LangChain 实现base.py当前字段转换与自动路由实现;主分支会变化

本文没有实测任何第三方平台,也没有验证用户账户的模型权限。字段结构已按官方资料核对;参数可用性、延迟、成本和输出质量仍需在固定模型、固定依赖版本及目标服务方上验证。未来更新时,应重点复核存储默认行为、推理 effort 取值、缓存配置、模型的工具支持,以及 LangChain 的自动路由与内容格式。