2026 年 7 月,Open Reasoning 展示了一件颇为反直觉的事情:Claude API 明明只返回空的 thinking 和一段不可读的 signature,网站却能从中重新得到隐藏推理里的随机秘密,甚至展示一段远长于可见答案的“原始推理”。
- Linh-Ice/open-reasoning:公开 examples
- YangWang92/open-open-reasoning:独立 harvest/replay 实现
这很容易被描述成“Claude 的 Chain-of-Thought 被解密了”,但这个说法混合了三个问题:
- 网站是否在本地破解了 signature?
- provider 是否通过官方协议恢复了 reasoning state?
- 模型后续展示的文本,究竟是原始推理本身,还是基于恢复状态的一次新生成?
Open Reasoning 没有在客户端破解 Claude 的加密。它重放真实的 thinking.signature,借助 provider 原本用于推理连续性的解封路径,让模型重新访问并输出隐藏状态中的信息。Canary 可以证明信息被恢复,但最终展示的仍是一次新的模型生成,不是原始 CoT 的直接导出。
Signature 从哪来
Claude Code 和 Codex 都要处理多轮、带工具调用的任务。模型调用工具之后,下一次请求不能忘记调用前的分析;但 provider 又不希望把完整隐藏推理明文交给客户端。
于是出现了一种折中设计:
1 | 模型生成隐藏推理 |
这里有三层概念:
| 层次 | 用户是否可读 | 用途 |
|---|---|---|
| Visible answer | 是 | 正常回答 |
| Reasoning summary | 是 | 有限、经过处理的推理摘要 |
| Encrypted reasoning state | 否 | 多轮、工具调用和无状态续接 |
Linh-Ice 镜像仓库中的三个 examples 正好展示了这种差异:Divisor Sums 的 Summary 只概括枚举和检查,Reasoning 则保留逐项计算;Randomized Bubble Sort 和 Functional Graph Counting 的长 Reasoning 还包含反复试探、错误方向与自我修正,而可见回答已经被整理成干净结论。这里展示的 Reasoning 应理解为模型根据恢复状态重新生成的详细复述,而不是原始隐藏推理文本本身。
thinking.signature 与 redacted_thinking.data
Anthropic Messages API 的一条 assistant message 可以包含多个 content blocks。display 为 summarized 时,thinking 中是可读摘要,同时仍带有 signature:
1 | { |
display 为 omitted 时,thinking 变为空字符串,但 signature 仍然存在:
1 | { |
被 provider 安全遮蔽的内容则不使用上述结构,而是独立的 redacted_thinking.data:
1 | { |
因此,thinking.signature 和 redacted_thinking.data 不是“签名 + 密文”的一对字段:
| 类型 | 典型字段 | 准确含义 |
|---|---|---|
| Summarized thinking | type: thinking;thinking 为摘要;signature | provider 返回一段可读摘要,同时保留该 thinking block 的不透明加密连续性封装 |
| Omitted thinking | type: thinking;thinking 为空;signature | 仍是普通 thinking block,只是不返回可读摘要;signature 仍用于后续校验和 reasoning continuity |
| Redacted thinking | type: redacted_thinking;data | provider 因安全策略遮蔽部分 thinking |
Wire format
第三方复现对真实 signature 进行 Base64 解码后,发现它是 protobuf 风格的 envelope:
1 | base64 signature |
长样本的 payload entropy 可接近 7.96 bits/byte。它很像密文或压缩数据,但字段语义仍需区分观察与推断。
Signature 更像 provider 签发的一种 sealed continuity capability:客户端不能理解,provider 可以验证并恢复,持有者在拥有 API 凭证的前提下可能将其重放。因此它也不应被当成无敏感性的普通日志字段。
Harvest → Replay
Harvest 阶段的 memorize prompt 会要求 Claude 在 reasoning 中逐字符处理 secret、构造 mnemonic,最终可见回复只输出 Done.。
请求的关键配置是:
1 | { |
理想响应是:
1 | { |
调用方看不到 thinking 文本,却拿到了 signature:
1 | Secret S |
Replay
第二次请求不会伪造 signature,而是人为构造 assistant message,把第一次获得的真实 signature 填回 assistant.thinking:
1 | { |
完整链路如下:
1 | Open Reasoning backend |
解密发生在 provider 编排层,但 provider 解封 reasoning state,不等于 API 直接返回原始 plaintext buffer。最终仍需要模型根据新 prompt 进行一次生成,因此输出会受到采样、模型语义 和 prompt 的影响。
“Return your exact prior reasoning”只是 elicitation,不是解密算法。
Canary 证明了什么
如果随机 secret 只出现在第一轮 hidden reasoning、可见回答只有 ‘Done.’,而 replay 后输出再次精确命中该 secret,就得到这条信息链:
1 | S -> hidden reasoning R -> signature C -> provider replay -> output Y=S |
这足以说明 signature/replay 路径携带了隐藏状态中的信息,结果不是仅凭可见答案猜出来的。但 Y 仍是基于恢复状态的一次新生成,不是第一次 inference 的原始 reasoning event;模型可能重组、遗漏或补全内容。反过来,canary 没出现也不能单独证明 replay 失败,因为它可能没有被写入、没有被复述,或被安全策略拦截。
1 | Canary 命中 => 隐藏信息可被重新访问 |
Codex 对照
Codex 底层使用 OpenAI Responses API reasoning item。
1 | { |
这里要区分 Responses API 的两种状态模式。它默认保存 Response,后续可以用 previous_response_id 或 Conversations API 继续;只有显式 store: false(或组织启用 ZDR)时,才进入无状态续接路径。
OpenAI 官方将 encrypted_content 定义为可传入未来调用的 encrypted reasoning tokens。在无状态路径中,调用方必须保留第一次 response 的完整 output items(包括 encrypted_content),再追加下一条 user message;有状态路径则由 provider 根据 previous_response_id 找回这些 items:
1 | store: false |
它和 Claude signature 都用于 reasoning continuity,但协议入口不同:
| Claude | Codex / Responses API | |
|---|---|---|
| Artifact | thinking.signature | reasoning.encrypted_content |
| 所属结构 | assistant content block | response output item |
| 续接方式 | 回传 thinking block | previous_response_id;无状态时回传完整 output history |
| 单独诱导泄露 | Open Reasoning 声称可以 | 缺少类似的公开证据 |
总结
Claude thinking signature 被放回 provider 支持的 reasoning continuity 路径后,模型可以重新访问并暴露其中的部分隐藏信息。Open Reasoning 展示的是隐藏状态的重新暴露,而不是原始 reasoning plaintext 的直接返回;最终看到的 Reasoning 始终是模型基于恢复状态产生的第二次生成。
参考资料