关于 review-llm-artifacts
review-llm-artifacts 是用于识别 LLM 编码 Agent 常见遗留问题的代码审查技能,涵盖死代码、过度抽象、测试重复和冗长风格。它规定四类审查,并要求先验证 JSON 报告再展示摘要。
主要功能
- 01审查测试、死代码、抽象和风格
- 02限定变更文件或扫描整个项目
- 03并行或顺序执行分类审查
- 04按文件和行号整理发现
- 05检查 JSON 报告完整性
适用场景
- 01审计 LLM 生成代码后的变更
- 02发现重复的测试准备或断言
- 03检查未使用代码和过度抽象
- 04生成经过验证的审查报告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ existential-birds/ beagle --skill review-llm-artifacts安装后在 Claude Code 中输入/review-llm-artifacts确认已加载。
详细介绍
LLM 代码产物审查
检测 LLM 编码 Agent 留下的常见产物:过度抽象、死代码、测试中的 DRY 违规、冗长注释和过度防御。
硬性门槛(按顺序)
只有在每项通过条件均客观成立时才能继续(避免在仍有代码产物时声称“审查完成”):
| 门槛 | 通过条件 |
|---|---|
| G1 — 范围 | 文件列表非空,或按原样输出 Step 1 消息并退出;scope 设为 all 或 changed。 |
| G2 — 四类审查 | 已分别审查测试、死代码、抽象和风格(支持时并行运行四个子 Agent,或按相同类别依次进行四轮审查)。如果有任何类别未完成,立即停止;不要写入 JSON,也不要撰写暗示已完成全面审查的摘要。 |
| G3 — 先写 JSON 再写摘要 | 在编写 Step 6 的 Markdown 之前,.beagle/llm-artifacts-review.json 已存在且为有效 JSON。 |
| G4 — 完整性 | 只有在 Step 7 的检查通过后,才能将本次运行视为完成。 |
参数
解析 $ARGUMENTS 中的标志和可选路径:
| 标志 | 效果 |
|---|---|
| (默认) | 已更改文件范围 — 仅包含自 git merge-base HEAD main 以来更改的文件(PR 风格范围) |
--all | 扫描整个项目 — 扫描目标路径下所有匹配的源文件 |
--parallel | 在支持子 Agent 时强制并行执行(默认在范围内有 4 个或更多文件时并行) |
| 路径 | 要扫描的根目录(默认为当前工作目录) |
Step 1:确定范围
A. 仅扫描已更改文件(默认):
显式解析基准引用,若未找到则明确报错 — 不要用 || true 包装 git merge-base 调用,否则会悄悄吞掉缺少 main/master 引用的问题,并在仓库仅有 origin/main 或使用 master 时报告“没有文件可扫描”。如果没有找到基准引用,建议用户改用 --all,不要静默回退。
BASE=$(for ref in main origin/main master origin/master; do
git rev-parse --verify "$ref" >/dev/null 2>&1 && { echo "$ref"; break; }
done)
if [ -z "$BASE" ]; then
echo "error: no main/master ref found (checked main, origin/main, master, origin/master). Pass --all for a full-project scan." >&2
exit 1
fi
MERGE_BASE=$(git merge-base HEAD "$BASE") || {
echo "error: git merge-base HEAD $BASE failed." >&2
exit 1
}
git diff --name-only "$MERGE_BASE..HEAD" | grep -E '\.(py|ts|tsx|js|jsx|go|rs|java|rb|swift|kt)$' || true
(grep 末尾的 || true 是有意保留的 — 没有匹配到源文件是合法的空范围结果,与基准引用解析失败不同。)
B. 全项目(--all):
从 TARGET(默认为 .)开始,列出源文件并剪除排除的依赖/构建目录,确保 find 不会进入这些目录。! -path "*/foo/*" 只会过滤输出;find 仍会遍历目录树(在大型 node_modules、target 等目录中会浪费数分钟的 I/O)。应改用 -prune:
find "$TARGET" \
\( -type d \( \
-name node_modules -o -name .git -o -name vendor -o -name __pycache__ \
-o -name .venv -o -name venv -o -name dist -o -name build \
-o -name target -o -name .next -o -name coverage -o -name .turbo \
\) -prune \) -o \
\( -type f \( \
-name "*.py" -o -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \
-o -name "*.go" -o -name "*.rs" -o -name "*.java" -o -name "*.rb" \
-o -name "*.swift" -o -name "*.kt" \
\) -print \)
大型仓库: --all 可能会生成很长的文件列表。如果文件数超过 400,请发出警告并建议缩小范围:将子目录作为 TARGET 传入,或者去掉 --all,回退到默认的已更改文件范围。除非用户明确取消,否则仍应继续。(默认的已更改文件范围已经受 PR 差异限制,因此不会触发此警告。)
如果未找到文件,则以以下内容退出:
No files to scan. Check the path, branch, or pass --all for a full-project scan.
在报告中设置 scope:--all 时设为 "all",默认的已更改文件范围设为 "changed"。
Step 2:检测语言
从文件列表中提取唯一的文件扩展名:
echo "$FILES" | sed 's/.*\.//' | sort -u
在报告中将扩展名映射为语言名称:
.py-> Python.ts、.tsx-> TypeScript.js、.jsx-> JavaScript.go-> Go.rs-> Rust.java-> Java.rb-> Ruby.swift-> Swift.kt-> Kotlin
Step 3:审查四类问题
涵盖以下所有四类问题。如果 Agent 支持子 Agent,且文件数 >= 4(或已设置 --parallel),则为每一类问题分别启动一个子 Agent 并行审查。否则,由你依次完成四类审查,产出相同的发现结果。无论采用哪种方式:
- 加载 llm-artifacts-detection 技能
- 审查每一类问题(并行时每个子 Agent 负责一类;按顺序审查时每轮处理一类)
- 按以下结构化格式收集发现结果
类别 1:测试
重点: LLM 生成带来的测试反模式
- 违反 DRY 原则(重复的设置代码、重复的断言)
- 测试库/框架代码,而不是应用逻辑
- 模拟边界错误(模拟过多或过少)
- 测试名称过于冗长,描述了实现细节
- 只是照搬实现方式的测试
类别 2:死代码
重点: 未使用或已过时的代码
- 未使用的导入、变量、函数、类
- 应已解决却仍存在的 TODO/FIXME 注释
- 针对已移除功能的向后兼容代码
- 已删除代码遗留的孤立测试文件
- 被注释掉的代码块
- 始终处于开启/关闭状态的功能标志
类别 3:抽象
重点: 过度工程化模式
- 不必要的抽象层(只有一种实现的接口)
- 复制粘贴导致的偏差(相似代码略有不同)
- 过度配置(可配置项实际上从未改变)
- 过早泛化
- 用于简单对象创建的工厂/生成器模式
- 深层继承体系
类别 4:风格
重点: 冗长或防御性模式
- 解释显而易见代码的冗长注释
- 过度防御(对不可为 null 的值进行 null 检查)
- 不必要的类型提示(类型显而易见的动态语言)
- 过于明确的错误消息
- 冗余日志
- 在代码可自我说明的情况下仍添加文档
第 4 步:汇总发现
前提条件: G2 已满足(四个类别的审查均已成功完成)。
四个类别的审查全部完成后(使用并行子 Agent 或依次审查),然后:
- 将所有发现合并为一个列表
- 分配唯一 ID(1、2、3……)
- 按类别分组显示
写入前回显(防止编造): 写入 JSON 的每条发现都必须来自类别审查输出中的 [FILE:LINE] ISSUE_TITLE,不得来自分支名称、目录或你自己的推断。分配 ID 后,回显汇总表——id | category | file:line | description——并确认每一行都能追溯到具体的类别审查结果。不得添加任何类别审查未报告的发现。
ID 锁定: ID 必须从 1..N 连续编号,不得有缺漏或重复。这组 1..N ID 是下游技能(verify-llm-artifacts、fix-llm-artifacts)按 1:1 绑定的锁定 ID 集合。summary.total 必须等于 N,且 summary.by_category 的计数总和必须等于 N。写入 JSON 前,先说明 ID 集合。
第 5 步:编写 JSON 报告
如果 .beagle 目录不存在,则创建该目录:
mkdir -p .beagle
将发现写入 .beagle/llm-artifacts-review.json:
{
"version": "1.0.0",
"created_at": "2024-01-15T10:30:00Z",
"git_head": "abc1234",
"scope": "all" | "changed",
"target": ".",
"files_scanned": 42,
"languages": ["Python", "TypeScript", "Go"],
"findings": [
{
"id": 1,
"category": "tests" | "dead_code" | "abstraction" | "style",
"type": "dry_violation" | "unused_import" | "over_abstraction" | "verbose_comment" | "...",
"file": "src/utils/helper.py",
"line": 42,
"description": "Repeated setup code in 5 test functions",
"suggestion": "Extract to a pytest fixture",
"risk": "Low" | "Medium" | "High",
"fix_safety": "Safe" | "Needs review",
"fix_action": "refactor" | "delete" | "simplify" | "extract"
}
],
"summary": {
"total": 15,
"by_category": {
"tests": 4,
"dead_code": 5,
"abstraction": 3,
"style": 3
},
"by_risk": {
"High": 2,
"Medium": 8,
"Low": 5
},
"by_fix_safety": {
"Safe": 10,
"Needs review": 5
}
}
}
第 6 步:显示摘要
前提条件: G3 已满足(JSON 已写入磁盘且可解析)。
## LLM Artifacts Review
**Scope:** Changed files since merge-base with main | Entire project under `<path>` (when `--all`)
**Files scanned:** 42
**Languages:** Python, TypeScript, Go
### Findings by Category
...
### Summary Table
...
### Next Steps
- Run the [verify-llm-artifacts](../verify-llm-artifacts/SKILL.md) skill to confirm findings and drop false positives before fixing.
- Run the [fix-llm-artifacts](../fix-llm-artifacts/SKILL.md) skill after verification (or to preview safe-only fixes).
- Review the JSON report at `.beagle/llm-artifacts-review.json`
第 7 步:验证(报告完整性)
完成前,验证审查是否正确执行:
- JSON 有效性: 确认
.beagle/llm-artifacts-review.json存在且可解析 - 类别覆盖: 所有 4 个类别的审查均已无错误地完成(使用并行子 Agent 或依次审查)
- 已捕获 Git HEAD: 报告中的
git_head字段非空 - 过时性检查: 如果存在上一份报告,将其中保存的
git_head与当前 HEAD 比较;如果不同,则发出警告 - ID 和计数完整性: 发现的 ID 必须从
1..N连续编号;summary.total == N;summary.by_category的计数总和必须等于N。如果不匹配,说明有发现被添加、删除或重复——完成前修正。
python3 -c "import json; json.load(open('.beagle/llm-artifacts-review.json'))" 2>/dev/null && echo "✓ Valid JSON" || echo "✗ Invalid JSON"
python3 - <<'PY'
import json
r = json.load(open('.beagle/llm-artifacts-review.json'))
ids = [x['id'] for x in r['findings']]
n = len(ids)
ok = ids == list(range(1, n + 1)) and r['summary']['total'] == n \
and sum(r['summary']['by_category'].values()) == n
print("✓ ids 1..N and counts consistent" if ok else f"✗ id/count mismatch: ids={ids} total={r['summary']['total']}")
PY
STORED_HEAD=$(jq -r '.git_head' .beagle/llm-artifacts-review.json 2>/dev/null)
CURRENT_HEAD=$(git rev-parse --short HEAD)
if [ "$STORED_HEAD" != "$CURRENT_HEAD" ]; then
echo "⚠️ Report was generated on $STORED_HEAD, current HEAD is $CURRENT_HEAD"
fi
如果任何验证失败,则报告错误并停止后续操作。
逐条发现验证(精确性,而非 JSON 语法)属于单独的技能:verify-llm-artifacts——在批量删除或对高风险项目使用 --fix 前运行。
每条发现的输出格式
[FILE:LINE] **ISSUE_TYPE** (Risk, Fix Safety)
- Description
- Suggestion: Specific fix recommendation
规则
- 按照 Hard gates 的顺序执行;不要跳过 G3(在 Step 6 之前处理 JSON)。
- 防止臆造: 每项发现都必须能追溯到某个类别审查的
[FILE:LINE]输出(Step 4 回显);绝不能根据分支名称、目录或推断臆造发现。参见 review-verification-protocol 技能 → 防止臆造(gate 0)。 - 始终先加载 llm-artifacts-detection 技能。
- 当文件数 >= 4 时,使用并行子 Agent(若 Agent 支持)执行四类审查;否则按顺序执行。
- 每项发现都必须包含 file:line 引用。
- 如实评估风险类别(不要夸大或淡化)。
- 仅当更改是机械性的且可逆时,才将修复安全性标记为“Safe”。
- 如有需要,创建
.beagle目录。 - 在显示摘要之前,先写入 JSON 报告。
- 默认范围是自与 main 的 merge-base 以来的更改文件;使用
--all扫描整个项目。