10-技术决策和Skills到底怎么分工

74 阅读14分钟

下篇:技术决策和 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 在我们提需求时,能基于业务决策和技术决策做出更精准的方案。

而这套制度真正能长期稳定运转,靠的就是每一层都只做自己该做的事。