← 全部文章

OpenAI Assistants API 8 月 26 日关停:最终迁移清单

OpenAI Assistants API 将于 2026 年 8 月 26 日硬关停,距今仅剩 14 天。本文给出一份可直接交给团队执行的迁移清单,涵盖 Assistants 到 Responses 的对象映射、tool loop 重写、Thread 导出脚本、Prompts 二次迁移陷阱,以及切流前应跑通的集成测试。

· TheRouter

OpenAI Assistants API 8 月 26 日关停:最终迁移清单

Assistants API 将在 2026 年 8 月 26 日硬关停,距离今天只剩 14 天。届时所有 openai.beta.assistants.* 和 openai.beta.threads.* 调用都会报错,OpenAI 没有宣布过延期(OpenAI deprecations 页面,2026-08-12 检索)。

我们在六月发过一篇概念性迁移指南。这篇文章是它的操作版,一份可以直接发给团队照着做的清单,每一步都带验证命令或具体测试。

8 月 27 日之后会发生什么

关停之后,Assistants API 的所有端点返回 HTTP 错误。存储在服务端的 Thread 历史通过 Assistants API 不再可访问。如果在截止日期前没有导出 Thread 消息,那些数据就没了。OpenAI 没有承诺关停后提供数据导出窗口(OpenAI Assistants 迁移指南,2026-08-12 检索)。

Responses API 是替代方案。Chat Completions 仍然受支持,不受本次关停影响(Migrate to Responses API 指南,2026-08-12 检索)。

对象映射表

动手改代码之前先理清命名变化。

Assistants APIResponses API 对应物变化说明
AssistantPrompt(仅 dashboard 创建,同样已宣布 11 月 30 日关停)配置搬进代码库或 Prompt 对象
ThreadConversation存储 item 流(消息、tool call、输出),而非纯消息
RunResponse同步请求-响应,简单调用不需要轮询
Run stepItem类型联合体,包括 message、tool_call、tool_call_output、reasoning
openai.beta.threads.messages.create()Response 请求中的 input items消息成为请求体的一部分
openai.beta.threads.runs.create()openai.responses.create()一次调用,不再需要 create + poll

来源见 OpenAI Assistants 迁移指南,2026-08-12 检索。

Prompts 二次迁移陷阱

OpenAI 的迁移指南建议在 dashboard 里把 Assistant 转换成 Prompt。然而 Prompt 对象本身也已宣布弃用,关停日期定在 2026 年 11 月 30 日(OpenAI deprecations 页面,2026-08-12 检索)。

如果现在把 Assistant 迁移成 Prompt,三个月后还得再迁一次。更稳妥的做法是把 Assistant 的配置(instructions、tool schemas、temperature、model 选择)直接搬进应用代码或版本管理下的配置文件,跳过 Prompts 这一中转。

清单:14 天完成切换

第 1 步 — 盘点所有 Assistants 调用点

在代码库里跑一遍 grep。

grep -rn "openai\.beta\.\(assistants\|threads\)" \
  --include="*.py" --include="*.ts" --include="*.js" \
  app/ services/ workers/ scripts/ lib/

对每个匹配项做分类。

  • A. 新会话聊天。 不依赖 Thread 历史,优先迁移。
  • B. 长生命周期 Thread。 需要在关停前导出历史,安排 backfill。
  • C. 重度 tool 使用的 Agent。 需要显式重写 tool loop,工作量最大。
  • D. File search / code interpreter。 验证 Responses API 的对应工具能覆盖你的用例。

第 2 步 — 立即导出 Thread 历史

不要拖。Thread 在关停后不可访问。导出所有活跃 Thread。

import json
from openai import OpenAI

client = OpenAI()

def export_thread(thread_id: str) -> list[dict]:
    messages = []
    for page in client.beta.threads.messages.list(
        thread_id=thread_id, order="asc"
    ).iter_pages():
        messages.extend(page.data)
    return [m.model_dump() for m in messages]

thread_ids = ["thread_abc123", "thread_def456"]
for tid in thread_ids:
    data = export_thread(tid)
    with open(f"export_{tid}.json", "w") as f:
        json.dump(data, f, indent=2)
    print(f"Exported {len(data)} messages from {tid}")

验证方法 确认每个导出文件包含预期数量和内容的消息。

第 3 步 — 新会话走 Responses API

最简单的迁移路径是停止创建新的 Assistant 和 Thread,新用户对话直接走 Responses API。

迁移前(Assistants)

thread = client.beta.threads.create()
client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Explain API routing"
)
run = client.beta.threads.runs.create_and_poll(
    thread_id=thread.id,
    assistant_id="asst_xxx"
)
messages = client.beta.threads.messages.list(thread_id=thread.id)
answer = messages.data[0].content[0].text.value

迁移后(Responses)

response = client.responses.create(
    model="gpt-5.5",
    instructions="You are a helpful API routing expert.",
    input="Explain API routing"
)
answer = response.output_text

多轮对话可以传 previous_response_id 或使用 Conversations。

resp1 = client.responses.create(
    model="gpt-5.5",
    input="What is API routing?"
)

resp2 = client.responses.create(
    model="gpt-5.5",
    input="How does fallback work?",
    previous_response_id=resp1.id
)

第 4 步 — 重写 tool loop

Assistants 通过轮询 Run 状态来执行 tool。Responses API 把 tool 执行交给你的代码,你收到 tool_call item,自己执行,再把结果作为 tool_call_output item 送回去。

迁移前(Assistants tool loop)

run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id="asst_xxx"
)
while run.status in ("queued", "in_progress"):
    time.sleep(1)
    run = client.beta.threads.runs.retrieve(
        thread_id=thread.id, run_id=run.id
    )
if run.status == "requires_action":
    tool_calls = run.required_action.submit_tool_outputs.tool_calls
    outputs = [execute_tool(tc) for tc in tool_calls]
    run = client.beta.threads.runs.submit_tool_outputs_and_poll(
        thread_id=thread.id,
        run_id=run.id,
        tool_outputs=outputs
    )

迁移后(Responses tool loop)

response = client.responses.create(
    model="gpt-5.5",
    instructions="You are a helpful assistant.",
    input="What is the weather in Tokyo?",
    tools=[{
        "type": "function",
        "name": "get_weather",
        "description": "Get current weather",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {"type": "string"}
            },
            "required": ["location"]
        }
    }]
)

for item in response.output:
    if item.type == "function_call":
        result = execute_tool(item.name, json.loads(item.arguments))
        response = client.responses.create(
            model="gpt-5.5",
            previous_response_id=response.id,
            input=[{
                "type": "function_call_output",
                "call_id": item.call_id,
                "output": json.dumps(result)
            }]
        )

第 5 步 — 把关键 Thread 历史回填到 Conversations

用第 2 步的导出数据填充 Conversations,保持用户对话的连续性。

import json

def backfill_thread_to_conversation(export_path: str) -> str:
    with open(export_path) as f:
        messages = json.load(f)

    items = []
    for m in messages:
        role = m["role"]
        for content_block in m["content"]:
            if content_block["type"] == "text":
                content_type = (
                    "input_text" if role == "user" else "output_text"
                )
                items.append({
                    "role": role,
                    "content": [
                        {"type": content_type, "text": content_block["text"]["value"]}
                    ]
                })

    conversation = client.conversations.create(items=items)
    return conversation.id

脚本改编自 OpenAI Assistants 迁移指南,2026-08-12 检索。

验证方法 回填完成后,通过该 Conversation 发一条测试消息,确认模型能引用导入的历史上下文。

第 6 步 — 处理 file search 和 code interpreter

两个工具在 Responses API 中都存在,但接口有变化。

  • File search vector store 仍然有效。Responses API 返回 file_search_call item 和带 annotation 的 message item,结果直接出现在 response output 中,不再需要轮询 Run step(OpenAI File search 指南,2026-08-12 检索)。
  • Code interpreter 返回 code_interpreter_call item,沙箱执行在服务端完成,结果包含文本输出和生成的文件。

两个工具都要用已知查询测一遍,再上生产。

第 7 步 — 跑集成测试

测试用例至少覆盖以下场景。

  1. 简单文本生成(无 tool)
  2. 多轮对话,验证 previous_response_id 正确传递上下文
  3. 至少一个 function 的 tool calling
  4. 已知 vector store 的 file search
  5. SSE streaming 事件处理
  6. 错误处理(rate limit、无效 model、格式错误)

新旧通路影子并行 24 到 48 小时,对比延迟、输出质量和报错率,确认没问题再切。

第 8 步 — 用 feature flag 切流

把 Responses 迁移放在 feature flag 后面,按以下节奏放量。

  1. 先给内部和 staging 环境开启
  2. 生产 10% 流量,观察 24 小时
  3. 放量到 50%,再到 100%
  4. 稳定运行一周后删除 Assistants 代码

在 8 月 26 日之前保留 Assistants 代码路径作为回滚选项。过了那天它已经无法工作,直接移除。

Azure OpenAI 用户

Azure OpenAI 确认了同样的 2026 年 8 月 26 日关停日期(Microsoft Learn,2026-08-12 检索)。迁移路径相同。

Azure 迁移中需要额外关注以下几点。

  • Deployment name 不变,API version 需要更新
  • 确认你使用的 Azure API version 支持 Responses 端点
  • Azure Content Safety 过滤对 Responses 的生效方式与 Assistants 一致

路由网关注意事项

如果你通过 TheRouter 这样的网关转发 OpenAI 请求,需要专门测试以下路径。

  • /v1/responses 端点 确认网关正确转发 Responses 格式的请求
  • Streaming Responses 的 SSE 事件格式和 Chat Completions 不同
  • Tool call function_call 和 function_call_output item 的类型与 Chat Completions 的 tool_calls 不同
  • Fallback routing 如果网关在 OpenAI 不可用时 fallback 到其他供应商,目标供应商也必须支持 Responses API 的请求格式,或者网关需要做格式转换

TheRouter 通过已配置的供应商路由 OpenAI 兼容请求,在线上产品路径支持的范围内提供 provider/model 路由和 fallback。具体的 model 和 tool 组合在切生产之前需要自行测试。

  1. 替换三个值,不是三个 SDK。在现有 OpenAI 客户端里改 api_key、base_url、model。请求与响应代码保持不变。
  2. 显式映射 model ID。目标供应商的 model id 几乎不会和 OpenAI 完全一致。 在业务代码之外维护一份 { openai_id: target_id } 映射。
  3. 验证流式格式。SSE 分片必须遵循 OpenAI 的 data: {...} + data: [DONE] 契约。切生产前先跑一次流式调用。
  4. 检查限流响应头。部分供应商不返回 x-ratelimit-*。 在包装层 做缺省兜底,缺头不要崩。
  5. 留回滚路径。用 feature flag 切流;新旧 endpoint 影子并行 24 小时,再正式切换。

时间线汇总

日期事件
2025 年 8 月 26 日Assistants API 弃用公告
2026 年 6 月 3 日可复用 Prompts 弃用公告
2026 年 8 月 26 日Assistants API 硬关停
2026 年 11 月 30 日可复用 Prompts 关停

常见问题

问 Chat Completions 也会关停吗? 不会。Chat Completions 仍然受支持。Responses API 推荐用于新项目,但 Chat Completions 没有被弃用(Migrate to Responses API 指南,2026-08-12 检索)。

问 能申请延期吗? OpenAI 表示开发者可以通过购买专用容量来保持访问,需联系销售团队了解详情(OpenAI deprecations 页面,2026-08-12 检索)。目前没有公开的延期公告。

问 我的 vector store 怎么办? Vector store 仍然可以访问。Responses API 的 file search 工具使用相同的 vector store 基础设施,不需要重新上传文件。

问 应该用 Conversations 还是在客户端管理状态? 如果会话生命周期短(单次任务,不需要跨天连续性),用 previous_response_id 在客户端管理状态。如果用户会跨天回到同一个对话继续聊天,用 Conversations 做服务端持久化。

问 Python / Node SDK 需要更新吗? 两个官方 SDK 都已支持 client.responses.create()。更新到最新版本即可。openai.beta.* 命名空间在 8 月 26 日后将停止工作。

来源

帮助与联系