SuperAPI AI 工具集

adverse-review

编程与开发

查看项目

更新于 10-15 10:04

技能介绍

用途

Adverse 是多智能体对抗式代码审查技能,是 adverse 项目的 Claude Code 原生侧实现。相同逻辑也提供独立 CLI(adverse review …)。在 Claude Code 内运行时优先使用本技能:它使用 Claude Code 原生 Agent 工具启动审查者(无子进程认证问题、更快),仅在确定性的源码收集与合成步骤调用 Node 辅助脚本。

何时使用

用户明确要求对其代码进行对抗式/多视角/小组评审,或者即将合并/落地/发布非平凡改动并希望再做一次检查时使用。如果 diff 是纯机械性的(格式化、依赖升级、拼写修正),不要调用本技能——直接说明并停止。

前置条件

PATH 中需有 node(>= 20)。用 node --version 验证。技能脚本位于 ${SKILL_DIR}/scripts/ 下,仅依赖标准库(无需 npm install)。

如果缺少 node,告知用户:从 nodejs.org(或其包管理器)安装 Node 20+ 后重新调用。不要退回到其他实现;确定性合成器是契约。

阶段 0 — 决定审查范围

在消耗 token 前先选定范围:

  • 如果用户指定了路径,那就是范围。
  • 否则如果 git status --porcelain 报告有未提交改动,审查这些(相对 HEAD 的 diff 模式)。
  • 否则如果当前分支领先于 main(或 master/配置的上游),审查自合并基点以来的 diff。
  • 否则审查整个工作目录。

用一句话说明所选范围,以便用户纠正。

阶段 1 — 收集源码

运行 Node 辅助脚本,遍历目标并生成单个可直接嵌入提示词的文本块:

node ${SKILL_DIR}/scripts/collect.mjs --target <path> [--diff [base]] --out /tmp/adverse-source.txt --files-out /tmp/adverse-files.json

/tmp/adverse-source.txt 是要嵌入审查者提示词的内容。/tmp/adverse-files.json 是文件列表(用于向用户确认范围)。该辅助脚本执行与 CLI 相同的源码大小上限。

如果 collect 失败,向用户暴露错误——几乎总是“目标未找到”或“diff 为空”。

阶段 2 — 第 1 轮:独立审查

使用 Claude Code 的 Agent 工具并行启动三个审查者,每个对应一个角色。每个审查者获得:

  • 系统提示词:从 ${SKILL_DIR}/scripts/prompts/<persona>.txt 读取(auditor / adversary / pragmatist)。
  • 用户消息:/tmp/adverse-source.txt 的内容,前缀为 ${SKILL_DIR}/scripts/prompts/round1.txt。
  • 模型:除非用户要求其他模型,否则用 opus。如果用户选择更小的模型,将其传给全部三个角色——不同角色使用不同模型会破坏单模型设计。

每个子智能体必须返回一个符合以下 schema 的 JSON 对象:

{ "persona": "<auditor|adversary|pragmatist>", "verdict": "approve|conditional|reject", "summary": "<one sentence>", "findings": [ { "severity": "critical|warning|info", "file": "<path or null>", "line": <int or null>, "title": "<short noun phrase>", "detail": "<2-6 sentences>", "fix": "<concrete remediation or null>" } ] }

将每个解析后的 JSON 对象保存到磁盘:

  • /tmp/adverse-round1-auditor.json
  • /tmp/adverse-round1-adversary.json
  • /tmp/adverse-round1-pragmatist.json

如果某个子智能体返回格式错误的 JSON,将该角色重试一次,并在原提示词后附加解析器/校验器错误。如果重试仍失败,丢弃该角色。如果存活角色少于 2 个,中止运行并报告失败——合成至少需要 2 个声音。

三个都完成后,将它们合并为一个文件供下一阶段使用:

node ${SKILL_DIR}/scripts/combine.mjs
--round1 /tmp/adverse-round1-auditor.json /tmp/adverse-round1-adversary.json /tmp/adverse-round1-pragmatist.json
--out /tmp/adverse-round1.json

阶段 3 — 第 2 轮:交叉审查

对于每个产出了有效第 1 轮审查的角色,启动一个子智能体,它:

  • 看到所有第 1 轮审查(合并后的 /tmp/adverse-round1.json)。
  • 对其认同的发现进行验证(跨泳道验证是信号)。
  • 对其认为错误/夸大的发现提出质疑(附具体理由)。
  • 可选地补充其他角度浮现的新发现。

系统提示词:与第 1 轮相同的角色文件。用户提示词:${SKILL_DIR}/scripts/prompts/round2.txt 的内容,然后是第 1 轮合并 JSON,再然后是源码块。

输出 schema:

{ "persona": "<auditor|adversary|pragmatist>", "validate": [{ "from": "<reporter>", "title": "<title>", "reason": "<…>" }], "challenge": [{ "from": "<reporter>", "title": "<title>", "reason": "<…>" }], "added": [<finding object>] }

将每个保存到 /tmp/adverse-round2-<persona>.json 并合并:

node ${SKILL_DIR}/scripts/combine.mjs
--round2 /tmp/adverse-round2-*.json
--out /tmp/adverse-round2.json

如果用户要求更快的审查或 --single-round,完全跳过阶段 3。合成器将缺失的第 2 轮视为空交叉审查。

阶段 4 — 合成

运行确定性合成器。它生成规范报告——绝不要自己用 LLM 渲染发现,合成器的分组(交叉验证/共识/争议/单独)承载信号。

node ${SKILL_DIR}/scripts/synthesize.mjs
--round1 /tmp/adverse-round1.json
--round2 /tmp/adverse-round2.json
--out /tmp/adverse-report.md
--json-out /tmp/adverse-report.json
--html-out /tmp/adverse-report.html

读取 /tmp/adverse-report.md 并向用户呈现摘要,而非完整报告:

  • 裁决行(例如 SHIP-WITH-CAVEATS (2/3 ship, 1/3 block))。
  • 按严重程度和置信度的计数。
  • 前 3 条发现(先交叉验证,再共识,再争议),附一行预览。
  • 指向磁盘上完整报告和 HTML 仪表盘的指针。

然后询问用户希望如何继续:

  • 仅对交叉验证的发现应用修复?(最高置信度)
  • 对除争议外的所有内容应用修复?(最常见)
  • 展示某条具体发现的完整推理?
  • 只保存报告;我自己审查。

在用户选择之前,不要开始编辑文件。

阶段 5 — 清理

用户处理完报告后,删除 /tmp/adverse-* 并告知用户运行完成。不要提交这些文件。

失败处理

失败 处理方式
collect.mjs 非零退出 暴露错误。常见原因:目标不存在、在非 git 目录使用 --diff、diff 为空。
某个审查者两次返回垃圾 用 2 个审查者继续,在摘要中标记运行为“降级”。
≥2 个审查者失败 中止。告知用户模型行为异常,建议用不同模型或 --single-round 重新运行。
PATH 中没有 node 告知用户安装 Node 20+。不要临时拼凑替代方案。
用户中断 停止启动新的子智能体。告知用户部分产物所在位置。

编排者注意事项

  • 本技能约消耗 6 次模型调用(3 × 第 1 轮 + 3 × 第 2 轮)。按用户要求跳过第 2 轮可减半。
  • 角色提示词刻意写成“守好本泳道”——不要用通用审查指令覆盖它们,这样做会瓦解设计所依赖的正交性。
  • 合成器是确定性的、无 Python 的 Node 代码(synthesize.mjs)。统计 validate/challenge 边是共识信号;不要运行第四次 LLM“裁判”轮。
  • 独立 CLI(adverse review)是另一条路径,它对任意编码智能体(claude -p、codex exec 等)进行子进程调用。仅在用户询问如何在没有 Claude Code 的情况下运行时提及它。