上周我在调一个挺复杂的 CI/CD 流水线,任务涉及三个环节:编译、静态分析、部署。按以前的做法,我得把整个流程写在一个 Prompt 里,结果 Claude 经常在中间步骤遗忘上下文,改一次 Prompt 要等好几分钟才知道对不对。
但我试了一轮 Claude Code 新版本里那个子智能体(Sub-agent)功能后,彻底回不去了。
说白了,Claude Code 的子智能体不是一个单独的模型,而是让当前会话动态派生出多个独立的推理线程,每个干自己的活,互不干扰。你把一个大任务拆成几个小任务,每个子智能体拿到自己的上下文、自己的指令,干完活把结果汇报回来,主智能体再做整合。
这听起来不就是函数调用吗?对,但区别在于——每个子智能体是带着完整的推理能力去执行,不是简单的 API 调用结果拼接。它真的会自己读代码、自己写文件、自己跑命令。
我第一个实战场景是这样的:给一个老项目加单元测试覆盖率报告。项目是 Java + Maven,几千个文件,手动改不现实。
我是这么拆的:
子智能体 A:扫描所有 pom.xml,找出 module 结构,确定哪些模块需要加 jacoco 插件。
子智能体 B:在找到的模块里插入 jacoco 配置,验证语法是否正确。
子智能体 C:写一个 shell 脚本,跑完整测试并生成覆盖率报告。
这三个任务是并行跑的——注意,不是串行,是并行。Claude Code 会自己管理并发,你只需要定义好任务就行。
这里有个踩坑的地方——依赖传递。我第一次跑的时候以为子智能体之间会自动共享文件系统状态,结果发现每个子智能体的工作目录是隔离的。子智能体 A 改了 pom.xml,子智能体 B 看不到改动,因为它在自己的沙箱里。解决方案是显式传文件路径,用 --input 和 --output 参数打通数据流。
第二个实战:代码审查自动化。PR 太大 reviewer 不想看的时候,我就让子智能体代劳。
拆法:
子智能体 1:diff 分析,找出改动涉及的所有类和接口,标注破坏性变更(改接口签名、删方法这种)。
子智能体 2:安全扫描,正则匹配常见漏洞模式(SQL 注入、XSS、硬编码密钥这些)。
子智能体 3:测试覆盖率变化,对比改动前后的覆盖行。
三个结果合并成一个 review report,自动贴在 PR 下面。效果比我预期好很多——虽然偶尔有误报,但至少把人从看完 500 行 diff 发现只是改了个变量名这种破事里解放出来了。
我发现子智能体最适用的场景有几个特征:
一是任务可以清晰拆解。如果你的需求是帮我优化这个项目,太模糊了,子智能体不知道从哪下手。但帮我找出项目中所有未使用的 import,逐个删除——这就是子智能体的菜。
二是每个子任务可以独立验证。子智能体的输出最好是能单独验证的:文件是否生成了、命令是否跑过了、测试是否通过了。如果一个子任务的结果要到最后合并阶段才能判断好坏,那说明任务拆得还不够细。
三是并行真的有收益。有些任务串行更快——比如数据清洗必须保证顺序。但在代码生成、批量修改、多文件分析这些 I/O 密集或计算密集的场景下,并发就是实打实的时间节省。
我目前踩过的坑还有几个值得一提:
上下文膨胀。每个子智能体启动时都会携带一部分上下文,如果父会话上下文已经很大,子智能体的启动速度会变慢。解决方案是只传最必要的文件路径或摘要。
还有个坑是结果合并冲突。两个子智能体同时改了同一个文件的同一行。目前我没什么优雅的解法,就是在任务拆分时尽量按文件维度切,避免两个子智能体碰同一个文件。
组里有人问我:你这么用,跟直接调 API 有什么区别?
说实话,如果是简单任务,直接调 API 更快。但子智能体的价值在于它在你的工作目录里运行,能直接操作你的文件、跑你的命令、读你的配置。它不是一个黑盒 API 调用——它是一个真正参与开发流程的智能体。这种区别在批处理、自动修复、持续集成场景下特别明显。