Agent 从一只变成一群:2124 次执行跑出来的并发账

2026-10-15T12:56:00+08:00 | 7分钟阅读 | 更新于 2026-10-15T12:56:00+08:00

@
Agent 从一只变成一群:2124 次执行跑出来的并发账

你在五个终端里各开一个 worktree,五个编码 agent 同时改同一个仓库。四十分钟后回来,五份 diff 摆在那儿:三份动了同一个文件,两份各自新建了一个功能重复的小工具,还有一份写着「完成」但测试没过。省下的是等待时间,多出来的是收尾工作。

十月七日,arXiv 上挂了一篇论文,专门量化这件事。作者拿 Codex、Claude Code、Kimi Code 三个前沿编码 agent,在五个基准上跑了 354 个任务、2124 次执行,记下 112 亿 token,按标准价折成 20780 美元。实验设计很干净:同一个任务、同一个模型、同一段 prompt,唯一变量是把「动态并发」打开还是关掉。动态并发指的是主 agent 在执行过程中自己决定要不要开子 agent、开几个、什么时候收结果。

结论可以一句话说完:并发首先是个规模放大器。指望它省时间省钱,方向就错了。

只有任务足够长,并发才划算

先看总量。开并发的 token 消耗是串行模式的 1.41 到 3.31 倍。任务通过率的净变化,从下降 11.9 个百分点一路到上升 2.3 个百分点,几乎覆盖了「明显变差」到「略有改善」的全部区间。同一套机制换到另一个任务上,可能就从赚变成亏。

分基准看才清楚。有界任务(SWE-bench Verified,解决一个 issue,补丁通常几十行)开并发没有收益,Claude Code 的任务通过率反而掉 24.0 个百分点。最长程的 LoopsBench(任务跨越多个有依赖关系的开发单元)上,Codex 和 Claude Code 的任务通过率最多提升 14.3 个百分点。

把四个长程基准按平均实现规模横向排开,测试通过率相对串行的优势依次是 RepoZero 负 8.29 个百分点、NL2Repo 负 0.04、ProgramBench 正 1.24、LoopsBench 正 4.31。实现规模越大,并发越划算。

账单这边更直接。按「每个成功解决的任务」摊 token,Codex 串行是 769 万,并发是 2412 万,涨了三倍多。三个 agent 全都上升。

时间也没省。15 个「agent 乘基准」的组合里,14 个的平均耗时变长了。Claude Code 在 SWE-bench Verified 上从 17.5 分钟涨到 27.8 分钟,解决的题还更少。并行不等于更快,在这份数据里是字面成立的。

失败大多不在模型推理里,在调度逻辑里

论文把 1062 条并发轨迹逐条人工标注,归纳出 4 个大类、13 个子类、28 种具体失败模式,在 650 条轨迹里标出 804 个实例。占比排序:共享状态与合并 33.2%,执行治理 29.0%,任务编排 28.5%,全局上下文管理 9.3%。

几个数字值得单独拎出来。

交付物覆盖占 14.9%。两个子 agent 各自写出自己的版本,后写的把先写的盖掉,丢的是哪一份没人知道。

扇出预算耗尽占 19.2%,属于「负载不均」子类。主 agent 一趟派出太多子任务,执行预算提前花完,关键路径上的活没时间做了。

子 agent 过早终止占 15.9%,最能说明问题。论文里有个 seqtk 重建的例子:主 agent 把 22 个子命令一次性分给 20 个子 agent,同时假设子 agent 的超时是两小时,而整个任务的预算只有 40 分钟。两个子 agent 分别在 22.3 分钟和 26.7 分钟报告完成,主 agent 一直等到最后才收,剩下 18 个在截止点被砍掉。负责 seq 命令的那个子 agent 压根没写出实现,最终程序通过 440 个测试里的 92 个。

分派本身没问题,等待策略是错的。这个 bug 不在模型的推理里,在编排逻辑里,换成人来写调度器也可能犯。

三个 agent 的并发习惯完全不同

这部分的数据最能直接照到日常操作。

先看什么时候开始派活。Codex 首个 sub-agent 的启动时间中位数落在一整条时间线的 4.0% 处,Claude Code 是 22.1%,Kimi Code 是 26.0%。Codex 几乎一开始就往外发,另外两个要先完成探索和分解。

再看重叠比例,即同一时刻至少有两个子 agent 在跑的时间占比。中位数分别是 Claude Code 52.7%、Codex 23.9%、Kimi Code 15.6%。

两组数字放一起就出现分叉。Codex 派得最早,但 24.3% 的执行创建了子 agent 却始终没让它们真正重叠。创建了不等于并发,它只是把活拆开,然后一个一个等。Claude Code 派得晚,一旦开起来能持续一半以上的时间线。

规模差距更大。LoopsBench 最难那档,Claude Code 平均每个任务创建 133.69 个子 agent,平均同时在跑 25.46 个;Kimi Code 创建 67.00 个,但峰值 37.46 个,因为它习惯整批发出去;Codex 始终维持小分队,峰值在 1.21 到 3.00 之间。任务变难,派出去的量也跟着涨,三档难度平均创建 6.69、7.53、15.84 个子 agent。

如果你在调自己的编排脚本,这几个数能当参照系。并发度上不去,先查是不是根本没发生重叠。并发度爆表,先查是不是把探索和评审也拆成子任务反复派了。

并发真正赚回来的地方

论文给了三个成立条件:子 agent 能做互补的工作,能探索不同解法,能独立验证主 agent 的实现。

有个数字我一直觉得被低估。在两种模式都解决了的 366 个任务里,并发有 102 次跑得更快(27.9%),其中 46 次快了 20% 以上(12.6%)。更快不普遍,但确实存在。

另一组是「独有的成功」。Claude Code 有 4 个 LoopsBench 任务只在并发模式下解掉,串行模式没有任何独有成功。在 SWE-bench Verified 上它整体通过率掉得很惨,却依然独有地解掉 5 个任务。Codex 两种模式总成绩持平,但各自独有地解掉 9 个任务。

并发换来的东西里,多样性比速度更实在。两倍的 token 换来多条不同的尝试路径,这些路径最后能不能收敛成一个能用的结果,取决于你有没有一个专门负责集成的角色。

放到自己的仓库上

隔离边界要挑对。git worktree 只隔离文件和索引,两个 agent 仍然共用同一台机器、同一份凭证、同一批端口。文档、测试、独立模块这类活,worktree 够用。要改依赖、要起服务、要跑来路不明的工具,就得把进程和网络一起隔开,上容器。跑得特别久的任务再往上一层,扔到远程或云工作区,别让它绑在笔记本的休眠上。

Claude Code 的 worktree 实现可以直接参考:它会拦掉指向主检出目录的 Edit、Write、NotebookEdit;拦掉工作目录解析到主检出的 shell 命令;拦掉通过 git -C、GIT_DIR 或 GIT_WORK_TREE 把 git 操作重定向到主检出的命令;也拦掉它无法从命令文本判断作用范围的命令。运行期间它在 worktree 上加 git worktree lock,防止并发清理把它删掉。这些检查同样覆盖子 agent。

任务拆分比并发度重要。独立任务、有依赖的任务、故意让多个 agent 竞争同一个结果的任务,以及会碰共享状态(同一份 schema、生成文件、中央接口)的任务,只有独立和故意的竞争适合默认并行。判据很朴素:两个任务会不会动同一个文件。会,就串起来,或者先把范围拆开。

并发上限由 review 带宽决定,不由算力决定。该盯的指标是「有多少 diff 排队等我看」,不是「今天起了几个 agent」。这个队列每小时都在变长,就得往下压并发度。

每个 agent 交付时给回执:改了哪些文件、跑了哪些命令、哪些检查通过、哪些检查跳过、哪些风险留着没处理。集成的时候你才不用从 diff 反推发生过什么。

最后

今天 GitHub 趋势榜上,Orca 这种自称 ADE 的东西、mattpocock/skills 这种技能目录、vercel-labs/skills 这种分发工具,都在讲同一件事:把 agent 装进工作台。这篇论文提醒的是另一面,装上去容易,收得住难。

我现在自己的做法是让一只 agent 先把关键路径走通,跑通了再加第二只。加之前问一句:这两件事会不会碰同一个文件。

论文里那句话我认同:把 agent 当成一批用完就扔的工人,别当成有状态的同事。它把「并发」这个词从模型能力的讨论里拿出来,放回预算分配的位置上。


参考来源

Me

Cut out summary from your post content here.

The remaining content of your post.