使用 Claude 和基于属性的测试寻找 Bug

Anthropic 开发了一种 AI Agent,能够通过自主推断通用代码属性并应用基于属性的测试 (PBT) 来高效地识别大型软件项目中的 Bug。通过利用类似于模糊测试 (fuzz testing) 的技术,该 Agent 在包括 NumPy、SciPy 和 Pandas 在内的知名 Python 包中发现了 Bug。

基于属性的测试 vs. 基于示例的测试

基于属性的测试侧重于验证代码的通用不变性或属性是否在广泛的输入范围内保持成立,而不是验证特定的、手动定义的示例。

  • 基于示例的测试: 开发者定义一个特定的输入(例如,[2, 10, 5, 4])并验证输出是否与预期结果匹配(例如,[2, 4, 5, 10])。这种方法往往会错过开发者未能预见到的边缘情况。
  • 基于属性的测试: 开发者指定一个通用属性(例如,“JSON 反序列化是序列化的逆过程”)以及输入域。随后,框架会自动生成大量有效的输入,以寻找破坏该属性的反例。

Anthropic 的 Agent 通过读取类型注解、文档字符串、函数名和注释来推断这些属性,然后使用 Hypothesis 库编写测试。

基于属性的测试 Agent 工作流

该 Agent 被实现为一个自定义的 Claude Code 命令。它接受一个目标——例如 Python 文件、模块或特定函数——并遵循五个步骤的迭代过程:

  1. 分析: 读取代码和文档以了解目标及其与代码库的关系。
  2. 提议: 基于分析结果提出属性。
  3. 实现: 使用 Hypothesis 编写基于属性的测试。
  4. 反思: 运行测试并评估结果。如果测试失败,Agent 会判断是发现了真实的 Bug,还是测试本身需要调整。如果测试成功,Agent 会评估该测试是平庸的还是有意义的。
  5. 报告: 如果对 Bug 的有效性有信心,Agent 会生成格式化的 Bug 报告。

为了管理长程推理,该 Agent 使用了一个待办事项列表。研究人员指出,与 Sonnet 4 相比,Opus 4.1Sonnet 4.5 的自我反思能力有了显著提升。

现实世界中的性能与验证

研究人员在超过 100 个流行的 PyPI 包上测试了该 Agent。评估分为两个阶段:

阶段 1:初步评估 (Opus 4.1)

在 Claude Opus 4.1 生成的 984 份 Bug 报告中,通过对 50 份报告进行人工审核,发现 56% 是有效的 Bug,32% 是有效且可报告的。为了提高精度,团队开发了一个 15 点评分标准来对 Bug 进行排名。应用该标准时,86% 的高分报告是有效的,81% 是有效且可报告的。

阶段 2:精细化评估 (Sonnet 4.5)

团队使用 Sonnet 4.5 在多个关键包上多次运行该 Agent,并采用了更先进的评估 Agent 来在最终的人工专家审核之前检查正确性和严重程度。

案例研究:已识别的 Bug

该 Agent 发现的几个 Bug 已在主要库中被报告并修复:

  • NumPy: Agent 发现 numpy.random.wald 有时会返回负数,违反了 Wald 分布的属性。修复方案涉及解决灾难性抵消问题,以创建一个更具数值稳定性的公式,将相对误差降低了近十个数量级。
  • aws-lambda-powertools: Agent 发现 slice_dictionary() 反复返回第一个数据块,因为迭代器没有递增。这是通过测试“切片并重构字典应该返回原字典”这一属性来识别的。
  • cloudformation-cli-java-plugin: Agent 发现 item_hash() 对所有列表都产生相同的哈希值,因为它使用了原地 .sort() 方法,该方法返回 None。这是通过测试“不同输入应产生不同哈希值”来捕捉到的。
  • tokenizers: Agent 发现 EncodingVisualizer.calculate_label_colors() 中缺少一个闭合括号,导致了无效的 HSL CSS,这是通过针对 HSL 颜色代码的正则表达式测试输出结果来发现的。

python-dateutil 中一个关于儒略历的报告被维护者标记为无效,这突出了一个局限性:Agent 难以处理包含只有维护者才能定义的微妙或隐式假设的代码。

未来方向

Anthropic 将 Agentic PBT 视为人类测试的批判性补充,特别是在 LLM 在从上下文中识别属性的能力不断提高的情况下。研究人员建议,下一个逻辑步骤是自动生成补丁。如果正确性属性可以被完全指定,那么修复 Bug 就会变得更简单,从而可能允许 LLM 为维护者审核提供高质量的补丁。

Sources

相关