Community写作与编辑github.com

sedricedwards/invertebrate

Invertebrate — 类 Greptile 风格的 AI 代码审查工具,针对 PR、分支或工作树差异进行分析。追踪每个变更符号在整个代码库中的调用者、被调用者和实现者,捕捉跨文件缺陷,并输出包含自然语言总结、0-5 置信度评分、发现表格、自动选择的 mermaid 图和内联注释的格式化报告。

invertebrate 是什么?

Invertebrate 是一款专为开发者设计的 AI 代码审查技能,灵感来源于 Greptile 的审查范式。它通过构建完整的代码库上下文依赖图(不仅限于变更文件),对每个变更的符号(函数、类、类型、路由等)进行全局搜索,追踪其调用者、被调用者和兄弟节点,从而发现跨文件错误、遗漏的安全检查、重构导致的接口断裂、并发竞态条件等传统 linter 难以捕捉的深层问题。该技能支持多种差异来源(PR 编号/URL、分支、当前工作树、.diff/.patch 文件),并能读取 `.invertebrate/` 或 `.greptile/` 配置文件夹中的自定义规则、忽略模式、指令等,实现高度可定制的审查行为。输出报告包含简明总结、0-5 置信度评分、结构化的发现表格(含 P0/P1/P2 严重等级和 logic/syntax/style 类型)、用于说明变更与潜在错误的 mermaid 图表,以及带建议修复 diff 的内联注释。同时也支持按需发布到 GitHub PR 评论。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/sedricedwards/invertebrate/tree/HEAD/skills/invertebrate

Installed? Explore more 写作与编辑 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Invertebrate — 类 Greptile 风格的审查

Greptile 相较于 linter 的优势在于上下文:它基于整个仓库的依赖图来审查差异,从而能够捕获那些使三个调用者崩溃的重命名、缺少装饰器的新端点、以及导致调用方无操作(no-op)的“优化”。本技能仅读取差异是无法做到这些的。

其第二个优势在于信号质量:每条评论都是一个具体、可验证的 bug,并附带修复方案,而不是一篇风格论文。团队会关闭那些总是虚报问题的审查工具。不确定时,宁可遗漏也不要误报。

1. 解析目标

用户提供差异来源
PR 编号/URLgh pr view <n> --json title,body,baseRefName,headRefName,files + gh pr diff <n>
分支git diff <base>...HEAD(三个点表示从合并基础点开始 diff;base = main/master/develop,以存在的为准)
无git diff HEAD(已暂存+未暂存);如果为空,则使用当前分支与其基础分支的比较
.diff/.patch 文件该文件;工作树视作变更后的仓库

如果可用,读取 PR 的标题/描述(从 gh 获取,或用户指向的描述文件)。“一个安全 PR 没有附带修复代码”是 Greptile 的一个真实捕获案例:列出描述中的每个声明(“修复 X”、“为 Y 添加验证”),并检查 diff 是否真的实现了它们。如果声称的修复未出现在 diff 中,则视为一个发现,其严重等级等同于该 bug 宣称要修复的问题。

一个干净的 PR 是有效结果。如果验证后没有发现任何问题,请明确指出,评分 4-5/5,然后停止——编造问题以显示全面的做法是让审查者被禁言的最快途径。

2. 加载审查配置

配置文件夹为 .invertebrate/。为了兼容已经在使用 Greptile 的团队,如果不存在 .invertebrate/,则读取 .greptile/(使用相同格式)。按目录解析:在每个目录中,如果存在 .invertebrate/ 则使用它,否则使用 .greptile/——绝不同时从一个目录读取两者。检查仓库根目录以及每个包含变更文件的目录(monorepo 场景:对于标量设置取最近的,列表/指令从父目录累积)。也接受根目录的旧版 greptile.json,字段相同。绝不创建或修改这些文件夹——它们只作为只读输入。

  • config.json:
    • strictness 1|2|3(默认 2)——参见 §5 中的过滤规则
    • commentTypes(默认 ["logic","syntax","style"])——丢弃未列出的类型的发现
    • ignorePatterns(gitignore 语法,换行分隔)——跳过匹配的文件
    • instructions——自由格式的审查指导,请遵循
    • rules[]——{id, rule, scope[glob], severity: low|medium|high, enabled};仅在 scope 匹配时应用;disabledRules 移除继承的 id
  • rules.md——该目录树的纯 markdown 规则
  • files.json——{files:[{path, description, scope}]}:当 scope 匹配时(或如果没有 scope 则总是)将这些文件作为上下文读取

两个文件夹都不存在?改用 CLAUDE.md / AGENTS.md / CONTRIBUTING.md 中的编码标准作为规则。在报告中注明使用了哪些配置。

规则违规会成为一个发现,并引用该规则(Rule: <id 或前几个词>)。规则严重等级映射:high→P1,medium→P2,low→P2。

3. 构建上下文图(关键部分)

对于每个变更的 hunk,识别它定义、删除、重命名或更改签名/语义的符号(函数、方法、类、类型、导出的常量、路由、数据库列、配置键、环境变量、事件名)。

对于每个这样的符号,搜索整个仓库,而不仅仅是变更的文件:

  • 调用者 / 引用——Grep 旧名称和新名称。一个被删除/重命名的符号若仍有存活的引用则必然是一个 bug。
  • 兄弟节点——执行同类操作的代码(路由中的其他端点、同一接口的其他处理器、其他迁移文件)。新代码跳过了所有兄弟节点都遵循的模式(认证装饰器、审计日志、验证、事务、锁、await)是 Greptile 的顶级捕获。
  • 被调用者——读取新代码调用的、其约定重要的任何内容的实现(是否抛出异常?返回 null?已经上锁?是否异步?)。
  • 数据流——输入的来源(用户控制?URL 参数?)以及去向(SQL/HogQL、shell、文件系统路径、动态代码执行、HTML)。

维护一个简短的列表:symbol → 依赖它的文件 → 变更对它们造成了什么影响。用它来编写发现,但不要将其转储到报告中。

4. 狩猎

带着上下文图遍历 diff。以下为 Greptile 实际报告的类别及真实示例:

  • 逻辑——循环提前退出导致部分状态;标志/条件取反;别名化值绕过检查;警告从未到达用户。
  • 重构——重命名导致调用者未定义;移动代码丢掉了副作用。
  • 安全——新端点缺少身份验证/授权;通过用户输入注入到查询/shell/路径;沙箱/作用域逃逸(符号链接、挂载、~、变量扩展);空/缺失字段绕过守卫。
  • 验证——接受空/畸形输入为有效;拒绝有效输入;未锚定的正则表达式。
  • 运行时 / 语法——调用未定义的方法;缺少 await;参数数量错误;类型不匹配;无法编译的代码。
  • 错误处理——吞没异常;原始回溯/机密泄漏给客户端;在错误路径上关闭错误/未定义的句柄上的资源。
  • 并发——先检查后执行(check-then-act)和读取-修改-写入(read-modify-write)竞态条件;跨任务/线程的共享可变状态;启动顺序导致事件丢失。
  • 数据丢失 / 完整性——非原子写入;重放时双重应用;静默截断;已删除的数据重新出现。
  • 性能——N+1 查询,热点路径上的 O(n²),一个实际上是静默无操作的“优化”。
  • 对齐 / 泄漏——真实数据或机密通过状态/调试端点或日志暴露。

在保留每条候选发现之前,必须进行验证。 你必须能够陈述:确切的行号、触发问题的具体输入/状态,以及错误的结果。如果你无法构造出失败场景,则丢弃该发现。重新阅读周围代码——一半看起来像真的 bug 实际上在三行后就已经被处理了。

5. 分类与过滤

每条发现获得:

  • 严重等级——P0 必须在合并前修复(安全漏洞、数据丢失、常见路径上的崩溃、构建失败)。P1 应该修复(错误行为、损坏的边缘情况、高严重等级的规则违规)。P2 考虑(可维护性、轻微性能问题、低严重等级规则)。
  • 类型——logic(bug、行为、边缘情况),syntax(无法编译/运行、语言使用错误),style(质量、命名、约定)。

根据 strictness 过滤:

  • 1——保留 P0、P1、P2。
  • 2(默认)——保留 P0、P1;仅当 P2 违反显式配置的规则时保留。
  • 3——仅保留 P0,外加这些 P1:安全漏洞、从用户输入可达的崩溃/500 错误,以及违反配置的 high 严重等级规则。严格度 3 意味着“仅当会呼叫某人或团队明确要求时”,远程可触发的崩溃符合条件。

然后丢弃不在 commentTypes 中的类型。纯格式化(格式化工具会修复的问题):绝不报告。

6. 置信度评分(0-5)

分数含义
5/5生产就绪——合并
4/5小修小补——小修复后合并(仅 P2)
3/5实现问题——先处理反馈(存在 P1)
2/5显著 bug——需要重做(多个 P1,或一个容易修复的 P0)
0-1/5关键问题——重新思考(P0 安全/数据丢失,或设计错误)

评分配置化:支付/认证/迁移中的同一个 bug 比内部脚本中的评分更低。给出一个句子的理由。

7. 图表

根据变更内容选择;对于微小变更(文档、配置更新、约小于 20 行的本地逻辑)跳过:

  • sequenceDiagram——多组件交互、API/请求流、异步/并发顺序(如有竞态条件则展示)
  • erDiagram——模式 / 数据模型变更
  • classDiagram——类/接口层次结构变更
  • flowchart——控制流 / 业务逻辑变更

图示变更本身,而非整个系统。控制在约 15 个节点以内。用 Note / 标签标记出有缺陷的步骤。

8. 输出

严格使用以下结构(仅在注明的部分可以省略):

## Invertebrate 审查结果 — <PR 标题或分支>

### 总结
<2-4 句,通俗语言:变更做了什么、影响谁/什么、原因。然后 1 句说明主要风险。>

### 置信度评分: N/5
<一句理由>

### 发现
| # | 严重等级 | 类型 | 位置 | 问题 |
|---|---|---|---|---|
| 1 | P0 | logic | `path/file.ts:42` | <简短标题> |
(如果没有:"未发现问题。")

### 图表
```mermaid
...
```
(对于微小变更省略该部分)

### 内联注释

#### 1. [P0 · logic] <简短标题>
`path/file.ts:42`

<问题是什么、具体的失败场景,如果是跨文件问题,说明哪些其他文件会受影响以及原因。2-5 句。>

```diff
- 旧行
+ 修复后行
```

#### 2. ...

---
<sub>审查了 <N> 个文件 · 配置: <.invertebrate 或 .greptite 路径 | CLAUDE.md | 默认值> · strictness <n> · <已知的 commit sha></sub>

建议修复的 diff 必须是真实的、最小的,并且适用于实际代码。如果修复跨越多个文件,则使用其路径作为标题行展示每个文件的 hunk。如果不存在安全的单 hunk 修复,则描述它,而不是编造一个。

在报告之后,提供:“说 fix all、fix P0 或 fix #2,我将应用它们。”不要在未经提示时应用修复。

9. 发布到 GitHub(仅当被要求时:--post、“post it”、“comment on the PR”)

发布是面向外部的——仅当明确请求针对该 PR 时才执行。

  1. 获取 owner/repo(gh repo view --json nameWithOwner -q .nameWithOwner)和 head sha(gh pr view <n> --json headRefOid -q .headRefOid)。
  2. 内联注释只能针对 PR diff 中存在的行(右侧,新行号)。diff 之外的行上的发现仅放入摘要正文。
  3. 将审查 JSON 写入临时文件,并通过一次调用发布:
{
  "commit_id": "<head sha>",
  "event": "COMMENT",
  "body": "<来自 §8 的完整 markdown 报告,不含内联注释部分>",
  "comments": [
    {"path": "src/file.ts", "line": 42, "side": "RIGHT",
     "body": "**P0 · logic** — <标题>\n\n<说明>\n\n```suggestion\n<精确替换第 42 行的内容>\n```"}
  ]
}
gh api repos/<owner>/<repo>/pulls/<n>/reviews --method POST --input review.json

仅当替换内容精确覆盖被注释的行时,使用 GitHub 的 ```suggestion 块(对于多行使用 start_line + line)。否则使用 ```diff 块。除非用户要求,绝不使用 REQUEST_CHANGES/APPROVE。从响应中报告审查 URL。

相关技能