Skip to content

KV Cache 回滚后的状态残留与推理一致性 ​

摘要 ​

有状态 Agent 可能先探索一个分支,再拒绝该分支并恢复先前对话。应用日志显示回滚成功,不代表模型实际关注的推理状态也已恢复。论文发现,应用只删除对话记录(transcript)、推理服务却继续复用同一 KV Cache 句柄时,中止分支仍留在缓存中,并可能改变后续受保护动作。

作者用“相同 token、不同缓存”审计隔离缓存影响。在七个开放权重模型家族、63 个配对单元中,旧 KV Cache 使 25/63 个单元改变受保护决策;重新按已提交对话记录构建缓存后为 0/63。论文将该保证称为回滚一致性(rollback consistency),结论只适用于跨逻辑回滚保留会话 KV 句柄的系统。

核心创新与差异 ​

原研究贡献。 论文区分两层性质:推理运行时是否恢复模型实际关注的状态,以及恢复前后受保护动作是否可观察地一致。same-token/different-cache 审计保持决策阶段 token 完全相同,只改变缓存来源;事务级重建、截断和快照恢复都能关闭已观察通道。

本站分析。 这不是一般提示词注入,也不是缓存键碰撞或跨租户侧信道。首个失效控制是逻辑状态事务没有覆盖推理缓存:应用认为分支已中止,Serving Runtime 却继续使用包含该分支的 KV。修复责任同时落在 Agent 状态管理器和推理会话接口,任何一层单独声明“回滚成功”都不够。

威胁模型与攻击链 ​

攻击者能够让 Agent 在可撤销探索分支中读取一段不可信内容,例如本地测试文档或工具返回。应用随后拒绝该分支,但为了延迟优化继续复用原 KV 句柄。攻击者不需要修改模型权重、缓存张量或后续请求文本。

  1. Agent 将不可信内容预填入当前会话 KV Cache。
  2. 应用拒绝探索结果,并从逻辑对话记录中删除该分支。
  3. 推理层没有把 KV 恢复到最后一个已提交状态。
  4. 后续请求只包含干净对话记录,但模型仍关注旧 KV 中的残留语义。
  5. 残留内容改变收件方、审批结果或其他受保护动作。

攻击方法与复现材料 ​

安全复现只需测试本地状态一致性,不应连接真实外发工具。下面的状态机使用 .invalid 测试目标,并省略论文中的敏感动作:

python
# DRY_RUN:本地模型和 Mock 工具,禁止网络与真实凭据。
committed = session.checkpoint()
session.explore("TEST_ONLY recipient=red-canary.invalid")
session.rollback_transcript(committed)
session.restore_kv(committed)  # 删除此行可模拟不一致实现
assert session.decide().recipient == "approved-local"

验证重点不是特定字符串,而是两组运行在决策阶段输入完全相同,唯一差异为 retained KV 与按已提交对话记录重建的 KV。测试应记录 token 序列、缓存长度、会话句柄和 Mock 动作结果。

实验设计与实际过程 ​

作者在七个 3.8B 至 36B 开放权重模型家族上设置 3 类内容进入路径和 3 种残留强度,共 63 个主审计单元。每个单元比较 stale KV、fresh KV 和冷启动条件,并验证攻击者 token 不在决策请求中。

研究还实现一个端到端会话应用,使用 HuggingFace Transformers 的 DynamicCache 默认复用路径,并把实验接入 LangGraph checkpointer/time-travel。防护对照包括框架原生逻辑回滚、提示词护栏、全局刷新、事务级重建、KV 截断和快照恢复。

关键结果与实际影响 ​

  • 主审计中,stale KV 改变 25/63 个受保护决策;fresh KV 和冷启动均为 0/63。
  • 所有 63/63 单元都验证决策阶段不含攻击者 token,且配对条件的决策 token 完全相同。
  • LangGraph 一手回滚 API 条件覆盖五个模型家族,逻辑状态确认干净后仍有 25/45 个 stale-KV 单元改变决策;接入事务级恢复后为 0/45。
  • 提示词护栏把五个易受影响家族的结果从 25/45 降到 14/45,没有关闭通道。
  • 事务级重建为 0/63;截断和快照恢复在四个易受影响家族的 36 个单元中均为 0/36。

三个模型家族在主设置中没有观察到动作改变,但它们仍接收了与已提交对话记录不一致的缓存状态。论文因此把缓存状态完整性和模型是否服从残留内容分开报告。

防护措施与验证方法 ​

  • 将对话记录、工具状态和 KV Cache 纳入同一事务;回滚成功条件必须包括 attended state 已恢复。
  • 为每个会话保存已提交 KV 长度或快照,回滚时只恢复当前事务,不全局刷新其他租户缓存。
  • 在框架与推理引擎接口中公开 cache epoch、checkpoint ID 和 restore 结果,避免只返回逻辑状态成功。
  • 建立 same-token/different-cache 回归测试,并覆盖中止、重试、人工拒绝、time-travel 和分支合并。
  • 对恢复前后动作做确定性 Mock 验证,同时测量恢复延迟、重新预填 token 数和受影响租户数。

局限与待验证问题 ​

  • 结论只覆盖保留会话句柄或显式 past_key_values 的实现。论文认为按请求内容寻址、只复用请求真实前缀的自动 prefix cache 不受该特定通道影响。
  • 实验主要使用 HuggingFace DynamicCache、作者会话应用和 LangGraph 组合,没有验证商业 API 的隐藏缓存;这些系统应记为 UNKNOWN。
  • 不同模型对残留内容的行为敏感性从 9/9 到 0/9 不等,不能把 25/63 外推为通用攻击成功率。
  • 尚未系统测试 RBAC、人工审批、混合 Mamba、Mistral Cache 和多引擎恢复成本。
  • 本站未运行开放工件,结果均来自作者的确定性封存测量(sealed measurements)。

参考链接 ​