下篇:技术决策和 Skills 到底怎么分工?别让 Claude Code 文档越写越乱
上篇我们讲了:这两篇文章的核心目的,是通过业务决策和技术决策,让我们向 AI 提需求时,AI 在 Plan/决策阶段就能更精准。
但真正落地时,很多人会遇到一个问题:技术决策和 skills 好像都在写“页面怎么创建”“接口怎么封装”“代码怎么组织”,内容是不是冲突了?
这篇就专门聊这个问题:技术决策、rules、skills 到底怎么分工,才能既不重复,又能让 AI 更准确地执行。
一、为什么你会觉得技术决策和 skills 冲突?
因为它们确实经常描述同一件事。
比如“创建一个前端页面”。
技术决策里可能写:
页面采用标准文件拆分模式。
页面入口负责渲染。
页面状态放在 useStore。
常量放在 constant。
复杂逻辑抽到 hooks。
skill 里也可能写:
创建页面时必须创建:
- index.tsx
- useStore.ts
- constant.ts
- types.ts
- style 文件
创建顺序:
1. 先写 constant
2. 再写 useStore
3. 再写 index
4. 最后写样式
一眼看上去,两边都在讲“页面怎么拆”。
所以很多人会疑惑:
这不重复了吗?
到底应该写在技术决策里,还是写在 skill 里?
如果两边不一致,以谁为准?
我的理解是:
它们不是天然冲突,而是层级不同。冲突通常来自边界没划清。
二、一句话区分:技术决策定方向,skills 定步骤
最简单的区分方式是:
技术决策:为什么这么做、采用什么方向、哪些边界不能破。
skills:在具体任务里,第一步做什么、第二步做什么、文件怎么建、模板怎么套。
可以用一张表理解:
| 维度 | 技术决策 | skills |
|---|---|---|
| 核心问题 | 为什么这么做 | 怎么一步步做 |
| 关注点 | 技术选型、架构模式、边界约束 | 场景流程、执行步骤、模板细节 |
| 稳定性 | 相对稳定,变化少 | 跟任务场景走,变化更多 |
| 适用范围 | 全项目或某个技术域 | 某个具体任务场景 |
| 典型内容 | 页面必须分层、API 必须封装、Token 不进 localStorage | 新建页面、新建组件、新建接口、执行 lint |
| 写法 | 状态 / 决策 / 为什么 / 边界约束 | Step 1 / Step 2 / 模板 / 检查清单 |
所以,同样是“页面拆分”:
技术决策说:为什么页面要拆,以及拆分边界是什么。
skill 说:这次创建页面时,具体创建哪些文件,按什么顺序写。
三、技术决策应该写什么?
技术决策应该回答四类问题。
1. 技术选型
比如:
前端用 React 还是 Vue?
状态管理用 MobX、Redux 还是 Zustand?
后端用 NestJS 还是 Express?
认证凭证放 Cookie 还是 localStorage?
这类内容适合放技术决策,因为它决定项目长期方向。
2. 架构模式
比如:
页面是否必须拆分入口、状态、常量、类型?
API 是否必须统一封装?
Controller 是否允许直接写业务逻辑?
数据库实体能不能直接返回给前端?
这类内容也适合放技术决策,因为它决定代码结构和边界。
3. 设计理由
技术决策最重要的不是“我们用了什么”,而是“为什么这样用”。
比如不要只写:
Token 使用 HttpOnly Cookie。
更应该写:
为什么:
- 降低 XSS 窃取 Token 的风险。
- 前端不需要手动保存和拼接 Token。
- 认证生命周期由后端统一控制。
有了“为什么”,AI 在遇到新场景时才知道怎么判断。
4. 边界约束
比如:
禁止 localStorage/sessionStorage 存 Token。
页面组件不得直接调用原始请求库。
Controller 不得直接返回 ORM 实体。
业务组件不得直接依赖页面私有状态。
技术决策里的边界约束是“红线来源”。
但注意:
技术决策可以写边界,但不要写太多操作步骤。
四、skills 应该写什么?
skills 更像“办事流程手册”。
它应该回答四类问题。
1. 什么时候用这个 skill?
比如:
当用户说“创建页面”“新增模块”“新建列表页”时,使用创建页面 skill。
当用户说“创建组件”“新增公共组件”时,使用创建组件 skill。
当开发完成后,使用 lint skill 做增量检查。
skill 需要明确触发场景。
2. 具体执行步骤是什么?
比如创建页面:
第一步:确定页面位置和目录结构。
第二步:创建核心文件。
第三步:判断是否需要子组件。
第四步:注册路由。
第五步:执行页面特有检查。
第六步:执行 lint。
这就是 skill 应该做的事情。
它负责把抽象规范变成可执行步骤。
3. 文件模板怎么套?
比如:
创建页面时读取:
- constant 模板
- useStore 模板
- index 模板
- style 模板
- 子组件模板
- hooks 指南
这类“生成时要读哪些模板、按什么顺序生成”非常适合放 skill。
因为技术决策不应该关心具体模板文件怎么加载。
4. 完成后检查什么?
比如:
- 核心文件是否齐全?
- 页面入口是否只负责渲染?
- 子组件是否通过 props 解耦?
- 样式层级是否和 JSX 结构一致?
- 是否执行增量 lint?
这些检查项属于流程验收,也适合放 skill。
五、真正容易冲突的三种情况
技术决策和 skills 本身不冲突。
真正的问题通常出在下面三种情况。
情况一:技术决策写得太像 skill
比如技术决策里写成这样:
创建页面步骤:
1. 创建 index.tsx
2. 创建 useStore.ts
3. 创建 constant.ts
4. 创建 style 文件
5. 先 import React
6. 再 import useStore
7. 最后 export default
这就不太像技术决策了,更像创建页面流程。
应该放到 skill。
技术决策只需要写:
页面采用标准拆分模式。
页面入口负责渲染,状态逻辑放 useStore,常量放 constant,复杂逻辑抽到 hooks。
也就是说:
技术决策写“为什么要拆”和“拆分边界”,不要写“第几步创建什么”。
情况二:skill 私自做了新决策
比如技术决策里写:
页面状态统一放 useStore。
但某个 skill 里写:
简单页面可以不用 useStore,直接 useState。
这就是真的冲突。
因为 skill 不应该私自推翻技术决策。
正确做法是:
先回到技术决策里补充边界:
- 简单展示页可以使用 useState。
- 有请求、分页、表单、复杂状态时必须使用 useStore。
然后 skill 再按这个决策执行。
原则是:
skill 只能执行决策,不能偷偷改决策。
情况三:同一条规则在多处重复维护
比如技术决策里写:
禁止页面直接调用 axios。
rules 里也写:
禁止页面直接调用 axios。
skill 里又写:
禁止页面直接调用 axios。
短期看没问题,但长期容易一边改了,另一边忘了改。
更好的写法是:
技术决策:说明为什么 API 必须分层封装。
rules:明确禁止页面直接调用 axios。
skill:在创建页面步骤里安排“创建 api 方法,并在 useStore 中调用”。
这样每一层都有自己的职责,不需要重复解释。
六、加一层 rules,冲突会少很多
我更推荐不要让“技术决策”和“skills”直接互相覆盖,而是让 rules 做中间层。
技术决策
↓
说明为什么这样设计
rules
↓
翻译成明确的必须项、禁止项、检查项
skills
↓
在具体任务流程中引用这些规则并落地执行
举个例子。
技术决策
### ADR-001: 采用 Monorepo 多微服务架构
**状态**: ✅ 已采纳
**决策**:
- Monorepo 单仓库管理多个独立微服务。
- `apps/web/`: 前端 H5 移动端应用。
- `services/auth-service/`: 认证授权服务(端口 8889)。
- `services/backend/`: 主业务服务(端口 8888)。
- `services/log-service/`: 日志服务(端口 8890)。
- `packages/shared-logging/`: 跨系统共享日志 SDK。
**为什么**:
- 微服务独立部署、独立扩展。
- 共享代码通过 `packages/` 目录统一管理。
- 明确的职责边界,符合单一职责原则。
**边界约束**:
- 新增系统必须放入对应目录:`apps/`、`services/` 或 `packages/`。
- 服务间通过 HTTP API 调用,不直接共享数据库。
rules
进入 apps/web/ 之后,具体代码生成不能只靠 ADR,还需要 rules 约束写法。
下面这些就来自项目里的 .claude/rules:
React 规则:全部使用函数组件 + Hooks,禁止 class 写法。
MobX 规则:页面允许使用 useObserver,业务组件完全禁止使用 MobX。
样式规则:SCSS 中全部使用 px,由 PostCSS 自动转 vw。
路径规则:接口服务使用 @Service,公共组件使用 @CComponents,静态资源使用 @Static。
禁止事项:禁止引入不必要依赖,禁止随意修改构建配置。
Lint 规则:禁止全局 lint 扫描,只能针对变更文件做增量检查。
skill
有了 rules 之后,真正创建页面时,还需要 skill 把规则变成步骤。
下面这些就来自项目里的 .claude/skills/frontend-developer-create-page.md:
创建页面时:
1. 先读取页面模板:constant、useStore、index、scss、子组件模板。
2. 在业务目录下创建页面结构。
3. 创建核心四文件:index.jsx、useStore.js、constant.js、index.scss。
4. 复杂逻辑按需拆到 hooks/。
5. 子组件放到 view/,并优先通过 props 解耦。
6. 生成 SCSS 前,先读取 index.jsx,提取 JSX className 层级。
7. index.scss 必须从根容器开始,按 JSX DOM 父子层级嵌套。
8. 完成后调用 lint skill,只做增量检查。
这样三层就很清楚:
决策层:Monorepo 决定前端应用放在 apps/web。
规则层:rules 决定 apps/web 里的代码必须怎么写、哪些不能做。
流程层:skill 决定创建页面时先读什么模板、建哪些文件、按什么顺序检查。
七、如果两边真的冲突,以谁为准?
我建议优先级是:
业务决策 > 技术决策 > rules > skills > agents
为什么?
业务决策优先级最高
因为业务决策决定系统边界。
比如:
前端状态不是业务事实源。
那无论某个 skill 怎么写,都不能让前端只靠本地状态裁决核心业务结果。
技术决策高于 rules 和 skills
因为技术决策决定架构方向。
比如技术决策说:
认证凭证使用 HttpOnly Cookie。
那 rules 和 skills 都不能再要求前端把 Token 存到 localStorage。
rules 高于 skills
因为 rules 是强制执行的红线。
比如 rules 里写:
禁止执行全局 lint 修复。
那 lint skill 就必须只做增量检查,不能为了省事跑全局修复。
skills 是场景流程
skills 负责具体任务怎么做。
它可以很详细,但它不能推翻上层决策。
八、一个实用判断标准:这句话该放哪?
你可以用一句话判断内容应该放哪里。
如果是“为什么 / 原则 / 边界”,放技术决策
例如:
为什么 Token 不能放 localStorage?
为什么页面不能直接请求接口?
为什么 Controller 不直接操作数据库?
为什么前端状态不是事实源?
放技术决策。
如果是“必须 / 禁止 / 检查项”,放 rules
例如:
禁止页面直接调用 axios。
禁止 Controller 直接返回 ORM 实体。
禁止前端展示数据库异常。
SCSS 选择器必须和 JSX DOM 层级一致。
放 rules。
如果是“第几步 / 创建什么 / 模板怎么写”,放 skills
例如:
第一步创建 index 文件。
第二步创建 useStore 文件。
第三步读取 style 模板。
第四步注册路由。
第五步执行增量 lint。
放 skills。
九、结合创建页面 skill 看一眼
以创建页面为例,一个好的 skill 应该更像“办事指南”,而不是“架构决策文档”。
它可以写:
创建页面前,先读取页面模板、状态模板、样式模板。
创建页面时,按固定目录生成文件。
生成样式前,先读取 JSX,提取 className 层级。
创建完成后,执行页面特有检查和增量 lint。
这些内容非常适合放 skill。
因为它们都在回答:
这次创建页面时,具体怎么做?
但如果 skill 里开始大段解释:
为什么项目选择这种状态管理方案?
为什么不用另一种技术栈?
为什么页面必须采用这种架构?
那就写重了。
这些应该回到技术决策里。
十、我建议的最终文档边界
如果要让 Claude Code 配置长期可维护,我建议这样划分:
FADR / DECISIONS
只保留:技术选型、架构模式、为什么、边界约束。
rules/
保留:强制项、禁止项、检查清单。
skills/
保留:具体场景流程、文件模板、执行顺序、验收清单。
agents/
保留:角色职责、工具权限、什么时候调用哪个 skill。
尤其是创建页面、创建组件、创建接口这类文件,应该像:
办事指南
而不是:
架构决策文档
它可以引用技术决策,也可以体现技术决策,但不要重新定义技术决策。
十一、一个简单落地模板
你可以按下面这个模板检查自己的文档。
技术决策模板
### ADR-001: 采用 Monorepo 多微服务架构
**状态**: ✅ 已采纳
**决策**:
- Monorepo 单仓库管理多个独立微服务。
- `apps/web/`: 前端 H5 移动端应用。
- `services/auth-service/`: 认证授权服务(端口 8889)。
- `services/backend/`: 主业务服务(端口 8888)。
- `services/log-service/`: 日志服务(端口 8890)。
- `packages/shared-logging/`: 跨系统共享日志 SDK。
**为什么**:
- 微服务独立部署、独立扩展。
- 共享代码通过 `packages/` 目录统一管理。
- 明确的职责边界,符合单一职责原则。
**边界约束**:
- 新增系统必须放入对应目录:`apps/`、`services/` 或 `packages/`。
- 服务间通过 HTTP API 调用,不直接共享数据库。
rules 模板
## 前端页面开发规则
- 全部使用函数组件 + Hooks,禁止 class 写法。
- 页面允许使用 useObserver,业务组件不得使用任何 MobX 功能。
- SCSS 中全部使用 px,禁止手写 vw。
- 接口服务使用 @Service,公共组件使用 @CComponents,静态资源使用 @Static。
- 禁止随意引入不必要依赖。
- 禁止随意修改项目构建配置。
- 禁止执行全局 lint,只能针对变更文件做增量检查。
skill 模板
## 创建前端页面流程
1. 读取页面模板:constant、useStore、index、scss、子组件模板。
2. 确定页面目录和业务线。
3. 创建核心四文件:index.jsx、useStore.js、constant.js、index.scss。
4. 判断是否需要拆分 hooks/ 和 view/ 子组件。
5. 子组件优先通过 props 传参,不直接 import 父页面 useStore。
6. 生成 SCSS 前先读取 index.jsx,提取 className 层级树。
7. index.scss 必须从根容器开始,按 JSX DOM 父子层级嵌套。
8. 完成后调用 lint skill,只做增量检查。
这三个文件描述的是同一个方向,但层级不同,所以不会冲突。
十二、总结
技术决策和 skills 看起来会重复,是因为它们经常围绕同一个工程动作展开。
但它们本质上解决的是不同问题:
技术决策:定方向,解释为什么,规定边界。
rules:定红线,写清楚必须和禁止。
skills:定步骤,把高频任务变成流程手册。
agents:定角色,控制谁来执行和能用什么工具。
如果两边冲突,优先级应该是:
业务决策 > 技术决策 > rules > skills > agents
一句话总结:
技术决策不要写成操作手册,skills 不要偷偷做架构决策。
回到这两篇文章的核心目的:
不是为了把 Claude Code 文档写厚,而是为了让 AI 在我们提需求时,能基于业务决策和技术决策做出更精准的方案。
而这套制度真正能长期稳定运转,靠的就是每一层都只做自己该做的事。