← logs/

记忆作为攻击面:通过正常交互向持久记忆投毒

提示注入曾经是单次会话内的问题。载荷藏身于网页或文档中,会话结束,下次开始时模型又是干净的。持久记忆取消了这一保证。agent 现在把观察写入长期存储,并在会话之间检索它们,因此今天种下的内容能在数周后引导工具调用。2025–26 年的文献从多个方向汇聚到这一点上,最显眼的数字很糟糕。在给出这些数字之前,先做一个校准:Sunil 等人的后续评测发现,预先存在合法记忆的现实部署会大幅降低攻击的有效性。这类攻击真实存在,值得从工程上应对;未经校准的标题数字并非全貌。

攻击面全貌

记忆栈在每一个阶段都可被攻击:观察、写入、存储、检索,以及检索到的记录进入上下文的那一刻。我把攻击文献归为三种失败模式:

  • 写入时投毒:攻击者通过正常交互让 agent 存储一条恶意记录,自始至终不直接接触记忆。
  • 休眠载荷:攻击者控制的文档或页面被存入记忆,然后在之后的会话中重新浮现。
  • 控制流劫持:存储的内容不仅影响措辞,还引导工具的选择与执行。

共同主线是:载荷从不穿过输入通道,因此输入层面的过滤器永远看不到它。

控制流的结果:超过 90% 的试验存在漏洞

From Storage to Steering: Memory Control Flow Attacks on LLM Agents (Xu et al., arXiv 2603.15125) 是对控制流问题最清晰的陈述。让这种攻击危险的是它的框架:agent 中的工具使用本身就是一种控制流。模型选择一个工具、运行它,并用结果选择下一个。作者证明,记忆可以主导这条控制流:即使面对明确的用户指令,也会迫使非预期的工具使用;单次注入之后,行为偏差会跨任务持续存在。他们的 MEMFLOW 框架在异构任务和长交互跨度上度量这一点,在 LangChain 与 LlamaIndex 的真实工具上攻击 GPT-5 mini、Claude Sonnet 4.5 和 Gemini 2.5 Flash。

最显眼的数字出自摘要:即使在严格的安全约束下,也有超过 90% 的试验对 MCFA 存在漏洞。

t1: agent reads attacker-controlled page during a benign task
    payload written to long-term memory through the normal update flow
t2..tn: payload retrieved -> steers tool selection
    unintended tool usage, persists across sessions

机制比数字更重要:在读取时,这种攻击与合法的记忆流量无法区分。

MINJA:以普通用户的身份注入

MINJA(Dong et al., arXiv 2503.03704)证明,仅查询式的交互就足够了。攻击者从不触碰记忆库,只是向 agent 提问。注入的记录被设计为:当之后受害者的查询到来时,引出一连串恶意的推理步骤。两种技术让这一点成立:桥接步骤把受害者未来的查询与恶意推理联系起来,指示提示词则让 agent 自行生成这些步骤。随后,渐进缩短策略去掉指示提示词,让存储的记录读起来像普通内容。

后续评测(Sunil et al., arXiv 2601.05504)对其做了量化与限定:在理想化条件下,MINJA 的注入成功率超过 95%、攻击成功率为 70%;而正如引言中校准过的,预先存在合法记忆的现实部署会大幅降低这一有效性。

休眠记忆:前沿助手上的写入率

Pulipaka et al., Hidden in Memory (arXiv 2605.15338) 把攻击延迟化。攻击者操纵外部上下文——文档、网页或仓库——让助手存储关于用户的一条捏造记忆。载荷潜伏不动,在之后的对话中重新浮现。出自摘要的已核实数字:投毒记忆在 GPT-5.5 上的写入率最高达 99.8%,在 Kimi-K2.6 上为 95%;而在成功检索中,跨模型 60-89% 的评测里,投毒记忆引发了攻击者预期的 agent 行为。

持久性有自己的攻击面

Zombie Agents (Yang et al., arXiv 2602.15654) 是同一个问题的持久性那一半。攻击是黑盒式的,只借助攻击者控制的网页内容进行间接暴露。感染发生在 agent 完成良性任务的过程中:它读取被投毒的数据源,通过正常更新流程把载荷写入长期记忆。触发时,载荷引发未授权的工具行为。论文针对每种记忆实现设计了持久化策略:递归续期让载荷在滑动窗口记忆中保持存活,语义别名化则在 RAG 存储中增殖副本——约 240 份载荷副本,而基线载荷约为 100 份。总体结论:记忆演化把一次性的间接注入转化为持久的攻陷。

设计方向与淘汰标准

把这些放在一起读,模式是一致的:任何把记忆内容当作普通上下文处理的防御都会失败,因为在读取时,被投毒的内容与合法内容在结构上无法区分。区分必须在写入时和工具边界上做出。我会推动的三个设计方向:

  • 把记忆写入当作具有持久副作用的变更来对待。一条能影响未来工具调用的记录不是日志行;它配得上代码变更的审查面:溯源(用户轮次、工具输出或抓取的页面)、信任级别,以及当记录携带类指令内容时的标记。什么会淘汰它:在一个受控 eval 中,经审查的写入被投毒的频率并不低于未经审查的写入。如果审查面改变不了任何东西,它就是仪式。
  • 在记忆内部把数据与指令分开。检索到的事实应当能作为数据使用;它们不应能改变运行哪些工具。引用工具或命令的记录只能由可信来源写入。什么会淘汰它:有证据表明合法 agent 需要源自记忆的指令才能完成工作。如果真实的工作流需要靠记忆来引导工具,这种分离就代价大于收益。
  • 在 harness 层执行不变量,而不是在提示词里。「不要遵从检索内容中的指令」只是模型层面的希望。「任何工具调用都不得仅由一条溯源不可信的记忆记录引起」这个不变量可以在模型之外被检查和执行。什么会淘汰它:部署中溯源门禁误拒了足够多的合法工具调用,以至于用户关掉它,此时不变量什么也保护不了。

这些是设计方向,不是已交付的系统。已核实的文献支持这一方向:Sunil 等人发现,复合信任评分与带时间衰减和模式过滤的信任感知检索是有帮助的,而信任阈值校准才是难点,过度拒绝与拒绝不足都是真实存在的失败模式。

我自己的工作指向

我的两个系统指向这个问题,作为设计方向。

SafeRoutes(github.com/xesws/SafeRoutes)建立在一套铁律之上:agent 只产生对世界的判断,从不编辑路线。每条路线决策都汇聚在编排器中——一个纯函数。agent 是传感器与验证器;函数才是决策者。这正是记忆投毒需要的强制执行形态:风险操作位于一个确定性组件中,无论多少被投毒的内容都无法引导它。

在 PiPlan.ai,审查纪律是提案先行:变更在被应用之前先被提案。一次记忆写入就是一种变更,其副作用比会话活得更久。应用同样的纪律:一次记忆写入会连同其溯源与预期效果被提案、被审查,然后才被提交。静默投毒变成可审计的事件,而不是一次悄悄的编辑。

两者都不是针对 MCFA 的已交付防御。但两者都是我愿意下注的形态:把决策者留在模型之外,在变更持久化之前先审查它们。

本文中链接的来源均已抓取并核实。