OpenAI Assistants API 迁移到 Responses API:路由架构指南
OpenAI Assistants API 将在 2026 年 8 月 26 日关闭。本迁移指南说明 Assistants 到 Responses 的对象映射、代码差异、状态迁移、工具循环变化,以及路由网关在切换前需要验证的内容。
OpenAI Assistants API 迁移到 Responses API:路由架构指南
OpenAI 的 Assistants API 将在 2026 年 8 月 26 日关闭。替代路径是 Responses API:Assistants 变为可版本化的 Prompts,Threads 变为 Conversations,Runs 变为 Responses,Run steps 变为输出 Items。如果你的生产智能体运行在路由网关之后,请把它当作架构迁移,而不是简单改 endpoint:先盘点 openai.beta.* 使用点,把新会话迁到 Responses,只在必要时转换历史 Thread,重新测试工具循环和流式输出,并且只在已验证的 chat/response 路径上启用 fallback 路由。
这篇文章面向已经知道截止日期、但需要落地迁移的团队。重点是代码级迁移和路由决策,同时严格限定产品能力表述:TheRouter 会通过已配置 provider 路由 OpenAI-compatible 请求,并且在实时产品路径支持的地方支持 provider/model routing 与 fallback。我们不承诺支持所有模型、零停机或保证最低价。
30 秒答案
- OpenAI 表示 Assistants API 已弃用,并会在 Responses API 达到功能对等后于 2026 年 8 月 26 日关闭 (OpenAI Assistants migration guide, 检索于 2026-06-21).
- 对象映射是:Assistants → Prompts、Threads → Conversations、Runs → Responses、Run steps → Items (OpenAI Assistants migration guide, 检索于 2026-06-21).
- OpenAI 不提供自动 Threads-to-Conversations 迁移;建议把新用户会话迁到 Conversations,并且只在必要时回填旧 Threads (OpenAI Assistants migration guide, 检索于 2026-06-21).
- Responses API 的 file search 是托管工具,使用 vector stores,并返回 file-search call items 以及带引用的 message items (OpenAI File search guide, 检索于 2026-06-21).
- 对 TheRouter 用户来说,要限定路由能力表述:仓库中存在
/v1/responses,并会把 Responses 形状的请求转换到 chat-compatible provider 路径;但 provider-specific hosted tools 必须按 provider 逐一测试后才能上线。
从 Assistants 到 Responses 到底变了什么
旧的 Assistants API 把行为、状态和执行都打包进 OpenAI 侧的持久化对象里。Responses API 把这几层拆开,让应用代码和路由网关有更清晰的边界。
| Assistants API | Responses 时代的对应物 | 迁移影响 |
|---|---|---|
| Assistant | Prompt | 把指令、工具 schema 和结构化输出预期迁移到可版本化的 prompt 或由应用自己管理的配置中。 |
| Thread | Conversation | Conversation 存储的是 item 流,而不仅是消息。新会话会获得新的 ID。 |
| Run | Response | 执行变成一次 response 请求;工具调用循环变成显式的应用逻辑。 |
| Run step | Item | Item 可以是消息、工具调用、工具输出、推理、引用以及其他泛化输出。 |
OpenAI 把 Responses 描述为更简单的模型:发送 input item、接收 output item,并可选地用 prompt 和 conversation 对象来存储配置和上下文 (OpenAI Assistants migration guide, 检索于 2026-06-21)。这种简化有利于路由,但也把责任转移到你的应用里:重试、裁剪、工具执行和灰度策略都需要刻意设计。
先找出所有受影响调用点
先做一次代码盘点。有风险的调用模式通常很容易 grep 出来:
grep -R "openai\.beta\.assistants\|openai\.beta\.threads\|threads\.runs\|assistant_id\|thread_id" \
app/ services/ workers/ scripts/
然后对每处用法分类:
- 新会话聊天流。 先迁这些,因为它们不需要转换历史。
- 长期存续的用户 Thread。 决定是把历史回填到 Conversation,还是通过 UX 引导关闭旧会话。
- 重度依赖工具的智能体。 显式重写工具循环,并补充集成测试。
- 检索 / file-search 流。 围绕 Responses 的 file search 重建向量库假设和引用处理。
- 后台任务。 用 response 生命周期处理替代轮询 Run,包括幂等和重试控制。
不要指望一次性完美转换。更稳妥的路径是双跑窗口:新会话走 Responses,旧 Thread 只读或按需回填,并做监控来对比回答质量、工具调用率、延迟和成本。
前后对比:最小聊天流程
Assistants 模式通常是创建或复用一个 Thread、追加一条消息、创建一个 Run、轮询它,然后再取回消息。Responses 把这些收敛成一次 response 调用,Conversation 状态可选。
之前:Assistants + Thread + Run
from openai import OpenAI
import time
client = OpenAI(api_key="<OPENAI_API_KEY>")
thread = client.beta.threads.create()
client.beta.threads.messages.create(
thread_id=thread.id,
role="user",
content="Summarize the deployment risks.",
)
run = client.beta.threads.runs.create(
thread_id=thread.id,
assistant_id="asst_...",
)
while run.status in ("queued", "in_progress"):
time.sleep(1)
run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
messages = client.beta.threads.messages.list(thread_id=thread.id)
print(messages.data[0].content[0].text.value)
之后:Responses API
from openai import OpenAI
client = OpenAI(api_key="<OPENAI_API_KEY>")
response = client.responses.create(
model="gpt-5.5",
input=[{
"role": "user",
"content": [{"type": "input_text", "text": "Summarize the deployment risks."}],
}],
)
print(response.output_text)
当你需要服务端上下文时,创建一个 Conversation 并在 response 调用中传入它的 ID。当你需要由应用自己管理上下文时,自行存储消息 / item 历史,并在每次调用时发送相关的窗口。真正重要的迁移决策不是语法,而是 Assistants 消失后谁来持有状态。
迁移 Threads 到 Conversations:不要过度迁移
OpenAI 明确表示不会提供把 Thread 迁移到 Conversation 的自动化工具,并建议把新的用户 Thread 迁到 Conversation,同时按需回填旧的 (OpenAI Assistants migration guide, 检索于 2026-06-21)。
一套实用策略:
- 不要回填已废弃的 Thread。 保留归档,只在用户重新打开会话时再迁移。
- 先回填文本。 把用户文本转成
input_text、助手文本转成output_text;图片、文件和工具输出留到第二轮处理。 - 单独保留元数据。 Thread 和 Conversation 的元数据并不是完整的审计日志。自己维护一张映射表:
old_thread_id、new_conversation_id、user_id、migrated_at、migration_version。 - 标记有损转换。 如果某个 Run step、工具输出或文件引用无法被精确表示,就记录下这个缺口,避免悄悄改变行为。
- 测试上下文窗口裁剪。 Conversation 可以存储 item 流,但你仍然需要一套关于成本、延迟和旧工具产物的策略。
一个轻量的回填骨架:
from openai import OpenAI
client = OpenAI(api_key="<OPENAI_API_KEY>")
def backfill_thread(thread_id: str):
items = []
for page in client.beta.threads.messages.list(thread_id=thread_id, order="asc").iter_pages():
for message in page.data:
content = []
for part in message.content:
if part.type == "text":
content.append({
"type": "input_text" if message.role == "user" else "output_text",
"text": part.text.value,
})
if content:
items.append({"role": message.role, "content": content})
return client.conversations.create(items=items)
把它当作起点,而不是完整的转换器。多模态输入、文件引用、code-interpreter 产物和工具输出都需要额外的映射和审查。
工具调用和 file search 最需要测试
Assistants 把大部分执行循环藏在 Run 背后。Responses 会返回 output item(包括工具调用 item),再由你的应用把工具结果送回去。这让行为更显式,有利于可观测性,但也意味着如果你不加幂等,重试逻辑可能会意外重放一次工具调用。
对于 file search,OpenAI 把 file_search 记录为由向量库支撑的 Responses API 托管工具。当模型调用它时,响应会包含一个 file_search_call output item 和一个带引用的 message item (OpenAI File search guide, 检索于 2026-06-21)。
工具迁移清单:
- 把工具 schema 从 Assistant 对象里移出来,放进可版本化的 prompt / 配置定义中。
- 给每个有外部副作用的工具调用加上幂等键。
- 记录每个工具调用 item 和工具结果 item,并带上 response ID。
- 决定哪些工具可以自动重试,哪些需要人工或应用确认。
- 对于 file search,验证向量库 ID、元数据过滤、引用渲染和最大结果数设置。
- 对于 web search、computer use、MCP、file search 等托管工具,测试你将在生产中使用的确切 provider 路径。
对路由网关的影响
这次迁移改变了路由决策所在的位置。在 Assistants 里,模型选择可能被嵌进 Assistant 对象。在 Responses 里,模型是 response 请求的一部分。这更契合网关路由,因为每个请求都可以携带 model ID、fallback 策略和 provider 约束。
对于 TheRouter 这类 OpenAI 兼容路由,把三层分开看:
| 层级 | 可安全声明的路由能力 | 仍需测试的部分 |
|---|---|---|
| 文本 response 请求 | 在实时 endpoint 支持该请求形态的地方,TheRouter 可以把 OpenAI 兼容请求路由到已配置的供应商。 | 针对你的 SDK 版本,请求 / 响应字段是否完全对齐。 |
| Fallback 链 | 在兼容的 chat-completion 路径上,TheRouter 支持 models 故障转移链 (TheRouter Model Fallbacks, 检索于 2026-06-21)。 | fallback 是否适合有状态的工具循环,以及所有候选是否都支持相同的工具。 |
| OpenAI 托管工具 | OpenAI 为 Responses 记录了 file search 等托管工具。 | 非 OpenAI 供应商或网关路径能否保留托管工具语义——不要想当然。 |
这种区分能避免一个常见的迁移错误:以为文本生成路由正确,就等于每个 OpenAI 托管的 Responses 功能也都能正确路由。托管工具和有状态会话是产品层行为,而不仅仅是模型推理。
前后对比:在已支持路径上通过 TheRouter 路由
如果你的 Responses 工作负载以文本为主,并且和你已经测试过的路由路径兼容,那么 base URL 的写法和其他 OpenAI 兼容迁移一致。
from openai import OpenAI
client = OpenAI(
base_url="https://api.therouter.ai/v1",
api_key="<THEROUTER_API_KEY>",
)
response = client.responses.create(
model="openai/gpt-5",
input="Classify this support ticket and return JSON.",
)
对于兼容的 chat-completion 流上的 fallback,TheRouter 记录了一个按优先级排序的 models 数组:TheRouter 先尝试第一个模型,当路由因宕机、限流或审核拒绝而失败时,重试下一个 (TheRouter Model Fallbacks, 检索于 2026-06-21)。为智能体使用 fallback 时要谨慎:所有 fallback 候选都应支持相同的输出格式和工具契约。
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://api.therouter.ai/v1',
apiKey: process.env.THEROUTER_API_KEY,
});
const completion = await client.chat.completions.create({
model: 'openai/gpt-5',
extra_body: {
models: ['anthropic/claude-sonnet-4.5', 'google/gemini-3.5-flash'],
},
messages: [{ role: 'user', content: 'Draft the migration test plan.' }],
});
Fallback 是一种韧性,而不是零停机保证。如果每个候选都失败,或者某个 fallback 模型无法满足相同的工具 / schema 契约,请求就应该显式失败。
8 月 26 日前的上线计划
以截止日期倒推排期:
| 时间窗 | 工作流 | 退出标准 |
|---|---|---|
| 现在 | 盘点 Assistants 用法,并按流量、营收和工具复杂度排序。 | 所有 openai.beta.* 调用点都已分配负责人。 |
| 接下来 1–2 周 | 把新会话迁到 Responses;保持旧 Thread 可读。 | 新用户会话不再创建 Thread。 |
| 接下来 2–4 周 | 只回填活跃的 Thread;迁移检索和工具循环。 | 主要工作流在 Conversation/Responses 下通过集成测试。 |
| 切换前 30 天 | 做双路监控和影子评测。 | 质量、延迟、成本和工具调用错误率都在阈值内。 |
| 最后 2 周 | 冻结 Assistants 改动并准备回滚。 | 除应急 fallback 外,Assistants 代码路径已停用。 |
回滚计划并不意味着永远退回 Assistants——这个 API 就要关闭了。它的意思是:在排查问题时,你可以临时把一部分流量路由到此前已验证的 Responses 实现、停用有风险的工具,或退回到更简单的聊天工作流。
路由团队测试清单
在宣布迁移完成之前,端到端测试以下场景:
- 会话连续性: 多轮上下文能跨请求和用户会话保留。
- 工具幂等: 重试不会重复产生外部副作用。
- 流式: 事件解析对文本增量、工具调用、完成事件和错误都能正常工作。
- 文件引用: 引用能正确渲染,并链接到预期的上传文件。
- Fallback 语义: fallback 候选共享相同的工具 schema、输出 schema 和安全约束。
- 用量核算: 正常响应和 fallback 响应的 token 用量与计费元数据都被记录。
- 供应商错误: 限流、供应商宕机、审核拒绝和不支持的工具错误被分别归类。
- 可观测性: 日志包含 response ID、conversation ID、实际服务的模型、fallback 位置和工具调用 ID。
更大迁移项目的内部链接
如果这是更大的供应商路由项目的一部分,请把本指南与以下内容搭配阅读:
- 从 OpenAI SDK 迁移到 TheRouter——base URL、API key 和 model ID 迁移。
- LLM API fallback 路由指南——fallback 链设计。
- OpenAI prompt caching 成本优化指南——围绕重复上下文的成本控制。
- OpenAI 供应商页 与 OpenAI GPT-5 模型页——当前可路由的模型可用性。
FAQ
Responses API 只是换了个名字的 Chat Completions 吗?
不是。Responses 使用 input 和 output item、支持 Conversation,并暴露 file search 等托管工具。Chat Completions 仍然是更简单的「消息进 / 消息出」接口。
8 月 26 日之后还能继续用旧的 Thread ID 吗?
不能。请按照 Assistants API 的 Thread 和 Run endpoint 会在关闭之日停止工作来规划。如果你要回填活跃会话,请自己保存旧 Thread ID 到新 Conversation ID 的映射。
是否每个 Assistants 工作负载都该用 Conversation?
不一定。无状态或短生命周期的工作流,用由应用自己管理、每次传入 Responses 调用的历史可能更简单。当供应商托管的 item 历史带来的复杂度下降超过它引入的锁定成本时,再用 Conversation。
fallback 路由能在会话中途切换供应商吗?
有时可以,但不要想当然地认为它对重度依赖工具的智能体是安全的。fallback 候选必须共享相同的工具契约、输出 schema 和上下文假设。在为生产智能体会话启用 fallback 之前,先测试多轮和工具调用行为。
来源
- OpenAI Assistants migration guide, 检索于 2026-06-21.
- OpenAI Responses API reference, 检索于 2026-06-21.
- OpenAI File search guide, 检索于 2026-06-21.
- TheRouter Model Fallbacks, 检索于 2026-06-21.
- TheRouter OpenAI SDK migration guide, internal reference.