Claude Code 实战:用 5 个自定义 Subagent 治好主会话上下文爆炸
前言
用 Claude Code 干公司项目一段时间后,最疼的问题不是它写不好代码,而是主会话上下文频繁压缩:调研时读一堆文件、排错时几十轮失败堆栈、全局 grep 的海量结果,全堆在主对话里,撑到压缩阈值就被截断摘要——决策细节一丢就返工,返工一次比不压缩还费时间。
后来我把整个开发流程里「过程脏活」拆给了 5 个自定义 subagent,主会话只留决策和编码。跑了一个多月,压缩频率明显下降,上面的漏改事故再没犯过。这篇把设计思路、5 个 agent 的配置和一线踩坑经验整理出来,配置样例可以直接抄走改。
1、先校准认知:subagent 省的是什么
动手之前先想清楚 subagent 到底省什么,不然容易越用越贵。
它省的是主会话上下文,不是总 token。 每个 subagent 冷启动要重新读文件、接收背景信息,总消耗可能还增加 30~50%。那为什么值得?三个理由:
- 主会话压缩频率下降,决策上下文保持连贯
- 关键信息通过落盘文档持久化,压缩了也不丢
- 过程性输出(失败堆栈、grep 结果)不进主对话,只在 agent 内部消化
还有一笔账要算。我用自己的网关日志做过归因:单日成本里 cache_read(缓存命中重发)占 65%,是最大头。机制是每轮请求都全量重发「系统提示 + 配置文件 + 全部对话历史」,命中部分按缓存价计费。所以控制上下文体积、控制对话长度,就是直接砍成本——subagent 体系恰好两个都干。
2、设计思想:拆什么,不拆什么
不是所有步骤都适合拆。我的判断标准是三条,命中即拆:
| 判断标准 | 特征 | 典型环节 |
|---|---|---|
| 读密集 | 过程要读大量文件/输出,结论只要一小段 | 现状调研、全局 grep 排查 |
| 试错密集 | 失败-重试多轮循环,中间输出毫无保留价值 | 编译排错、写单测跑到全绿 |
| 边界清晰 | 输入规格和输出产物能一次写清楚 | 清单式审计、机械扫描 |
反向三条,命中即留:决策密集(要和用户来回拍板)、连贯编辑(跨文件的一致性编码)、风险操作(Git 提交发布)。这些拆出去信息损失太大,还失控。
按这个标准把公司项目的开发全流程过了一遍,拆出 5 个 agent(前缀 wk 取自 workflow——都是流程里的固定岗位):
| Agent | 干什么 | 为什么该拆 |
|---|---|---|
wk-scout |
代码现状调研 | 读密集:读大量代码 + 查库验证,产出只要一页事实清单 |
wk-impact-scanner |
改动影响面排查 | 读密集:全局枚举一个字段/方法的所有消费点,过程输出量大、结论只要一张表 |
wk-test-writer |
写单测跑到全绿 | 试错最密集:写→跑→修 mock→再跑,失败堆栈是上下文杀手 |
wk-build-doctor |
编译/单测排错 | 试错密集:多轮「复现→假设→验证→修」 |
wk-code-auditor |
规范审计 | 清单式机械检查,边界清晰 |
方案设计讨论、设计文档撰写、编码主体、修复方案决策,全留主会话。
3、五个 agent 的配置设计
3.1 一个 agent 就是一个 markdown 文件
放在 ~/.claude/agents/ 下,frontmatter 定身份,正文当岗位说明书:
|
|
配置上有四个关键设计点:
① 工具权限最小化。 只读型 agent(scout/scanner/auditor)坚决不给 Edit/Write,审查员就不该改代码;test-writer 和 build-doctor 给编辑权限,但 prompt 里写死「只许改测试代码/最小修复,业务代码动了必须先报告」。
② description 写满中文触发短语。 主会话靠它做语义匹配决定何时派活,用户说「先调研一下现状」「分析下影响面」就能自动触发,不追求 hooks 硬约束,半自动够用。
③ 坑清单固化进正文。 每个 agent 的 prompt 里都沉淀了该环节所有历史踩坑,每条注明出处事故。比如 wk-impact-scanner 里写死一条铁律:
- 查询侧和发送侧常分处不同模块分开读同一个参数,两边都要 grep(漏一边出过生产事故)
这些坑不写进 prompt,agent 每次都会重新踩。
④ 输出契约写死。 每个文件末尾都有 Output contract 段:产出落盘到哪、什么格式、限长多少、返回摘要怎么写。不写死的后果是 agent 返回一篇散文,前面省的上下文全赔回去。
3.2 输入/输出契约总表
| Agent | 必备输入(缺了要追问,不许猜) | 产出 | 返回主会话 |
|---|---|---|---|
| wk-scout | 需求描述 + 调研问题清单 | research 文档:现状/同类参照/数据验证/风险/待决策 | 摘要 ≤400 字 + 文档路径 |
| wk-impact-scanner | 目标字段/方法 + 改动意图 | 消费点清单表(>20 条落盘) | 表格 + 摘要 |
| wk-test-writer | 被测类 + 测试要点清单 + 既有测试参照 | 测试类文件 | 用例数/全绿结论/疑似 bug 清单 |
| wk-build-doctor | 失败命令 + 错误摘录 | 小修复直接改 / 大问题只出诊断报告 | 根因 + 改动说明 |
| wk-code-auditor | 改动文件范围 | P0/P1/P2 问题清单 | 清单 + 摘要 |
两个细节值得强调:
- test-writer 不猜业务规则。测试要点由主会话在设计阶段写好(正常路径/边界值/异常分支),agent 只负责翻译成代码并跑到绿。它发现被测代码疑似 bug 时只记录报告,不擅自改。
- auditor 允许「待人工确认」。比如多租户条件的注入可能在更高层拦截器里,从改动文件里看不出来,这时标注待确认而不是报个假 P0——审计 agent 最怕的就是狼来了。
3.3 提示词语言策略
正文用英文写(比中文省 25~40% token,agent 每次启动都注入),但有三处例外:description 保留中文触发短语(语义匹配用户中文输入)、中文错误消息保持原文(grep「找不到符号」要用原词)、末尾加一句 Always respond in Chinese.。实测效果稳定。
4、标准开发流水线
五个 agent 串进日常流程是这样的:
提需求
├─① [scout] 调研 → research 文档(事实+风险+待决策清单)
├─② 主会话:和用户讨论方案 → 决策当场写进设计文档(含测试要点)
├─③ [impact-scanner] → 消费点清单并入设计文档
├─④ 主会话:编码(编译自测)
├─④a [test-writer] 写单测跑绿 → 发现疑似 bug 只报告
├─⑤ [auditor] 审计 → P0/P1 清单
└─⑥ 主会话:修复到清零(连败 2 轮 → [build-doctor] 接手)
配套三条协作铁律,比 agent 本身还重要:
- 交接物落盘:agent 产出必须写进
docs/(文档 = 持久上下文,会话被压缩后重读文档即可恢复全部决策,不依赖对话记忆) - 产出格式统一:
文件:行号 + 证据 + 结论,禁止散文式摘要和大段贴码 - trust but verify:agent 改了代码,主会话必须 review diff 才算完成;test-writer 的测试还要抽查断言有效性(防恒真断言凑数)
5、模型搭配:不是越强越好,也不是越省越好
agent 按任务性质分了两档:
- 判断密集型(scout 调研、build-doctor 根因推理、test-writer 断言质量):用主力模型。调研结论决定设计质量,免费也不能拿质量换
- 机械型(scanner 枚举、auditor 清单检查):本想用本地部署的开源 27B 小模型零成本跑,实测翻车了——两次启动 API 挂起零输出,transcript 3 分多钟零增长,最后只能杀掉主会话手动审计。已全部回退继承主模型
教训:开源小模型的 agentic 多轮工具调用稳定性是另一码事,协议通了不等于能干活。真要用,先小任务试运行,观察工具调用格式和是否循环卡死,不稳立即回退。好在工具调用慢半拍的质量损失,多半比不上它把主会话搞挂的损失小——判断标准是降级后人工接管快不快。
6、实战踩坑(值钱的部分都在这)
6.1 agent 会卡死,必须挂监控
第一次全链路实战就撞上:audit agent 启动后 API 挂起,一点输出都没有。不挂监控的话主会话只能干等或反复手动查。我的方案是两个脚本:
- watchdog(准实时):派完 agent 顺手后台启动,30 秒轮询一次 agent 的 transcript 文件;判死条件是「静默超 180 秒 且 没有构建进程在跑」双信号(防止把长编译误判成卡死);检出即退出报警,自动唤醒主会话处置
- monitor(手动快照):一次性列出所有 agent 的心跳状态,排查用
处置 SOP:收到报警 → 核实确实没产出 → 杀掉 → 降级主会话接管。手动审计那次只花了几分钟——agent 挂了不可怕,快速识别才是关键。
6.2 交接 prompt 要过预检 checklist
派活前把这几条核对完,能省掉大量 agent 自作主张的排障时间(实测缺第一条,agent 自己排了 40 分钟的编译错):
- 依赖模块改过的话,先让它
mvn install装到本地仓库(单模块构建拉到旧 jar 必报「找不到符号」) - 给足单模块构建命令模板,提醒避免
-am全链联编 - 已知的 mock 坑交代清楚(agent prompt 里有,但要确认任务里没有新坑)
- 边界声明:「不许改主代码,发现 bug 停止报告」
- test-writer 必须带上测试要点清单
6.3 其他几条
- 环境阻塞期别派活:系统负载高(比如工具进程泄漏把机器拖慢)时先把环境修好,否则 agent 一起跑就被拖挂
- 慢的三因子:hook 进程泄漏 + 本地仓库旧 jar + Maven 全链联编。前两个是环境病,后一个是用法病——验证编译优先单模块,联编只在最终跑一次
- MCP/schema 能瘦就瘦:每会话固定注入的 schema 是 cache_read 大头,用不上的插件果断禁用
7、小结
最后把整套思路收敛成四句话:
- 拆过程,不拆决策——读密集/试错密集的脏活给 subagent,需要上下文连贯和用户拍板的留主会话
- 文档是持久上下文——产出落盘、格式统一、摘要限长,压缩了也不怕
- 坑清单是最贵的资产——每次踩坑都固化进对应 agent 的 prompt,它替你永远不再踩
- agent 是员工不是神器——会卡死、会自由发挥、会拉旧 jar,所以要有监控、有验收、有预检 checklist
配置文件全是 markdown,维护成本约等于零;改动 agent prompt 下一轮会话就生效。如果你的主会话也开始频繁压缩、丢决策细节,值得照这套思路把流程过一遍——从最疼的那个环节拆起,一两周就能看到差别。
- 原文作者:Anttu
- 原文链接:https://anTtutu.github.io/post/2026-10-14-claude-code-subagent-system/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。