Claude Code 工程化:从"偶尔惊艳"到"稳定输出"

CC 用久了你会发现,同一个任务今天跑出完美结果,明天给你一坨垃圾。不是模型退化了,是你在裸跑。五层工程化配置,把成功率从 70% 拉到 95%。


同一个提示词,昨天跑出来的代码直接能用,今天跑出来的编译都不过。

你开始怀疑是不是模型变笨了。不是。是你在"裸跑"------没有分层约束、没有验证闭环、没有跨会话记忆。CC 不是聊天机器人,它是个需要工程化配置的 Agent。配好了,稳定输出;没配,看天吃饭。

我花了几个月踩坑,摸出一套五层配置体系。不用一次全上,按需叠加就行。


第一层:CLAUDE.md 分层------规则写对地方

你的 CLAUDE.md 是不是已经 200 行了?技术栈、代码规范、禁止事项、模块约定全塞一个文件里。结果 CC 该遵守的不遵守,不该管的瞎管。

问题不在规则多,在于没分层。CC 读一个 200 行的文件,注意力会被稀释------上下文膨胀会直接降低推理质量。

我的做法是三层:

objectivec 复制代码
~/.claude/CLAUDE.md              → 个人习惯(全局生效)
项目根目录/CLAUDE.md             → 项目级约束(团队共享)
子模块目录/CLAUDE.md             → 模块级细节(精准命中)

具体怎么分:

全局层~/.claude/CLAUDE.md)------放永远不变的个人偏好:

markdown 复制代码
- commit message 用 conventional commits 格式
- 代码注释用中文
- 不要生成 @author 注解

项目层 (项目根 CLAUDE.md)------放"什么不能做":

markdown 复制代码
- 禁止 @Autowired 字段注入,必须用构造器注入
- 禁止 System.out.println,用 Slf4j
- Controller 必须返回 ResponseEntity<T>
- 所有 REST 接口必须有参数校验注解

模块层 (比如 order-service/CLAUDE.md)------放"怎么做":

markdown 复制代码
- DTO 转换使用 MapStruct,不要手写 BeanUtils.copyProperties
- Repository 方法命名遵循 Spring Data 规范
- 金额字段统一用 BigDecimal,精度 scale=2

原则就一条:越靠近代码的层级越具体,越靠近全局的越抽象。 项目层管"禁止什么",模块层管"怎么做"。CC 进入 order-service 目录时会同时读三层,但模块层的具体规则权重最高。

翻车记录:不同层级写了矛盾规则时,CC 的行为不确定。比如全局写了"用 Lombok @Data",模块层写了"禁止 @Data 用 @Getter/@Setter"------CC 会随机选一个。解法:层级之间不要有矛盾,上层只管抽象原则。


第二层:SubAgent 拆任务------复杂度可控

一个大任务丢给 CC,它跑了 10 分钟,改了 30 个文件,最后你发现第 3 步就跑偏了,后面全白干。

这不是 CC 的问题,是你把 10 个需求塞进了一个 prompt。你不会把 10 个需求塞进一个方法,凭什么塞进一个对话?

工程化做法:拆成多个 SubAgent,每个有明确边界和退出条件。

比如"重构 order-service 的支付模块",我会这么拆:

bash 复制代码
第一步(分析):分析 payment 包下的代码结构,输出类依赖关系和调用链,
写到 /tmp/payment-analysis.md

第二步(重构):基于 /tmp/payment-analysis.md 的分析结果,
重构 PaymentService,只动 payment 包下的文件,
改完跑 mvn compile -pl order-service 验证

第三步(测试):为重构后的 PaymentService 补充单元测试,
跑 mvn test -pl order-service,失败就修到绿灯

每一步单独开一个对话(或用 Agent tool 派发 SubAgent)。关键原则:

  • 限定文件范围:"只动 payment 包下的文件"------防止 CC 顺手改了 common 模块
  • 明确退出条件:"编译通过 + 测试绿灯"------不是 CC 说 done 就是 done
  • 串行不并行:SubAgent 之间改同一批文件会冲突,老老实实一个接一个

那 SubAgent 之间怎么传递信息?它们没有共享上下文。我的土办法:让上一个 Agent 把结论写到文件里,下一个 Agent 读这个文件。 简单粗暴但有效。

翻车记录:SubAgent 执行时间越长越容易漂移。一个子任务超过 10 次 Tool Use 还没完成,大概率已经跑偏了。解法:任务粒度再切小,宁可多拆一步也不要让单个 Agent 跑太久。


第三层:Memory------跨会话不失忆

每次新开会话,CC 又忘了你上次确认的架构决策、踩过的坑、选型的理由。你反复解释同样的上下文,烦得想摔键盘。

CLAUDE.md 解决的是"规则"问题,Memory 解决的是"决策记忆"问题。

适合存 Memory 的东西:

markdown 复制代码
# 架构决策
- 缓存选了 Redis 而不是本地 Caffeine,因为多实例部署需要共享
- 消息队列用 RocketMQ,不用 Kafka,因为运维团队只维护 RocketMQ

# 踩坑记录
- MyBatis-Plus 3.5.3 和 Spring Boot 3.2 有兼容问题,必须升到 3.5.5+
- Redisson 分布式锁在 cluster 模式下 watchdog 续期有 bug,用 3.27.0+

# 团队约定
- 所有 API 必须走 gateway,不允许服务间直连
- 数据库变更必须走 Flyway migration,禁止手动 DDL

不适合存的:代码结构(直接读代码就行)、临时任务状态(用 TodoList)、git 历史(git log 更准)。

实操上,我会在关键决策确认后直接跟 CC 说:"把这个决策存到 Memory,下次会话要能想起来。" CC 会自动写入 memory 文件。

翻车记录:Memory 会过期。三个月前存的"用 Spring Boot 2.7"现在已经迁移到 3.2 了,CC 还在按旧记忆行事。解法:把 Memory 当文档维护,定期清理过时条目。每次大版本升级后花 5 分钟扫一遍。


第四层:Hooks 验证闭环------CC 说 done 不算数

CC 改完代码跟你说"已完成",你信了,push 上去 CI 红了。

问题在于:CC 的"完成"标准是"我觉得改对了",不是"编译通过了、测试绿了"。你需要用 Hooks 强制它在关键节点自动验证,绕不过去。

jsonc 复制代码
// .claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "command": "cd $(git rev-parse --show-toplevel) && mvn compile -q -pl $(basename $(pwd)) 2>&1 | tail -3"
      }
    ],
    "Stop": [
      {
        "command": "cd $(git rev-parse --show-toplevel) && mvn test -q -pl $(basename $(pwd)) 2>&1 | tail -10"
      }
    ]
  }
}

这套配置的逻辑:

  • 每次改文件后(PostToolUse):自动跑编译。编译不过 CC 立刻能看到报错,当场修------不让错误累积到最后
  • 任务结束前(Stop):跑单元测试。测试不过就不算完成,CC 会继续修

关键细节:-q 静默模式 + tail 只取最后几行。Hook 太重会拖慢 CC 的迭代速度------你不想每改一行就跑 3 分钟的全量测试。编译用静默模式秒级反馈,测试只跑当前模块。

翻车记录:Hook 里的命令如果本身有 bug(比如路径写错),CC 每次改文件都会收到一堆无关报错,然后开始"修复"这些根本不存在的问题。解法:Hook 配置好后先手动跑一遍确认没问题。


第五层:Prompt 模板------输入标准化

每次写提示词都从零开始,质量全看当时的状态。上次写得好的提示词,下次想不起来了。

工程化做法:把高频任务的提示词存成 Custom Command,一键触发。

markdown 复制代码
# .claude/commands/new-feature.md
---
description: 生成完整的 CRUD 功能模块
---
参考 $ARGUMENTS 的写法,新增指定实体。
要求:
1. 生成 Entity(JPA 注解 + Lombok)
2. 生成 Repository(Spring Data JPA)
3. 生成 Service + ServiceImpl(构造器注入)
4. 生成 Controller(RESTful + 参数校验)
5. 生成 Request/Response DTO
6. 生成后跑 mvn compile 验证编译通过

用的时候一句话:/new-feature Order.java,CC 就会参考 Order 的写法生成一整套新模块。

再来一个 review 模板:

markdown 复制代码
# .claude/commands/review-api.md
---
description: API 安全与性能审查
---
审查当前模块的 Controller 和 Service 层:
1. 检查是否有缺失的权限校验(@PreAuthorize)
2. 检查 JPA 查询是否存在 N+1 问题
3. 检查 Entity 是否直接暴露到了 API 响应
4. 检查事务注解是否合理(只读方法加 readOnly=true)
列出问题并给出修复建议

模板的原则:约束"必须做什么",不约束"怎么做"。 你告诉 CC 要生成哪些文件、要通过什么验证,但不要规定它用什么算法实现------留出灵活性。

团队里多人用 CC 的话,这些模板提交到 git 仓库。所有人用同一套模板,CC 的输出质量就有了基线保障。


五层金字塔:按需叠加

markdown 复制代码
          ┌───────────────┐
          │  Prompt 模板   │  ← 输入标准化
         ┌┴───────────────┴┐
         │  Hooks 验证闭环  │  ← 输出有保障
        ┌┴─────────────────┴┐
        │  Memory 跨会话记忆 │  ← 上下文不丢
       ┌┴───────────────────┴┐
       │  SubAgent 拆任务     │  ← 复杂度可控
      ┌┴─────────────────────┴┐
      │  CLAUDE.md 分层架构    │  ← 规则有层次
      └───────────────────────┘

不用一次全搭。我的建议:

先搞底下两层CLAUDE.md 分层 + Hooks 验证闭环。这两个 ROI 最高,10 分钟配好,立刻见效。CC 的输出质量能从"时灵时不灵"变成"大部分时候靠谱"。

等你发现"CC 老是忘事":加 Memory。把反复解释的架构决策和踩坑记录持久化。

等任务越来越大:加 SubAgent 拆分。一个任务超过 5 个文件的改动,就该拆了。

等团队开始用:加 Prompt 模板。统一输入质量,新人也能用出老手的效果。

从偶尔惊艳到稳定输出,中间差的不是运气,是工程化。

相关推荐
代码简单说2 小时前
Codex接入DeepSeek教程:使用CC-Switch配置API渠道(图文详解)
openai·ai编程
沈麽鬼2 小时前
【人机协作:AI 编程高效落地指南】提示词篇:AI指挥提示词体系
ai编程·cursor·vibecoding
sweet丶2 小时前
Git Worktree 与AI Coding 协作并行开发
ai编程
沈麽鬼2 小时前
【人机协作:AI 编程高效落地指南】原理篇:AI Coding 底层认知
ai编程·cursor·vibecoding
沈麽鬼2 小时前
【人机协作:AI 编程高效落地指南】生态篇:配套工具与入门方案(1)
ai编程·cursor·vibecoding
沈麽鬼3 小时前
【人机协作:AI 编程高效落地指南】流程篇:标准化落地开发法则
ai编程·cursor·vibecoding
roman_日积跬步-终至千里3 小时前
【SDD】高风险场景下的 SDD 最佳实践:分层风控+分级落地,约束AI编程边界
大数据·人工智能·ai编程
TYKJ0233 小时前
租GPU服务器前必须确认的5个隐藏成本
服务器·后端·ai编程