博客

AI 编码 agent 说不之后,交付会怎样?

大部分无人值守 agent 停在 PR。本文记录一次真实交付:另一个模型两次拒绝代码,随后修复、合并并发布;commit 和 Release 都能点开查看。

本页目录 · 7 节
  1. 这次交付
  2. 拒绝
  3. 截图说不出来的那部分
  4. 闸门能拦住交付之后,变的是什么
  5. 自己试
  6. 账本
  7. 相关

搜「AI 编码 agent」,会看到很多能自动开 PR 的工具。开 PR 已经不难。

少有人展示的是拒绝:另一个东西读完 diff,判断这份代码不能发。下面这次交付真的发生过。

这次交付

Issue #1018 是我们自己发版代码里的一个真实缺陷: 有个改动把文档同步挪到了打 tag 之前,于是开出三个窗口,让「已发布的 tag」可能没有对应的文档页。

这张票打上 ai-ready。没有别的配置。

Orbi 认领它,在隔离的 worktree 里干活,基于一个记录下来的 base commit 开出 PR #1023。到这里为止,每个 agent 都能做。

然后另一个会话,全新的上下文、完全不记得自己写过这些代码,去读那份 diff。

拒绝

第一轮回来一条 Major。不是风格建议:

Location: src/orbi/release.py:2377

Note: 如果 publish_release 在 tag 推上去之后失败,rollback_release_docs 会删掉文档 commit,却把远端的 tag 留在那里。CI 于是可能看到一个没有文档页的 已发布 tag,违反验收项。

修 bug 的那个改动,在更窄的窗口里把 bug 又造了一遍。评审点出了文件、行号、成因, 以及正确的修法长什么样。

Orbi 读了这条 finding,补上恢复路径,再跑一遍。第二轮又回来了,这次是覆盖率: 新分支没有测试。再来三个 commit。

一共九个 commit,+427/-43,从 Issue 到合并三小时零两分钟。然后是 v0.5.17, 生成的 release notes 里列着这张 Issue 和这个 PR。

这段时间里没有人做过任何决定。

截图说不出来的那部分

我们用这次运行剪了个视频,有一处必须在画面上标注,否则帧本身会骗人。

runner 是拿我自己的 GitHub 账号发东西的。它用我的 token,所以它的 commit 署我的名, 它的评审意见也署我的名、配我的头像。屏幕上,拦下 PR #1023 的那条评审显示在 xqliu 名下,徽章写着 Collaborator 和 Author。

第一次看到的人会把这读成「一个开发者在审自己的 PR」,恰恰是这整件事要反驳的东西。 而那条评论正下方,坐着一条 github-actions 的评论,带着 Bot 徽章。 同一屏先教会你「机器人长这样」,再给你看一条不是机器人的评审。

我没法让 GitHub 显示成别的样子。我能做的是把它说出来:那是第二个模型, 跑在独立的会话里,不记得自己写过被它拒掉的那些代码。

闸门能拦住交付之后,变的是什么

一个能写代码、能开 PR 的 agent,只是把活挪给了人。总得有人去读、去判断、去合。 agent 干的是打字那部分。

把闸门做成真的,多半是管道活。verdict 必须绑定到某个具体 commit, 否则后来的推送会绕过一个为更早的 commit 出具的判断。finding 也必须具体到 一个全新的、不记得原始工作的会话能据此动手。只会说「还没完成」的检查, 会让下一个会话去猜。

更难的部分是,它得被允许直接把整次交付判死。我最近在和几个做类似闸门的维护者对账, 他们说的是同一件事:大家都把检查留成 advisory,因为会拦的检查拖慢迭代速度。

我觉得这件事的关键是谁在等,而不是检查对不对。拦一个人的 PR,当场花掉那个人的时间, 他能感觉到。拦一个 agent 的 PR,不花任何人的时间。agent 读完 finding 自己再跑一遍, 凌晨三点,所有人都在睡觉。

自己试

整条流水线是一个容器。systemd 在里面当 PID 1,那几行 cgroup 挂载就是为了这个:

docker run -d --name orbi \
  --stop-signal SIGRTMIN+3 \
  --tmpfs /run --tmpfs /tmp \
  --cgroupns=host -v /sys/fs/cgroup:/sys/fs/cgroup:rw \
  -v orbi-deploy:/orbi \
  -v orbi-work:/work \
  -e GH_TOKEN="github_pat_xxx" \
  -e ORBI_SOURCE_REPO="OWNER/REPO" \
  -e ORBI_PI_PROVIDER=deepseek \
  -e ORBI_PI_MODEL=deepseek-chat \
  -e ORBI_PI_BASE_URL=https://api.deepseek.com \
  -e ORBI_PI_API_KEY="sk-xxx" \
  ghcr.io/orbi-build/orbi:latest

引擎就是那四个变量指向的模型。给一张 Issue 打上 ai-ready,下一次 tick 就会认领它。 评审跑在独立的会话里,对的是冻结的 head;那个会话不放行,就不会合并。 完整步骤见 docs.orbi.build/docker。

账本

这套东西跑在它自己的仓库上。到今天为止,27 天:orbi/ 分支合并了 334 个 PR, 发布了 51 个打了 tag 的 release。

每一个都是能点开的链接,包括那些拦下了东西的评审,以及之后补上的 commit。

Orbi 以 AGPL-3.0 开源并支持自托管:github.com/orbi-build/orbi。

相关

继续阅读:Orca 对比 与 Cloud。

每周一个真实交付

每周一封,讲一次真实交付。随时退订。