前言

用 Claude Code 干公司项目一段时间后,最疼的问题不是它写不好代码,而是主会话上下文频繁压缩:调研时读一堆文件、排错时几十轮失败堆栈、全局 grep 的海量结果,全堆在主对话里,撑到压缩阈值就被截断摘要——决策细节一丢就返工,返工一次比不压缩还费时间。

后来我把整个开发流程里「过程脏活」拆给了 5 个自定义 subagent,主会话只留决策和编码。跑了一个多月,压缩频率明显下降,上面的漏改事故再没犯过。这篇把设计思路、5 个 agent 的配置和一线踩坑经验整理出来,配置样例可以直接抄走改。

1、先校准认知:subagent 省的是什么

动手之前先想清楚 subagent 到底省什么,不然容易越用越贵。

它省的是主会话上下文,不是总 token。 每个 subagent 冷启动要重新读文件、接收背景信息,总消耗可能还增加 30~50%。那为什么值得?三个理由:

  1. 主会话压缩频率下降,决策上下文保持连贯
  2. 关键信息通过落盘文档持久化,压缩了也不丢
  3. 过程性输出(失败堆栈、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 定身份,正文当岗位说明书:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
---
name: wk-scout
description: 代码现状调研员。方案设计前的必选前置:调研现有实现、同类参照、
  数据现状,产出结构化事实清单落盘 docs/。只读不改代码。
  触发短语:需求调研、现状调研、方案设计前调研、技术调研
tools: Read, Grep, Glob, Bash, Agent
---

# Role
你是代码调研员,产出结构化事实清单……(岗位说明书)

配置上有四个关键设计点:

① 工具权限最小化。 只读型 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 本身还重要:

  1. 交接物落盘:agent 产出必须写进 docs/(文档 = 持久上下文,会话被压缩后重读文档即可恢复全部决策,不依赖对话记忆)
  2. 产出格式统一:文件:行号 + 证据 + 结论,禁止散文式摘要和大段贴码
  3. 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 分钟的编译错):

  1. 依赖模块改过的话,先让它 mvn install 装到本地仓库(单模块构建拉到旧 jar 必报「找不到符号」)
  2. 给足单模块构建命令模板,提醒避免 -am 全链联编
  3. 已知的 mock 坑交代清楚(agent prompt 里有,但要确认任务里没有新坑)
  4. 边界声明:「不许改主代码,发现 bug 停止报告」
  5. test-writer 必须带上测试要点清单

6.3 其他几条

  • 环境阻塞期别派活:系统负载高(比如工具进程泄漏把机器拖慢)时先把环境修好,否则 agent 一起跑就被拖挂
  • 慢的三因子:hook 进程泄漏 + 本地仓库旧 jar + Maven 全链联编。前两个是环境病,后一个是用法病——验证编译优先单模块,联编只在最终跑一次
  • MCP/schema 能瘦就瘦:每会话固定注入的 schema 是 cache_read 大头,用不上的插件果断禁用

7、小结

最后把整套思路收敛成四句话:

  1. 拆过程,不拆决策——读密集/试错密集的脏活给 subagent,需要上下文连贯和用户拍板的留主会话
  2. 文档是持久上下文——产出落盘、格式统一、摘要限长,压缩了也不怕
  3. 坑清单是最贵的资产——每次踩坑都固化进对应 agent 的 prompt,它替你永远不再踩
  4. agent 是员工不是神器——会卡死、会自由发挥、会拉旧 jar,所以要有监控、有验收、有预检 checklist

配置文件全是 markdown,维护成本约等于零;改动 agent prompt 下一轮会话就生效。如果你的主会话也开始频繁压缩、丢决策细节,值得照这套思路把流程过一遍——从最疼的那个环节拆起,一两周就能看到差别。