跳到正文
Hacker News· Labo333·· 10 天前AI 评分62

LLM Fuzz CI 发布:让编码智能体攻击你标记的测试

Show HN: LLM Fuzz CI

AI 导读

Louis Abraham 和 Nicolas Devatine 发布 LLM Fuzz CI,一个 GitHub Action,让编码智能体读取代码并为被标记的测试生成对抗性输入,再由常规测试运行回放,因此报告出来的都是真实断言失败。

正文 · AI 翻译

作者:Louis Abraham 和 Nicolas Devatine 2026年10月5日 5 分钟阅读

我们发布了 LLM Fuzz CI,这是首个让 LLM 智能体攻击你编写的测试、并且只报告真正使测试失败的输入的 CI 工具。

LLM Fuzz CI 是一个 GitHub Action,它让编码智能体读取你的代码,并为你标记的测试编写对抗性输入。你正常的测试运行会重放这些输入,因此每份报告都是你自己的断言真实发生的失败。

代码智能体在编程方面已经变得非常出色,包括发现 bug(别让我开始吐槽智能体制造 bug 的事)。遗憾的是,智能体也极其擅长废话连篇产出海量文本,用看似无比重要的信息洪流淹没程序员。安全扫描器更糟:它们让 CISO 们淹没在被评为“中危”的 CVE 报告中,程序员很快将其视为小问题而不予理会,而且它们根本不测试业务逻辑。

我们给自己定下的任务是,通过创建一个遵循以下原则的工具来解决这个问题:

  1. 程序员应当(即使在智能体的帮助下)定义需要通过测试来验证的行为。(*)
  2. 工具发现的任何 bug 都是对你的测试的真实违反:智能体只编写输入,而你正常的测试运行会重放它们。没有误报。
  3. 该工具应在代码变更时和/或定期启动(因为软件包会更新,模型会变得更聪明,非显而易见的 CVE 会被公布)。

(*)随着越来越多的代码将由 LLM 编写,可能大部分代码都是如此,程序员的角色实际上将保持不变:把业务需求转化为规格说明,并产出符合这些规格说明的系统。这两个步骤都需要技术技能:编写无歧义的规格说明(几轮提示和一些技术性的 claude 语)、定义验证它们的正确方式,以及发现原始意图与所产出系统之间的任何差距。即使有最好的编码智能体,非技术人员仍然在这两个步骤上挣扎:没有技术语言,他们无法很好地讨论自己的规格说明。

解决方案相当自然:让程序员把测试标记为目标,然后运行一个智能体来尝试对它们进行模糊测试。

工作原理

你标记一个测试,用 budget_usd 设置支出限额,并可选地用 params 将智能体限制在某些输入键上。我们支持使用 pytest 的 Python 和使用 vitest 的 JavaScript。

import pytest

@pytest.mark.llm_fuzz(budget_usd=0.5)
def test_foo(llm_fuzz_case):
    result = foo(**llm_fuzz_case.input)
    assert "<script>" not in result
import { expect } from "vitest";
import { fuzzTest } from "llm-fuzz-ci";

fuzzTest("foo escapes its input", { budgetUsd: 0.5 }, (input) => {
  expect(foo(input.value)).not.toContain("<script>");
});

智能体的任务是用一个会使测试失败的值替换 llm_fuzz_case.input / input.value。

然后你可以配置一个 CI action,它将在两台独立的机器上分两个阶段启动该工具。首先,一个编码智能体(默认是使用 OpenAI 或 OpenRouter 密钥的 Codex,但我们也支持 Claude Code)读取代码和被标记的测试,尝试攻破它们,并在成功时导出输入。

其次,一个全新的 runner 再次检出你的代码,下载这些输入,并通过你正常的测试运行重放它们。智能体可以在第一台机器上为所欲为:运行你的代码、安装东西、编辑文件以理解它们。这些都不会传到第二台机器。唯一跨越的是输入文件。

最后,每次运行都会写入一份摘要、一个包含输入和智能体轨迹的 artifact,并可选地创建一个 GitHub issue,还可以使构建失败。

你可以在 README.md 中找到更多信息。

LLM 模糊测试将如何改变测试

模糊测试(fuzzing)最初是指向代码抛入大量意料之外的输入,然后观察哪里会出错。经典的模糊测试器从种子输入开始,随机变异字节,有时由覆盖率引导,然后寻找崩溃、超时或令人意外的结果。这对底层代码很有效,但面对更高层的代码就力不从心了:模糊测试器不知道你的函数应该做什么、哪些参数会相互影响,也无法区分逻辑缺陷和合法的边界情况。依赖语义的检查会被漏掉,因为随机生成器永远碰不到那些有趣的组合。而 LLM 智能体可以阅读代码和测试,直接瞄准这些组合。

将 LLM 与模糊测试结合并不新鲜。Google 的 OSS-Fuzz-Gen 和 PromptFuzz 让 LLM 为 C 和 C++ 库编写模糊测试目标。Garak 和 promptfoo 模糊测试的是 LLM 本身,而不是你的代码。XBOW(托管式渗透测试,附带已验证的漏洞利用)、OpenAI 的 Aardvark 和 Google 的 Big Sleep 自行寻找漏洞,不以你的测试作为评判标准。但 LLM Fuzz CI 是第一个做到以下事情的工具:

  • 在 CI 中运行,因此你可以安排定期检查或为发布设置关卡
  • 使用单独的步骤来生成输入,这(在大多数情况下)能防止奖励黑客行为
  • 并且接入 pytest 和 vitest,让程序员以熟悉的方式定义要测试的内容

与经典的安全扫描器不同,LLM Fuzz CI 能够通过真正阅读和理解代码来发现高级漏洞。与“PR 审查”类工具不同,它不会产生噪音:这是一个供程序员用来强制保证其代码正确性的工具。

生成任意输入使得标准模糊测试工具无法覆盖的用例成为可能,例如通过提示词攻击 LLM 智能体。我们首先在测试分支上用这个工具测试了一个会计智能体,发现当提示词中给出一个不同于该用户的合法账户 ID 时,它会启动一个工具,错误地允许访问另一个账户的数据。因此,智能测试智能体能够从端到端测试(而不仅仅是单元测试)中发现并演示复杂的缺陷(甚至借助提示词工程)。这使 LLM Fuzz CI 成为我们去年发布的另一个测试概念的良好补充:缓存桩通过缓存非确定性步骤和外部调用,将端到端流水线转变为快速、可复现的测试。

关于开源发布的一点说明

代码已经成为一种商品,任何近期的编程智能体都应该能够复现我们的仓库。

这不是悲剧,反而挺好:没有人需要在意我们的具体实现。它很容易被复现,甚至被复制(请随意)到将会传播它的框架中。这个新时代更加看重概念。创新的核心始终是新想法。技术实现既是一道门槛,因为展示这些想法需要技术能力,也是一种有趣的消磨时间的方式(至少对我来说是这样)。

这次发布不仅仅是一个工具,更是一种新颖、简单且有用的范式,关于如何善用代码智能体来保护软件质量和维护者的时间。

来源:Hacker News · tiime-software.github.io