这篇是我 2026 年 9 月的实践记录。之后本机工具环境有变化,文中的 CLI 状态和命令不代表现在仍然适用。
为什么搞这个
2026 年 9 月,我想把几个 CLI 编码助手接进同一条可检查的流程。任务一大,同一个模型又想方案、又改代码、又验收,就容易只凭自己的说法宣布做完,测试报错也没认真追,聊久了还可能偏离原目标。
我看过一些现成的多 Agent 框架,感觉对本地个人项目来说太重。消息队列、数据库和中间件一多,环境出点问题,排查成本可能比写代码还高。
于是我拼了一套轻量流程,核心规矩是,负责拆任务和验收的人,不直接替执行者写那部分代码。
当时分工大致如下。
- 我只跟 Codex 说目标,最后由我验收。
- Codex Desktop先了解项目、拆任务、写清要求;执行者交付后,它再看文件和
git diff,自己跑构建和测试。 - 执行者在 AGY(Antigravity CLI)和 Claude Code 之间切换,AGY 负责日常的局部实现,Claude Code 按需接任务或临时替代。
我(提目标、最终验收)
|
v
Codex Desktop(拆任务、定规矩、验收)
|
叫谁来干活
|
+--------+--------+
v v
AGY(默认) Claude Code(指定/备用)
一套引擎,两个入口
当时我给 Codex 配了两个 Skill,一个负责调用 AGY,一个负责调用 Claude Code。Skill 只决定「什么时候该叫谁」,真正管理任务的底层共用一套引擎。
tmux 会话、进程管理、超时、日志、任务状态、断点续接、防休眠和 Git 锁都在这套引擎里处理。两个入口共用它,就不用把同一套运行逻辑维护两遍。
怎么知道活干完了
我不靠「哪个文件看起来最新」来猜任务状态。
每个大目标有一个 task_id。每一轮依次编号为 job-001、job-002……所有内容都放在 .agent-work/<task_id>/<job_id>/ 里。
prompt.md写清本轮要做什么。stdout.log和stderr.log保存执行日志。manager.log记录管理进程的状态。result.json保存这一轮的结束结果。
等待方式也有讲究。
- 执行进程放在 tmux 里,和 Codex 那次调用分开,Codex 不用一直等着。
- 本地 waiter 轮询
result.json。等待时不再调用模型,也不继续消耗模型额度。不过 Codex Desktop 关闭后,等待过程不会自己恢复。 - waiter 中断不代表任务进程已经退出。用
status、wait或recover加上 task 和 job 编号可以接着查看;只有明确执行cancel才会终止它。
result.json 不等于验收通过
执行者说「做完了」,只说明它这么认为。
result.json 由管理进程根据退出码和日志写入,执行者不能自己改。它只说明「这个进程结束了」,不说明代码一定正确。
Codex 还得自己验,先看改了哪些文件,再核对 git status 和 git diff,最后实际运行 build、test 和 lint。执行者的报告可以当线索,不能代替这些证据。
出错得说清楚错在哪
只说「报错退出了」,我还是不知道问题出在哪。
引擎会区分正常结束、一般错误、额度用完、认证失效、权限不足、超时、取消、进程崩溃和协议错误。错误类型和工作区是否被改动也分开记录。有的任务报错了,但留下的代码仍然可用;有的则只有半成品。
Codex 得读日志,把真正原因找出来。只转述「Agent 报错退出」,我没法判断该换执行者、检查认证,还是处理代码问题。
返工不能只说「继续改」
测试没过,或者交付和目标不一样,不能只丢一句「继续修改」。要求太模糊,执行者很可能沿着错误方向继续补。
返工说明要写清文件、当前表现、预期结果、能定位问题的证据(报错、测试断言或 diff),还要标出哪些地方不能改,以及修改后怎么验。
能接回原会话就接回去;接不上时,就让 Codex 整理一份简短交接,再开新会话。
真踩过的坑
这套流程里有几次坑,我到现在还记得。
Claude 返回了文字,但没改文件。 有一次它正常输出了回答,进程也退出了,可 Git 里一个文件都没变。后来我切到 stream-json 模式,检查 tool_use → tool_result → end_turn 有没有走完,也核对工作区内容,才知道那次实际没有执行修改。
模型名写死会出错。 早期我把后端模型名写在配置里,网关映射一变就收到 400。还有一次,本地代理重启后把模型连接也断了,执行者当场没有模型可用。后来 Claude 跟着 CC Switch 的配置走,AGY 单独指定。
管道会堵。 执行者输出多时,普通管道的缓冲区会满,整条流程就停住了。后来我改成持续写入文件。超时或取消时也不能只结束最外层进程,整个进程组都要处理,否则编译器等子进程可能留下来。
Mac 不能合盖。 caffeinate 可以阻止空闲时休眠,但合上盖子仍可能中断任务,我不把它当成支持场景。同一个 Git 工作区也只允许一个执行者写,开始前要留 baseline 快照,不能覆盖我自己尚未提交的改动。
把 6 次、10 次的轮数上限删了
一开始,我怕它一直返工,就给每个任务设了轮数上限。
后来真遇到一个任务,上一轮结束时还有明确缺陷,返工说明也准备好了,计数器却到顶了,流程只能停在那儿。
我就把轮数上限删了。调用历史照样记录,下一轮要不要继续,由 Codex 根据 diff 和测试结果判断。当然也不是让它无限跑,额度用完、认证失效、网络不通、权限不够或缺少关键信息时都要停下来,再把原因说清楚。
后来又加了一层,让网页版 ChatGPT 当军师
CLI 这一层能用了以后,我又加了一环。
当时我有个手动流程,Codex 审完代码,我把报告复制给网页版 ChatGPT,请它判断下一步,再把回复贴回 Codex。这个来回有用,但任务一长,复制粘贴就很烦。
于是我把这一步做成 Skill。Codex 先读本地代码,写好报告,再通过浏览器发进专门的会话。回复要带协议头和结束标记,但网页说「完成」还不够,本地验收证据也得齐全。发送状态不明时先暂停,不盲目重发;执行记录缺失时,就回到文件和 diff,不凭一个标记重放任务。
这套流程当时在隔离的演示项目里跑过三轮,十项离线测试全部通过。第一轮回复因为格式不符合要求,被本地拒收并保存了原文。
当时的真实边界
这套做法也有几条当时没解决的限制。
- 没跑过两小时以上的无人值守长任务。短任务验证过,长的没试。
- Codex Desktop 关掉之后,等待不会自己恢复。当时只能靠那次还没返回的调用撑着,或者手动用命令接回来。
- Git 锁只管得住这套体系里的工人,管不了我在 IDE 里手动改,也管不了别的进程。
- 没有系统级沙箱。「别改这个目录」只是写在提示词里的要求,不是真的锁。
- Git 只能还原仓库里的东西。仓库外的文件、外部接口的调用,快照救不回来。
最后
我当时的想法很简单,个人项目不一定非要先搭一套大平台。把手边的 CLI 分好工,把每轮任务和验收证据留下来,已经能让流程清楚不少。
其他项目可以在 GitHub 查看。
留下你的回应
正在加载回应…