在一把 key 上把 Assistants API 的会话改从 Chat Completions 端点重放
解释如何把保存在 Assistants API 中的 thread、工具调用与文件引用,转换为标准的 chat completions 请求,并验证不同后端模型(Claude、GPT、DeepSeek 等)的兼容性。
为什么需要重放
许多聚合站只暴露 OpenAI 兼容的 Chat Completions 端点,而不实现 Assistants API 的对象模型(assistant、thread、run、message、file)。如果你之前用 Assistants API 保存了会话历史,并希望在一个 API key 下切换不同模型(比如从 GPT 切到 Claude 或 DeepSeek),就需要把 thread 里的数据“压平”成标准的 messages 数组,再通过 chat completions 端点重放。
理解对象模型的差异
Assistants API 把对话组织为:
- Thread:一个会话容器,包含多条 Message。
- Message:某条消息,有 role(user/assistant)、content(可能包含文本、图片、文件引用等)。
- Run:一次执行,可能包含 tool_calls 和 tool 输出。
而 Chat Completions 端点只接受一个扁平的 messages 数组,每条消息的 role 为 system、user、assistant 或 tool,content 为字符串或内容块数组。关键区别在于:
- 没有 thread 对象,需要自己维护消息顺序。
- 工具调用以 assistant 消息的
tool_calls字段和后续的 tool 角色消息表示。 - 文件引用需要转换为可访问的 URL 或内联文本。
分步转换方法
1. 提取 thread 中的所有 message
按时间顺序获取 thread 中的 messages。注意只保留 role 为 user 和 assistant 的消息(除非你显式需要 system 消息)。每条 message 的 content 可能是一个数组,包含文本、图片或文件附件。
2. 把 content 数组拍平为文本或内容块
对于文本内容,直接提取文本。对于图片,如果后端支持多模态(如 GPT-4V),可以转换为 imageurl 内容块;否则替换为占位文本(如 [图片])并记录日志。对于文件引用(fileid),需要先通过文件下载 API 获取内容或生成可访问链接。如果文件是文本类,可以内联为文本;如果是二进制,可上传到自己的存储并生成 URL,再以 image_url 或文本描述形式传入。
3. 处理工具调用
Assistants 的 run 步骤中,工具调用记录在 assistant 消息的 tool_calls 字段,工具结果在 tool 角色的消息中。转换时:
- 把带
toolcalls的 assistant 消息原样保留(保留toolcalls数组)。 - 把每个工具结果作为一条 role 为
tool的消息,携带toolcallid和 content。 - 注意工具调用的 id 在转换后保持唯一,避免与不同后端冲突。
4. 合并为 messages 数组
按时间顺序拼接所有转换后的消息。如果原 thread 有 system 指令(如 assistant 的 instructions),可以提取为第一条 system 消息。最终得到一个标准的 messages 数组,可以直接发给 chat completions 端点。
逐个后端确认兼容性
不同模型后端对消息格式和工具调用的支持程度不同。你需要逐个确认:
- GPT 系列:完全支持 messages 数组、tool_calls 和 tool 消息,多模态内容也支持。
- Claude 系列:通过兼容层通常支持 system、user、assistant 消息,工具调用格式类似但字段名可能略有差异(如
tooluse与toolcalls)。建议先发送纯文本消息测试,再逐步加入工具调用。 - DeepSeek、Qwen、GLM、Kimi:多数提供 OpenAI 兼容接口,但工具调用和图片支持可能有限。可以先用纯文本 messages 测试,确认基础对话正常;若需要工具调用,检查返回中是否有
tool_calls字段。 - 通用验证方法:构造一个最小 messages 数组(一条 user 消息),逐个模型发送,确认返回 200 且内容合理。然后逐步加入 assistant 消息、tool_calls 和 tool 结果,观察是否报错或忽略字段。
注意事项
- 文件引用:Assistants 的 file_id 不能直接用于 chat completions,必须转换为 URL 或文本。
- 工具调用 id:不同后端可能要求 id 格式一致,建议在转换时重新生成短 id 或保留原 id 但确保唯一。
- 消息顺序:严格按时间顺序,确保 tool 消息紧跟在对应的 assistant 消息之后。
- 内容截断:长 thread 可能超出上下文窗口,需要截断或摘要,但不要破坏工具调用的配对关系。
- 测试策略:先用简单文本会话验证连通性,再逐步增加复杂度,避免一次性转换全部历史导致难以定位问题。