最近,我开始把 Agent 开发和安全学习放在一起看。之前收集的智能渗透比赛资料,关注的是 Agent 怎样推进安全测试;另一批 Agent 安全文献,关注的是外部信息怎样影响它的决策和工具调用。这两条线放在一起,反而更容易看清一个 Agent 系统需要解决什么问题。

这篇文章以资料阅读和源码分析为主,重点参考腾讯智能渗透挑战赛资料、BreachWeave,以及 AgentDojo、AgentPoison 和 CaMeL。文中没有独立复现的比赛成绩或实验指标;后面的实现建议,是我根据这些材料整理出的开发思路。

两个方向,先分清楚

“用 Agent 做安全测试”和“测试 Agent 的安全性”经常出现在同一段讨论里,但它们的目标不同。

方向 测试对象 需要回答的问题
Agent 辅助渗透测试 已授权的应用、接口或靶场 能否根据反馈调整路线,并拿出可验证的发现?
Agent 自身的安全测试 Agent 的输入、记忆、工具和权限 不可信内容能否改变任务目标,或者触发越权操作?

前者强调任务能力,后者强调执行边界。一个能熟练调用工具的 Agent,也可能被工具返回的内容误导。因此,开发时需要同时考虑“任务有没有推进”和“推进过程中有没有偏离授权范围”。本文讨论的渗透测试场景限于授权环境与隔离靶场。

工具调用之后,还需要一个任务闭环

我最初理解 Agent 时,比较容易把注意力放在工具上:能调用终端、浏览器和检索接口,似乎就能组合出完整流程。但工具返回结果以后,系统还需要判断这次动作说明了什么。

例如,一次接口请求没有得到预期结果,可能是参数不符合要求、环境暂时不可用,也可能是当前假设不成立。这几种情况对应的下一步完全不同。如果只记录“失败了”,后面就很容易重复执行相同动作,或者过早放弃仍有价值的方向。

因此,我更愿意把 Agent 看成一个持续更新状态的程序:提出假设,选择动作,读取反馈,核对证据,再决定继续、换路或停止。模型负责理解和选择,运行框架负责保存状态、执行约束和检查结果。

腾讯智能渗透挑战赛的资料仓库提供了答辩材料、项目导航和赛事接口文档,很适合用来观察不同团队如何组织这个过程。阅读时,我会把答辩中的设计主张、代码中能确认的实现,以及自己据此作出的判断分开记录。部分幻灯片信息有限,不适合仅凭几个术语就还原整套架构。

BreachWeave:把编排、执行和监督拆开

本次重点查看的 BreachWeave 采用 Manager、Solver、Observer 三种角色。为了让阅读结论可追溯,下面的实现分析以本地保存的 ceac953 版本为准,而不假设它代表项目之后的所有变化。

角色 主要职责 我关注的设计问题
Manager 组织题目推进、分配执行者、汇总状态 如何安排任务,减少重复工作?
Solver 面向具体方向执行工具和验证假设 每一步有没有带来新的证据?
Observer 检查执行状态,维护策略与记忆 怎样在上下文变长后保留有效信息?

这组分工可以在该版本的 README 中找到说明。我从中得到的启发是:长任务里的调度、执行与复核,可以有不同的输入和职责,不必全部挤在同一个对话里。

不过,多 Agent 是否值得,仍然需要评测。增加角色会带来额外的模型调用、同步和冲突处理。如果两个执行者一直做相同尝试,并发只会放大成本。对我后续的实现来说,应该先让单个执行者形成可靠闭环,再观察哪些工作确实适合独立出去。

Idea 和 Memory:假设与记录要有不同的位置

在 memory.ts 中,Idea 有 pending、testing、verified、failed、skipped 等状态;Memory 则区分事实、证据、失败、笔记和提示,并保留来源及引用。

这比把所有内容写成一份不断增长的聊天摘要更容易检查。假设回答“接下来验证什么”,记录回答“目前观察到了什么”。但记录被放进 Memory,并不意味着内容天然可信;它仍需要来源和证据支持。

下面是我自己整理的记录示例,并非项目原始数据格式:

1
2
3
4
5
6
7
8
{
"hypothesis": "两种测试账号可能拥有不同的资源读取权限",
"status": "testing",
"observation": "账号 A 和账号 B 在同一测试条件下得到不同响应",
"evidence_ref": "lab-run-001/response-diff.txt",
"unknown": "差异来自权限规则还是测试数据",
"next_check": "使用预先准备的资源和账号组合复核"
}

这里刻意保留了未知项。响应不同只是观察,权限存在缺陷还需要进一步验证。提前把推测写成事实,后续规划和最终报告都会受到影响。

Observer:保留有用的信息,也保留失败的边界

该版本的 Observer 实现 强调维护已有思路、合并重复记录,以及在缺少新证据时不新增内容。它也区分“一次具体尝试失败”和“整条假设已被排除”。

这个区别对普通开发也很有用。一次测试报错,可能只暴露了环境或输入问题;如果把它直接概括为“方案不可行”,摘要就会误导下一轮工作。我的理解是,压缩上下文时应优先保留前提、证据位置、失败条件和未决问题,让后续执行者知道结论在哪里有效。

停止条件应当连接到可检查的结果

BreachWeave 的 ralph-loop.ts 会在 Agent 结束时向宿主检查题目完成状态;未完成时可以触发续跑,连续错误则有重试上限和退避。也就是说,一次模型回复结束,与题目完成是两个不同事件。

我想把这个思路迁移到自己的 Agent 开发中:先定义可观察的验收条件,再设计执行循环。修复代码要对应相关检查结果;整理资料要对应来源和交付文件;安全测试报告则需要对应复现条件、证据和影响范围。

真实测试比 CTF 更复杂,不能直接照搬“拿到 flag 即完成”的判定。预算耗尽、环境故障、范围受限和发现已验证,也应该分别记录。否则,“没有验证到问题”很容易被误写成“已经证明没有问题”。

Agent 读取的测试对象,也可能影响 Agent 本身

整理完执行架构,再回头看 Agent 安全文献,会发现一个直接相关的问题:测试中的网页、接口响应和文档,本身就是 Agent 要读取的外部内容。

如果这些内容混入要求改变目标、读取额外文件或调用其他工具的指令,系统需要区分它们与用户的真实任务。这也是提示注入研究关注的核心问题之一。

  • AgentDojo 提供了工具交互环境,用来评测外部数据中的提示注入攻击与防御。它提醒我同时看正常任务表现和攻击后的行为,避免把“大量拒绝正常任务”误当作充分的安全改进。
  • AgentPoison 研究长期记忆或知识库投毒。它让我进一步注意到,风险可能在检索后进入后续规划,因此记忆的来源、写入和复用都需要考虑信任边界。
  • CaMeL 从控制流、数据流和能力权限出发设计防护层。对开发的启发是,把部分约束落实到运行系统中,而不能只依赖提示词。论文中的安全性质有具体前提,不能推广成所有 Agent 都已得到通用保证。

据此,我会优先考虑三类约束:限定工具能访问的资源,区分外部内容与任务指令,以及让关键动作留下可审计记录。监督 Agent 可以辅助发现问题,权限控制仍应由程序执行。

下一步,我想做一个能比较的最小实验

这些资料给了我不少实现思路,但阅读材料还不足以回答哪种设计对自己的任务最有效。下一步更适合在可重置的本地靶场里,先做一个小实验。

基线系统只放一个执行者、少量工具、结构化记录和明确的终止条件。随后分别加入记忆管理、旁路监督和受限并发,每次只改变一项机制。比较时固定模型版本、题目集合、时间与调用预算,并保留多次运行的结果。

观察项 记录什么
任务完成情况 外部验收通过的任务数,以及未完成原因
发现质量 已复核发现、误报和证据缺失情况
执行效率 耗时、调用次数与重复动作
状态恢复 中断后能否利用已有记录继续
执行边界 是否尝试超出范围的动作,是否被系统阻止

这只是后续实验计划,目前没有对应的实测结果。对我来说,当前最有价值的学习收获,是开始把 Agent 的能力拆成可以实现、观察和比较的环节:任务怎么分配,证据怎么保存,状态怎么恢复,结果怎么确认,权限又在哪里执行。

资料入口

本文依据本地已有资料重新整理,并核对了以下公开来源。源码细节以文中固定版本链接为准;不将竞赛表现等同于真实生产环境效果。

  1. 腾讯智能渗透黑客松资料仓库:赛事材料、团队项目与接口文档入口。
  2. BreachWeave:多角色架构及任务状态管理源码。
  3. AgentDojo:提示注入攻击与防御评测。
  4. AgentPoison:长期记忆和知识库投毒研究。
  5. Defeating Prompt Injections by Design(CaMeL):控制流、数据流与能力权限防护。
  6. Design Patterns for Securing LLM Agents against Prompt Injections:继续阅读不同防御结构及其适用条件。

本文由 AI 辅助查找本地资料、核对来源和整理表述。源码阅读结论、个人理解与后续实验计划已分别说明。


从 Agent 开发到智能渗透:一次源码与安全学习整理
https://shang-swk.github.io/2026/10/16/agent-pentest-learning-notes/
作者
shang-swk
发布于
2026年10月16日
许可协议