tk3.biz
返回博客列表

我只用了 dev-orchestra 的审查功能,把本地的改动交给多个 AI 看

前言

上一篇让 dev-orchestra 在最后把整个变更又审查了一次。

dev-orchestra 是一个 Claude Code / Codex / Antigravity 的插件,只需一句话的请求,就能跑完设计、实现、测试、多个 AI 的审查和修复。

不过,“从设计开始全部交给它”,作为尝试来说步子有点大。很多时候,手头只是有一个写到一半的改动,只想让几个 AI 帮忙看看。

dev-orchestra 的审查可以脱离其他环节单独使用。这次介绍只用审查的步骤。

  • 3 条命令:review snapshot → review run → review show
  • snapshot 固定的是什么,.ai/ 里会留下什么
  • 常用的选项,以及审查 PR 分支时 --base 怎么选
  • 不审查代码、而是审查文字(本博客的文章)的例子

dev-orchestra 已在 GitHub 上开源(MIT 许可证)。如果觉得有用,欢迎给个 Star。

→ github.com/istb16/dev-orchestra

试用环境

项目内容
dev-orchestra1.3.0,预设 standard(optimization.level 为默认的 balanced)
审查者claude-general(Claude Opus)、codex-general(Codex CLI 0.163.0,gpt-6.1-sol)、claude-security(Claude Sonnet)、claude-test(Claude Sonnet)
Claude Code2.1.312
环境Windows 11、Git Bash、Python 3.14.7、Git 2.55.0。配置放在与平时不同的文件夹(DEV_ORCHESTRA_HOME)中

安装 dev-orchestra 的步骤写在 Claude Code 篇和 Codex 篇中。只用审查时,安装方法和初始设置也一样。

素材:添加了优惠券的分支

为此我做了一个小的 Python 包 shopcart。main 上只有计算购物车小计的函数,分支 feature/coupon 添加了优惠券的函数。

PERCENT_OFF = {"SAVE10": 10, "SAVE20": 20}
AMOUNT_OFF = {"SAVE500": (500, 3000)}  # code: (yen off, minimum subtotal)


def apply_coupon(amount, code):
    """Return the amount to pay after applying the coupon `code`."""
    if code in PERCENT_OFF:
        discount = amount * PERCENT_OFF[code] // 100
        return amount - discount
    off, minimum = AMOUNT_OFF[code]
    if amount > minimum:
        return amount - off
    return amount

README 里写着:“SAVE500 在小计达到 3,000 日元时减 500 日元”“不认识的代码不改变金额”“代码区分大小写(有意为之)”。也就是说,这段代码里故意埋了 2 个缺陷(> 应该是 >=;不认识的代码会引发 KeyError)。优惠券的 3 个测试(加上购物车的测试共 5 个)全部通过。

1. 固定改动(review snapshot)

固定从分支起点(main)开始的改动。

dev-orchestra review snapshot --base main
Snapshot: .ai/workflows/b1627574daa6/reviews/review-target.diff
  strategy: git diff main
  files:    4
  size:     2249 bytes (sha256 27ff110afa0b)

snapshot 这一步会把要审查的差异固定到 1 个文件中,让所有审查者看到同样的内容。固定之后即使再修改文件,这一轮审查者看到的差异也不会变。不加 --base 时,固定的是工作树与 HEAD 之间的差异(还没有 commit 的改动)。还没有 commit 的新文件默认也会包含在内。

固定的内容会留在 .ai/ 下。

文件内容
review-target.diff给审查者看的差异本身
review-target.json差异的来源(base、base_commit、head)、改动的文件列表、新增和删除的行数、差异的 sha256、没有发送的文件(withheld)
state.json这次工作(workflow)的记录

sha256 也会写进各审查者的报告里,事后可以确认“所有人看的是同一个差异”。

.ai/ 里会自动放一个只写了 * 的 .gitignore,所以不会不小心被 commit。

如果在配置中设置 review.context.surrounding: enclosing,还可以把差异周围的函数和类一起固定下来交给审查者(默认是 none)。详情见 references/reviews.md。

2. 运行审查(review run)

dev-orchestra review run
ok      claude-general     claude   opus               3 finding(s)

1 successful, 0 failed
Consolidated: .ai/workflows/b1627574daa6/reviews/consolidated.md
note: claude-test (when: relevance) added: shopcart/__init__.py is not documentation
note: no test result recorded for this change, so the review is running unchecked. `state record test ok` before `review run` lets this stop a review of a red tree.
note: low-risk change (4 file(s), 49 line(s)): 1 reviewer instead of the full panel (claude-general). Cross-model disagreement is what a second reviewer buys; raise optimization.level or the low_risk thresholds to keep it.

17 秒就结束了。不过审查的只有 1 人。第 1 条 note: 是在告知:因为“这不是只改文档的改动”,所以把测试视角的审查者 claude-test 列入了候选。即便如此,实际运行的只有 claude-general。正如最后一条 note: 所说,在 balanced 下,规模小且不涉及高风险路径的改动(这次是 4 个文件、49 行)会把审查者减到 1 人。在测量篇中也发生了同样的事。

第 2 条 note: 是在提示没有记录测试结果。只用审查时可以不用管它。如果不想审查测试失败的改动,可以先记录 dev-orchestra state record test ok(或 failed),结果为 failed 时就会停止审查。

3. 查看结果(review show)

dev-orchestra review show

输出的开头和第 1 个问题如下(之后省略)。

Source: .ai/workflows/b1627574daa6/reviews/consolidated.json
# Consolidated review

- Generated: 2026-10-29T13:19:24Z
- Iteration: 1
- Snapshot: 27ff110afa0b
- Reviewers: 1 ok / 1 total
- Coverage: round complete, change complete
- Findings: 3 (0 duplicate report(s) merged)

## Reviewers

- ok [general] claude-general / claude / opus -- 3 finding(s)

## Findings

### F1 [HIGH] correctness

- Location: `shopcart/coupon.py`:12
- Reported by: claude-general
- Possible duplicate of: none
- Triage: needs-triage
- Problem: Any code missing from `PERCENT_OFF` drops through to `AMOUNT_OFF[code]`, so an unknown code raises `KeyError`. The README says an unknown code should leave the amount unchanged.
- Impact: Checkout crashes when a user enters a mistyped or lowercase code like `save10`. The README calls out lowercase codes as invalid on purpose, so this input is expected.
- Evidence: `off, minimum = AMOUNT_OFF[code]`
- Recommended fix: Add `if code not in AMOUNT_OFF: return amount` before the lookup, or use `AMOUNT_OFF.get(code)` and return `amount` when it is `None`.

问题共 3 个:埋下的 2 个缺陷(F1 的 KeyError、F2 的 >),以及指出缺少边界测试的 F3。每个问题都按固定的格式列出严重程度、位置、问题、影响、依据和修改方法。

加上 --json 可以用 JSON 输出同样的内容,也可以交给其他工具处理。

4. 交给多个 AI 看(—only)

减到 1 人的话,就算不上“多个 AI”了。用 --only 点名审查者,人数就不会被减少。我在同一个 snapshot 上加上了其余 3 人。

dev-orchestra review run --only codex-general claude-security claude-test
ok      codex-general      codex    gpt-6.1-sol        2 finding(s)
ok      claude-security    claude   sonnet             4 finding(s)
ok      claude-test        claude   sonnet             5 finding(s)

3 successful, 0 failed
Consolidated: .ai/workflows/b1627574daa6/reviews/consolidated.md
note: claude-test (when: relevance) added: named by --only
note: no test result recorded for this change, so the review is running unchecked. `state record test ok` before `review run` lets this stop a review of a red tree.

3 人并行运行,19 秒结束。即使用 --only 只运行一部分,汇总结果(consolidated)中也会包含其他审查者对这个 snapshot 的报告。看 review show,变成了 4 人、14 个问题。

- Reviewers: 4 ok / 4 total
- Coverage: round complete, change complete
- Findings: 14 (0 duplicate report(s) merged)

埋下的 2 个缺陷,都有 3 人各自作为缺陷指了出来,claude-test 也以“没有确认它的测试”的形式提到了。14 个问题中哪些采纳、哪些作为重复或驳回,下一篇再讲。

如果一开始就想让 4 人看,可以在 --only 中列出 4 人,或者调高 optimization.level。也可以用角色名(general、security 等)点名。

5. 常用的选项

选项用途
--only <id 或角色>只运行部分审查者。减少人数的机制也会失效
--sequential一个一个按顺序运行。用于排查哪个审查者卡住了
--context "…"给所有审查者相同的前提(“README 就是规格”“这是文章”等)
--timeout <秒>仅在这次运行中更改每人的时间限制

组合起来使用是这样的。这一节和下一节是在题材仓库的副本中试的。workflow 的名字用环境变量 DEV_ORCHESTRA_WORKFLOW 定为 pr-check(不指定的话,会自动起一个像 b1627574daa6 这样的名字)。

dev-orchestra review run --only claude-general codex-general --sequential --timeout 300 --context "This is a pull request that adds coupons. The README is the spec."
ok      claude-general     claude   opus               3 finding(s)
ok      codex-general      codex    gpt-6.1-sol        2 finding(s)

2 successful, 0 failed
Consolidated: .ai/workflows/pr-check/reviews/consolidated.md
note: no test result recorded for this change, so the review is running unchecked. `state record test ok` before `review run` lets this stop a review of a red tree.

因为是按顺序运行的,花了 27 秒。

6. 审查 PR 分支时的 —base

--base main 取的是 main 与当前工作树之间的差异(strategy: git diff main)。如果建立分支后 main 又往前走了,main 上新增的改动会像是被这个分支删掉了一样出现在差异中。

我试着在建立分支后,往 main 上 commit 了一行 README 的改动,再用 --base main 固定一次。差异里出现了这一行。

-- `subtotal` ignores nothing: every item counts

这个分支没有碰过的行,被当作“删除的行”给审查者看了。把分支的分叉点(merge-base)传给 --base,这一行就不会出现了。

dev-orchestra review snapshot --base $(git merge-base main HEAD)
Snapshot: .ai/workflows/pr-check/reviews/review-target.diff
  strategy: git diff 77d4296d87f869eb4af4d5cf1ca41b135cef2b31
  files:    4
  size:     2249 bytes (sha256 27ff110afa0b)

sha256 与 main 前进之前取的第一个 snapshot 相同。GitHub 的 PR 显示的差异也是从分叉点开始的,所以审查 PR 分支时,推荐传入 merge-base。如果要和远程的 main 比较,就在 git fetch 之后使用与 origin/main 的 merge-base(这次我是用本地的 main 试的)。

7. 不发送 lockfile 的内容(review.exclude)

升级依赖时,lockfile 里会出现几百行的差异。这些不是人写的,却要按审查者的人数消耗 token。dev-orchestra 默认不发送 lockfile、dist/、vendor/、node_modules/、压缩过的 JS 和 CSS、source map、*.snap 的差异内容(review.exclude)。

我试着在题材的副本中放了一个 306 行的 package-lock.json,当作 npm 的 lockfile(尚未 commit 的新文件),又给 cart.py 加了 1 行注释,然后不加 --base 固定了快照(workflow 的名字是 excl)。

Snapshot: .ai/workflows/excl/reviews/review-target.diff
  strategy: git diff HEAD
  files:    1
  size:     311 bytes (sha256 a42cd872c7e8)
  withheld: 1 file(s), 306 changed line(s) not sent to reviewers
    package-lock.json (package-lock.json)
    reviewers are told these changed; --no-exclude sends them in full

文件名和改动的行数会告诉审查者,所以并不是隐瞒。想全部发送时,加上 --no-exclude。token 和费用的话题,我整理在了本系列第 17 篇(预计 2026 年 11 月 23 日发布)中。

8. 不只是代码,文字也能用

要审查的差异不一定是代码。本博客在发布文章之前,会用 review run 审查文章(docs/blog/series.md 中的“审查”一节)。这篇文章写完之后,我也和下一篇文章一起,像下面这样让它审查了。

dev-orchestra review snapshot
dev-orchestra review run --only claude-general codex-general --context "These are two Japanese blog posts (a series on dev-orchestra), not code. Review facts, not style: check that every command, option, output and behaviour described matches dev-orchestra 1.3.0, whose docs are in C:/Projects/dev-orchestra (references/reviews.md, references/cli.md, references/workflow.md) and ~/.claude/plugins/cache/dev-orchestra/dev-orchestra/1.3.0. The outputs quoted were captured from real runs against a small sample repo; flag any claim that contradicts the docs, any internal inconsistency between the two posts, and anything misleading to a reader. Repository rules for posts are in CLAUDE.md and docs/blog/writing.md."

审查者被要求的是审查代码。所以我用 --context 告诉它们“这是文章而不是代码”以及“去哪里核实事实”。我从没在不加 --context 的情况下审查过文章,所以不加会怎样并没有试过(命令中主目录的路径换成了 ~)。

把这篇和下一篇文章一起审查时,claude-general 和 codex-general 提出了 6 个问题。除了“还没有翻译”(因为还在写)之外,还发现了文章之间数字不一致的地方,比如“2 篇文章中的测试数量对不上(应该是 3 个 + 5 个,却写成了 10 个)”“2 篇文章中发现缺陷的人数不一致”,我全都改了。

也写一下缺点

  • 差异会被发送给所登记的各审查者所属的厂商。 4 人的配置中,差异被同时发送给了 Anthropic 和 OpenAI。审查者能以只读方式读取周围的文件,所以发送的不一定只有差异。不能拿到公司外的代码,请使用让本地 LLM 当审查者的方法(英文)
  • 小改动默认会减到 1 人。 想让多个 AI 看,就需要用 --only 或 optimization.level 定好人数
  • 问题只是主张,不是事实。 4 人看了提出 14 个问题,但内容重叠的很多,直接照着改就会把同一个修改请求好几次
  • token 与人数成正比增加。 审查者并行运行,所以时间不会延长多少,但费用要按人数付

总结

  • dev-orchestra 的审查可以不用设计和实现环节,单独使用
  • 用 review snapshot 固定差异,用 review run 审查,用 review show 查看
  • 固定的差异和结果留在 .ai/ 中,通过 .gitignore 排除在 commit 之外
  • 小改动默认会减到 1 人。想让多个 AI 看,就用 --only 点名
  • 审查 PR 分支时,把 merge-base 传给 --base
  • lockfile 等的内容默认不发送。不只是代码,也能用来审查文章

下一篇(预计 2026 年 11 月 13 日发布)会把这次的 14 个问题分成采纳、驳回和重复,再交给修复者去改。

GitHub: istb16/dev-orchestra(给个 Star 就是对我最大的鼓励)

本系列的文章可以在“dev-orchestra”文章列表中集中阅读。

相关文章