09-不要只让 AI 进入 Plan 模式,要先给 AI 一套工程制度
别再只让AI进入“Plan模式”了,先给它一套工程制度
很多团队刚开始用Claude Code的时候,已经学会了不直接让它撸代码。他们会先让AI进入Plan模式,分析方案,确认后再动手。这比“直接写代码”的做法确实靠谱不少。

但这并不意味着问题就彻底解决了。因为Plan模式只能保证两件事:AI会先想一想,然后给个方案,等你确认后再执行。它没法天然保证这个方案一定符合你的业务边界、技术决策、目录结构,更没法保证它不会越过已有的架构红线。
比如在一个真实的前后端项目中,AI在Plan阶段就可能问错方向:
- 新接口该放
auth-service还是backend? - 公共日志能力应该放在
services/log-service,还是packages/shared-logging? - 前端页面是扔进
apps/web,还是干脆新建一个应用? - 服务之间能不能直接共享数据库?
- Controller能不能直接操作Prisma?
- 请求参数的校验,是写在Controller里还是DTO里?
- 新增模块需要同步走API契约审查吗?
如果这些判断只存在于团队老成员的脑子里,AI在Plan模式下也是两眼一抹黑。于是就会出现一种更隐蔽的返工:AI不是代码写错了,而是方案从一开始就偏了;不是不会执行,是压根不知道项目真正的边界在哪里。
所以说,真正要解决的核心问题不是“AI会不会写代码”,而是“如何让AI在正确的约束下写代码”。
我的做法:把Claude Code分成四层来治理
我倾向于将Claude Code的项目配置理解成四个层次:
决策层
规则层
角色层
流程层
对应到项目文件里,大致是这样的结构:
DECISIONS / BUSINESS-DECISIONS→ 决策层rules/→ 规则层agents/→ 角色层skills/→ 流程层
用个更通俗的比喻:决策文件就像公司的战略和技术方案,rules像是团队制度,agents像是不同岗位的人,而skills则像是具体的办事流程手册。这四层组合起来,AI就不再是“自由发挥”,而是在一套项目制度里工作。
为什么第一层必须是“决策”?
很多人一上来就会去写rules或skills,比如“禁止页面直接调用axios”“创建页面时必须创建index、store、constant、style”“Controller不允许直接操作数据库”。这些规则当然有用,但问题在于:如果只有规则,没有决策,AI只知道“必须这样做”,却不知道“为什么必须这样做”。这会带来两个麻烦。
1. 遇到新场景时,AI不知道怎么判断
比如rules里写“页面请求必须走service”,但碰到一个非常简单的静态页面,AI可能会犯嘀咕:这个页面没有接口,还要不要建service?但如果决策层写清楚了“API分层封装是为了统一处理认证、错误、缓存和接口契约”,那AI自然就明白了:没有接口请求的页面,不需要创建service。
2. 规则变化时,没有依据可循
假设团队将来想把某个状态管理方案换掉。如果只有skill里写了具体步骤,那改起来就会很乱:这个skill里写了旧方案,那个模板里也写了旧方案,某个Agent的说明里还写着旧方案。但如果技术决策里明确记录了“当前用的什么方案、为什么选它、哪些场景必须用、哪些场景不需要用”,那后续演进时就能先改决策,再同步rules和skills,逻辑清晰得多。
决策层应该怎么拆?
我建议把决策文件拆清楚,而不是只写一个巨大的“项目规范”。对于一个通用的前后端项目,可以拆成5类决策文件:
| 文件 | 解决的问题 | 典型内容 |
|---|---|---|
| BUSINESS-DECISIONS | 全局业务边界 | 系统定位、业务事实源、前后端职责 |
| FRONTEND-BUSINESS-DECISIONS | 前端业务职责 | 页面边界、展示缓存、交互校准 |
| BACKEND-BUSINESS-DECISIONS | 后端业务职责 | 服务边界、数据归属、一致性规则 |
| FRONTEND-DECISIONS | 前端技术方案 | 技术栈、页面拆分、状态管理、API封装 |
| BACKEND-DECISIONS | 后端技术方案 | 服务拆分、认证、数据库、异常、缓存 |
拆开之后,AI在处理不同任务时能更精准地加载上下文。比如:改前端页面,重点看FRONTEND-DECISIONS和FRONTEND-BUSINESS-DECISIONS;改后端接口,重点看DECISIONS和BACKEND-BUSINESS-DECISIONS;改跨端流程,重点看BUSINESS-DECISIONS和前后端业务决策;做安全审查,则重点看认证、Token、权限、日志相关的决策。这比一个几千行的“大规范文档”更容易维护,也更容易让AI执行。
决策文件推荐写法
决策文件不要只写结论。更推荐使用这种结构:
### 编号: 决策标题
**状态**: 已采纳 / 待治理 / 待实现
**决策**:
- 做什么
- 采用什么方案
- 哪些边界已经明确
**为什么**:
- 为什么选这个方案
- 为什么不选其他方案
- 这个方案解决什么问题
**边界约束**:
- 禁止什么
- 必须什么
- 哪些情况需要后续补充决策
这种格式有三个好处:人能快速看懂背景,AI能知道哪些是硬约束,后续架构变化时也有依据可查。
一个完整决策案例就够了
这里不需要把所有决策都展开,读者真正需要先理解的是决策文件长什么样,以及它为什么能约束AI。所以,一个完整案例足矣。
ADR-001: 采用Monorepo多微服务架构
状态
决策
- Monorepo单仓库管理多个独立微服务。
apps/web/: 前端应用。services/auth-service/: 认证授权服务。services/backend/: 主业务服务。services/log-service/: 日志服务。packages/shared-logging/: 跨系统共享日志SDK。
为什么
- 微服务可以独立部署、独立扩展。
- 共享代码通过
packages/目录统一管理。 - 每个服务有明确职责边界,符合单一职责原则。
边界约束
- 新增系统必须放入对应目录:
apps/、services/或packages/。 - 服务间通过HTTP API调用,不直接共享数据库。
- 共享包只能放通用能力,不能反向依赖具体业务服务。
这个案例看起来只是目录和服务拆分,但它会深刻影响很多后续执行:创建前端页面时放到apps/web,创建认证接口时放到services/auth-service,创建主业务接口时放到services/backend,创建日志SDK时放到packages/shared-logging。服务通信时走HTTP API,而不是直接共享数据库。这就是决策层的价值——不是为了把文档写厚,而是为了让AI知道边界。
技术决策不需要全部展开,抓重点即可
技术决策很容易写得很细,比如技术栈、目录结构、接口封装、异常处理、缓存策略等。但在文章里没必要全部展开,用清单说明核心方向就足够了:
| 方向 | 决策重点 |
|---|---|
| 前端页面 | 页面怎么拆、状态放哪、请求放哪 |
| 前端组件 | 什么是通用组件,什么是页面私有组件 |
| 前端API | 是否允许页面直接请求接口,错误在哪里统一处理 |
| 后端分层 | Controller、Service、DTO各自负责什么 |
| 后端数据 | 能不能直接返回数据库实体,敏感字段怎么过滤 |
| 安全认证 | Token放哪、权限谁校验、日志不能打印什么 |
有了决策之后,后面三层才有依据
决策层定方向之后,后面三层才有依据。比如决策层写了“采用Monorepo多微服务架构,前端放apps/web,认证服务放services/auth-service……”,那么rules就可以翻译成具体规则:“新增前端应用必须放在apps/目录,新增后端服务必须放在services/目录,服务间不得直接访问彼此数据库”。agents可以定义不同角色的职责,“frontend-developer负责apps/web下的页面和组件,backend-architect负责services下的服务边界”。skills则可以落地为标准化步骤:“新增后端接口时,先判断接口属于哪个服务,再在对应目录下创建Module、Controller、Service、DTO……”。这样一来,一条决策就能从“方向”一路传导到“执行”。
决策文件写好了,Claude怎么加载?
决策文件拆好之后,还差最后一步:在CLAUDE.md里建立引用关系。否则这些文件只是放在项目里的文档,AI不一定每次都会主动读取。
这里有一个容易踩的坑:在CLAUDE.md里写“决策文档索引”,不等于Claude会自动读取这些文档的全文。比如只写“技术决策见.claude/FRONTEND-DECISIONS.md”,Claude能看到“有这些文档”,但不会仅仅因为出现了Markdown链接,就自动把这些文件全部展开进上下文。
所以更稳妥的做法,不只是“列索引”,而是把它变成一条明确的加载制度:CLAUDE.md声明哪些任务必须读取哪些决策文档,通过@文件路径把关键决策纳入上下文,或要求执行前显式读取,在Plan阶段遇到相关问题时,先读取对应决策再做方案。
比如可以在CLAUDE.md里加一段更强的决策读取规则:
## 决策文档强制规则
以下决策文档是项目级强制上下文,任何Plan、开发、重构、审查、性能分析、安全审计前必须先参考:
@.claude/DECISIONS.md
@.claude/FRONTEND-DECISIONS.md
@.claude/FRONTEND-BUSINESS-DECISIONS.md
@.claude/BACKEND-BUSINESS-DECISIONS.md
执行要求:
1. 涉及技术方案、架构模式、组件模式、状态管理、路由、HTTP、样式时,必须遵循技术决策。
2. 涉及业务流程、渠道策略、产品矩阵、合规准入、交易、资产账户、数据埋点时,必须遵循业务决策。
3. 未参考对应决策文档前,禁止输出实现计划,禁止修改代码。
4. 输出方案时,必须说明本次参考了哪些决策文档。
这里有两个关键点。第一,单纯写链接只是“告诉AI文档在哪里”;而@文件路径或明确的读取规则,是在告诉AI“这些文档属于当前任务的前置上下文”。第二,CLAUDE.md不只是做文档导航,更应承担“项目执行制度入口”的职责。举个例子,当用户提需求说“帮我新增一个文章详情页,并支持点赞”时,如果没有这个索引,AI可能直接开始设计页面和接口;但有了索引之后,AI在Plan阶段就会先判断:这是前端页面需求,先看FRONTEND-DECISIONS;涉及文章展示和点赞,再看FRONTEND-BUSINESS-DECISIONS;涉及点赞结果是否生效,还要看BACKEND-BUSINESS-DECISIONS。这样一来,它就知道前端只负责展示和交互,点赞结果必须以后端返回为准,页面不能自己用本地状态裁决业务结果。这才是决策加载制度的真正价值。
如果希望更进一步,还可以用自定义命令替代直接的/plan。团队可以不直接使用/plan,而是封装一个项目自己的命令,比如/project-plan 新增文章详情页并支持点赞。这个命令内部先加载决策文档,再进入计划阶段。这样做的好处是,不是每次靠人提醒AI先看文档,而是把“先看文档”变成了固定入口。
这套体系真正解决了什么?
1. 减少AI自由发挥
AI最大的问题不是不会写,而是太能发挥。它经常会自己补设计、自己选目录、自己改结构。四层治理的作用,就是把发挥空间收住:该放哪、该怎么写、谁来做、做几步,全部提前规定清楚。
2. 把团队经验变成项目资产
过去很多经验都在资深同学脑子里:“这个接口不能这么改”“这个组件不能直接调接口”“Token不能放localStorage”“数据库异常不能直接返回前端”……现在这些经验可以沉淀到决策文件、rules、agents和skills里,新人能看,AI也能执行。
3. 把Review前移
传统方式是代码写完再Review发现问题再返工。有了这套治理体系后,变成了写代码前先加载决策和规则,按角色和流程执行,生成时就尽量符合规范。它不能替代人工Review,但能大幅减少低级返工。
总结
Claude Code真正有价值的地方,不只是“帮我写代码”。更重要的是:
上篇主要讲了第一层:决策层。业务决策告诉AI系统边界是什么,技术决策告诉AI架构方向是什么,rules把决策翻译成具体规则,agents把任务交给合适角色,skills把高频动作变成标准流程。
一句话总结:
先给AI定制度,再让它干活。
不过,到这里会出现一个很常见的问题:技术决策里写了页面怎么拆,skill里也写了页面怎么创建;技术决策里写了API要封装,skill里也写了请求要走service。那技术决策和skill到底是不是重复了?这就是下篇要重点聊的问题了。