记录下用 GitHub Projects + Orca 把 AI 编程工作流跑通的过程,踩的坑都在里面,以 macOS 为例。
背景:手头有个 side project(panta-log,本地优先的语音复盘工具),之前 issue/PR 规范一直躺在另一个项目里没落地。这次目标很明确:看板管任务,Orca 跑 agent,一天之内把「领任务 → 开发 → 测试 → 合并 → 状态自动流转」整条链跑通。
先看最终跑通后的闭环长什么样:
看板挑卡(Todo) → Orca 从卡片开 worktree → agent 干活(自跑测试)
→ PR 触发 CI → 审 diff → squash merge
→ issue 自动关闭 → 看板卡片自动进 Done → 远端分支自动删除
第一步:规范落地
直接从自己的 boss-zhipin-scraper 项目抄了一套:issue 模板(bug/feature/question 三个 yml)、PR 模板、CONTRIBUTING.md,改成新项目的技术栈(uv、pytest、macOS 权限那些禁忌)。推上去之后仓库的 New issue 页面就有中文表单了,这步没什么好说的,五分钟的事。
第二步:用 gh CLI 批量建 backlog
Roadmap 文档里本来就有六个工作包、带验收标准,照着拆就行。原则:
- 只把「需改造」和「需新建」的任务建成 issue,已经能用的不建,别污染看板
- 标题带上任务编号(WP-A1 这种),看板上一眼能对回文档
- 正文直接引用 roadmap 的验收标准原文,再加一句建议批次(第几周做)
- 全部挂到 milestone 上,milestone 描述里写清退出条件
18 个 issue,两个 for 循环的事。
第三步:踩坑重灾区——gh project CLI
Projects 的操作大部分能用命令行做,但命令的坑一个接一个,全是实际踩出来的:
坑 1:gh auth refresh 非交互执行必须加 -h
在 Claude Code 里用 ! 前缀跑命令是非交互模式,直接报错:
--hostname required when not running interactively
要写成 gh auth refresh -h github.com -s read:project,project。另外这个命令要设备授权,进程会卡在那等浏览器确认,放后台跑,从输出里把 one-time code 捞出来,去 github.com/login/device 输入就行。
坑 2:field-create 的参数是 --name,不是 --title
gh project field-create --title "Phase" 会直接 unknown flag。帮助文档里两种写法都出现过,以 --name 为准。
坑 3:-q 必须配 --format json
这条最阴险。gh project item-add <n> --owner me --url xxx -q '.id' 会静默失败,报错是 cannot use --jq without specifying --format json。批量脚本里 18 个 item 全挂了还看不到原因(stderr 被吞了)。正确写法:
gh project item-add 2 --owner eatmoreduck --url "https://github.com/xxx/issues/1" --format json -q '.id'
坑 4:item-edit 用的是 --project-id,不是 --owner + --project-number
前面 item-add 都是 number + owner 的组合,到 item-edit 突然变了,要用项目全局 ID(形如 PVT_xxxx,project list 里能看到):
gh project item-edit --id <item-id> --project-id PVT_xxxx \
--field-id <field-id> --single-select-option-id <option-id>
坑 5:item-list 的 JSON 里 fieldValues 是 null
挂完板想核对字段值,gh project item-list --format json 返回的 fieldValues 全是 null,不是没设置上,是这接口压根不返回。想验证只能上 GraphQL:
gh api graphql -f query='query($login:String!,$number:Int!){
user(login:$login){ projectV2(number:$number){
items(first:30){ nodes{
content{ ... on Issue { number } }
fieldValues(first:20){ nodes{
... on ProjectV2ItemFieldSingleSelectValue { name field{ ... on ProjectV2FieldCommon { name } } }
} }
} } } }
}' -f login=eatmoreduck -F number=2 --jq '...'
建两个单选字段(Phase 对应版本分期、Area 对应模块),18 张卡批量挂板、设 Status/Phase/Area,再建两个日期字段给时间线用。一次搞定。
Orca 接入:比想象的省事
本来以为要在 Orca 里走一遍 GitHub OAuth,结果打开集成页面发现 GitHub 已经是 Connected 状态。原因是 Orca 的 GitHub 集成直接读本机 gh CLI 的登录凭据,gh 登录过就算接好了,根本不存在「连接并授权」按钮。

还有个小迷惑:想找看板找不到。Orca 的「任务」页面顶部有三个标签——议题、PR、项目。issue 列表在「议题」里,看板在「项目」标签里,从卡片右键就能创建 worktree,composer 会自动预填任务名并链接 issue。

看板自动化:两条规则,默认就是开的
闭环的引擎是 Project 自带的两条工作流:
- Item added to project → Set Status = Todo(新卡自动入列)
- When pull request merged → Set Status = Done(合并自动流转)
有个反直觉的地方:这两条项目创建出来就是 On 的状态,什么都不用配。我一开始以为得去网页设置里手动开,还专门写进了待办清单,后来打开 Workflows 面板一看,人家早就在干活了。查了一圈才确认 gh CLI 压根没有管理 Workflows 的子命令(gh project --help 里只有增删改查 item 和 field),所以这东西既没法命令行关掉也没法命令行开,只能去项目页面的 Workflows 面板查看和调整。

它们生效之后,merge PR 的瞬间:issue 自动关(commit 里写了 Closes #n)、卡片自动进 Done,全程无感。
Roadmap 时间线:日期值可以命令行灌
时间线视图打开一片空白,因为每个 item 都没有日期。做法:
- 建
Start date/Target date两个日期字段 - 视图工具栏的 Date fields 里把起止指向这两个字段
- 日期值按 roadmap 的执行批次用命令灌:
gh project item-edit --id <item-id> --project-id PVT_xxxx \
--field-id <start-field-id> --date "2026-09-14"
灌完时间线上就是一根根条了,之后直接拖拽调期,字段值会跟着变。

多开 agent:可以,但别贪
Orca 的核心玩法就是一个任务一个独立 git worktree,几个 agent 并行互不踩分支。实测确实如此,两个任务同时跑,互不干扰。
但有几个实际经验:
- 挑卡要避开文件冲突。两个任务都改同一个文件,后合的必然冲突。同子系统的任务(比如都动转写模块的)别并行
- 并行 2-3 张,merge 串行。瓶颈根本不在写代码,在 review。一口气开五个 agent,五个 PR 堆在那里你审不过来,盲合进核心管线等于裸奔
- 智能体仪表盘三列(需要你 / 工作中 / 已完成)就是多开时的管理面板,agent 停下来等确认会出现在「需要你」列

另外 Orca 不会自动从看板领卡派活,挑哪张卡什么时候开还是人说了算。这反而是好事。
CI 也扔给 agent 建
仓库没有 CI,PR 级的自动测试就是空的。我的做法是先提一个 issue 把约束写死:私有仓库 Actions 分钟数计费、macOS runner 按 10 倍费率所以必须锁 ubuntu runner、只加一个 workflow 文件、不引入 ESLint/mypy。然后开个 worktree 交给 agent。
结果它把验收标准全打勾了:backend(ruff + 88 个测试)和 frontend build 双 job 全绿,合计 40 秒出头。中间还自己踩坑自己修——ubuntu 的 sounddevice 缺 PortAudio 依赖,它在 CI 里补了 apt-get install libportaudio2。更绝的是第一轮它故意看着 CI 红了一次才修,验证失败报警机制真的能响。

这里有个经验值得记:给 agent 的 issue 写得越具体(约束、边界、验收标准),产出越省心。模糊的「帮我加个 CI」和带计费约束、验收标准的 issue,产出质量差很远。
审查和合并不用出 Orca
审 diff、给 agent 提修改意见、合并,全程在 Orca 里:
- Diff viewer 逐行看,有问题直接在那个 worktree 的 agent 会话里说,改完 push 同一个 PR 自动更新
- Checks 面板看 CI 状态,失败可以直接一键把失败的 check 交给 agent 修
然后是这次最典型的一个误用:合并按钮找不着,右上角那个「提交」按钮还是灰的。
灰是对的——那是 git 推送按钮,没东西可推当然灰。合并入口在 PR 详情视图里(从 PR 列表点进去那一页),合并按钮带方式下拉,跟网页版一个逻辑。

merge 方式:选 squash,别犹豫
三种方式的区别一句话说清:
- Squash:整个 PR 压成 master 上一个提交,中间提交全丢弃
- Rebase:每个提交逐个重放上来,中间提交全保留
- Merge commit:原样合并,再加一个合并节点,历史变分叉图
AI agent 的产出场景,squash 是唯一解。agent 的中间提交全是「fix typo」「round 2」这种碎片,没有保留价值。squash 之后一张卡对应 master 上一个干净提交,回滚就是 revert 一条,Closes #n 写在 PR 描述里照样生效。另外两种只在多人协作保留分支拓扑、或你亲手精心整理过提交序列时才有意义。
仓库设置:两个开关分开看
- Automatically delete head branches:合并后自动删远端分支。开了立即受益,不然二十张卡的分支堆在远端没人清。本地 worktree 不受影响,用完在 Orca 里手动删
- Allow auto-merge:让 PR 可以设「checks 全绿自动合」。注意这只是解锁功能,不对具体 PR 启用就什么都不会发生。还有,没有 CI 的时候开了也是摆设——没有任何 checks 可等。所以顺序是:先开自动删分支,auto-merge 等 CI 上线再说
一天下来的小结
| 事项 | 状态 |
|---|---|
| issue/PR 模板 + 贡献指南 | 已推送生效 |
| 19 个 issue + milestone + 看板字段 | 全部挂板,GraphQL 逐条核验过 |
| 两条看板自动化 | 默认开启,零配置 |
| Roadmap 时间线 | 三批次日期已灌入 |
| CI(agent 自建) | 已合并生效,双 job 全绿 |
| 完整闭环 | 第一张卡从挑卡到 Done 全自动流转验证通过 |
最大的感受:这套东西搭完之后,「管理任务」这个动作本身消失了——剩下的就是把卡一张张挪完。工具链各管一段:GitHub Projects 记状态,Orca 管 agent 和 worktree,gh CLI 补一切自动化的缝。
后面打算把「每天开工先看看板挑两张卡」养成习惯,看板不撒谎,进度不用记。

