丹尼拉(Dayfing)
返回文章列表
3,369 字12 分钟

Assistants API 于 2026 年 8 月 26 日停用:迁移到 Responses API 的完整指南

Assistants API 已于 2026 年 8 月 26 日正式停用,当前无法继续使用。生产应用需要把生成、对话状态、工具和数据流程迁移到 Responses API。稳妥做法是先盘点所有 Assistant、Thread、Run 和工具,再把行为重建为 Responses 配置,从应用自己保存的记录导入历史,最后在切换流量前验证输出和副作用。停用日期及对象对应关系以 OpenAI 官方 Assistants 迁移指南 为准。

2026 年 8 月 26 日停用后发生了什么

这次变化涉及端点和对象,不是模型改名。停用后,对旧 Assistants 资源的调用不再是临时警告。创建或读取 /v1/assistants、/v1/threads、/v1/threads/messages 或 /v1/threads/runs 的代码都需要替换路径。不要用旧 API 开始新集成,也不要设计假设旧对象仍可查询的回退方案。

OpenAI 当前给出的对应关系如下:

Assistants API Responses 平台 实际含义
Assistant Prompt 或请求配置 将模型、指令、工具声明和输出规则放入可版本控制的配置。当前指南允许在控制台中从 Assistant 创建 Prompt,但同时提示可复用 Prompt 对象正在弃用。
Thread Conversation 或应用历史 Conversation 保存包括消息、工具调用和工具结果在内的项目。也可以在自己的数据库中保存状态并发送所需项目。
Run Response Responses 请求接收输入项目并返回输出项目。独立的 Run 对象和轮询循环不再是核心抽象。
Run step Item 处理带类型的 message、function_call、function_call_output 和 reasoning 项目,不要假设每个结果都是消息。

请同时阅读 Responses API 迁移指南。该指南将 Responses 列为新项目推荐的 API,并说明它与 Chat Completions 的差异以及输入和输出结构。

新的工作模型

过去,Assistant 是服务器端持久化的配置集合,Thread 保存消息,Run 在 Thread 上执行 Assistant。Responses 把这些职责分开。请求指定模型、指令、输入和工具,返回的 Response 带有类型信息,output 是按顺序排列的项目列表。

这样,应用可以明确负责编排。代码决定如何识别用户、发送多少历史、允许哪些工具调用、如何验证工具参数、如何处理失败重试,以及何时需要人工批准。OpenAI 仍然提供状态管理选项,但这些选项需要由应用选择,不是隐含的 Assistant 生命周期。

状态通常有三种策略:

  1. 使用无状态请求,在每一轮传递有界的输入项目。这样由自己的数据库控制保留期限和历史裁剪。
  2. 使用 previous_response_id 串联对话轮次。对话状态文档 展示了这种方式。它适合短流程,但此前的输入 token 仍计入费用,保存方式也必须符合自己的政策。
  3. 创建 Conversations API 对象,并将其 ID 传给 Responses。Conversation 有持久标识符,可跨会话、设备和任务使用。其项目会一直保存到删除,因此这个 ID 代表保留的应用状态,不是隐私开关。

每个产品流程选择一种策略。不要在没有明确权威来源的情况下,同时使用本地重建的记录、Conversation 和 previous_response_id 链。重复轮次可能改变模型行为、增加费用,并让删除请求更难执行。

修改代码前先盘点依赖

为每个 Assistant ID 和每条生产会话路径建立迁移记录。记录模型、指令、默认参数、工具 schema、vector stores、文件、Code Interpreter 的使用情况、响应格式、元数据、保留要求,以及所有轮询 Run 状态的代码。搜索范围不能只包括后端,还要检查后台任务、管理脚本、控制台、测试和分析消费者。文本响应成功,不代表 file search、结构化输出、流式传输或有副作用的函数仍然具有相同表现。

把行为与已存数据分开。指令和工具声明可以从配置中重建。Thread 消息和上传文件是数据资产,需要导出或由应用保留的副本。如果系统从未在 Threads 之外保存用户消息,应在删除任何内容前确定处理办法。停用后的指南指出,获取旧 Thread 消息的调用已经不能使用,应改用应用已经保存的消息。

重建基本请求

对于纯文本交互,用一次 Responses 调用替换 beta Thread 和 Run 序列。input 字段可以是字符串,也可以是类似消息的项目列表。将稳定的系统行为放到 instructions,把用户文字放到 input。普通文字可以从 response.output_text 读取,但只要可能出现工具或非文本项目,就应检查 response.output。

from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-5.6",
    instructions="清晰回答,并引用提供的记录。",
    input=[{"role": "user", "content": "总结订单状态。"}],
    store=False,
)

print(response.output_text)

新的端点是 /v1/responses,SDK 方法是 client.responses.create。不要原样保留 messages 请求字段、choices[0].message.content 响应路径或从 Run 复制的轮询循环。如果需要保存 Responses,应当把它作为明确的设计决定。数据控制文档 当前说明,Responses 的应用状态默认或在 store 为 true 时保留 30 天,并有文档列出的例外。

正确保留对话历史

如果应用拥有对话记录,应将它规范化为 Responses 输入项目。用户文本转换为 input_text,助手文本转换为 output_text,图像转换为带 URL 或文件引用的 input_image。保持时间顺序,并保留理解旧轮次所需的工具调用和工具结果配对。

下面的示例使用应用拥有的历史创建持久 Conversation,然后发送新一轮:

from openai import OpenAI

client = OpenAI()

conversation = client.conversations.create(
    items=[
        {
            "role": "user",
            "content": [{"type": "input_text", "text": "我的订单号是 1842。"}],
        },
        {
            "role": "assistant",
            "content": [{"type": "output_text", "text": "我可以查询订单 1842。"}],
        },
    ]
)

response = client.responses.create(
    model="gpt-5.6",
    conversation=conversation.id,
    input=[{"role": "user", "content": "它准备好发货了吗?"}],
)

print(response.output_text)

停用后不要通过 threads.messages.list 迁移。停用后的系统应使用应用保留的记录,导入前核对用户身份、删除请求、地区规则、附件和时间戳。必须验证客户端提供的 Conversation ID 属于已认证用户。

迁移工具和函数调用

Responses 工具在请求中声明。web search、file search、computer use、Code Interpreter、图像生成和远程 MCP 等内置工具见 Using tools 指南。自定义函数仍需由应用实现。模型可以请求函数,但不能替应用授权或执行业务操作。

控制循环现在由应用明确管理。发送第一个请求,检查 response.output 中的 function_call 项目,验证并执行每个允许的函数,追加模型输出项目和 function_call_output 项目,然后发送下一次请求。使用推理模型时,必须保留与工具调用一起返回的 reasoning 项目,具体方式见 function calling 指南

import json
from openai import OpenAI

client = OpenAI()

tools = [
    {
        "type": "function",
        "name": "lookup_order",
        "description": "返回已认证用户拥有的订单状态。",
        "parameters": {
            "type": "object",
            "properties": {
                "order_id": {"type": "string"},
            },
            "required": ["order_id"],
            "additionalProperties": False,
        },
        "strict": True,
    }
]

input_items = [{"role": "user", "content": "我的订单 1842 在哪里?"}]

response = client.responses.create(
    model="gpt-5.6",
    tools=tools,
    input=input_items,
)

input_items += response.output
for item in response.output:
    if item.type == "function_call" and item.name == "lookup_order":
        arguments = json.loads(item.arguments)
        result = {"order_id": arguments["order_id"], "status": "packed"}
        input_items.append(
            {
                "type": "function_call_output",
                "call_id": item.call_id,
                "output": json.dumps(result),
            }
        )

response = client.responses.create(
    model="gpt-5.6",
    tools=tools,
    input=input_items,
)

print(response.output_text)

strict 模式有助于让调用遵守 schema,但不会授予权限。在应用代码中验证认证用户、订单所有权、范围、枚举值和业务状态。对收费、删除、发布或发送等操作使用幂等键或事务。执行失败时返回结构化工具错误,不要伪造成功。限制工具轮次,并在敏感值脱敏后记录调用、结果和批准决定。

保留结构化输出

如果旧 Assistant 使用 JSON mode 或响应 schema,请将它映射到 Responses 的 text.format 配置,不要原样复制 response_format。结构化输出指南说明了当前 schema 结构和 SDK 辅助方法。在写入数据库、显示界面或交给其他工具前验证解析结果。合法 JSON 仍可能包含错误订单号、危险指令或不完整的业务决定。

保持 schema 小型化,并与 Prompt 或请求配置一起版本控制。声明必填字段,在严格模式要求时设置 additionalProperties=false,测试拒绝、不完整响应和 schema 演进。仅凭 JSON 对象存在,不能判断操作成功。

迁移后的安全和数据处理

迁移改变了状态边界,应按安全架构变化进行评审。API key 只放在可信服务器,验证每个会话,并将 Conversation 或本地记录绑定到服务器侧用户身份。不要把密钥、授权 token 或无限制数据库查询放进指令和工具说明。

每个请求只提供必要的最小工具集。分离只读函数和写入函数,对重要操作要求明确确认,并独立于模型输出执行授权。把检索到的文件、网页和远程 MCP 响应视为不可信输入。远程 MCP 服务有自己的保留政策,托管的 Code Interpreter 容器在活动期间可能保存临时状态。数据控制指南列出了这些端点级限制。

每条流程选择 store、Conversation 或应用自己保存的历史。文档说明,未经明确同意,API 数据不会用于训练 OpenAI 模型,但这不替代对保留、访问、删除、区域处理和供应商的审查。store=false 不是通用删除政策,也不会让 Conversation 变成临时状态。

限制输入和输出,在适用时使用审核,并为高影响决定安排人工检查。OpenAI 安全最佳实践明确建议针对提示注入做对抗测试,使用审核并加入人工监督。记录请求 ID 和事件类型,但按政策隐藏用户内容、凭据、函数参数和工具结果。

常见迁移错误

旧端点返回错误

2026 年 8 月 26 日后,对 Assistants 的请求就是迁移缺陷。删除旧客户端路径,不要反复重试。如果后台 worker 还在轮询 Run ID,应部署 Responses worker,并把 thread_id 和 run_id 字段换成会话及 Response 标识符。

响应为空或解析器崩溃

Responses output 是异构项目列表。output_text 适合普通文本,但工具调用、拒绝或不完整响应需要检查状态和项目类型。不要按索引取第一个项目并假设它一定是消息。

模型重复上下文或费用上涨

选择一种状态策略并制定裁剪规则。previous_response_id 不会让此前输入 token 变成免费,同时把同一记录放入 Conversation 和 input 会重复上下文。在 staging 中使用真实的长对话测量输入和输出 token。

函数执行两次

重试、并行工具调用、网络超时和重新连接都可能重放调用。为每个有副作用的操作使用由 call ID 和认证用户组成的幂等键,并在执行前检查业务事务。模型返回成功消息,不代表函数只提交了一次。

旧文件或检索结果消失

独立于 Thread 历史盘点 vector stores、文件 ID、过期规则和权限。重建受支持的检索路径,验证每个租户的访问,并测试引用和空结果。转换 Assistant 配置不等于复制文件数据。

迁移检查清单

对每条生产流程按顺序执行:

  1. 记录旧 Assistant、Thread、Run、文件、vector stores、工具、Prompt 和元数据依赖。
  2. 将面向用户的指令和工具 schema 放入版本控制的配置。
  3. 选择 Responses 模型,并确认工具、多模态输入、结构化输出和区域可用性。
  4. 选择唯一状态策略:无状态项目、previous_response_id 或 Conversations。
  5. 将 messages 映射为 input,将 choices 映射为 output,将文本读取映射为 output_text。
  6. 重写函数定义,实现明确且有上限的工具循环。
  7. 分别重建 file search、Code Interpreter、web search、MCP、streaming 和结构化输出。
  8. 只导入应用拥有的历史,保留顺序、身份、附件、工具调用和删除语义。
  9. 加入授权、输入限制、审核、幂等性、脱敏日志以及副作用的人工批准。
  10. 运行基准对话、对抗提示、工具错误、重试、拒绝、长上下文和并发会话测试。
  11. 比较回答、引用、工具效果、token、延迟、错误和保留行为。
  12. 在 feature flag 后发布,停止旧 worker,监控 Responses 错误,并保留不依赖停用 API 的回退路径。
  13. 确认导出、审计和支持流程后,再删除旧 Assistant 代码和密钥。

系统设计见生产环境 AI 智能体架构指南,回归与行为检查见AI 智能体评估指南

如何判断迁移完成

当没有生产路径依赖 Assistants,每个会话有状态所有者,每次工具调用获授权且能处理重放,Responses 输出有测试时,迁移才算完成。保留模型、Prompt、schema、保留和失败记录。模型变化时重新审查并评估。

更多文章