Anthropic 于 2026 年 11 月 2 日将 message threads 推入公测。这个功能最容易被误解的地方是:对于 500K–1M token 的请求,首 token 延迟中位数大约降低 35%,但 token 账单一分不会少。对长时间运行的 Agent 来说,它解决的是请求传输效率,而不是推理成本,而且闲置超过 5 分钟就会失效。
请求更快,账单不变:threads 到底改变了什么
Message threads 是 Messages API 的临时服务端对话状态,于 2026 年 11 月 2 日开启公测。首次请求通过 thread: { "type": "create" } 发送完整历史,后续请求则使用 thread: { "type": "continue" },只提交新增消息和 previous_message_id。根据 Anthropic 官方公告和平台文档,状态保存在加密内存中,不会写入磁盘;闲置 5 分钟后过期,并且最迟会在最后一次使用后 1 小时被删除。
线程中的每个请求都必须带上 beta 请求头 anthropic-beta: message-threads-2026-08-12。价格和速率限制都没有变化:Claude 每一轮仍会读取完整对话,因此输入和输出 token 的费用不变,只是上传的字节数大幅减少。
“嗯,这确实不错,但它并不会降低 token 成本 :( Claude 每一轮仍会读取完整对话,token 消耗保持不变。” —— @_navicstein,回复官方发布帖
官方公告称,在 500K–1M token 的请求中,TTFT 中位数大约降低 35%,但没有任何 token 折扣。
一句话说清 threads 和 prompt caching 的区别
Threads 减少的是你需要发送的内容;prompt caching 减少的是需要按全价付费的内容。Threads 不会自动缓存任何东西,你仍然需要设置 cache_control 断点。下面关于两者如何配合的细节来自实现分析:每次 continuation 都要保留顶层 cache_control,缓存读取价格为基础输入价格的 0.1 倍(Claude Opus 5.5 和 Sonnet 5.5 为 0.05 倍)。
别把它和 managed-agent session threads 混为一谈
搜索结果里经常会把两种“threads”混在一起。本文讨论的 Messages API message threads,是一种用于减少请求体大小的临时机制,没有 list/read/delete API。Managed-agent session threads(GET /v1/sessions/{session_id}/threads/{thread_id})则是 Anthropic managed-agents API 中的执行线程,提供 list、retrieve、archive 端点。如果文档提到子线程、事件流或归档,那你看到的就不是本文对应的 API。需要确认具体接口时,请查看session threads API 参考。
线程实际如何推进:创建、继续与过期
实际使用中,线程是一个只追加、不回溯的链路:创建时提交完整上下文,继续时提交增量,丢失后重新播放。它没有分支、编辑、回滚或检查 API。每个响应都会返回一个新的 id,而每个 id 只能被继续使用一次。本节中的字段和错误规则以平台文档为准,具体实现细节参考实现分析。
创建线程时需要提交完整信息:messages、system 和 tools,以及:
{
"model": "claude-opus-5-5",
"system": "You are a support agent for Acme. Keep replies short.",
"messages": [{ "role": "user", "content": "Hi! I have a question about an order." }],
"thread": { "type": "create" }
}
继续请求只携带新增内容,通常是一条用户消息或若干 tool_result 块:
{
"model": "claude-opus-5-5",
"messages": [{ "role": "user", "content": "How long does standard shipping usually take?" }],
"thread": { "type": "continue", "previous_message_id": "msg_xxx_from_create" }
}
继续时不要发送 system 和 tools——即使写成 "system": null 也会触发 400。使用流式响应时,要等到 message_stop 后再继续;可用于 continuation 的 ID 会在 message_start 中返回。
线程中途哪些字段能改
Anthropic 会对创建请求中的部分字段生成指纹。修改被指纹保护的值后,会返回 thread_fingerprint_mismatch,并强制你创建新线程。
| 分组 | 示例 | 继续请求时的规则 |
|---|---|---|
| 仅创建时使用 | system、tools | 绝不能重新发送;发送 null 同样会失败 |
| 固定字段 | model、tool_choice、thinking、mcp_servers、context_management、output_config、容器 skills、顶层 cache_control 处理方式 | 必须保持完全一致 |
| 可自由调整 | max_tokens、stop_sequences、stream、metadata、service_tier | 每一轮都可以修改 |
| 每次都要重新发送 | MCP server URL / auth token、container ID | 不会存储在服务端,使用时必须每次带上 |
使用 extended-thinking 模型时要格外小心:修改 system 或 tools,可能会使之前的 thinking / redacted_thinking 块失效。如果线程过期后进行完整重放返回 400,不要原样重试,而应从重放历史中移除过期的 thinking 块。
5 分钟过期规则,以及必须实现的重放机制
把 threads 当成“尽力而为”的临时状态来用:完整历史、system、tools 和文件引用都要保存在本地,因为只有下一次 continuation 成功后,才能确认服务端确实保留了状态。文件是按引用保存的;如果线程进行期间文件被删除,后续 continuation 就会失败。
每次成功存储响应后,过期计时都会重置。闲置 5 分钟后,下一次 continue 会返回 404,此时必须把完整对话作为新的 create 请求重新发送。数据最迟会在最后一次使用后 1 小时被删除。
| HTTP | 错误代码 | 发生了什么 | 应该怎么做 |
|---|---|---|---|
| 404 | thread_not_found | 线程已过期、未被存储、使用了错误的 key/workspace、向仅支持文本的线程首次添加图片、请求由 fallback model 处理,或响应仍在生成 | 检查 key/workspace 和配置,然后将完整历史作为新的 create 请求重新发送 |
| 400 | thread_fingerprint_mismatch | 某个固定字段发生了变化 | 恢复原值,或创建新线程 |
| 400 | thread_already_continued | 该 previous_message_id 已经被使用过 | 从最新的 id 继续 |
| 400 | thread_continue_in_flight | 同一个 ID 上存在并发 continue | 等待当前请求完成,然后使用它返回的新 ID;否则进行重放 |
| 400 | thread_unsupported_request | 使用了不支持的设置(例如超过 4 个缓存断点、批处理) | 移除该设置,或不使用 thread 发送请求 |
根据文档摘要,失败的 thread 请求会在模型执行前终止,因此不会消耗 token,也不会重置过期计时器。在接受下一轮请求前,应以原子方式持久化最近一次成功响应的 ID;如果工具操作具有副作用,还要为重放做好幂等保护。
Python 重放示例(这里只处理经过确认的 thread_not_found;指纹不匹配、并发和不支持请求需要单独分支):
try:
resp = client.beta.messages.create(
model="claude-opus-5-5",
messages=[new_msg], # delta only
thread={"type": "continue", "previous_message_id": last_id},
extra_headers={"anthropic-beta": "message-threads-2026-08-12"},
)
except NotFoundError: # thread_not_found after checking identity/config
resp = client.beta.messages.create(
model="claude-opus-5-5",
system=SYSTEM, tools=TOOLS,
messages=full_history + [new_msg], # you stored this
thread={"type": "create"},
extra_headers={"anthropic-beta": "message-threads-2026-08-12"},
)
代理和密钥轮换造成的 404 陷阱
以下是运营者报告的行为,官方文档目前尚未收录:线程会绑定创建它的 organization、workspace 和 credential。假设中继服务每个请求轮换 API key,那么创建请求使用 key A,继续请求使用 key B,结果看起来就和线程过期完全一样:不断收到 404,随后进行全量重放,却始终得不到延迟收益。
“thread 绑定创建它的 key 和 workspace,换 key 会 404 thread_not_found。中转站轮换 key 会先吃 404 再全量重发。” —— @ak12kpoot(关于代理行为的中文开发者记录)
让一个线程固定使用同一个 key,或者在共享路由上直接禁用 threads。
Threads 支持哪些平台、有哪些限制,现在值得切换吗
Message threads 目前支持 Claude API、AWS 上的 Claude Platform、Anthropic 管理的 Google Cloud Claude Models,以及 Microsoft Foundry 中的 Claude。公测中的所有模型都覆盖在内,不存在单独的模型白名单,也没有官方公布的等待名单。
对于上线规划来说,下面这些限制更值得关注:
| 范围 | 状态 |
|---|---|
| Amazon Bedrock | 不支持 |
| Message Batches | 不支持——批量线程项会失败 |
| Token counting endpoint | 不支持——需要自行计算完整历史 |
| Compaction / context editing | 不支持(keep all 模式下的 clear_thinking 除外) |
| Zero data retention、HIPAA-ready、inference hooks | 不符合使用条件 |
| Thread management API | 没有——无法列出、读取或删除 threads |
是否采用的判断清单
- 现在就用:活跃的 coding agent、带截图的 computer-use 循环,或者每轮间隔少于 5 分钟、需要连续运行几十轮的文档密集型流程。记得同时配置 prompt caching 和重放路径。
- 暂时跳过:按人工节奏进行的聊天、会暂停的工作流、批处理流水线、ZDR/HIPAA 工作负载,或部署在 Bedrock 上的应用。
- 两者结合时要注意:每个请求的顶层
cache_control都会计入 4 个断点的上限;创建请求中system/tools的断点,在每次 continue 时也会再次计数。超过上限会返回thread_unsupported_request,因此同时启用两种机制前,先合并断点。
另请参阅:Claude API pricing guide 2026、Claude Skills API guide。
常见问题
需要使用什么 beta header 和参数?
线程中的每个请求都要发送 anthropic-beta: message-threads-2026-08-12。首次调用使用 thread: { "type": "create" },之后则使用 thread: { "type": "continue", "previous_message_id": "<last response id>" }。
线程过期后会发生什么?
下一次 continue 会返回 404 thread_not_found。将完整的 messages 以及原始 system/tools 重新作为新的 create 请求发送。线程闲置 5 分钟后过期,最迟会在最后一次使用后 1 小时被删除。
可以列出、查看或删除 threads 吗?
不可以。Messages API threads 没有管理 API。你保存在本地的历史记录才是唯一持久化的记录。
支持 Amazon Bedrock 吗?
不支持。支持的平台包括 Claude API、AWS Claude Platform、Microsoft Foundry,以及 Anthropic 管理的 Google Cloud。Bedrock 请求应继续采用发送完整历史的方式。
可以在线程中途修改 system prompt 或 tools 吗?
不可以。需要使用新的 system/tools 创建新线程。在 continue 中发送修改后的值会触发 thread_fingerprint_mismatch。model、tool_choice 和 thinking 配置也遵循同样的规则。
支持 streaming、tools 和 MCP 吗?
支持,但有一些规则:继续请求前要等到 message_stop;每一轮都要重新发送 MCP URL/token 和 container ID;要么每个请求都发送 fallbacks,要么一个都不要发送——由 fallback model 返回的响应不会被存储,必须重新播放。