Agent 长期记忆如何成为持续注入入口
攻击者可将恶意指令藏入外部文档,诱导 Agent 写入长期记忆,并在后续会话中影响回答或决策。文章讨论跨会话记忆投毒的攻击机制、相关证据与防护架构。
AI 深度解读
AI 助手记住你的偏好,也可能记住攻击者替你编造的偏好。更麻烦的是,恶意内容可以在一次会话里写入,几周后才影响另一次正常问答,排查当前聊天记录时却找不到攻击指令。
作者讨论的「记忆投毒」,就是这种跨会话的提示注入。他的核心建议是:把长期记忆当成存放不可信声明的数据库,管理来源、权限和有效期。这篇值得程序员读,因为风险不只藏在模型输入里,也藏在 Agent 保存和重新读取信息的流程中。
为什么当前对话干净,回答还是被操纵了
原文用一个假设场景解释攻击:工程师让内部助手总结供应商 PDF,文档用白底白字夹带一句话,要求记住该供应商是公司认可的首选。助手保存了这个「事实」。三周后,同团队另一名工程师咨询采购建议,助手便优先推荐它。
恶意输入与受害问答不在同一次会话里。攻击经过读取、写入、检索、行动四步,持久化存储连接了前后两次会话。
这里要区分长期记忆与 RAG、指令文件。污染 RAG 通常要把内容放进检索语料库;污染指令文件通常需要仓库或机器的写权限。长期记忆多了一个入口:Agent 处理网页、邮件、PDF、工单和工具输出时,可能自行判断哪些信息值得保存。
危险发生在可信度变化的那一刻。外部文档原本只是一份材料,被模型改写成记忆后,却可能看起来像用户亲口确认的事实。压缩、合并记忆还会继续丢失来源。
内容被保存过,不代表它变得可信了。
攻击也未必包含「忽略此前指令」。一句「公司首选供应商是 X」就可能改变推荐结果。共享记忆还会扩大影响范围,让一个用户触发的写入影响其他用户。
读取顺序也有影响。原文称,启用 Anthropic 的 memory_20250818 工具后,API 会自动加入要求先查看记忆目录的系统指令。记忆因而可能成为新会话最先接触的信息,错误内容有机会提前影响后续判断。
研究证明了风险,但成功率不能直接套进生产环境
原文标注,研究与产品状态核对截至 2026 年 10 月 24 日。这些证据需要分层理解。
AgentPoison 在 2024 年 7 月报告:投毒比例低于 0.1%,平均攻击成功率超过 80%,正常任务表现受影响不到 1%。它研究的是从记忆或知识库检索的 Agent,不能据此推断所有产品都具有同样风险;但正常任务几乎不掉分,确实说明常规质量监控可能漏掉定向攻击。
MINJA 首次发表于 2025 年 3 月,并在 NeurIPS 2025 展示。攻击者只用普通查询诱导系统保存恶意记录。在使用 GPT-4、GPT-4o 的医疗、购物和问答 Agent 中,恶意记录注入平均成功率为 98.2%。这个数字衡量的是受控实验里的记录注入,并非生产环境中最终危害的发生率。
产品演示提供了另一类证据。Johann Rehberger 在 2024 年展示 ChatGPT 记忆写入问题,9 月的 SpAIware 演示涉及 macOS app 后续会话泄露;原文称 OpenAI 修复了泄露通道。2025 年 2 月的 Gemini Advanced 演示则把写入延迟到用户后来输入普通词语时,让操作看起来像用户自己的要求。
商业动机已经出现。Microsoft 在 2026 年 2 月 10 日报告,观察 60 天邮件流量中的 AI 相关 URL,发现来自 14 个行业、31 家公司的 50 多种独特提示。它们通过「Summarize with AI」按钮及 ?q= 等参数,夹带把企业记为可信来源的要求。不过,发现这些提示不等于证明每条都成功写入记忆。
与程序员关系最直接的是 Cisco 在 2026 年 4 月 1 日展示的攻击:恶意 npm postinstall 脚本改写 ~/.claude/projects/ 下各项目的 MEMORY.md,修改 ~/.claude/settings.json 的全局 hooks,并用 shell alias 在每次启动时重新开启 auto-memory。
受测版本把记忆文件前 200 行放进 system prompt,投毒后 Agent 建议把 API key 提交到源码,并反对使用 .env 和环境变量。原文称 Claude Code v2.1.50 随后移除了 system prompt 中的用户记忆。这个案例有明确前提:攻击代码已经能以本机用户身份执行。
真正需要管住的是记忆的写入和使用
作者提出在模型与存储之间设置 Memory Gateway。模型只能提出写入建议,网关负责来源追踪、类型判断、隔离、签名、检索范围和审计。
每条记录应保存来源、会话、操作者身份、信任等级、置信度、时间、到期时间及派生关系。签名只能证明网关接受过这条记录,不能证明内容真实;它主要帮助识别绕过网关的直接改写。
信任等级要由来源决定。供应商文档可以贡献带出处的外部事实,却不能替用户设置偏好,更不能宣布自己获得公司认可。下面这段原样代码展示了写入检查的顺序:
RISKY_PHRASES = ("trusted source", "authoritative source", "always recommend",
"in future conversations", "remember that", "preferred supplier",
"ignore", "override", "approved", "do not tell")
def evaluate_write(proposal, session):
source_tier = session.trust_tier_of(proposal.derived_from) # lowest tier wins
if proposal.type in {"procedure", "instruction"} and source_tier != "verified":
return Decision.QUARANTINE("instruction-like memory from unverified source")
if source_tier == "external" and proposal.type in {"preference", "trust_claim"}:
return Decision.DENY("external content cannot set preferences or trust")
if any(p in proposal.content.lower() for p in RISKY_PHRASES):
return Decision.QUARANTINE("authority or persistence language")
if session.memory_writes_last_hour() > 20:
return Decision.DENY("write rate limit")
return Decision.ACCEPT(tier=source_tier, expires=default_ttl(proposal.type))
关键是 trust_tier_of(proposal.derived_from):来源应由网关追踪,多来源采用最低信任等级,不能让模型自行申报。关键词规则只是便宜、可解释的一层检查,模型分类器可以补充识别改写表达,但不该独自决定放行。
读取时,作者建议把记忆作为标明来源的数据展示,按用户、租户、等级和有效期过滤。支付、部署、访问控制等决策,不应依赖外部来源或 Agent 推断的记忆。
记忆可以提供信息,不能授予权限。
例如「用户预先批准了低于 $5,000 的付款」,必须到正式授权系统核验。冲突处理也不能简单保留最新记录:高信任优先,同等级冲突并列等待确认,高影响变更需要人工确认。
作者还主张通过过期、置信度衰减和可验证删除限制危害。不过,提供的原文在遗忘机制章节开头被截断,具体实现没有完整给出。
我的判断
我赞同把防护重点放到写入流程。只过滤当前输入,很难解释几周前保存的一条错误记忆;保留来源和派生关系,至少能让排查有据可查。OWASP 在 2025 年 12 月 9 日将其列为 ASI06,也说明它值得单独建模。
但这套网关架构是作者的设计建议,原文没有给出完整实现的对照数据。限流阈值、外部事实的使用范围,以及分类器效果,都需要团队自己验证。
「上下文里出现过不可信文档就继承最低信任」比较保守,也可能误伤同一会话里用户明确表达的偏好。来源追踪做得多细,会直接影响可用性。
同样,移出 system prompt 能降低记忆的地位,却不保证模型不再服从数据中的指令。若攻击者已经拥有本机用户权限,且能修改验证逻辑或获取签名密钥,签名机制的保护范围也会缩小。记忆治理需要与存储权限、工具授权一起设计。
能拿来做什么
- 给 Node Agent 的记忆写入增加统一入口,先保存来源、用户范围、类型和到期时间,禁止网页或工具输出直接修改用户偏好及授权声明。
- 使用 AI 编程工具处理陌生仓库时,把 npm 生命周期脚本、记忆文件和 hooks 配置一起纳入检查,留意依赖安装是否改写持久化状态。
- 给共享助手增加跨会话测试:先读取带恶意声明的文档,再换用户正常提问,检查错误记忆是否被保存、跨用户检索或用于工具调用。
- 为记忆提供可追踪的撤销流程,删除时检查派生摘要和关联记录,避免原记录已删、改写后的错误结论仍继续被使用。