加密推理块也需要一份“不可见状态契约”
面向创始人的实操指南:审计加密推理状态、阻止会话记录泄漏、选择有状态或无状态 API,并在重放漏洞披露后验证修复效果。
一篇名为《Stealing Reasoning Traces from Proprietary LLM APIs》的新论文称,研究者在 2026 年 7 月上旬测试 Anthropic、OpenAI 和 Google 的模型时,发现这些平台返回的加密推理块可以在不同会话、用户和模型之间移动,再诱导较弱的模型还原其中隐藏的推理。研究团队还扫描了公开的 Agent 会话记录,解码 315,320 个推理块,并将其中 367 项归为个人身份信息、182 项归为凭据。
这个标题很容易让人以为:现在仍然存在一个能普遍破解推理块的解密漏洞。论文给出的结论更有边界,也更值得产品团队关注。这一攻击使用的是普通模型 API,并没有窃取加密密钥;实验只覆盖特定模型和 API 版本;还原出的推理也无法在所有情况下与真实原文逐字比对。所有受影响的供应商都确认收到了报告。更重要的是,研究者明确表示,负责任披露之后,同样的攻击已经无法再次执行。因此,我们没有依据告诉用户“目前所有推理块仍然都能被解码”。
但凡是在构建 AI 应用,这件事仍然有一个必须立即吸收的产品教训:即使你的团队读不懂某个字段,它仍可能承载或影响敏感状态。如果这个字段会经过浏览器存储、会话数据库、可观测性工具、客服导出、评测数据集或公开代码库,就必须进入安全模型。本文写给正在使用推理模型、工具循环、客户端管理历史记录或 Agent 会话导出的创始人和小团队。你会得到一份不可见状态契约、一张模式选择矩阵、一个具体场景、六项安全的失败测试,以及一套 48 小时审计流程。本文不会提供推理提取方法。
论文证明了什么,又没有证明什么
原始论文总结了可移植加密推理状态可能带来的四类后果:提取专有推理、从公开日志中恢复敏感数据、用不可见状态携带隐藏指令,以及暴露没有出现在最终回答中的有害信息。作者采用的是“普通 API 攻击者”假设:没有供应商基础设施权限,没有模型权重,也没有被盗的加密密钥。公开日志中的数字需要谨慎理解。研究者扫描了 6,708 条公开轨迹,解码 315,320 个推理块。经过分类和过滤后,他们报告了 367 项个人身份信息和 182 项凭据。这是一个有明确目标、并不穷尽所有数据的样本计数,不能当作所有 AI 应用的泄漏率。有些值来自 benchmark 或合成场景;论文另外分析了真实会话,并称完成汇总分类后删除了所有恢复出的秘密。不要把这些数字直接外推成你自己产品的暴露概率。
时间线同样关键。实验覆盖的是 7 月上旬可用的模型和 API。正式发布前,作者已经向受影响的供应商、Microsoft 和 Hugging Face 披露问题。论文称,所有模型供应商都确认收到了报告,之后研究者已无法再次发动相同攻击。公开文档目前还没有给出逐个供应商、逐个端点的完整密码学修复记录。我们可以说:论文演示的攻击到发布时已经被缓解;但不能断言现在每个端点究竟依靠模型拒绝训练、账户绑定、会话绑定、密钥轮换还是网关检查中的哪种组合得到保护。
所以,正确反应既不是恐慌,也不是忽略。不要在生产服务上尝试复现攻击。先审计你自己的产品能够控制的数据路径,向供应商索要当前范围内的证据;对于过去公开过的会话记录,在凭据已经轮换、敏感材料已经评估之前,应视为可能暴露。
盘点之前,先定义什么是不可见推理状态
不可见推理项,是指供应商返回给应用、但应用本身不应解析的状态。它可能表现为加密推理字段、签名、经过隐藏处理的思维块,或带签名的 thought step。应用保留或回传这些内容,是为了让模型在一次工具调用之后或后续轮次中继续推理。它与三个容易混淆的概念不同:
- 推理摘要是给用户或开发者阅读的文本,不一定忠实还原模型的隐藏推理过程。
- 会话消息是应用可见的内容,例如用户请求、助手回答或工具结果。
- 供应商侧 response ID是让供应商找回已存状态的引用。它可以减少应用自行携带的状态量,但会引入另一组关于保留期限和访问权限的决策。
encrypted_content,并要求开发者在重放历史时保留输出项。Google 的 Gemini thinking 指南将 thought signature 定义为模型内部推理状态的加密表示;无状态模式要求客户端原样回传 thought block,而有状态的 Interactions API 会在服务器端管理它们。Anthropic 的 thinking 文档则说明,完整推理被加密在签名中;工具调用轮次内必须完整、原样回传相关块,并明确要求把签名视为不可解析字段。
这些都是协议功能要求。它们绝不等于“应该永久记录这些块”,也不意味着可以把它们展示给终端用户、跨租户复制,或放进公开 benchmark 数据集。
加密保护可读性,却不会替你守住整条数据路径
团队最常犯两类分类错误。第一类是:“我们读不懂这个值,所以它不可能包含敏感信息。”第二类是:“供应商已经加密,所以怎么使用都一定安全。”
加密可以阻止人直接阅读或篡改一个块,但仍然没有回答下面的问题:
- 谁可以重放? 即使密文本身有效,如果错误的账户、租户、会话或模型也能接受,它仍然可能带来风险。
- 它可以流向哪里? 即使员工无法解码,不可见字段也可能被复制到日志、分析系统、导出文件、工单和代码库。
- 有效期多久? 一个没有实际过期或撤销路径的块,与只在单次工具轮次内有效的块,影响范围完全不同。
- 它由什么信息生成? 模型可能使用过用户数据、工具结果、环境变量或凭据,而这些内容不一定出现在最终回答中。
- 谁能消费它? 接收方模型必须处理隐藏状态。仅靠传输层加密,无法保证模型永远不会泄露或遵循其中内容。
这些是供应商需要完成的控制。你的应用仍然要负责数据最小化、租户隔离、保留期限、日志、删除、导出和事故响应。如果产品把带有明文工具结果或有效凭据的会话公开发布,供应商的加密无法替你修复这个问题。
画出每个推理块可能经过的位置
从一次具有代表性的推理模型请求开始,沿着完整状态路径往下追,不要在模型网关处停下。一个常见 AI 应用可能在九个位置制造副本:
| 阶段 | 合理用途 | 常见的意外副本 |
|---|---|---|
| 模型响应 | 继续工具循环或后续轮次 | debug 日志记录完整响应 |
| 应用服务器 | 组装下一次请求 | 原始 JSON 进入请求历史 |
| 会话数据库 | 恢复会话 | 用户删除可见聊天后,不可见块仍被保留 |
| 任务队列 | 继续后台任务 | payload 被复制到死信存储 |
| 浏览器或设备 | 客户端管理会话 | 状态暴露给扩展、备份或分享链接 |
| 可观测性系统 | 诊断延迟和错误 | prompt、响应和推理块被记录为 span 属性 |
| 客服工具 | 复现用户故障 | “下载诊断包”导出原始会话 |
| 评测流水线 | 重放生产失败样本 | 数据集被公开或交给外部承包方 |
| 源代码管理 | 保存测试 fixture | 真实会话以 JSON 形式提交到 Git |
OpenTelemetry 的 GenAI 可观测性指南提供了一个值得采用的默认值:由于 prompt 内容和工具参数可能包含敏感数据,默认不采集,只有操作人员明确选择时才记录。对供应商返回的不可见状态也应采用相同原则。可以保留模型名称、延迟、状态、token 数,以及你自己生成的非敏感关联 ID;除非某个严格限定范围的调查确实需要,否则不要保存原始推理块。
你的盘点必须同时覆盖“逻辑删除”和“物理删除”。用户删除会话后,要继续检查 trace、队列、对象存储、客服工单、分析仓库、备份和已经导出的评测集里是否还有副本。“从聊天表删除”不等于端到端删除完成。
用一个跨租户客服场景看清风险
假设有一家小型创业公司 ResolveKit,为网店提供 AI 客服 Agent。模型可以搜索订单系统、判断退款政策,并起草一个等待人工批准的动作。由于客户要求尽量减少供应商侧的数据保留,ResolveKit 使用无状态 API。为了让 Agent 能在每次工具返回之后继续工作,服务器会保存完整的响应 JSON。
Store A 的一名用户查询订单。订单工具返回了收货地址和一个内部退款 token。最终回答只显示预计送达日期,但模型在做决策时使用过地址和 token,所以不可见推理项仍可能反映这些信息。
此时,三个产品捷径会产生风险。第一,为了排查超时,应用把完整模型响应写入日志。第二,评测任务把所有店铺的失败会话复制到同一个共享数据集,却没有为每个不可见项保留租户标签。第三,客服工程师下载 JSON,在手动删除可见姓名和邮箱后,把文件附在公开 issue 中。
上述任何一步都不需要破解加密。敏感状态已经离开了原定上下文。供应商修复或许能阻止跨账户解码,但会话中仍可能存在明文工具结果或仍然有效的凭据;应用也没有证据证明所有历史推理块都已经失效。ResolveKit 必须轮换退款 token、移除公开文件、扫描 Git 历史与 fork,按照事故预案通知受影响客户,并改造导出器:按类型直接丢弃不可见状态,而不是让人工去识别它。
更安全的设计会使用绑定租户的会话记录,将可见消息与不可见续接状态分开存储;后者默认不进入客服和分析导出,并在工具轮次结束后过期。如果 ResolveKit 改用供应商管理状态,也必须明确记录供应商的保留和删除行为,而不能假装数据“消失了”。
有状态还是无状态,要做有意识的选择
“无状态”并不等于“没有任何人存储状态”。它通常意味着:由你的应用携带足够历史来继续工作,而不是让供应商的会话服务保存。这可能是正确的隐私或架构选择,但控制责任也会随之转移到你的产品。
| 模式 | 适合何时使用 | 主要责任 | 出现什么情况必须暂停上线 |
|---|---|---|---|
| 供应商管理会话状态 | 你接受已记录的供应商保留规则,并需要简化续接 | 访问控制、删除请求、供应商条款、response ID 管理 | 保留期限、区域、删除或租户边界不清楚 |
| 客户端管理加密推理 | 需要 store: false、兼容 ZDR、可移植或自定义历史 | 安全存储、租户/会话绑定、最小化、过期、导出过滤 | 原始响应默认进入日志或共享数据集 |
| 单轮临时推理 | 任务不需要此前的隐藏推理 | prompt/工具最小化、可见输出审查 | 产品声称拥有实际并不存在的连续性 |
| 不使用推理模式 | 简单分类器或确定性流程已经达标 | 准确率和普通输入输出控制 | 推理增加成本与状态,却没有可测的结果收益 |
不要仅仅因为“零保留”听起来更安全,就选择客户端管理状态。OpenAI 明确说明,无状态或 Zero Data Retention 模式会返回加密推理内容,交给客户端继续携带。隐私问题由此变成:你的应用会把它放在哪里,谁能访问,何时删除?
同样,也不要为了逃避建设控制而选择供应商管理状态。你依然需要理解保留、访问、区域、事故通知和删除语义。这张矩阵的目的,是把责任放到团队真正能够验证的位置。
建立一份不可见状态契约
针对每个供应商、模型家族和产品工作流,分别记录一份契约。它是一份产品工件,不是供应商或监管机构的官方模板:
workflow_id: resolvekit-refund-assist
reviewed_at: 2026-08-12
provider: example-reasoning-api
model_family: production-model-alias
mode: client_managed_stateless
opaque_state:
response_types: [reasoning, redacted_thinking, thought_signature]
purpose: continue_current_tool_turn
allowed_storage: encrypted_conversation_store
forbidden_sinks: [client_logs, analytics, support_exports, public_datasets, git]
tenant_binding: required
session_binding: required
model_switch_rule: provider_documented_only
ttl: 24h
delete_with_conversation: true
exports:
visible_messages: reviewed_and_redacted
tool_results: excluded_by_default
opaque_state: always_drop
evidence:
sdk_version: pending
provider_security_notice: pending
cross_tenant_fixture_test: pending
deletion_test: pending
log_sink_test: pending
incident_owner: founder
decision: hold
这份契约能阻止一种常见错误:把任意 JSON 当成不可拆分的完整会话。应用应该通过供应商 SDK 的类型对象或正式 schema 识别状态,而不是猜测“所有很长的 Base64 字符串都是推理”。一旦出现新的响应类型,默认应该失败关闭。未知字段先进入隔离区,直到团队决定它是否可以安全保留、重放或导出。
契约必须版本化,因为供应商 schema 和模型切换规则会变。比如 Anthropic 当前文档称 thinking block 与生成它的模型绑定,切换模型时应移除旧的 thinking 和 redacted-thinking block。Google 当前的无状态指南却要求在切换模型时仍回传之前的 thought block,由后端负责兼容。用一个通用的“推理签名处理器”抽象所有供应商,并不安全。
上线前运行六项安全的失败测试
这些测试验证的是你的应用,不是尝试解码隐藏推理或攻击供应商。
跨租户组装测试
创建两个只有无害内容的合成租户。给历史记录组装器提供一条租户 ID 与当前会话不匹配的记录。请求必须在到达模型之前就被拒绝。消息、工具结果、不可见块、缓存响应和后台任务 payload 都要分别测试。
导出剥离测试
准备包含所有正式记录的不可见响应类型、再加一个未知类型的 fixture。依次运行客服导出、用户下载、评测导出、错误上报和“复制 debug JSON”。不可见状态与未知状态都不应出现。必须检查最终序列化字节;干净的 UI 预览不算证据。
可观测性测试
分别触发成功请求、供应商错误、超时、重试和工具失败。搜索所有日志与 trace 目标,看是否出现 fixture 值和不可见字段,同时检查死信队列与错误追踪工具。通过条件是:留下足够的运维元数据,但没有 prompt、工具结果、秘密或不可见状态。
fallback 与模型切换测试
强制主模型失败,观察 fallback 路径。对于推理项,必须遵守供应商当前规则。不能因为“看起来能工作”就把某个块复制给另一模型。通过条件还包括一个可见事件,明确说明连续性是被保留、主动丢弃,还是从头重建。
删除与过期测试
删除测试会话,等待文档写明的异步处理窗口,然后查询主存储、缓存、队列、导出、分析系统和备份。接着验证:过期的不可见项无法由你的应用恢复。产品侧删除和供应商侧删除要分别记录。
SDK 与 schema 变化测试
向集成层输入一条带有新字段或新块类型的历史响应。系统应隔离未知值、通知负责人,并避免导出或重放。每次 SDK 或模型升级,都要把这项 fixture 放进发布门槛。
把旧会话当作事故,而不是普通清理
如果团队曾经发布、提交或广泛共享原始推理模型响应,只删除最新文件远远不够。副本可能仍存在于 Git 历史、fork、包产物、构建日志、issue 附件、镜像和下游数据集。
先做控制与收口:
- 停止新的会话导出,关闭受影响的分享路径;
- 保存一份严格限权的事故记录,不要把原始秘密再复制进另一个工具;
- 找出收到材料的代码库、bucket、工单、数据集、供应商和人员;
- 撤销并轮换所有可能出现在可见内容或隐藏处理路径中的凭据;
- 删除公开材料,并要求下游托管方删除;
- 与合格律师评估个人数据和合同通知义务;
- 完成类型化剥离和回归测试后,再重新开放导出。
在不复现攻击的前提下完成 48 小时审计
前 6 小时,冻结原始会话发布,列出生产环境中的每个推理供应商、模型 alias、SDK、状态模式、工具循环、会话表和导出路径。请工程人员为每条路径提供一份合成响应 fixture。不要使用客户数据,也不要要求模型泄露隐藏推理。
到第 24 小时,使用 fixture 运行导出、可观测性、跨租户和 fallback 测试。搜索代码库和共享数据集中是否出现 encrypted_content、signature、redacted_thinking、thought_signature 等正式字段名。字段名搜索只能找出候选项,并不等于发现真实秘密。限制搜索结果的访问权限,不要把匹配到的原始值复制进新的事故文档。
到第 36 小时,为每条路径分类:
| 决策 | 所需证据 |
|---|---|
| 上线 | 类型化剥离有效,隔离与删除测试通过,供应商行为已有文档 |
| 限量试点 | 核心控制通过,只剩一个非关键供应商问题,数据为合成或低敏感内容 |
| 暂停 | 不可见状态进入公开、共享或跨租户存储;删除或 fallback 不清楚 |
| 事故 | 原始会话曾公开分享,或凭据可能已经暴露 |
到第 48 小时,轮换受影响凭据、删除公开材料、向供应商开 case、分配修复负责人,并为不可见状态契约建立新版本。下一次 SDK 或模型升级后安排复测。OWASP 的敏感信息泄漏指南提醒我们:仅靠 prompt 指令不是可靠的数据防泄漏控制,必须由导出与存储边界执行政策。
向供应商索要你的应用真正能使用的证据
论文称负责任披露后,同样的攻击已无法执行,但“已修复”并不是一份完整的集成规范。每个供应商都应该回答与你工作流直接相关的问题:
- 当前不可见推理项绑定到了账户、project、租户、会话、对话位置、模型、区域或 API 端点中的哪些维度?
- 修复前的密钥是否已轮换,旧推理项是否已失效?如果没有,它们的有效期多久?
- 客户端在错误会话或错误身份下重放时,系统会怎么处理?
- 哪些模型切换和平台迁移是明确支持的正常行为?
- 重放尝试是否被记录、限速,并能否向客户提供?
store: false、ZDR、prompt caching、compaction 和后台任务会怎样改变保留规则?- 删除 response 或会话时,供应商管理的推理状态是否同步删除,处理周期多久?
- 导出器需要剥离哪些 SDK 类型,包括 redacted、omitted、compaction 或内置工具签名?
- 哪一份安全通知或版本说明,能够证明你正在使用的模型已经包含相关修复?
明确这道门槛何时适用、何时可以简化
只要应用存在以下任一情况,就应执行完整的不可见状态门槛:
- 自行管理模型历史;
- 跨 API 调用返回工具结果;
- 使用
store: false、ZDR 或其他无状态模式; - 为客服、评测、研究或用户下载导出会话;
- 在 worker、设备、环境或模型 fallback 之间共享历史;
- 处理个人信息、凭据、私有代码、健康信息、财务数据或受监管记录。
这道门槛也不能证明模型最终回答正确、推理摘要忠实,或供应商满足法律要求。它处理的是一个更窄的产品问题:不可见续接状态是否像敏感数据一样,被正确隔离、最小化、保留、导出和删除。
用证据做出发布决定
只有团队能够证明以下事项时,才应正式上线:
- 已针对具体供应商和 SDK 版本,盘点所有不可见状态类型;
- 应用代码会拒绝租户与会话不匹配;
- 日志、trace、导出、工单和评测集默认排除不可见状态;
- fallback 和模型切换遵守供应商当前文档;
- 已分别记录保留、过期、用户删除和供应商删除;
- 已确定旧共享会话的影响范围,并轮换暴露凭据;
- 六项失败测试都有通过证据;
- 有明确负责人审查 schema、模型和 SDK 变化。
这次重放问题留下的长期教训,不是“所有加密都失效了”,而是“读不懂的状态仍然是状态”。创始人不需要逆向密文,但产品必须知道它流向哪里、为何保留、谁可以重放、何时过期,以及如何删除。即使标题中的漏洞已经修复,这份契约仍然有价值。
参考资料
- Panfilov 等,《Stealing Reasoning Traces from Proprietary LLM APIs》
- 研究项目与披露网站:Stealing Reasoning Traces
- Matthew Green:《Let's talk about encrypted reasoning》
- OpenAI:推理模型与无状态加密推理
- Anthropic:thinking block 的保留与加密
- Google:Gemini thinking 与 thought signature
- OpenTelemetry:GenAI 可观测性与敏感内容默认值
- GitHub:Secret scanning 与凭据修复
- NIST AI 600-1:生成式 AI 风险管理框架
- OWASP LLM02:2025:敏感信息泄漏