别把 agent 当成并发槽位:并行开发要先切边界
一个 agent 写到一半卡在排查日志,另一个窗口已经开始改同一个模块,这种场面很熟。看起来在并行,最后通常是两份解释不同、改动互相踩脚的 diff。问题不在 agent 数量少,而在我们把“能同时运行”误当成“工作可以并行”。
Claude Code 把 subagent 定义为在独立上下文中处理特定任务的助手;它适合把大量搜索结果、日志和文件内容留在侧路,只把结论带回主会话。[1] GitHub Copilot 的 custom agent 也采用 Markdown agent profile,把提示词、工具和 MCP 配置封装为面向特定工作流的角色。[2] 两边的共同点很朴素:并行的单位不是“再叫一个模型”,而是一份有明确输入、边界和交付物的小任务。
先拆证据,再拆代码#
我现在会把任务先分成两类。第一类是只读调查:查调用链、复现 bug、比对文档、列出受影响测试。第二类才是会写文件的实现。调查任务很适合并发,因为它们只会产生笔记;代码任务如果碰到同一批文件,就先后执行,或者重新切分。
比如“给支付回调加重试”这件事,不要同时派三个人去“研究并实现”。可以这样拆:
- A:只读,找回调入口、幂等键和现有失败路径,交付
findings.md。 - B:只读,查队列 SDK 的重试语义和现有测试夹具,交付风险清单。
- 主 agent:读完两份结论,决定改动方案。
- C:只改队列 worker 和对应单测。
- D:只做独立代码审查,不能编辑。
这不是流程洁癖。调查者可以把长日志、无关调用方和失败尝试留在自己的上下文里;主 agent 只需要拿到“入口在哪、哪些约束不能碰、验证命令是什么”。如果一开始让多个 agent 都能写,后面还得花时间判断哪一份改动保留,省下的并发时间很快又吐回去了。
给每个 worker 一张任务卡#
任务卡不必写成 PRD,但至少要把下面几件事说清楚:目标、允许读写的路径、禁止事项、交付格式和验收命令。没有这些,agent 会用它自己的默认理解补齐空白,而不同 agent 补出来的东西往往不一样。
# worker: retry-worker
目标:为支付回调的临时网络错误增加有限重试。
可修改:src/jobs/payment-retry.ts、tests/payment-retry.test.ts
只读:src/webhooks/**、docs/architecture.md
禁止:不改数据库 schema;不改变成功回调的响应码。
交付:提交 diff,并说明重试次数、退避规则和一个仍未覆盖的边界。
验收:pnpm test payment-retry && pnpm lint
“可修改路径”特别重要。Claude Code 的子 agent 可以配置具体工具和独立权限;限制工具本来就是它的用途之一。[1] 但工具权限不是文件所有权。即使所有 worker 都有 Edit,也应该在任务卡里规定谁拥有哪个目录。权限控制防止危险操作,文件边界防止正常操作互相干扰,两件事别混在一起。
主 agent 只做三件事#
并行之后,主 agent 很容易退化成消息转发器。更有价值的做法是让它只负责三个决策:确认拆分是否互斥、把调查结论变成实现约束、按验收结果决定是否合并。它不应该把每个 worker 的原始日志全文塞回上下文,也不要因为 worker 说“完成了”就直接接收代码。
我会要求所有只读 worker 用同一种结束格式:
结论:一句话说明发现。
证据:文件路径、命令输出摘要或文档链接。
影响:可能要改的文件和风险。
未知:还不能确认的点。
这四行够用了。结论没有证据,就当猜测;“未知”没有被显式写出来,主 agent 很容易把沉默当成确认。GitHub 的文档也强调,agent profile 可以把团队的规范、框架和期望结果直接编码进去,并限制可用工具。[2] 真正值得固化的不是一大段人格设定,而是这种每次都要交付的结构。
一个能直接照抄的启动顺序#
先让两个只读 agent 并行调查,每个最多 10 分钟或一个明确命令周期。主 agent 汇总后写一个简短计划,再启动一个写代码的 agent。实现结束后,派只读 reviewer 看 diff 和测试结果。reviewer 找到阻塞问题,就回到同一个实现 agent 修;没有阻塞问题,主 agent 才合并。
调查 A + 调查 B
↓
主 agent 写计划和文件边界
↓
实现 worker
↓
只读 review + 测试
↓
主 agent 合并或退回修复
别为了“多 agent”硬凑并发。一个小 bug、一个文件、一次明确修改,单 agent 往往更快。需要并行的信号是:调查量大、任务能按目录或职责切开,或者有独立的验证工作可以同时进行。反过来,若所有人都要改同一个核心文件,就承认它是串行任务,先把决策做扎实。
Vibe Coding 里最贵的不是 token,而是合并两套看似合理、其实假设不同的实现。并行前先写边界,worker 才是在替你减负,不是在制造一场小型协调事故。
Sources#
[1] https://docs.anthropic.com/en/docs/claude-code/sub-agents — Claude Code Docs: Create custom subagents [2] https://docs.github.com/en/copilot/concepts/agents/cloud-agent/about-custom-agents — GitHub Docs: About custom agents