先说结论:如果你最近在跟安全圈的朋友聊自动化测试,一定会发现话题已经从“大模型能不能写个POC脚本”变成了“AI Agent能不能一个人把渗透测试从头跑到尾”。USENIX Security 24 之后,Excalibur 这类预印本被反复提起,我想认真聊的其实不是某个AVI分数,也不是某个benchmark的数字,而是所有人都绕不开的那个痛点:AI 渗透 Agent 在长链路任务里为什么总是崩。
我先把“长链路”这个词拆一下。一次完整的渗透测试,不是“扫一下端口、看到个CVE、甩个exploit”这么简单。它大概是:信息收集、指纹识别、漏洞定位、利用尝试、权限提升、内网横向、痕迹清理,中间还夹杂着大量“此路不通换一条路”的判断。每一步都可能依赖上一步的输出,任何一步的判断错了,后面整个链路就会跟着歪。人类测试员能扛住这种长链路,靠的是经验和上下文记忆;传统的自动化工具能扛住一部分,靠的是提前写好的逻辑分支;而AI Agent想扛住,目前最尴尬的地方恰恰就在这里——它在大模型加持下看起来很聪明,但真正跑长链路的时候,错误会像滚雪球一样越滚越大。
这篇预印本给了我很多值得琢磨的素材,我把它当成一次案例分析读完了。下面我会依次拆一下这件事的背景、长链路必崩的底层原因、以及真正落地时该怎么设计一个“不那么容易崩”的Agent。不保证你看完就能造出自动化渗透系统,但至少能让你在给别人讲“为什么大模型做不了渗透”的时候,说出点有信息量的话。
1. 从“单点脚本”到“长链路任务”,AI 渗透 Agent 到底在涨什么本事
1.1 传统自动化与 Agent 式自动化的本质区别
先说为什么大家会突然对 AI 渗透 Agent 这么上心。传统的自动化渗透,本质上是“人写规则,机器执行”。比如你用某个漏扫工具扫了一轮,拿到结果,再根据结果决定下一步,或者让脚本按预置流程走一遍。这套逻辑在短链路、确定性高的场景下非常稳,但它有个硬伤:当环境变得复杂,或者目标行为超出预设规则时,自动化就断了。规则没覆盖到,机器就只能停在那,等人来看。
Agent 式的做法完全不一样。它把“观察-思考-行动-反馈”这条循环交给大模型来驱动。也就是说,同样面对一个未知端口,传统脚本会看“有没有匹配已知服务的特征”,而 AI Agent 可以临时推理:“这个端口返回的 banner 有点怪,我是不是该额外发几个探测包?”这种临时推理能力,在单点任务上已经被验证过很多次了,比如拿 LLM 去辅助写正则、辅助分析 JS 文件、辅助判断漏洞类型,效果都不差。
但渗透测试真正难的地方不是单点,而是链路。你需要同时记住“目标网段有多大”“之前测过哪台机器”“那台机器上留了一个 webshell 还没清理”“当前这台机器的权限是普通用户”“接下来应该先提权还是先看内网路由”。这些信息横跨几十甚至上百轮交互,每一轮都可能产生新的临时结论。大模型本身擅长处理局部判断,但在这种需要持续维护“全局状态”的任务里,它的缺陷会快速暴露出来。
1.2 Excalibur 这类预印本为什么会被反复转发
Excalibur 在标题里被反复提及,我理解它的价值不在于“提出了一套完美方案”,而在于它把失败这件事讲得很系统。之前大家在社区里吐槽 AI 渗透 Agent 的时候,多半是零散的经验:“跑着跑着就开始胡言乱语了”“上下文太长了它就忘了目标”。但这些吐槽没有形成体系,也很难指导别人改进。
Excalibur 这类工作做了一件事:它把“长链路必崩”拆成了可以观察、可以量化的失败模式。为什么要这么做?因为只有把崩的原因定位清楚,后续才能有针对性地设计架构、设计工具调用方式、设计记忆管理机制。这就像医疗诊断一样,你得先知道是心脏问题还是血管问题,才能谈治疗方案。预印本的价值也就是这个:先给出诊断框架,而不是急着宣称自己发明了万能药。
当然,预印本和正式论文还是有区别的。预印本更多是早期成果分享,可能在实验设置、基线对比上还不够完善。所以看这类材料的时候,我的建议是重点看问题定义和失败分析,不要只盯着最后的指标。
2. 长链路必崩的底层原因:五个“死法”拆开看
我读完 Excalibur 的失败分析之后,又结合自己实际跑过的一些 Agent 任务,把“长链路必崩”的原因归纳成五个层面。这五个层面不是孤立的,它们经常叠加发生,但拆开看会更清楚。
2.1 错误累积:一步错,后面全错
这是最直观也最致命的问题。LLM 生成的每个中间结论都不是百分百可靠的。单点任务里,一个结论错就错在这次任务;但在长链路里,错误是会传递的。
举个例子。第一轮侦察,Agent 从 HTTP 响应头里判断目标是个 Nginx 服务,然后基于这个判断去查对应漏洞。如果这个判断是错的,后续所有基于“Nginx”的推理都建立在沙地上。更麻烦的是,Agent 经常不会回头质疑自己之前的判断,它会把错误当成既定事实继续往后推。这跟人类测试员不一样,人有“直觉不对”的时候,会重新验证;大模型在生成长链路回复时,倾向于保持逻辑一致性,于是错误就被“一致性”包装得越来越像正确结论。
我自己的体会是,这类错误最好的解法不是让大模型更聪明,而是在关键节点引入“外部验证”。比如如果一个结论会被后续步骤依赖,那就必须有一次独立的工具调用来确认,而不是让模型凭经验推断。可惜,很多 Agent 架构并没有强制这种验证逻辑。
2.2 上下文记忆衰减:token 越滚越多,有效信息越来越少
长链路的另一个硬伤是上下文窗口。现在的模型上下文窗口做得越来越大,但大不代表好用。当对话轮次超过几十轮之后,早期的重要信息会被淹没在海量的中间步骤里。模型不是记不住,而是“不知道该重点记什么”。
打个比方,你让一个实习生去整理一份 100 页的报告,他的理解能力没问题,但让他从第 1 页一直读到最后,中途还要不断做决定,他大概率会在第 60 页的时候忘了第 10 页提到的某个关键限制。LLM 也一样,上下文窗口里每个 token 的注意力权重不是均匀分配的,早期的、细节性的信息很容易被后续大量观测结果稀释。
Excalibur 的分析里有一个现象很有意思:Agent 在任务后期经常会“忘记”自己已经拿到过的权限或已经确认过的信息,然后重复做之前已经做过的操作。这不仅是效率问题,更是正确性问题——重复探测可能会改变目标状态,导致后续判断全部失效。
所以长链路设计里,“记忆管理”不是一个优化项,而是一个必需项。不能把所有历史都塞给模型,而是要有一套机制,把关键状态、已确认事实、待办目标单独维护起来,让模型随时可以查询。
2.3 规划退化与目标漂移:跑着跑着就忘了原本要干嘛
LLM 在做长链路规划时还有一个典型问题:目标漂移。刚开始的时候,Agent 的目标很清晰,比如“先拿下 DMZ 区的一台边缘机器”。跑了几十轮之后,它可能已经在一个子域名上折腾半天了,完全忘了自己原本是要通过这台机器打进内网的。
这背后其实是“长期规划”和“短期反应”之间的冲突。大模型天然擅长对当前这一步做出合理反应,但它对“当前动作与最终目标之间关系”的感知是随着上下文变长而减弱的。我见过一些 Agent 的日志,前 20 轮还很有章法,到第 40 轮就开始出现大量重复动作,甚至开始探测一些与目标完全无关的端口。看起来像是模型“无聊”了,其实是它已经丢失了对全局规划的掌控。
为什么人类测试员很少犯这种错?因为人会时不时停下来反问自己:“我现在在哪?我离目标还有多远?我这一步到底是在推进还是原地打转?”这种元认知能力,目前的大模型在长序列生成里很难自发维持。
解决办法不是让模型更强,而是把规划拆成两层:高层规划在关键节点重新生成,低层执行调用则聚焦当前子任务。不要让同一个上下文既负责“想战略”又负责“打战术”,否则两头都会崩。
2.4 工具调用的反馈黑洞:命令执行了,但 Agent 没看懂结果
渗透测试 Agent 的日常工作大量依赖工具调用,比如扫描器、探测脚本、各类命令行工具。工具本身是可靠的,但工具输出未必是模型能消化的。
这里有个很现实的问题:很多安全工具是为人类设计的输出格式,不是为机器设计的。比如某个扫描工具会输出大量噪声信息,人类可以凭经验过滤掉无关内容,只看关键端口和版本,但 LLM 面对几百行原始输出时,它需要先判断哪些是重点,再结合当前任务进行推理。这个过程中,模型很容易被噪声带偏。
更麻烦的是“空输出”问题。有些工具调用本身是成功的,但没有任何有价值的返回。比如一个端口扫描没有发现开放端口,这是有效信息;但 Agent 可能会把这个结果当成“工具执行失败”,触发重试或者换一个完全无关的方向。反过来,如果工具报错了,Agent 又有可能分不清是环境问题、权限问题,还是目标确实无响应。
在我实际测试里,工具调用失败后的错误处理,是 Agent 崩溃率最高的环节之一。无论是“反馈黑洞”(有输出但没理解),还是“过度反应”(看到非零退出码就乱猜),都会把链路带偏。一个健壮的 Agent 架构必须把“工具结果解析”当成一个独立的、高优先级的模块来设计,而不是让模型直接读原始输出。
2.5 缺少真正的状态追踪:Agent 不知道自己“在哪”
最后这个层面,其实是前面几个问题的根源:Agent 没有一个显式的、可查询的“当前状态模型”。它所有的状态都隐式地存在于上下文的 token 之间,这导致它没法可靠地回答“我现在处于什么阶段”“我有哪些资产”“我有哪些权限”“我试过哪些路径,哪些已经失败”。
为什么渗透测试特别需要状态追踪?因为这个领域的信息是高度分层的:目标资产的层级、权限的层级、网络可达性的层级。人类测试员脑子里会维护一张“地图”,知道自己从哪进来的、已经探索到哪、哪些区域还没去。而现在的 Agent 大多只是把历史对话当作记忆,并没有真正维护这样一张地图。
Excalibur 里总结的失败案例中,“Agent 在已经拿到的权限范围内反复横跳”和“Agent 尝试再次利用已经失败过的漏洞”都是高频错误。这两个问题本质上就是状态追踪缺失的表现。没有状态地图,Agent 就成了一个“失忆的冒险者”,每个决策都像是在随机试错。
这也是为什么我认为,任何号称能做长链路渗透的 Agent 产品,如果底层没有一套显式的任务状态管理器,那么它在真实复杂任务上的崩溃只是时间问题。
3. 实操视角:怎么设计一个“不容易崩”的 AI 渗透 Agent
讨论完原因,就该聊怎么办了。下面这些思路是我结合 Excalibur 的失败分析、以及我自己做过的 Agent 实验总结出来的,不一定是最优解,但至少在长链路稳定性上有实质帮助。
3.1 把“规划者”和“执行者”拆开,别让一个模型干所有的活
我见过很多失败的 Agent 都是单体架构:一个 LLM 被赋予了全部上下文,它既负责判断当前状态,又负责决定下一步动作,还要负责解读工具输出。这就像一个项目经理同时当一线工程师,短期看他好像什么都能干,长链路一跑起来必乱。
更稳的思路是拆分角色。规划者负责维护宏观目标,它不需要关注每一次工具调用的细节,只需要在关键节点拿到摘要,判断当前是否偏离主航线,然后修正子目标。执行者负责具体动作,它只需要聚焦当前子任务,把工具输出整理成结论回传给规划者。两者之间通过一个结构化的“任务队列”和“状态快照”通信。
这个设计的好处是,执行者的上下文可以及时清理,不会无限膨胀;规划者的注意力可以始终保留在目标上,不容易漂移。代价是架构复杂度变高,通信开销变大,但这点代价换来的稳定性是非常值得的。
3.2 显式记忆与检查点:让 Agent 学会“写笔记”
前面说过,大模型很难在大上下文里自动维持有效记忆。所以解决办法是,不要让它全靠上下文记,而是给它一个显式的“笔记系统”。
具体来说,就是在架构中加入一个独立的记忆模块。当 Agent 发现一个事实(比如“目标开放了8080端口,是某框架的默认端口”)时,它就把这条信息写入结构化笔记;当它完成一个阶段性目标(比如“拿下了 web 服务器的低权限 shell”),就更新状态地图。每个新任务开始前,Agent 先读取笔记,而不是翻历史对话。
我试过这种设计之后,最明显的变化是“重复探测”和“重复利用漏洞”这类低级错误大幅减少。笔记系统还可以配合检查点使用:每完成一个子目标,就把当前状态快照保存下来。如果后续某一步崩了,可以直接恢复到最近的检查点,而不是从头开始。
这背后其实借鉴了开发领域的“事务回滚”思想。安全测试本身就是一个充满不确定性的探索过程,允许失败、允许回滚,但不要让失败直接摧毁整个任务。
3.3 工具结果要做结构化处理,别让模型直接啃原始输出
前面提到工具输出的噪声问题,这里说解法。专业做法是在工具和模型之间加一个处理层,把原始输出转换成结构化摘要。
比如扫描器输出了一大段文本,处理层负责提取关键字段:开放端口、服务版本、已知漏洞编号、目标响应状态。模型看到的不是几百行日志,而是几行结构化的 JSON。这样模型就只需要基于解析后的结果做决策,而不是在噪声里大海捞针。
如果工具调用本身出错了,处理层也应该给出标准化的错误分类:是连接超时、权限不足、还是工具不存在?这样模型就不会把“连接超时”误判为“目标不存在”,也不会因为一个权限错误就乱换攻击路径。这一步看起来不起眼,但在我实操里,它对长链路稳定性的提升是立竿见影的。
3.4 给探索行为设置“止损线”,防止 Agent 一条路走到黑
人类测试员在测试过程中会“止损”:一个漏洞利用尝试了两次没成功,就换一个思路;一条路径走不通,就回到上一个分叉点重新选择。而 Agent 常常会在同一个点位上反复尝试,甚至越试越激进,导致任务时间无限拉长。
这需要在架构层面做硬约束。比如给每个子目标设置最大尝试次数,超过次数就强制 Agent 回到规划层重新评估;给整个任务设置最大行动步数,防止陷入死循环;对工具调用频率做限制,防止某些副作用过强的操作被反复执行。
我尤其建议对“破坏性动作”做严格约束。渗透测试里有些操作是不可逆的,比如修改目标系统文件、发送大量流量导致服务崩溃。如果 Agent 在长链路中因为状态丢失而重复执行这类操作,后果会很严重。所以这类动作前面必须加一个“确认阀门”,无论是模型自检还是外部审核,不能让它因为上下文里的某个结论就自动触发。
4. 从 Excalibur 的评估思路里提炼几个关键指标
设计得再好,也得有办法衡量。Excalibur 在评估方面给了我不少启发,我结合自己的实践,挑几个对长链路 Agent 最关键的指标来说。
4.1 任务成功率之外,一定要看“步骤成功率”
很多论文在报指标时喜欢报“任务成功率”,也就是 Agent 有没有最终完成任务。但长链路场景下,任务成功率是个很粗糙的指标。它无法告诉你 Agent 是在第 5 步崩的,还是在第 50 步崩的。
更值得关注的是“步骤成功率”,特别是“关键子目标完成率”。你可以把一次渗透测试拆成若干个里程碑,比如:完成信息收集、发现可利用漏洞、获取初始权限、提升权限、内网横向移动。每个里程碑单独统计“是否完成”和“尝试了多少步”。这样才能定位出 Agent 的瓶颈在哪个阶段。
我自己做过一个统计,很多 Agent 在“信息收集——漏洞发现”这一段的完成率还不错,但一到“权限提升——内网横向”就开始断崖式下跌。这说明模型对跨主机、跨权限的整体推理能力还是弱项,而不是它不懂工具。
4.2 平均“崩溃步数”和“恢复成本”
除了成功率,还要看崩溃发生的位置和恢复难度。具体来说,可以统计一个指标:Agent 从开始到出现不可恢复错误或者明显偏离主线的平均步数。这个数字越高,说明 Agent 的稳定性越好。
“恢复成本”更实用。一次失败之后,Agent 需要回退多少步才能重新走上正轨?是需要回退 3 步,还是需要从头开始?如果你设计的架构有检查点,恢复成本应该被控制在一个很小的范围内。如果某个 Agent 一崩就得重跑,那它本质上还是一次性脚本的质量,不具备长链路能力。
4.3 评估环境的选择:靶场和真实环境的差距
最后提醒一下评估环境的问题。很多 Agent 在靶场环境里跑得很好,一到真实目标环境就各种崩。原因是靶场环境的结构相对固定,信息收集阶段就能比较准确地判断出技术栈,而且不会出现真实环境中常见的反爬、流量干扰、动态端口、跳板机等意外情况。
所以看预印本里的评估结果时,一定要关注它用的测试环境是什么。如果是自建靶场或者已知的 CTF 环境,那只能说明 Agent 在理想化了条件下的能力;如果它能在真实授权测试环境里跑通多个不同的业务系统,含金量会高很多。Excalibur 在这方面的设置我没有细看,但我觉得对于任何做 Agent 评估的人来说,这一点都值得单独拿出来琢磨。
5. 落地路上的避坑笔记
5.1 别真把整个渗透流程全权交给 Agent,人机协同更现实
很多人被“AI 渗透 Agent”这个词刺激到,以为它真的能全自动接管一次完整的渗透测试。我自己的结论是,至少在现阶段,长链路自动化只能做到“有人监督的半自主”。Agent 能帮你省下大量前期侦察、批量验证、基础利用的时间,但在关键决策点,比如是否使用某个有风险的操作、是否进入内网横向阶段,最好还是人来做最终判断。
这不是保守,而是现实考量。Agent 的推理能力虽然在进步,但它对“上下文之外”的业务的判断能力非常有限。比如当一个操作可能触发目标系统的告警,或者可能违反测试授权边界时,Agent 可能完全没有感知。这种“边界感”需要人类经验来兜底。
5.2 Agent 自身的安全问题也要提防
最后提一个容易被忽略的角度:Agent 本身也会成为攻击目标。当你把大模型接入渗透测试工作流,它要读取大量目标信息、要执行很多命令,如果 Agent 的调用链路被污染,比如提示词注入、工具结果被篡改,那么它不仅帮不了你,反而可能被目标系统反向利用,把恶意指令带给你的基础设施。
所以做 Agent 架构的时候,一定要把输入输出的隔离做好。目标系统的响应内容不应该直接作为高权限指令的来源;工具解析层要对输出做清洗,过滤掉可能包含恶意指令的内容。Agent 的日志和状态数据也要按敏感级别分开存储,避免测试过程中泄露过多目标信息。这个点现在越来越多地被论文里提到,我认为未来它会成为 AI 安全里一个非常重要的分支。
6. 最后分享一点个人体会
如果在看完这一堆分析之后你只能记住一件事,那就是:长链路不等于“更多的对话轮次”,它是对 Agent 的记忆系统、规划系统、状态追踪系统和容错机制的综合考验。
Excalibur 以及类似预印本给我最大的启发,不是“原来 AI 渗透 Agent 不行”,而是“原来不行可以不行得这么清楚”。失败模式被拆明白了,改进就有方向。我在自己的项目里验证过,只要把状态追踪和上下文管理做到位,长链路的成功率提升会非常明显——虽然还达不到让人彻底放手的水平,但已经足够在授权的攻防演练里成为靠谱的副驾驶。
如果你正准备上手做 AI 渗透 Agent,或者只是对这个方向感兴趣,我的建议是从小任务开始,把每个环节拆开,先解决“不崩”的问题,再追求“更快更强”。毕竟在复杂任务里,不崩本身就是一种很强的能力。