返回博客

Claude Code Subagent与结构化任务分解:何时使用哪种方式

Claude Code Subagent与结构化任务分解:何时使用哪种方式

你有一个feature需要同时做三件事。你可以在单个Claude Code会话中spawn subagent让它们并行工作。或者你可以把工作拆成三个独立任务,分别交给各自tmux窗格中的独立agent,让它们在互不知晓的情况下运行。

两种方式都能并行化工作。解决的问题不同。选错了,你要么把上下文窗口烧在协调开销上,要么制造出比原始任务更耗时的merge冲突。

这是我每天在同一个代码库上运行13个Claude Code agent时使用的决策框架。不是理论。是犯了足够多的错之后,才知道边界在哪里。

两种并行性

Claude Code支持两种不同的并发执行方式。

Subagent是在单个Claude Code会话内spawn的子进程。父agent启动多个subagent,每个处理问题的一部分,然后收集结果。它们共享同一个工作目录和父级的上下文。把它们想象成单个进程中的线程。

Parent agent
  ├── Subagent A: "Search lib/ for all usages of parseConfig"
  ├── Subagent B: "Search server/ for all usages of parseConfig"
  └── Subagent C: "Search components/ for all usages of parseConfig"

独立agent在独立的Claude Code会话中运行,通常位于不同的tmux窗格中。每个都有自己的上下文窗口、自己的CLAUDE.md身份文件和自己对代码库的视角。它们不共享内存。通过制品进行通信:任务评论、状态更新、已commit的代码。把它们想象成没有共享状态的独立进程。

tmux pane 1: eng1 agent → "Build the REST endpoint"
tmux pane 2: eng2 agent → "Build the React component"
tmux pane 3: qa1 agent  → "Write integration tests for both"

心智模型很重要,因为它决定了工作如何在单元之间流动。Subagent可以低成本地把数据传回父级。独立agent通过文件系统、git或外部任务追踪器传递数据。

Subagent胜出的情况

当工作共享状态且结果需要汇聚时使用subagent。

并行研究。 需要在五个目录中搜索一个模式,阅读三个文档文件,并将发现综合成一个建议。Subagent可以各自承担一条搜索路径,返回结果,父级无需序列化开销即可合并。

对相同数据的独立转换。 你在重构一个模块,需要在一次连贯的变更中更新类型定义、测试和文档。每个subagent处理一个文件,但父级因为在commit前看到所有三个结果而能确保一致性。

快速探索。 你在调试,需要同时检查git log、测试输出和运行时配置。Subagent可以并行收集三者,父级综合诊断。

模式:扇出,收集,基于合并结果行动。 如果你的并行化以父级需要对所有输出一起推理而告终,subagent是正确的工具。

Subagent的短板: 任何每个分支耗时超过几分钟的工作,任何修改重叠路径文件的工作,或任何需要独立验证的工作。Subagent共享工作目录,所以两个subagent写同一个文件会互相破坏。而且因为共享上下文,长时间运行的subagent会消耗父级的可用窗口。

独立agent胜出的情况

当工作可以独立验证且不需要共享上下文就有意义时使用独立agent。

同一feature的不同组件。 "构建API端点"和"构建调用它的前端"在集成之前是独立的。API工程师的上下文中不需要React组件。前端工程师不需要数据库schema。给每个人配备有范围限定的CLAUDE.md的专属agent,保持上下文干净,防止一个agent的复杂性渗入另一个的工作。

不同的验收标准。 如果任务A在端点返回正确JSON格式的200时完成,任务B在组件以适当错误状态渲染数据时完成,这些是独立的验证目标。QA agent可以独立验证每一个。Subagent不能被独立QA,因为它们产生的是合并输出。

触及代码库不同部分的工作。 文件所有权是防止merge冲突最简单的方式。Agent A拥有server/,Agent B拥有components/。谁也不进入对方的领地。如果用subagent尝试这个,父级需要管理文件锁,这就违背了并行化的目的。

不同时间跨度的任务。 一个任务10分钟,另一个2小时。用subagent,父级等待最慢的子级。用独立agent,短任务完成、验证、发布,长任务还在运行中。

模式:发射,遗忘,分别验证。 如果每件工作独立成立且可以独立检查,带结构化任务的独立agent更干净。

交接问题

真正的决策点归结为交接。

Subagent的交接成本低。子级在同一上下文中向父级返回数据。没有序列化,没有文件写入,不用等状态更新。父级启动三个subagent,返回三个结果,父级拥有所需的一切。

独立agent间的交接成本高但持久。Agent A完成工作、commit代码、更新任务状态、评论自己做了什么。Agent B捕获信号(通过协调者或轮询任务追踪器)并开始其依赖工作。开销是实实在在的:需要任务系统、状态协议和agent发现其他agent工作的方式。

经验法则:如果并行单元间需要超过一次交接,使用subagent。 单次fan-out-and-gather,subagent更简单。如果Agent A的输出是Agent B的输入,而Agent B的输出又是Agent C的输入,独立agent的协调成本是合理的,因为每次交接产生一个经过验证的已commit制品,即使agent崩溃或达到上下文限制也不会丢失。

一个具体例子。你需要:

  1. 找到所有返回用户数据的API端点
  2. 给每个添加rate limiting
  3. 为新的rate limit编写测试
  4. 更新API文档

步骤1和2紧密耦合。搜索结果(步骤1)直接输入到修改(步骤2)。Subagent处理搜索;父级应用更改。这是subagent模式。

步骤3和4彼此独立但依赖步骤2。测试需要实际的端点代码。文档需要最终的API形态。这些是给独立agent的独立任务,各有自己的验收标准,各自可独立验证。

这就是 Beadbox 要解决的问题。

实时查看整个 agent 队列正在做什么。

Beta 期间免费试用 →

结构化任务分解实践

当答案是"独立agent"时,你需要一种方法把feature分解成可以并行运行而不互相干扰的任务。

分解过程:

1. 识别依赖图。 在拆分任何东西之前,先标注什么依赖什么:

Feature: User profile page with activity feed

- API endpoint: GET /users/:id/profile     (no deps)
- API endpoint: GET /users/:id/activity     (no deps)
- React component: ProfileHeader            (depends on profile API)
- React component: ActivityFeed             (depends on activity API)
- Integration test: profile page end-to-end (depends on all above)

两个API端点没有依赖关系。可以并行运行。两个React组件各依赖一个API。集成测试依赖所有。

2. 划定所有权边界。 每个任务获得一个文件范围。Profile API agent拥有server/routes/profile.tsserver/services/profile.ts。Activity API agent拥有server/routes/activity.tsserver/services/activity.ts。谁也不碰对方的文件。如果共享工具需要修改,一个agent创建变更,另一个等待。

3. 为每个任务定义验收标准。 每个任务需要一个明确的"完成"条件,可以在不查看其他任务的情况下验证。"Profile API以正确格式返回200"是可验证的。"个人资料页面能用"不行,因为它依赖集成。

4. 指定交接制品。 下游agent从上游agent需要什么?通常是:已知分支上的已commit代码、状态更新、以及描述接口契约的评论(API形态、组件props、函数签名)。

这种分解将模糊的"构建个人资料页面"转化为五个离散任务,带有明确的依赖关系和验证标准。每个任务可以分配给一个恰好拥有所需上下文且不多不少的agent。

用Beads进行结构化分解

这就是拥有真正任务系统的重要性所在。你不能用便签和终端输出追踪五个并行任务。

beads是一个本地优先的issue追踪器,原生地建模这种分解。Epic代表feature。Children代表子任务。Dependencies阻止agent在前置条件完成前开始工作。

实践中的分解如下:

# Create the epic
bd create --title "User profile page with activity feed" \
  --type epic --priority p2

# Create subtasks as children
bd create --title "GET /users/:id/profile endpoint" \
  --parent bb-epic1 --type task --priority p2

bd create --title "GET /users/:id/activity endpoint" \
  --parent bb-epic1 --type task --priority p2

bd create --title "ProfileHeader React component" \
  --parent bb-epic1 --type task --priority p2 \
  --deps bb-profile-api

bd create --title "ActivityFeed React component" \
  --parent bb-epic1 --type task --priority p2 \
  --deps bb-activity-api

bd create --title "Profile page integration test" \
  --parent bb-epic1 --type task --priority p2 \
  --deps bb-profile-header,bb-activity-feed

结构现在是显式的。运行bd show bb-profile-header的agent看到它依赖profile API任务。如果那个任务还没完成,agent知道不该开始。当API agent完成并标记任务完成时,前端agent的依赖被解除。

Agent工作流遵循可预测的循环:

# Agent claims the task
bd update bb-profile-api --claim --actor eng1

# Agent comments its plan before writing code
bd comments add bb-profile-api --author eng1 "PLAN:
1. Create route handler at server/routes/profile.ts
2. Add service layer at server/services/profile.ts
3. Return shape: { id, name, avatar, bio, joinedAt }
4. Test: curl localhost:3000/users/1/profile returns 200"

# Agent implements, tests, commits
# ...

# Agent marks done with verification steps
bd comments add bb-profile-api --author eng1 "DONE: Profile endpoint implemented.
Returns { id, name, avatar, bio, joinedAt }.
Verified: curl returns 200 with correct shape.
Commit: abc1234"

bd update bb-profile-api --status ready_for_qa

每一步都有记录。QA agent读DONE评论,准确知道如何验证。下游agent读PLAN评论,在代码完成之前就知道API契约。

这不是为了流程而流程的开销。这是防止五个并行agent产出五份不兼容代码的最小结构。

默认选择

在生产工作中运行并行agent数月之后,这是我遵循的决策树:

从subagent开始,当:

  • 任务是研究或探索(搜索、阅读、比较)
  • 结果需要汇聚为单一行动
  • 所有工作在一个上下文窗口内
  • 不需要对每个并行单元进行独立验证

切换到独立任务,当:

  • 工作的不同部分触及不同文件
  • 每个部分有自己的验收标准
  • 你希望QA独立验证各部分
  • 工作时间足够长,一部分可能比另一部分早完成数小时
  • Agent需要不同的上下文(前端agent不需要数据库内部细节)

复杂feature的混合方式: 研究和规划阶段使用subagent(扇出、收集信息、综合计划),然后将实现分解为独立agent的独立任务。Spec-driven development工作流在这里自然契合:一个带subagent的单一agent编写spec,然后spec分解为多agent舰队的任务。

可视化分解

当你有五到十个带依赖关系的结构化任务时,在终端中追踪进度变得困难。bd list显示的是扁平列表。它不显示哪些任务被阻塞、哪些准备开始、或epic进展到了哪里。

这就是Beadbox解决的问题。它读取同一个beads数据库,渲染带进度指示器、依赖关系和agent分配的epic树。你可以看到哪些子任务已完成,哪些因前置条件而阻塞,哪些准备好让agent领取。用--deps指定的依赖图变成你并行工作的可视化地图。

当agent完成任务并更新状态时,Beadbox实时反映变化。不用刷新,不用重新运行bd list。树更新了,进度条移动了,阻塞的任务随着依赖解除而解除阻塞。

同样的数据。只是变得可见了。


如果你正在构建这样的工作流,在GitHub上给Beadbox一颗星。

Like what you read?

Beadbox is a real-time dashboard for AI agent coordination. Free during the beta.

Share