一个用于自主攻击性LLM代理的确定性测试框架与操作手册,通过强制执行授权、范围和证据门控,确保渗透测试的可复现性与诚实性。
一个用于自主攻击型智能体的确定性约束框架。模型始终是概率性的。宿主应用拥有授权、允许的操作、证据记录和验收权。重放冻结的输入和策略可以复现这些控制决策;但这并不能使实时目标或模型响应变得可重复。
python3 -m pip install -r requirements.txt
python3 -m harness.demo --out /tmp/harness-report.json
diff -u harness/report.json /tmp/harness-report.json
python3 -m pytest tests/test_harness.py
本次发布已在 CPython 3.14 上验证。较早的 Python 版本不属于发布证据的一部分;如果你使用较早版本,请在依赖结果之前运行下面完整的门禁序列。
分阶段构建:约束副作用边界和阶段顺序;描述通过测量事实和目录来刻画目标;证明通过捕获和独立的策略谓词来验证声明;控制与核算授权、门禁、完成情况和未完成的工作。开发顺序不是运行时顺序:授权和门禁先于调度。
公开实验室不发起任何网络请求,也不调用任何模型。其证明谓词是合成的,其宿主和适配器是可信的,每条发现都标记为需要人工审查。实验室不实现个人的验收或报告签署流程。逐字引用确立的是引用完整性,而非可利用性。更少的模型调用和更少的返工是设计目标,而非由语料库测量的节省。
以下章节描述了早期的 core/ 和 walkthrough/ 实现及其已公开的缺陷。其缺失的模型调用验证器在该历史路径中仍然缺失。新的 harness/ 包是一个独立的离线控制参考;它不会追溯性地修复语料库或历史模块。在复制历史组件之前,请先阅读第 07 章的边界和修正。
将一个能力强大的模型指向一个宿主,交给它一个工具箱并告诉它运行渗透测试,它会做出合理的事情。明天再运行一次,它会做出其他合理的事情,而两次运行都无法告诉你为什么它跳过了另一次捕获到的内容。本手册主张让模型承担更小的任务:将每个决策交给能够正确做出该决策的最廉价层级,并且仅在答案确实无法从已有信息中推导出来时才投入模型能力。从表格能做出的决策到少数需要模型的决策,这个排序就是第 00 章标题中的梯度。各章节跟随一个工作中的攻击性安全智能体及其失败所要求的控制项。
历史系统有两条编排路径。在服务器驱动路径上,编排器维护自己的阶段列表,只向模型提供该阶段允许的工具。在智能体驱动路径上,编排模型规划运行并自行调用工具,其下的各层被构建但并非总是被咨询。共享写入路径使记录的操作和发现可审查,但可用的 shell 可以绕过它。虚构的端点会获得捕获的响应,而非自动的漏洞判定。严重性治理器不能提升;独立验证器的历史提升门禁检查引用但不确立可利用性。授权在工具边界处被询问,而非在每个出站请求处。报告章节区分了未发现任何内容的扫描与被拒之门外的扫描。意图与执行之间的这些差异是案例研究的一部分,而非要复制到新框架中的属性。
除第一章外的每一章都以承认其控制项仍然存在的错误结尾,而诚实性部分承载了证明这些错误的测量数据。如果你正在决定是否信任其余内容,请先阅读诚实性部分:语料库是一个系统的运行历史,选定的公开目标运行是作者记录的聚合数据,旁边发布了两次被排除的运行,而能够展示确定性层实际贡献多少的消融研究尚未运行。该仓库不包含选定运行的原始发现、地面真值或匹配器,因此记录的精确率在此处无法独立复现。设计论证是论证出来的,而非测量出来的,第 05 章正是用这些词说明的。
第 00 章中的规范文本,在此复制。每一条都是设计意图,每条法则末尾命名的章节是此系统被对照检验的地方:哪些部分通过构造成立,哪些仅在两条编排路径之一上成立,哪些依赖于编排器的良好行为,哪些尚未成立。
模型提议;确定性代码处置。 给模型一个提议接口,而非对目标、原始存储或严重性最终决定权的直接访问。确定性代码验证、执行并记录被接纳的工作。历史系统并非在所有地方都强制执行该边界:两个编排器都可以访问 shell,其写入路径携带一个无需执行即可存储发现的子命令。虚构的端点可能返回 404、登录页面或应用 shell;记录响应并单独判断声明。共享写入器不是沙箱。第 01 章和第 02 章。
关于过去的声明必须引用。关于未来的提议必须执行。 这是不同类型的陈述,需要不同的门禁。关于已观察事物的声明必须引用自己的捕获;匹配的引用确立的是引用完整性,而非结论为真。历史门禁存在泄漏:即使没有一项通过,它每批次也保留一项,并且在一条编排路径上,调用方提供的置信度可以替代检查。提议的测试不能通过引用它尚未做出的观察来验证。它只能在授权、范围、门禁和预算检查允许之后运行,其结果仍需要解释。该法则不是执行每个提议的许可。第 02 章。
严重性默认降低,仅凭证据提升。 确定性治理器可以降低严重性或标记发现为误报,但不能提升。这限制了其权限;这并不使其结论正确。低报可能隐藏真实漏洞,因此每条降级规则都需要匹配和反例测试以及可审查的理由。历史提升端点检查逐字引用但不强制执行其契约要求的作者评分。仅引用不是可利用性证明。将捕获绑定到发现,应用经审查的领域证明策略,并保留独立的人工审查和签署流程。第 03 章。
范围是函数,而非判决。 写入提示中的授权与上下文窗口中的每条其他指令竞争。将操作者的许可编码为可审查的策略,并在每个出站操作之前强制执行,并记录拒绝情况。历史守卫存在不足:它在工具边界而非每个请求处被询问,扩大了某些宿主边界,并且在终止开关下或在未构造目标时默认开放。实验室在其可信回调之前拒绝未列出的来源,但传输隔离仍属于适配器。策略决策的正确性取决于其评估的授权和目的地。第 04 章。
报告你未做的事情。 未发现任何内容的扫描与无法到达任何内容的扫描是不同的扫描,而将它们渲染为相同的报告是在以省略方式撒谎。覆盖率、门禁状态以及每个被跳过宿主及其原因的账本应属于交付物,与发现并列。这是历史报告未满足的要求:只有覆盖率到达,且是针对其最弱分母计算的,并标注了不同分母的名称。实验室核算计划中的工具和 URL 操作、已执行的工作、错误和跳过;该分母不衡量漏洞覆盖率。第 05 章。
| 章节 | 主题 |
|---|---|
| 第 00 章:确定性梯度(源) | 为什么方差是设计问题而非能力问题、四个层级以及五条法则 |
| 第 01 章:固定程序(源) | 阶段机、确定性工具评分、作为文件中计数器的先验,以及不会说出你想要的轮次比 |
| 第 02 章:窄腰(源) | 每个副作用一个写入器、模式验证和修复循环,以及为什么声明和提议需要不同的门禁 |
| 第 03 章:不对称信任(源) | 不能升级的治理器、只能凭证据提升的验证器,以及无法被证明的攻击链 |
| 第 04 章:范围即代码(源) | 授权作为函数、跳过账本、任何函数都不应决定的底线,以及选定运行中记录的范围缺口 |
| 第 05 章:扫描无法到达的内容(源) | 可达性作为记录值、覆盖率分母、整合、诚实的部分结果,以及如何评估你自己的系统 |
| 第 06 章:构建你自己的(源) | 有序手册:每一步都说明其保护的不变量,并在公共树携带它们的地方命名执行文件、测试和已提交工件 |
| 第 07 章:框架实验室(源) |
core/ 下的历史代码是为了被阅读、运行和质疑而存在的。它是洁净室实现,并且刻意不作为实时测试器运行:性能分析、相关性评分、调度和工具调用验证是真实且可运行的,而所有会将数据包发送到网络上的内容都被扣留。运行 ls core/*.py 查看实际发布的内容,而不是相信此处写下的数字——这种声明在模块被添加的那一刻就会过时。后续章节依赖的控制项就在其中:写入路径是 core/store_protocol.py,严重性治理器是 core/severity_governor.py,范围守卫是 core/scope_guard.py,门禁检查是 core/gate_check.py,阶段机是 walkthrough/run.py。历史模型调用验证器被扣留。第 06 章对其进行了规范;第 07 章发布的是一个独立的确定性证据守卫,而非该验证器,也非人工验收流程。保持它们的工作分离:接地批评者检查引用包含性,治理器限制严重性,提升路径必须满足独立审查的证明策略。它们都不能替代人工审查和签署。
walkthrough/ 在已提交的夹具上驱动该阶段机,并将各章节引用的工件写入 walkthrough/artifacts/。使用 python3 -m walkthrough.run 重新生成它们,如果你不想触碰已提交的副本,该命令接受 --out 目录;tests/test_walkthrough_is_in_sync.py 将一次全新的内存运行与这些副本逐字节比较,因此未经重新运行而编辑的夹具会变红而非发布。该门禁无法捕获的是在两处都错误的工件,其自身的文档字符串也说明了这一点。
每个章节中的每个数字都解析为 data/stats.json 中的一个键,或带有注释说明该数字是什么以及为什么它不是从目标获取的测量值。在第 00 章至第 05 章以及本 README 中,十三条注释命名了代码的常量或属性,三十五条覆盖了数字检查无法读取的拼写数量,五条命名了 HTTP 状态码,一条命名了此仓库自身两个已发布快照之间的比较。统计文件是带有已发布窗口的冻结快照,而非实时查询,第 05 章解释了为什么重新运行流水线无法复现它。
第 05 章报告了系统针对公开的故意易受攻击应用程序的 F1 分数,并将其与 OWASP ZAP 被动扫描分数并列。此仓库证明了算术运算并使四个聚合分数文件与 data/stats.json 保持同步;它不包含证明两个工具在受控正面比较中被评估所需的原始发现、地面真值条目、匹配器、目标标识符或运行标识符。将这对数据视为历史的、作者记录的数据点,而非公平基准。样本量、因此未报告的离散度,以及被排除的运行及其各自被排除的原因,都在该章节中。
各章节的生成副本,每个数字都解析为其实际值,每条代码引用都转换为指向 core/ 的链接,位于渲染树中供在 GitHub 上阅读;它由 scripts/render.py 生成,并由 tests/test_rendered_is_in_sync.py 与源保持同步。
如果你要发布该仓库,请遵循 PUBLICATION.md。将无历史的快照发布到新的公共仓库;不要更改开发仓库的可见性,也不要假设干净的工作树已清除其可达的 Git 历史。强制性的预提交 scripts/publication_gate.sh 拒绝发布,除非私有黑名单确实被合并、公共 Git 作者身份与批准值匹配,且暂存仓库没有先前的引用、对象或 reflog。
scripts/audit.sh 扫描仓库中的标识符,scripts/prose_check.sh 和 scripts/verify_claims.sh 扫描散文,tests/test_gates.sh 针对它们植入违规以证明它们仍然触发,测试套件将参考实现与各章节所述内容进行对照。一个章节在以下每一项都通过之前不算完成:
python3 -m pip install -r requirements.txt
# pytest,仅此而已:core/ 下的每个模块
# 仅使用标准库
export HANDBOOK_ROOT=.
bash scripts/audit.sh . # 始终是已发布的模式;雇主、客户端
# 和宿主黑名单仅在其存在处,且该
# 文件是私有的,因此没有克隆携带它。哪
# 一半运行了在其打印的"sanitization scope:"行中
# 而非退出状态中,因此请阅读
# 该行
./scripts/prose_check.sh handbook # 机械式 AI 痕迹检查
./scripts/verify_claims.sh handbook # 引用、未引用数字、交叉引用、
# 声明锚点、来源归属
./scripts/prose_check.sh README.md # 两个门禁都接受目标,默认指向 handbook/,
./scripts/verify_claims.sh README.md # 因此此文件必须被命名才能被检查
./scripts/test_gates.sh # 针对植入违规的门禁、树、
# README 和章节声明;
# 章节自身的散文由上述指向 handbook 的
# 散文和声明门禁覆盖,
# 而非由此扫描覆盖
python3 -m pytest tests/ # 整个套件,它打印自己的计数
# 而非在此处写下一个。上面的每一
# 行都运行门禁脚本和这些脚本接入的 pytest 文件,
# 这些是关于本文档的;
# 五条法则所涉及的控制项的测试——严重性
# 治理器、范围守卫、门禁检查、共享写入路径、
# 接地批评者——由此行到达,
# 而非由上面的任何行。其中一个的破坏
# 仅在其也移动已提交的 walkthrough 工件时
# 才会使上面的行变红
该套件中的 tests/test_chapter_claims.py 是最值得借鉴的。它包含针对参考实现和已发布统计数据的断言,每条断言都锚定到其支持的逐字句子,因此改变事实的编辑会失败测试而非悄然发布。
Theodoros Moutesidis.
| 推荐的离线参考:强制执行边界、检查完整报告,并测试必须被拒绝的内容 |
| 附录 A:编排器契约(源) | 交给模型的工具,从私有原件泛化而来 |
| 附录 B:模式(源) | 工具调用、发现和治理记录的形状,以及每一项保证什么和不保证什么 |
| 附录 C:失败博物馆(源) | 真实的误报及其根本原因和消除每种误报的规则,以及此仓库能固定其中哪些 |