引言
论文原文The Attack and Defense Landscape of Agentic AI: A Comprehensive Survey。
为什么 Agent 的安全问题不是给模型加一道护栏那么简单
Agent 的安全问题,核心不在模型会不会说错话,而在它已经开始读文件、调用工具、改系统、代表用户行动。普通 LLM 出错,很多时候只是生成了错误内容;Agent 出错,可能直接把敏感数据发出去、改坏文件、执行危险命令,甚至在多步流程里把一个很小的输入问题放大成真实世界的事故。真正需要理解的主线只有一句话:Agent 越灵活,攻击面越大;而防守也不能只盯着模型,必须把整个系统一起设计。
代理为什么比普通 LLM 更难防
先把 Agent 看成一个混合系统,而不是一个会聊天的模型。它通常至少包括几个部分:负责推理和决策的 LLM,保存历史和知识的记忆模块,连接外部世界的工具,真实运行任务的外部环境,以及让人和系统交互的界面。更复杂的系统里,还会把同一个 Agent 拆成 planner 和 actor,前者负责规划,后者负责执行;再进一步,就会演化成多 Agent 协作。

这类系统和传统软件的差别也很明确。传统软件主要靠预先写死的符号逻辑执行;Agent 会把模型推理和传统程序拼在一起。传统软件的流程大多是固定的;Agent 的流程可能由模型在运行时动态决定。传统系统通常用结构化查询访问状态;Agent 则会把历史、经验和上下文塞进向量化记忆里,再按语义检索出来。也正因为这样,它获得了极强的适应性,但安全边界也开始变得模糊。
理解 Agent 风险,最有用的办法是看七个设计维度:输入信任度、敏感数据访问级别、工作流灵活性、行动能力、记忆能力、工具范围,以及用户界面复杂度。它们几乎都指向同一个结论:从“没有外部数据、没有工具、只能文本回复”一路走到“可读写任意环境、可调用任意工具、可跨会话持久记忆、可操作网页和 IDE”,功能当然更强,但攻击面也同步扩大。安全和灵活性之间,不是局部取舍,而是系统性的拉扯。
真正危险的不是一种攻击,而是一整条攻击链
很多人一提 Agent 安全,首先想到的是 prompt injection。但这只是问题的一部分。更完整的攻击面,至少要从三种对手模型去看:外部攻击者、能直接给 Agent 喂输入的用户级攻击者,以及已经碰到系统内部组件的内部攻击者。
对应地,攻击路径也不止一条。外部攻击者可以把恶意指令藏在网页、文档或检索结果里,形成间接提示注入;也可以注入恶意数据,让系统在处理金融参数、软件包或其他结构化输入时触发错误。工具本身也可能被污染,既可能是工具描述被做手脚,也可能是工具实现带毒。用户级攻击者可以直接把恶意提示拼进输入。更强的内部攻击者还可以做模型投毒或记忆投毒,让后门和错误知识在后续执行里持续生效。

比攻击向量更重要的是,Agent 暴露出来的风险类型已经从“模型答错”扩展成七类系统风险。最底层的是异构的不可信接口:网页、数据库、记忆库、第三方工具、长期存储、UI,全都可能成为入口。接着是错误地遵循了错误指令,也就是 Agent 被攻击者的上下文带偏。再往后是一个对 Agent 很关键的概念:不受约束的数据流。在传统软件里,数据传播通常受到类型系统、访问控制和明确逻辑约束;在 Agent 里,不可信输入经由模型推理后,很可能自由流向用户回复、后续工具调用,甚至下一步执行环境。再叠加上幻觉和模型失误,问题就不再停留在生成层,而会继续演变成私有数据泄露、未授权操作与数据破坏、以及资源耗尽和拒绝服务。
Agent 的风险会级联放大,而不是彼此独立
Agent 的安全难点,在于这些风险不是并列摆放的,而是会顺着系统链路层层放大。输入信任度、记忆和工具范围的扩张,直接增加攻击入口;工作流越动态,模型越容易在推理链里被劫持;一旦 Agent 又拥有敏感数据访问、执行能力和复杂界面,后果就会从“说错一句话”升级成“泄露、破坏、耗尽”。

一个典型的级联过程是这样的:攻击者先利用不可信外部接口把内容塞进系统,再诱导模型跟随错误指令或让数据沿错误路径流动,最后把结果导向敏感数据泄露或危险操作。这里最值得警惕的是,很多事故不需要特别高深的 payload,只要让 Agent 在一个看似合理的多步流程里走错一步,后面的工具、记忆和权限就会把这个错误放大。
攻击手法本身也在演进。早期很多攻击仍然高度依赖人工构造注入点和 payload,但自动化已经开始出现,例如面向 Agent 的模糊测试、专门生成恶意指令的小模型,以及针对记忆系统的语义注入:把错误内容优化得和目标查询在向量空间里足够接近,从而更容易被检索出来。对 Agent 来说,这意味着“检索到什么”本身也可能是一种被操纵的执行前提。
真正可用的防守,必须从运行时一路做到架构层
如果攻击是一条系统链,防守就不能只在入口加一个分类器。更合理的目标可以分成四个方向:保密性、完整性、可用性,以及 Agent 特有的上下文安全。前三者很熟悉,第四个更像是给 Agent 补上的安全基线:系统在执行过程中,究竟哪些上下文能进入决策,谁的优先级更高,什么信息在当前任务里本来就不该被采纳。

落到技术实现上,防线大致分成四层。
第一层是运行时保护。输入护栏负责检查用户输入、检索结果、记忆内容;输出护栏负责拦截危险回复、代码和工具调用。信息流控制与 taint tracking 试图回答一个更本质的问题:不可信数据是否影响了本不该被影响的决策。监控系统则从更长的执行轨迹里看异常,而不是只盯某一个 prompt。再往前一步,人类确认机制可以在高风险动作发生前加入最终授权。
第二层是架构层的安全设计。最重要的是最小权限和权限隔离。planner 和 executor 可以分开,工具结果处理和工具规划可以分开,甚至不同能力由不同 Agent 承担,这样即使某一部分被攻破,影响范围也不会立即蔓延到整个系统。形式化验证也开始进入这个领域,试图在 GUI 操作、计划约束和工具顺序上做可证明的安全保证,虽然它和概率式模型之间还存在很大的方法鸿沟。
第三层是身份与访问管理。当 Agent 真的开始代表用户调用外部服务时,系统就必须回答几个以前不够紧迫的问题:当前执行主体到底是谁,是用户、Agent 实例,还是某个短期任务身份;权限是怎么委托下来的;访问控制是静态规则还是会随上下文变化;凭证又该如何存储、轮换和分发。没有这一层,Agent 很容易变成一个拿着过度权限四处行动的自动化代理。
第四层是组件加固。模型侧可以训练它更稳定地遵循高优先级指令,工具侧可以对工具描述和元数据做签名、审核和版本控制,减少工具投毒与描述欺骗。
但每一层都有现实代价。护栏会有误报和漏报,信息流控制会带来高开销和“标签蔓延”,监控会引入存储与隐私问题,人类确认会导致决策疲劳,权限隔离会损失易用性,形式化验证又很难完整刻画随机模型的行为。所以,Agent 安全真正需要的不是某个银弹,而是协调好的纵深防御:多层机制一起工作,而且彼此不能互相拆台。
现实里的 Agent 现在防到哪一步了
把视角拉回现成系统,会发现今天的大多数防御都还停留在“能挡一点后果,但挡不住成因”的阶段。
编码 Agent 的思路相对统一:既然它们主要在用户相对信任的工作目录里工作,那就优先限制动作,而不是试图把所有输入都洗干净。于是,文件写入、命令执行、越权访问通常会被输出护栏、访问控制和人工确认包起来。Codex 倾向于把命令默认放进受限沙箱里执行,必要时再申请提权;Gemini CLI 更依赖 allowlist、denylist 和用户审批;OpenHands 进一步把不同能力拆给不同 Agent,并在工具调用前打安全风险分数。问题在于,这些系统普遍缺少强信息流控制、细粒度身份管理和真正自动化的异常检测,很多监控仍然只是事后看日志。
Web Agent 的情况更难,因为它们天然要处理来自开放网络的不可信内容,同时又常常代表用户接触登录态、支付、邮件和云盘。于是,输入护栏、输出护栏、凭证保护和监控成了常见组合。Browser Use 会过滤部分页面元素并对敏感信息做占位替换;Nanobrowser 会用分隔符和额外提示把用户目标与页面内容隔开,同时把 planner 和 navigator 拆开;Skyvern 则更强调一次性密码之类凭证的隐藏与恢复。但这些方法大多依赖人工维护规则,覆盖面有限,而且监控通常还没有接上实时拦截能力。
AutoGPT 给出的教训是补丁常常只修后果,不修源头
AutoGPT 之所以有代表性,不只是因为它常见,而是因为它几乎把 Agent 的高风险能力都暴露了出来:能搜网、能读文件、能查历史记忆,也能执行 shell、改文件、跑 Python。这样的系统一旦把外部内容纳入执行链,风险会非常直观地落到真实漏洞上。
它暴露过几类很典型的问题。比如 Docker Compose 配置文件可被覆盖,导致重启后容器逃逸;路径遍历可以把文件写到沙箱之外;网页中的 ANSI 转义序列能伪造终端输出,误导人类操作员;缺失 CSRF 保护和宽松 CORS 会让恶意页面代替用户发起请求;命令校验如果只检查第一段 token,就拦不住 &&、; 这类链式命令。这里尤其值得注意的一点是,最后一种情况甚至不一定需要外部攻击者,模型自己的幻觉也可能生成危险组合命令。

这些漏洞后来的修补方式也很说明问题:只读挂载、路径规范化、正则过滤 ANSI、CSRF token、严格 CORS、命令 allowlist。它们当然有用,但大多只是在后果发生前加一个窄口子。真正更上游的问题——间接提示注入为什么能进入决策链,不可信数据为什么能一路流到 shell、文件系统和终端——往往还留在系统里。这也是今天很多 Agent 安全方案的共同短板:它们擅长给具体事故贴补丁,却还没有把“不可信输入如何穿过整个系统”这件事从根上管住。
下一步真正值得投入的方向
接下来最值得做的,不是继续堆更多单点防御,而是把 Agent 当成真正的系统来治理。几个方向尤其关键。
第一,要有更接近生产环境的评测方法。很多防御在简化设定里看起来有效,一到真实网页、真实文件系统、真实工具链和长流程任务里就掉线。
第二,要让多层防御能组合,而不是互相打架。输入清洗、输出护栏、信息流控制、权限隔离、人工确认、访问控制,这些机制要能在同一条执行链里协同,不要一层为了“更安全”反而破坏了另一层依赖的上下文。
第三,身份、权限和凭证管理必须标准化。只要 Agent 继续代表用户行动,谁在执行、以什么权限执行、凭证由谁持有、何时失效,就不再是附属问题,而是系统核心。
第四,安全性和可用性必须一起设计。一个处处弹窗确认、处处误报的 Agent,最后很可能只是逼着用户把所有保护都关掉。真正可落地的系统,需要能在风险、延迟、成本和用户体验之间做动态平衡。
Agent 安全已经不再是“防模型被绕过”这么简单了。它更像是把传统系统安全、应用安全、身份治理和模型行为控制重新压进同一个运行时。谁能先把这几层拼起来,谁才有机会做出真正可用、也真正可信的 Agent。