什么时候需要 Subagent:任务拆分、上下文隔离与协作成本
分工并不总是更快。先判断隔离的收益,再承担协作的代价。
让三个 AI 分别调查、分析、修改,听起来比一个 AI 做完整件事更专业。但如果每一步都依赖前一步刚发现的细节,交接反而会丢信息:调查者找到的异常没有写进摘要,修改者又从头排查。
Subagent 最值得讨论的不是数量,而是边界。一项工作能否带着明确输入独立进行?它返回什么,主任务才能继续?这两个问题回答不清,分工通常只是把混乱分成了几份。
我会先画出依赖,再决定分工。能独立调查、能够核查结果的部分,才值得单独交出去。
本文用一个虚构的订单导出模块,设计一次只读调查与交叉检查。目标是拿到可信的调用链和缺陷线索,不让多个 Agent 同时修改同一份代码。
01 / 定义:独立的是上下文,不一定是工作目录
Subagent 可以理解为被委派去完成一项具体工作的助手。主 Agent 给出任务,它在自己的上下文中搜索、阅读或执行允许的工具,再返回结果。大量中间材料可以留在分支中,主任务只接收继续工作所需的信息。
这里最容易混淆的是“独立”。上下文隔离不等于文件隔离,更不等于权限隔离。两个 Agent 可能读写同一个工作目录;若没有另外安排隔离和合并方式,它们仍可能覆盖彼此的改动。
| 机制 | 改变什么 | 不能据此推断什么 |
|---|---|---|
| Skill | 当前工作使用的方法与参考资料 | 不保证自动新建独立工作上下文 |
| Subagent | 任务在单独上下文中展开 | 不保证换了模型、工作目录或拥有更多能力 |
| 独立工作目录 | 减少文件修改互相干扰 | 不解决两个方案的业务冲突 |
| 工具权限限制 | 限制可执行操作 | 不保证调查结论正确 |
人类分工的类比也有限:子 Agent 没有自动共享你脑中的背景。不要只说“像刚才一样处理”。文件、目标、排除范围和结果格式应当随任务一起交给它。
02 / 推导:什么时候分工才有净收益
假设调查导出模块有两个问题:谁检查权限?数量限制在哪里执行?它们可以分别查找,最后合并成一条调用链。相比之下,“复现错误→定位原因→修复代码”会不断产生下一步必须知道的细节,更适合连续处理。
- 先问依赖:任务 B 能否在 A 没有完成时开始?不能就别因为有两个名字而并行。
- 再问信息量:主任务需要全部中间输出,还是几条带位置的结论?需要反复追问细节时,隔离收益会变小。
- 再问修改冲突:任务是否会改同一文件、数据或公共配置?会就先划分所有权或改为只读调查。
- 最后问核查成本:主任务能否迅速复核返回结果?若只能相信一句“没有问题”,就缺少有效交接。
分工收益要扣除启动、交接和复核成本。独立任务的耗时有机会重叠,但读者支付的不只是模型执行时间。拆得越细,汇总与返工可能越多;两个上下文也可能产生同一种误判。
图中的汇合点不是简单拼接两段文字。假如一人说接口有权限检查,另一人说越权数据仍能导出,主任务要追查“接口权限”和“数据范围”是不是检查了不同层,而不是投票决定谁对。
03 / 交接:先写清任务,再创建角色
为“专家”取一个名字很容易,真正决定表现的是它收到的任务。下面这份委派单可以直接使用,也可以先放在普通对话中检查是否完整。
目标:定位订单 CSV 导出的权限检查和数据范围过滤。
输入:本练习项目 src/ 下的代码;只使用当前保存的版本。
允许:读取、搜索。禁止修改文件、安装依赖或访问外部系统。
排除:不要评估支付业务,不要修改 UI,不要全面重构。
输出:
1. 从入口到导出函数的调用链,每步注明文件与函数。
2. 权限检查发生的位置,以及它实际检查了什么。
3. 数据过滤发生的位置,以及是否使用当前用户身份。
4. 每个疑似缺陷的触发条件、证据和仍需验证的部分。
5. 未读到的文件、缺失依赖或其他阻碍。
完成条件:已找到链路并核对相关条件;找不到时明确停在何处。
这里故意没有写“你是世界顶级专家”。专业性应当体现在检查对象、证据标准和停止条件里,而不是角色称号中。也不要把“没有发现问题”当默认收尾,它只在明确检查范围后才有意义。
输入的版本尤其重要。调查期间若主任务正在重写代码,子 Agent 返回的行号和结论可能已经过期。最小做法是先保存文件、暂停相关修改;多人协作时则记录明确提交或快照。
04 / 实操:做一次可以手动复核的只读调查
① 准备三个练习文件
在空目录中新建 src/access.py、src/export.py 和 src/api.py。代码特意保留了一个缺口,不连接真实数据库。
# src/access.py
def can_export(user):
return user["role"] == "admin"
后两份文件负责筛选与入口调用:
# src/export.py
def select_rows(rows, project_id):
return [r for r in rows if r["project_id"] == project_id][:1000]
# src/api.py
from access import can_export
from export import select_rows
def export_orders(user, rows, project_id):
if not can_export(user):
raise PermissionError("export denied")
return select_rows(rows, project_id)
本例业务约定:管理员只能导出自己所属项目的数据。这条约定写入 requirements.md,委派时连同代码一起提供。没有这个前提,调查者无法仅凭代码判定跨项目访问是缺陷。
② 创建一个只读调查者
在 Claude Code 中可用 /agents 管理自定义 Subagent,也可以在项目里保存 .claude/agents/export-investigator.md:
---
name: export-investigator
description: 调查订单导出的调用链、权限检查和数据范围。调用时必须提供文件范围与业务约定;仅调查,不修复。
tools: Read, Grep, Glob
model: inherit
---
按委派单读取指定材料。
先定位入口,再沿调用链检查角色判断与数据过滤。
把代码事实、业务约定和你的推断分开。
返回文件与函数、触发条件、证据、未验证项和阻碍。
不修改文件。没有证据时说明无法判断。
这份配置只开放阅读和搜索工具,连 Bash 都未开放。因为通用命令执行工具也能写文件,不能只排除 Edit 和 Write 就认定没有写入能力。实际可用工具还受宿主版本与设置影响,运行前检查配置是否被发现。
③ 委派一个明确任务
请使用 export-investigator 检查 src/ 的导出调用链。
业务约定见 requirements.md:管理员只能导出所属项目。
按照委派单返回证据和疑似缺陷,不修改任何文件。
应当得到的关键链路是 export_orders → can_export → select_rows。角色检查存在,但筛选采用调用者传来的 project_id,没有核对它与用户所属项目是否一致。这个区别比一句“权限有漏洞”更有用。
④ 主任务亲自复核关键结论
保存以下测试到 src/check_export.py,在练习目录执行 python3 src/check_export.py。它只读取演示数据,不写业务数据。
from api import export_orders
user = {"role": "admin", "project_id": "P-01"}
rows = [{"id": "O-99", "project_id": "P-02"}]
result = export_orders(user, rows, "P-02")
print(result)
assert not result, "跨项目数据被返回:项目边界未校验"
当前有缺陷的版本应打印 O-99 并触发断言。如果调查者只看到 admin 检查便宣布安全,这个反例会推翻它。测试在这里是反证工具,而不是为调查者的结论盖章。
⑤ 把修复留给主任务
先由人确认预期:越权请求是拒绝还是返回空结果。采用拒绝时,在入口核对 project_id == user["project_id"],不匹配便报权限错误。然后分别检查同项目管理员成功、跨项目管理员拒绝、普通成员拒绝、空数据正常返回。修复与测试不要偷偷交回只读调查者。
05 / 验收:不要只检查有没有返回报告
一次委派完成,要看三个层面:是否遵守范围、是否有可核查的事实、是否能推动下一步决定。报告篇幅与 Agent 数量都不是质量证据。
| 检查点 | 合格表现 | 常见伪完成 |
|---|---|---|
| 版本与范围 | 说明读了哪些文件与业务约定 | “已全面审查”,但没说明对象 |
| 权限与数据 | 区分角色检查和项目过滤 | 发现一个 if 就断言安全 |
| 返回证据 | 给函数、条件与最小反例 | 只有风险标签和改进建议 |
| 阻碍 | 缺文件或无法执行时明确说明 | 把无法检查写成没有问题 |
| 副作用 | 本次没有修改练习文件 | 边审边修,掩盖原始问题 |
需要多个调查者时,可以一个检查权限链,一个检查数量与异常行为;双方共享同一份材料,各自返回证据。若结论冲突,先确认是否同一版本、同一入口、同一前提,再用最小输入验证。
独立上下文有助于减少对既有方案的依赖,但不能保证独立正确。让两个同类模型赞同,不等于测试通过;缺陷复现和实际输出仍需要核查。
06 / 扩展:从一次调查到可持续分工
先重复两三次同类任务,记录委派耗时、复核耗时和返工原因。若主任务总在追问文件位置,把位置加进返回契约;若总在重新解释背景,把前提加进委派输入。不要用增加 Agent 数量治疗交接不清。
- 多处修改:先约定文件归属与公共接口;需要独立目录时安排差异合并和冲突处理。
- 使用 Skill:需要专门检查方法时,明确提供或配置所需 Skill,检查子任务实际取得了什么,不假定主上下文的资料全部继承。
- 执行测试:委派测试要返回命令、退出码与完整失败位置;需要实时调试时留在主任务。
- 遇到阻碍:返回缺失项与影响,不无限搜索、不偷偷扩大权限。
换个场景:三份访谈记录是否适合并行分析?
可以分别提取每份记录中的原话、场景和问题,但应共享同一套字段与“事实/推断”的区分。跨访谈合并主题和决定产品方向留给汇总阶段。若你让三人分别直接决定路线,再把结论投票合并,遗漏的是共同证据与统一判断标准。
当任务能独立展开、结果能快速核查,Subagent 才能减少主任务的负担。否则,保留连续上下文可能更有效。方法复用可以看 Skill 的制作与测试;外部工具怎样连接则属于 MCP 的职责范围。