2
0

为什么漏洞挖掘 Agent 不能只是“大模型加循环”?

2026-06-22

最近我在准备一套能够长时间运行的漏洞挖掘系统。它需要读取目标项目、调用分析工具、理解结果、提出新的检查方向,并在尽量少依赖人工干预的情况下持续工作。由于运行环境后续可能断网,模型、工具、知识库和执行脚本还必须提前部署完整。

这个过程让我重新思考了一个看起来很简单的问题:一个大模型能够调用工具,再给它套上一层循环,它是不是就成为了可以持续工作的 Agent?

短时间演示时,这种方案往往确实能跑。模型读代码、执行命令、分析输出,然后决定下一步,看起来已经具备完整的自主性。但当运行时间从十分钟延长到几小时甚至几天,问题会迅速暴露出来。真正困难的部分不再是“模型会不会分析漏洞”,而是整个系统能否持续、可靠、可恢复地推进任务。

会调用工具,不等于能够长期工作

最简单的 Agent 可以被概括为一个循环:模型观察当前信息,生成动作,工具执行动作,再把结果返回给模型。只要任务规模不大,这个结构非常有效。

但漏洞挖掘不是一次问答。它可能包含代码审计、入口定位、调用链分析、危险函数确认、约束推导、测试用例生成和结果验证等多个阶段。一次工具调用失败不代表方向错误,一次命令成功也不代表漏洞成立。系统需要在大量不完整证据之间不断调整策略。

如果所有历史信息都直接塞进上下文,输入会越来越长,真正重要的线索反而会被命令输出和重复讨论淹没。模型可能忘记已经检查过的函数,也可能对同一条失败路径反复尝试。更麻烦的是,长时间运行时一定会出现超时、进程退出、输出截断、磁盘空间不足或服务重启。单纯的循环并不知道应该如何处理这些异常。

因此,“能做下一步”与“能把整个任务做完”其实是两种能力。前者主要依赖模型,后者依赖系统工程。

长时间运行会放大四类问题

1. 上下文不是可靠的长期记忆

模型的上下文适合保存当前推理所需的信息,却不适合作为整个任务的数据库。随着分析深入,原始代码、搜索结果、编译日志和模型结论都会不断累积。即使上下文窗口足够大,也不意味着把所有内容放进去就是合理的。

长期任务需要把信息分层保存:原始工具输出进入文件或数据库;已经确认的事实写入结构化状态;当前阶段只加载与眼前决策有关的内容。模型应该消费经过筛选的证据,而不是每次重新阅读全部历史。

2. 错误会在循环中累积

一次错误判断在普通对话中只影响一个回答,在自主 Agent 中却可能影响后续几十步。比如模型错误地把某个函数判断为外部输入入口,之后的污点分析、路径搜索和测试生成都会建立在错误前提上。

因此,关键结论不能只记录“模型认为是什么”,还要记录证据来自哪里、是否经过工具验证、置信度如何,以及什么结果可以推翻它。漏洞挖掘尤其需要区分“可疑点”“可达路径”和“已验证问题”,否则系统很容易把猜测逐渐包装成结论。

3. 工具执行不是天然可靠的

安全分析工具常常运行时间长、输出量大,而且不同工具的返回码和错误语义并不统一。命令超时可能意味着目标过大,也可能只是参数不合适;静态分析没有结果,既可能说明不存在问题,也可能说明规则没有覆盖。

Agent 不能只看到一段终端文本。执行层至少需要记录命令、开始与结束时间、退出状态、标准输出、错误输出、资源消耗和产物位置,并为不同失败类型设置不同的重试策略。否则模型得到的只是一个模糊的“失败了”,很难做出稳定判断。

4. 进程活着不等于任务在前进

一个 Agent 可以连续运行很久,却一直重复搜索相同关键词,或者在几个方向之间来回切换。CPU 和模型服务都在工作,但任务没有获得新的证据。

所以系统必须定义“进展”。它可以是发现新的入口函数、确认新的调用关系、排除一个候选点、生成可复现的测试结果,或者完成一个分析阶段。监督模块需要定期检查这些指标。如果若干轮都没有有效进展,就应该压缩上下文、切换策略、回滚到检查点,或者结束当前分支。

一个可持续的 Agent 至少需要四层

在实践中,我更倾向于把系统拆成四个职责明确的部分。

第一层是模型。它负责理解代码、提出假设、选择工具和解释结果。模型擅长处理语义与不确定性,但不应该独自承担状态保存和进程管理。

第二层是工具执行器。它把模型给出的意图转换成受约束的命令,控制超时、工作目录、资源和输出规模,并将执行结果整理为统一格式。对漏洞挖掘而言,这一层还应限定允许调用的工具和参数范围,避免一次错误决策影响整个环境。

第三层是任务编排器。它维护任务队列、阶段状态、依赖关系和检查点。例如,只有在入口分析完成后才进入路径验证;一个候选点失败后,应当回到待分析队列,而不是让模型凭记忆决定接下来做什么。

第四层是监督器。它不直接分析漏洞,而是观察 Agent 是否仍在推进:模型服务是否可用、工具是否频繁超时、上下文是否过长、同一动作是否重复、磁盘和内存是否接近上限。必要时,它负责重启任务、恢复检查点或终止失去价值的分支。

这四层可以运行在同一个程序中,但职责不能混在一起。模型负责“想”,执行器负责“做”,编排器负责“接下来做什么”,监督器负责“系统是否还正常”。

恢复能力比连续运行更重要

设计长时间任务时,一个常见目标是让 Agent 永远不要停。但实际环境中,进程退出和服务重启无法完全避免。真正可靠的系统并不是从不失败,而是失败后知道自己做到了哪里,并能从最近的有效状态继续。

每完成一个关键阶段,系统都应该保存检查点,其中至少包括:当前任务、已确认事实、待验证假设、已执行动作、产物路径和下一步候选动作。恢复时不应重新把全部日志交给模型,而应先加载结构化摘要,再按需读取原始证据。

任务还需要具备幂等性。相同动作被再次调度时,要么能够安全重复执行,要么能够识别已有结果并直接复用。否则一次重启就可能导致重复扫描、覆盖产物,甚至让多个进程同时处理同一目标。

从这个角度看,断点恢复不是附加功能,而是长时间 Agent 的基本能力。

断网环境暴露了真正的依赖

联网时,许多缺失依赖可以临时下载,模型也可以随时查询外部资料。断网部署迫使我们提前回答一些平时容易忽略的问题:模型文件是否完整?容器镜像能否离线恢复?知识库是否已经建立索引?工具的规则库和运行时依赖是否齐全?重启后服务以什么顺序恢复?

这反而是一种很好的系统检验。一个真正可控的 Agent,核心能力不应该依赖运行过程中临时访问未知资源。模型、知识、工具和状态都应当有明确的位置、版本和恢复方式。

对于漏洞挖掘系统来说,这也意味着模型不是唯一资产。经过验证的规则、历史分析经验、项目构建信息、工具输出解析器,以及能够复现结果的脚本,同样决定了最终效果。

Agent 的价值不是替代所有人工判断

我并不认为现阶段的漏洞挖掘 Agent 应该以“完全替代安全研究员”为目标。它更现实的价值,是持续完成那些范围大、重复度高、需要多轮工具配合的工作,并把值得人工关注的路径连同证据一起整理出来。

模型可以提出大胆假设,但系统必须保守地管理结论;Agent 可以自主探索,但每一步都应留下可审计记录;任务可以长时间运行,但必须能够被暂停、恢复和复现。

当这些基础能力具备后,更强的模型确实会带来更好的代码理解和策略选择。反过来,如果没有状态管理、执行约束和监督机制,再强的模型也可能只是在更快地消耗上下文和计算资源。

结语

“大模型加循环”是构建 Agent 的起点,却不是一个可长期运行系统的终点。真正的难点藏在循环之外:如何组织证据、判断进展、隔离失败、恢复状态,并保证每个结论都能追溯到实际结果。

漏洞挖掘天然具有长链路、高不确定性和强验证要求,因此它也是检验 Agent 工程能力的一个好场景。最终决定系统能否工作数天的,可能不是某一次推理有多精彩,而是它在第一百次工具调用失败之后,仍然知道自己在哪里、为什么失败,以及下一步应该做什么。

Comments