AI小白

Codex / 子代理 / 工作流复盘

一个任务跑了 2 小时 37 分:我如何把 Codex 从无意义空转中拉回来

我把两个超过 2 小时的回合拆成等待、模型停顿和真实工具执行。最慢的回合里,至少 67.5% 的时间没有花在编译、测试或文件操作上。

2h37m27s异常回合 A 的总耗时
32.7 秒回合 A 的本地命令累计
≥67.5%回合 A 的等待或停顿占比
6m30s轻量路径复测总耗时

01 先看这 2 小时 37 分花在哪

我最初以为这是一个很重的开发任务。界面一直有活动,子代理也不断返回状态,测试、审查和返工轮流出现。只看过程,它像是在认真干活。

把总耗时拆开以后,感觉完全变了。异常回合 A 精确跑了 2h37m27s,156 次 wait_agent 累计 62.3 分钟,占 39.5%;89 次本地 exec 只用了 32.7 秒,占 0.35%。另有约 28% 的时间没有工具事件,属于模型停顿或无事件等待。

wait_agent 与这段无事件时间不重叠。两项加起来,至少约 67.5% 的时间花在等待或停顿上。编译、测试和文件操作没有吃掉两个半小时,本地命令甚至没有跑满一分钟。

回合 总耗时 wait_agent 本地 exec 能确认的结论
异常回合 A 2h37m27s 156 次,62.3 分钟,占 39.5% 89 次,32.7 秒,占 0.35% 至少约 67.5% 是等待或停顿
异常回合 B 2h04m40s 126 次,50.7 分钟,占 40.7% 251 次,31.4 秒,占 0.42% 同样出现高等待、低工具执行

第二个独立任务也跑了 2h04m40s。它调用了更多本地命令,累计时间却仍只有 31.4 秒。两个任务来自不同工作范围,却长出了同一种耗时结构。

02 触发器:普通任务启动了重流程

这两个任务都有明确目标,本来不需要把流程铺得很长。问题从自动套用重工作流开始:计划、实现代理、独立审查、返工、复审,每一环都能继续派生下一环。

Superpowers、Data Analytics、Agent Reach,以及 autopilotralphteamultrawork 这类重流程都有适用场景。普通实现任务自动带上它们时,流程约定会先于问题本身接管任务。

我现在把它们改成显式点名才启用。普通写作、实现、排障和核查先用模型原生能力。预计 15 分钟内能完成的工作,主线程直接做。

这条规则处理的是收益阈值。子代理交接上下文、等待结果、合并结论也有成本。任务小到不足以覆盖这笔成本时,拆分只会增加步骤。

03 放大器:子代理把等待变成循环

子代理本身有价值。代码搜索、边界清楚的实现、独立审查和浏览器验证,都可能并行节省时间。两个长回合暴露的问题,是代理没有明确的退出条件。

主线程交出任务后开始轮询。子代理没有新结果,主线程继续等;阶段结果回来后,再启动审查;审查给出修改意见,又回到实现、测试和复审。循环里每一步看起来都合理,合在一起却不断重复支付等待成本。

回合 A 的 156 次等待和回合 B 的 126 次等待,就是这种循环留下的痕迹。单次等待没有必要很长,只要轮询足够密、阶段足够多,总时间就会被拉到小时级。

上下文也会随着计划、实现记录、审查意见和测试输出不断膨胀。压缩能够让会话继续,却不会自动删掉已经形成的多轮工作流。任务仍会沿着原来的链条往下跑。

04 失灵的刹车:绿测后还在继续

两个任务都出现了绿测后的重复验证。实现已经通过 focused tests,后面仍可能再跑独立审查、返工后的复测、完整测试和另一轮复审。

测试全绿以后,如果没有新代码、新依赖或新环境变化,继续独立重跑同一套验证不会稳定增加信息。它只会延长链条。

我还核对了几个容易背锅的方向。MCP 和浏览器没有成为两个超过 2 小时回合的共同主因;任务没有进入部署;日志里也没有大量网络 429 或 5xx。资源压力会拖慢请求,但只能当放大器,无法单独解释 50~62 分钟的代理等待。

这一步很重要。没有拆耗时前,任何慢都可以被归到网络、浏览器、机器性能或「模型在思考」。把等待和真实执行分开,才知道应该在哪里踩刹车。

05 我最后改了什么

第一组改动收紧触发条件。重 Skill 和重流程显式点名才用;普通任务走模型原生能力;预计 15 分钟内的工作不拆代理。

第二组改动限制代理规模。默认不自动创建子代理。确实有并行收益时,每个阶段最多 1 个实现代理和 1 个审查代理,避免相同范围被重复实现、重复阅读。

第三组改动给等待设置退出点。90 秒没有可见进展,只询问一次状态;3 分钟仍没有实质进展,主线程接管,不再循环轮询。

第四组改动限制验证。focused tests 和 full tests 按风险各跑一次。结果全绿且代码、依赖、环境没有变化时,不再为了「更保险」启动新的独立重跑。

时间盒必须能真的结束任务

30 分钟汇报当前结果和剩余风险;45 分钟停止增加范围、代理和评审回合;60 分钟结束当前任务。完成不了就缩小交付,明确未验证部分,不让同一种工作方式继续空转。

06 旧长任务为什么要轻量接班

护栏改完以后,我又处理了长期任务的历史负担。13 个长期置顶任务被替换成轻量接班任务:保留原名和必要结论,不复制完整历史。

旧任务会标注历史最长耗时并取消置顶,新任务只带当前职责、事实边界和操作红线。重 Skill 与子代理默认关闭,需要时再明确开启。

长线程的问题不只在文本多。旧对话里形成的流程习惯、未完成分支和大量历史结论,会继续影响新的任务。轻量接班把长期职责留下,把不需要反复加载的历史放下。

07 6 分 30 秒的轻量路径复测

同一个本地工具项目进入下一阶段后,我用轻量路径重新完成了一次开发。用户指令、实现、focused tests、full tests、build 和真实 CLI 验证全部保留,总耗时约 6 分 30 秒。

这次只使用 1 个审查代理,wait_agent 累计 49.66 秒,本地 exec 累计 13.45 秒。验收没有被删掉,减少的是代理轮询和重复流程。

和异常回合 A 的整体耗时相比,约快 24.2×;按旧回合平均每个 Task 比较,约快 6.1×。前后任务复杂度不同,这两个倍数只能当趋势证据,不能当严格同构基准。

我看重的是耗时结构变了。工具执行、测试、构建和真实入口验证都还在,等待从几十分钟降到了不到一分钟。

08 可直接放进 AGENTS.md 的规则

我最后保留了这份短规则。它不要求停用子代理,只要求每次拆分都能说清收益、边界和退出条件。

## 轻量任务执行规则

- Superpowers、Data Analytics、Agent Reach 与重工作流仅在用户明确点名时启用。
- 普通写作、实现、排障和核查优先使用模型原生能力。
- 预计 15 分钟内完成的任务由主线程直接处理。
- 默认不自动创建子代理;需要并行时,先说明可独立交付的子任务。
- 每个阶段最多使用 1 个实现代理和 1 个审查代理。
- focused tests 与 full tests 通过后,没有新变化就不重复独立重跑。
- 90 秒无可见进展只询问一次;3 分钟无实质进展由主线程接管。
- 30 分钟汇报,45 分钟停止扩张,60 分钟结束任务。
- 长期置顶任务采用轻量接班:保留名称、必要结论和红线,不复制完整历史。

以后再遇到 Codex 变慢,我会先问三个问题:真实工具执行了多久,等待和停顿占了多少,当前流程有没有明确的停止点。

只看总耗时,很容易把空转误认成复杂度。把时间拆开以后,子代理该留下的能力能继续用,不产生收益的等待也有了退出条件。