PhilipLudington/Assay

GitHub: PhilipLudington/Assay

Assay 通过植入缺陷的 TypeScript 语料库与可重复的 Python 评分工具,量化评估各类 AI 代码审查 Agent 的精确率和召回率。

Stars: 0 | Forks: 0

# Assay **衡量代码审查 Agent 的实际能力** —— 一个 TypeScript 语料库,包含 植入的缺陷,以及一个 Python 测试工具,用于为每位审查者打分,评估其精确率和召回率,并提供置信区间。 ## 问题所在 团队发布 AI 生成代码的速度远超他们审查的速度,而随之而来的问题 —— *你怎么知道它是正确的?* —— 并没有一个好的答案。随着 diff 体量的增加,人工 审查逐渐退化为橡皮图章。通过的测试仅仅覆盖了测试本身已经知道要检查的内容,而且这些测试通常是由 编写该 bug 的同一个 Agent 编写的。 在这之下隐藏着一个更隐蔽的问题,而这正是 Assay 要解决的。那些 *确实*构建了审查 Agent pipeline 的团队,无法判断该 pipeline 是否有效。你添加了一个“安全审查者”的 prompt,它生成了听起来很可靠的 发现结果,然后每个人都认为它能捕获安全漏洞。没有人去衡量 召回率。也没人知道它漏掉了什么。pipeline 产生了严谨的 感觉,却缺乏实质内容 —— 这比没有 pipeline 还要糟糕,因为它让人们 停止了人工排查。 任何人都可以写一个“审查我的代码”的 prompt。但几乎没有人能告诉你,他们的 审查者在处理空指针解引缺陷与注入缺陷时的召回率,或者 在更换模型时性能是否出现了退化。Assay 的存在就是为了让这个数字 获取成本更低,且发布时更诚实。 ## 衡量内容 审查者针对 **fixtures** 运行:这些是自包含的代码库,包含正在审查的 diff 以及记录了植入缺陷的答案表。 - **召回率** —— 至少被一项发现结果捕获的植入缺陷。 - **精确率** —— 匹配到真实植入缺陷的发现结果,在所有发现结果中的比例。 这两项指标都会**按审查者和缺陷类别**进行报告,作为 K 次运行的 平均值,并附带 bootstrap 95% 置信区间。回归判定是基于运行之间置信区间不重叠,而不是逐点比较 —— 审查者输出是 非确定性的,单次运行无法将真正的回归与 采样噪声区分开来。 每个 fixture 还带有 **distractors**(干扰项):审查者可能会标记的 看似合理但实际上错误的内容。如果没有这些干扰项,任何审查者的精确率都会接近 1.0,该指标也就失去了意义。 ## 工作原理 ``` corpus/ reviewers/ executor/ │ │ │ └────────► run ◄──┴──────────────────┘ ← spends money │ ▼ results/runs//*.jsonl ← durable transcripts │ ┌───────────┴───────────┐ ▼ ▼ match ──► judge ──► score ──► report ← free, re-runnable ``` `run` 和 `score` 之间的硬边界是该系统中最重要的结构 决策。transcript 下游的所有操作都是免费的、 确定性的,并且可重复运行。更改匹配器、更换评判器、修复 评分 bug 或添加指标都不需要任何成本,也不会使 历史运行失效 —— 因此,绝不存在因为预算压力而保留糟糕评分规则 的情况。 发现结果分两个阶段与植入的缺陷进行匹配:首先是一个免费的 **邻近度筛选**(proximity gate) (同一文件,窗口范围内的行)缩小候选范围,然后由廉价模型上的 **语义评判器** 决定一项发现是否真正描述了缺陷。 仅仅依赖行匹配太脆弱了 —— 审查者可能会正确地识别出缺陷, 但引用的却是调用处而不是守卫处。 ## 评估工具通常会忽略的三个方面 **评判器本身经过了验证,并且其一致率已公开。** 一个人工标记的裁决集被提交到了代码库中;每次评分运行 都会针对它重放评判器,并在审查者得分旁边报告一致率。 未经证实的评判器只是将信任问题向下转移了一层并加以隐藏。如果评判器的 一致率很低,这里的每一个审查者数据都是可疑的 —— 这正是读者有权知道的事实。 **答案表的隔离是强制的,而非假设。** 如果审查者能够读取 fixture 的答案表,其得分将接近完美,而且这种失败是悄无声息的 —— 这 相当于基准测试中的训练/测试集污染,它已经让真实的 基准测试失效过。清单文件位于审查者可见的目录之外,fixtures 发布时不带 git 历史记录,执行器强制执行严格的路径边界,并且 测试会断言答案表是不可访问的。该测试失败会使代码库中的每一个 数字失效,因此它被视为一项正确性测试。 **任何输出 SARIF 的审查者都可以被评分,**无需编写专门的集成 代码。参考组是首批被衡量的对象,而不是唯一 可衡量的对象。 ## v1 研究问题 Assay 首次发布的结果回答了一个问题: v1 中发布了两种审查者模式 —— 单次执行模式,以及具有只读 `Read` / `Glob` / `Grep` 导航能力的 agentic 模式。两者都从**相同的基础条件**开始:diff 以及 它触及的每个文件的全部内容。只有工具能力上限不同。不同的 基础条件会将上下文容量与工具访问权限混为一谈,从而使 比较变得无法解释。 每个缺陷都按局部性(`local`、`touched_file`、`cross_file`)进行标记,因此 结果是按局部性细分报告的,而不仅仅是汇总。这 同时也起到了自我检查的作用:工具应该在处理 `cross_file` 缺陷时提供实质性帮助,而在处理 `local` 缺陷时几乎没有帮助。如果它们看起来对 `local` 缺陷也有帮助,那么匹配器或基础条件肯定出了问题 —— 这需要 在发布之前找到原因,而不是在发布之后。 ## 范围 这些是刻意省略的内容,而非疏忽。完整的界限在 [DESIGN.md](DESIGN.md#non-goals--out-of-scope) 中。 - **无自动修复。** 你无法干净地为同时编辑代码的审查者打分。 - **无托管组件。** 没有服务、仪表板、数据库或账号。Assay 是一个库和一个写入文件的 CLI。 - **无提供商抽象。** 仅支持 Anthropic 模型。 - **单一语料库语言。** Bug 分类体系不可移植;v1 使用 TypeScript。 - **非生产级 CI 门禁。** 该组件可在 CI 中使用,但 Assay 并不 与商业 AI 代码审查工具竞争,也不会以这种方式进行推销。 ## 状态 设计已敲定;实现尚未开始。各阶段定义在 [PLAN.md](PLAN.md) 中。 | 阶段 | | 状态 | |---|---|---| | 0 | 试点 —— 解决经验上的未知问题 | 未开始 | | 1 | 语料库格式与隔离 | 未开始 | | 2 | 审查者与运行路径 | 未开始 | | 3 | 匹配、评判器及评判器验证 | 未开始 | | 4 | 评分与报告 | 未开始 | | 5 | 语料库构建 | 未开始 | | 6 | 首次发布扫描 | 未开始 | 阶段 0 是一次一次性的试点,旨在回答三个问题而不是去猜测它们:稳定的得分需要多少次运行,fixture 代码库必须有多大才能让导航变得复杂,以及 prompt-cache 前缀共享是否能在 Agent SDK 中保留。任何耗资巨大的构建都不会基于未经验证的假设 进行。 ## 诚实的局限性 在此声明这些局限性而不是将其掩埋,因为隐藏这些局限性的基准测试只是 一个营销数字。 - **语料库很小且是手工编写的。** v1 发布了 15 个 fixtures,反映了 一个人对真实 bug 样貌的看法。这无法代表真实缺陷的 空间。如果没有其 `n`,任何百分比都不会被报告。 - **一切都依赖于评判器。** 如果评判器一致率低,每个数字都是 噪声。这就是为什么要发布一致率的原因 —— 如果结果 很差,诚实的回应是如实说明,而不是调整裁决集直到 它看起来更好。 - **循环论证。** Anthropic 模型审查代码,由 Anthropic 模型评判,并在一个推荐 Anthropic 模型的代码库中评分。这是一个真实的 利益冲突,已被披露出来而不是被解释过去。 - **结果很快就会过时。** 模型发布会在几个月内使已发布的数字 失效。每个结果文件都带有日期戳和模型戳,并且 重新运行被视为常规操作。 ## 由 Agent 构建,置于审查门禁之下 Assay 由人工设计和指导,由编码 Agent 在专门的 审查门禁下实现。在这个项目中,这正是核心论点而不是附加说明:一个用于验证 Agent 编写代码的工具,其本身也是由 Agent 编写的,并且有 评估结果证明其自身的门禁是有效的。 ## 文档 | | | |---|---| | [IDEA.md](IDEA.md) | 问题、考虑过的可能性、未知因素 | | [DESIGN.md](DESIGN.md) | 构建什么以及为什么 —— 决策及其依据 | | [PLAN.md](PLAN.md) | 阶段细分、各阶段验证、预算 | ## 许可证 Apache 2.0 是预期的许可证(宽松型,带有明确的专利授权 —— 这是公司在 CI 中运行开发工具的 常态)。`LICENSE` 文件尚未添加。
标签:AI代码审查, Python, TypeScript, 准确率与召回率, 大语言模型评测, 安全插件, 无后门, 缺陷检测, 逆向工具