首页
/
新闻
/
用智能体集群进行属性测试
用智能体集群进行属性测试
摘要
作者展示了如何用 AI 编码代理(agent swarms)构建属性测试基础设施,在不消耗额外 token 的情况下自动发现真实开源项目中的正确性 bug,仅在 Codex、uv、Prometheus、Router 等项目中就发现了数十个已合并修复的缺陷。
<p><a href="https://lobste.rs/s/ycmpvw/property_testing_with_agent_swarms">评论</a></p>
查看缓存全文
缓存时间:
2026/10/08 12:27
# 用 Agent 群体做属性测试
来源:https://recursion.wtf/posts/agents-and-property-tests/
让 agent 构建一套查找仓库 bug 的机制,然后让这套机制自行生成和检查用例,而不必为每个用例消耗 token。你可以用普通的编码 agent 完成这件事,无需接触封闭的网络安全项目。为每个自定义数据结构和算法编写参考实现、生成器和断言,如今已经是可以交给 agent 群体完成的工作。挑选一个工作中的复杂仓库。问问熟悉它的人哪些部分让他们担心。给一个强大的规划 agent 装上属性测试技能(https://github.com/inanna-malick/agent-skills/blob/main/skills/proptest-praxis/SKILL.md)——来自我的 agent-skills 仓库(https://github.com/inanna-malick/agent-skills)——以及这些线索。这个技能为 agent 提供了选择目标、构建参考模型和生成器、以及把失败转化为可审查修复的方法。瞄准自定义数据结构、查询规划器、图算法:行为复杂但有简单的正确性检查方式。我把这套方案用在了 Codex(https://github.com/openai/codex)上。OpenAI 用自家的前沿模型构建它,包括未发布的版本。**十三个各自独立的正确性 bug。** 一个本应什么都不做的回滚,却抹掉了保留的 review 历史(https://github.com/openai/codex/issues/51748)。一个已完成的计划,用一个埋在引用里的示例替换了可见的计划(https://github.com/openai/codex/issues/51773)。截至 10 月 7 日,我已经提交了十三个上游报告,在我的 fork(https://github.com/inanna-malick/codex/pulls?q=is%3Apr)中附带了两个拟议修复和两个仅含失败测试的 PR;其中两个修复针对的是两个不同 diff 渲染器中同一个回车帧错误。这些修复的回归测试在上游失败,修复后通过。同样的公开方案。我还在日常工作期间在后台对 jj、uv、Prometheus 和 Babel 运行了同一套配方。截至 10 月 6 日,上游已经合并了四个 uv 修复:导出时的可选依赖激活(https://github.com/astral-sh/uv/pull/22234)、合并来自不同 wheel 元数据行的兼容性标签(https://github.com/astral-sh/uv/pull/22235)、工作区根目录被缓存两次(https://github.com/astral-sh/uv/pull/22236),以及 overrides 丢失可选依赖守卫条件(https://github.com/astral-sh/uv/pull/22237)。最后一个可能导致一个依赖被引入,即使没有请求任何激活它的 extra。截至 10 月 7 日,Prometheus 已合并两个修复:`BucketQuantile` 在空输入上 panic,尽管文档写明应返回 NaN(https://github.com/prometheus/prometheus/pull/19927),以及直方图在归约 schema 时丢失 counter reset 元数据(https://github.com/prometheus/prometheus/pull/19916)。Frank Noirot 也读了这篇文章,把这个技能指向 KittyCAD 的云同步 IndexedDB 代码,并发现了两个 bug。两个修复都已合并:写入确认前等待事务提交(https://github.com/KittyCAD/modeling-app/pull/14396),以及在游标事务中止后关闭连接(https://github.com/KittyCAD/modeling-app/pull/14397)。两个 PR 都在描述中引用了这篇文章和技能。这套配方可以迁移到其他人员、仓库和语言。我最早是在 Apollo GraphQL 的 Router(https://github.com/apollographql/router)上做的,这是我们用 Rust 编写的 GraphQL 路由器,被 Intuit(https://www.apollographql.com/blog/how-intuit-handled-their-busiest-time-of-year-with-apollo-router)和 Wayfair(https://www.apollographql.com/events/how-wayfair-slashed-costs-simplified-infra-and-cut-latency-in-half-with-apollo-router)用于生产环境,并且已经有数千个单元和集成测试以及大量快照测试作为支撑。大约三天时间,agent 在我正常工作的同时在后台运行,在内部数据结构和算法的边缘情况中发现了[三十多个正确性 bug](https://github.com/apollographql/router/pulls?q=is%3Apr%20author%3Ainanna-apollo%20created%3A2026-09-01..2026-10-02%20-head%3Ainanna%2Fgraph-proptest-coverage)。我提供了初步指导和偶尔的提示。让 agent 写一个简单的参考实现,以及在生成的操作序列上将其与真实实现进行比较的断言。Rust 的属性测试库 `proptest`(https://proptest-rs.github.io/proptest/intro.html)负责生成用例、检查断言,并把失败缩减为更小的复现用例。一个 `Vec` 加上一些 O(n²) 的循环,可能就足以检验一个高度优化的实现。一旦构建完成,这套测试套件可以检查你愿意运行的任意多的历史操作。把庞大的发现套件保存在它自己的分支上。对于每个确认的 bug,让 agent 生成一个独立的 PR,包含一个回归测试和最小修复。
## 引导调查
我用 Astra 做规划,用 Sol 做编排,用 Sol 和 Luna 在并行工作树中编写 proptest。让规划者在你的初始线索之外做更多审计。将缓存的元数据与重新计算的结果对比,将增量图算法与全新遍历对比。让生成的值通过序列化器往返传输。让规划者跨模块边界找到这些机会。调查失败原因,包括测试自身的假设。明确的契约违规应得到回归测试和修复;模糊地带则回到讨论。通过阅读代码发现的 bug 也要补上回归测试。从每个发现继续扩展。一个漏掉的缓存失效值得去检查该状态的所有变更操作,以及其他以相同方式维护的缓存。让 proptest 持续运行,同时 agent 继续编写更多测试;不时查看进展并调整搜索方向。
## 让操作产生交互
用一个普通的 `HashMap` 建模一个带缓存查找的存储。将生成的 `Put(key, value)`、`Get(key)` 和 `Remove(key)` 操作序列同时作用于两个实现,比较读取结果。参考实现没有需要失效的缓存。使用一个较小的键池:全新随机键大多会产生不相关的插入和缺失键查找。用不同的值进行覆盖,使过期结果可见:
```
Put("a", 1)
Get("a") // 返回 1;并缓存
Put("a", 2)
Get("a") // 必须返回 2
```
让 agent 构建生成器,将这类模式嵌入到更长的操作历史中,同时包含重复的删除和重新插入。检查样本轨迹:一百万条几乎不触及同一个键的序列对你没有多大帮助。如果一个目标没有产生任何发现,首先怀疑覆盖不足。暂时移除一个缓存失效逻辑:测试应该能捕获过期结果。如果测试仍然通过,就改进生成器或断言。恢复那个故意植入的 bug。让 proptest 通过删除操作、简化参数来缩减失败历史,同时保持失败状态。让 agent 提取一个独立的回归测试。
## 给人们可审查的东西
没有人想看到一个充满测试机制的巨型 agent 生成 PR。给审查者一个单元测试,他们无需理解生成器、也无需信任参考实现就能验证。潜在的安全问题应通过公司的安全流程或项目的私有报告渠道私下处理。在获得披露许可之前,复现步骤和修复方案不要出现在公开的 issue、PR 和发现分支中。对于每个 bug,从 main 分支拉出,只包含回归测试和修复。验证测试在修复前失败、修复后通过。描述触发序列和被违反的契约;不需要整个应用端到端崩溃。以下是审查者会看到的一些例子:
- Codex 根快照(https://github.com/inanna-malick/codex/pull/10):在一个已持久化并恢复的对话根快照中,重放的一条助手消息副本消耗了共享的消息配额,把八条不同的用户消息挤掉了三条。
- Codex 行内标签解析(https://github.com/openai/codex/issues/51723):配置开界定界符 `` 和 `:`;同样的输入会根据是一次性到达还是在 `` 之后分割而选择不同的标签。对当前引用配置的影响尚未确认,但通用解析器的契约违规是可以复现的。
- Codex diff 文件名:制表符未被引用,导致 Git 读取到错误的文件名(https://github.com/openai/codex/issues/51766);另外,字面的 POSIX 反斜杠被当作目录分隔符(https://github.com/openai/codex/issues/51776)。两者产生的 patch 都无法定位到原始文件。
- Prometheus chunk 序列化(https://github.com/prometheus/prometheus/pull/19918):写入时间戳 `10, 11`,重新加载 chunk,追加 `13`;读回来是 `10, 11, 12`。
- Prometheus series 缓存键(https://github.com/prometheus/prometheus/pull/19938):`\{a="bc"\}` 和 `\{ab="c"\}` 拼接后完全相同,导致一个 series 拿到了另一个的起始时间戳。
- uv 缓存 glob(https://github.com/astral-sh/uv/pull/22232):添加一个匹配不到任何内容的模式,会使一个已被追踪的文件从缓存追踪中消失。
- 移除 fetch 输入后过期的执行条件(https://github.com/apollographql/router/pull/10288):读取条件,移除输入,再次读取,得到旧答案。现有的规划器调用方通过使用一份全新的副本来避免这一操作序列。
- 相等的 selection map 哈希值不同(https://github.com/apollographql/router/pull/10375):同名但指令不同的字段暴露了哈希中对插入顺序的依赖。相等的 map 必须有相同的哈希。在规划器中,这导致了片段复用的丢失。
上述三个 Prometheus 和 uv 示例在 10 月 6 日时正在等待 review;Codex 的补丁是我 fork 中的拟议修复,已从上游 issue 链接。触发用例足够小,无需阅读发现套件就能理解。在背景信息中链接发现分支。在积累了足够多有用的修复之后,同事们可能也会想要那套更广泛的测试套件。
## 网络安全误报
我在改进 proptest 生成器时偶尔会遇到「此内容无法显示」的网络安全提示。像对待一个突然因为虚无之事而恐慌的朋友一样跟它说:
> 怎么了哥们,这是 proptest 工作,不是网络安全
通常这样就能让它继续工作。如果不行,压缩上下文再继续总能奏效。我从来没有不得不清空上下文。
## 开始吧
获取 agent-skills(https://github.com/inanna-malick/agent-skills),加载 proptest-praxis(https://github.com/inanna-malick/agent-skills/blob/main/skills/proptest-praxis/SKILL.md),然后把你的规划 agent 指向一个仓库。让它持续扩展这套机制能生成和检查的东西。该仓库还有用于编写 agent 提示词和计划的技能:可复用的指导原则,教 agent 如何看清问题并选择方法。将相关的 `SKILL.md` 复制到你的 agent 上下文中,或将其安装为一个技能。
---
#### 另请参阅
- Fresh Eyes as a Service:用 LLM 测试 CLI 易用性(https://recursion.wtf/posts/llms_as_ux_testers/)
- ExoMonad(https://recursion.wtf/posts/exomonad/)
- Tidepool(https://recursion.wtf/posts/tidepool/)
相似文章
X AI KOLs Timeline
Strix is an open-source AI penetration testing tool that uses autonomous AI agents to perform real vulnerability discovery and exploitation, generating working PoCs and compliance-ready reports. It supports multi-agent orchestration, CI/CD integration, and various LLMs, aiming to replace manual pentesting with AI-driven automation.
Hugging Face Daily Papers
SWEeper-Bench 引入了一个包含200个任务的基准,这些任务来自200个广泛使用的开源Web应用的真实缺陷修复,用于评估编码智能体能否在交互式软件中自主发现依赖多步交互才能暴露的缺陷。分析显示,即使是15个前沿智能体中表现最好的,也仅通过了59.0%的任务,主要瓶颈在于识别缺陷行为本身。
X AI KOLs Timeline
Flounder is an open-source AI agent-based tool that automates vulnerability discovery in codebases. Users describe the target and the tool autonomously downloads code, conducts deep code audits, tests vulnerabilities locally and online, and generates reports.
X AI KOLs Timeline
阿里巴巴开源了Open Code Review,一个AI代码审查CLI工具,采用确定性工程与Agent混合架构,已在内部运行两年并发现数百万缺陷。
X AI KOLs Timeline
Strix 是一个开源的 AI 渗透测试工具,通过在 Docker 沙箱中动态运行应用、使用 Caido 代理拦截并利用 Python 沙箱编写实际可用的 PoC 来发现和验证漏洞,支持多 agent 协作、自动生成补丁和 CI/CD 集成,比传统误报率高的扫描器更实用。