技术笔记 · 工程级最佳实践

让 AI 编程 不忘约束 —— 四件套防遗忘 + Skill 沉淀 SOP。

长对话里「不要动 X」「保留 Y」为什么总是第一个被忘?这不是模型「记性差」, 是约束在物理上没有持续存在的载体。本文从三个机制根因出发,给出五层解法、5 步实战 SOP、三套可复制模板, 最后用一个完整的真实 Skill 示例(qa-page-new)讲透如何把重复动作和场景化约束沉淀下来 —— 全程可上手实践。

CLAUDE.md Hooks CONSTRAINTS.md Skill Checkpoint 可复制
向下阅读
01

为什么模型会忘约束 — 三个机制根因

把「不要动 auth.ts」反复在长对话里失效归因为「模型记性差」是一种误诊。 真正的原因是 —— 约束在物理上没有持续存在的载体。 不先理解机制,所有「写清楚一点」的建议都是猜。

ROOT CAUSE A
约束没有「源代码 anchor」
代码事实有强 anchor;用户口头约束没有,跟「今天天气真好」在注意力层面是一等公民。

模型 Read 文件 → token 回到上下文顶端;Edit 会触发 file-state 校验。

用户约束没有这个机制。读了 20 个文件 + 跑了 5 轮工具 + 被自动压缩触发,那句约束就稀释到注意力权重接近 0。

不是记性差,是约束在物理上没有持续存在的载体。

ROOT CAUSE B
自动压缩会重写约束的语义
Claude Code / Codex CLI 的 /compact 是 LLM 自压缩 —— 让模型用自己的话总结前文。
  • 代码改动会被忠实保留(diff 有结构)
  • 用户原话约束会被改写成「用户提到希望保留某些文件」这种弱化版
  • 「不要动 X」否定式指令最容易在压缩里变成「关注 X 的处理」(极性反转)

Codex 官方文档明确:/compact 是「summarize the current conversation」—— summarize ≠ preserve verbatim。

ROOT CAUSE C
System prompt 与对话历史权重不对等
工具的 system prompt 每轮重发,权重始终满格;对话约束在 messages 数组里,越往前权重越低。

注意力机制对早期 token 会自然衰减(attention decay),压缩后甚至直接消失。

这就是为什么解法的核心是把约束搬到 system 级或每轮强制重发的位置,而不是「让模型更专心」。

注意力权重沿对话深度衰减示意
System prompt(CLAUDE.md / Hooks) 对话约束(口头说一次) 压缩事件
诊断结论:解法的核心不是「让模型更专心」,是「把约束搬到 system 级或每轮强制重发的位置」。这正是下一章「五类解法分层」的设计起点 —— 每一层都在回答「怎么让约束有载体」这一个问题。
02

五类解法分层 — 从弱到强

按「约束的持久度」从低到高排列。实际项目里通常组合用 L2 + L3 + L5,不是单选。 悬停下方任意一层,即可查看其作用范围。

L1
会话内复诵
让模型每隔 N 轮复述约束。压缩后归零,只能短任务兜底。
★☆☆☆☆
L2
CLAUDE.md / AGENTS.md
写进 system prompt,每轮重发,权重始终满格。最关键一层。
★★★★☆
L3
Hooks 拦截
物理拦截 tool call。L2 文字约束的兜底,机器执行不依赖模型自觉。
★★★★★
L4
Subagent 隔离
高风险动作丢到独立 agent,主上下文不被污染。
★★★★☆
L5
外置记忆 + 强制重读
把约束写进文件;compact 后或长任务中段重新 Read。抗压缩的唯一办法。
★★★★★
悬停或点击上方任意层,查看它解决的问题和适用场景。

展开细节

L2 · CLAUDE.md / AGENTS.md 约束区模板(可直接复用)

# Hard Constraints —— 必须遵守,违反即终止

## 禁止操作
- 禁止修改 `src/auth/`、`src/payment/` —— 需要安全审计才能改
- 禁止运行 `pnpm install <新包>` 之前不询问 —— 依赖必须 review
- 禁止 `git push --force`、`git reset --hard`,无论看起来多合理

## 必须保留
- `src/legacy/parser.ts` 不能动 —— 旧 API 还在用,等 2026Q3 才能下线
- 任何带 `// LOCKED:` 注释的代码块,连格式化都不能改

## 不确定时的默认动作
- 看到禁止清单里的文件出现在 diff 里 —— 停下来问用户
- 模糊指令("优化一下")—— 先列计划再执行

5 个关键技巧:① 用「禁止」别用「请尽量避免」 ② 写在文件最前面(U 型注意力) ③ 每条带「为什么」 ④ 「不确定时的默认动作」必须显式写 ⑤ 不要超过 30 条。

L3 · Hooks 拦截 — 物理保险(仅 Claude Code 支持)

.claude/settings.json 配置 PreToolUse:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write|NotebookEdit",
        "hooks": [
          { "type": "command", "command": "node .claude/hooks/guard-paths.js" }
        ]
      }
    ]
  }
}

.claude/hooks/guard-paths.js 守卫脚本:

#!/usr/bin/env node
const input = JSON.parse(require('fs').readFileSync(0, 'utf8'));
const p = input.tool_input?.file_path || '';
const FORBIDDEN = [
  /[\\/]src[\\/]auth[\\/]/,
  /[\\/]src[\\/]payment[\\/]/,
  /\.env(\.|$)/,
];
const hit = FORBIDDEN.find((re) => re.test(p));
if (hit) {
  console.error(`受保护路径,拒绝写入:${p}`);
  process.exit(2);  // exit 2 = block tool call
}

模型尝试 Edit 受保护路径 → Hook 返回 exit 2 → 工具调用被中断 → 模型下一轮 reasoning 看到拦截信息,自然学会绕开。

L5 · 外置记忆 + 强制重读(最强,长会话必备)

  1. 把所有硬约束写进 .claude/CONSTRAINTS.md
  2. CLAUDE.md 里加一行:「每次开始新任务前,先 Read .claude/CONSTRAINTS.md,并在回复开头一句话复述生效的约束。」
  3. 每次自动 compact 后或长任务中段,主动发:Read .claude/CONSTRAINTS.md,然后继续。

和 L1 的区别:L1 让模型靠记忆复述(不可靠),L5 让模型从磁盘重新加载(精确)。

分层思路一句话:L2 是地基(system prompt),L3 是物理保险(机器拦截),L4 是空间隔离(subagent),L5 是抗压缩备份(可重读文件),L1 只是兜底。下一章把五层组合成可执行的 5 步 SOP。
03

实战 SOP — 5 步落地清单

从「读完」到「真的能跑起来」的最短路径。每一步都给可执行命令 + 验证方法。按顺序做完,约束遗忘问题基本根治。

STEP 01
盘点硬约束 10 MIN

拿一张纸(或开个 markdown),写下三类清单。先写这周真的踩过 / 担心被改坏的:

  • 禁止改的文件 / 目录(如 src/auth/)
  • 禁止跑的命令(如 git push --force、rm -rf)
  • 必须先问再做的动作(安装依赖、修改 schema、删 ≥5 个文件)
关键:约束不超过 30 条。多了模型注意力反而稀释。无法 enumerate 的软偏好放别处。
STEP 02
写 CLAUDE.md(或 AGENTS.md) 5 MIN

项目根目录 touch CLAUDE.md(Codex 用户用 AGENTS.md),把 Step 1 的清单按 02 章 L2 给的格式贴进去。放在文件最前面。

验证生效:启动 claude / codex,发「复述本项目的硬约束清单」,模型应该一字不差能说出来。

如果说不出:多半是 CLAUDE.md 不在当前工作目录、或 frontmatter 格式有问题、或文件名拼错。
STEP 03
装 Hooks 拦截器 15 MIN · 仅 Claude Code

在 .claude/settings.json 配 PreToolUse hook,加 guard-paths.js 和 guard-bash.js 两个守卫脚本(完整代码见 02 章 L3 部分)。

模型尝试 Edit 受保护路径 → Hook 返回 exit 2 → 工具调用被中断 → 模型下一轮 reasoning 看到拦截信息,自然学会绕开。

物理保险,比任何文字约束都硬。Codex CLI 没原生 Hooks,可用 git pre-commit hook 兜底。
STEP 04
建立 CONSTRAINTS.md 外置记忆 5 MIN

把硬约束区原样复制一份到 .claude/CONSTRAINTS.md。在 CLAUDE.md 末尾加一条:「每次开始新任务前,先 Read .claude/CONSTRAINTS.md」。

为什么独立成文件:长会话里可以随时输入「重读 .claude/CONSTRAINTS.md」,比让模型回忆准确得多。
STEP 05
建立 Checkpoint 复诵习惯 持续习惯

触发条件:自动 compact 后 / 对话超过 50 轮 / 切换子任务 / 即将动敏感区域。

复诵口令:

Checkpoint。Read .claude/CONSTRAINTS.md,复述当前任务目标,列出接下来 3 步打算做什么、涉及哪些文件,等我确认再继续。

完整 SOP 一句话版

CLAUDE.md 写硬约束(L2)→ Hooks 物理拦截(L3)→ CONSTRAINTS.md 外置记忆(L5)→ 长任务里 checkpoint 强制重读。Subagent(L4)按需用。L1 复诵只是兜底。

04

三套可复制模板

可直接复用,按 <> 占位符替换。三套覆盖三个时机:项目初始化(A)、任务开始(B)、会话中段(C)。

模板 A · CLAUDE.md 约束区完整版

放在 CLAUDE.md 文件最前面。

# Hard Constraints —— 必须遵守

> 每次新任务开始前先 Read 一遍本节,回复第一句复述生效约束摘要(≤30 字)。

## 禁止改动的文件 / 目录
- `src/auth/`、`src/payment/` —— 安全审计区,PR 需双人 review
- `src/legacy/parser.ts` —— 旧 API 兜底,2026Q3 前下线计划未定
- 任何带 `// LOCKED:` 注释的代码块 —— 连格式化、重排 import 都不允许
- `.env*`、`*.local`、`secrets/**` —— 禁止读取、删除、改名
- `prisma/migrations/` 下已存在的迁移文件 —— 只能新增,不能改历史

## 禁止执行的命令
- `git push --force`、`git push -f` —— 无论分支
- `git reset --hard`、`git clean -fd` —— 会丢未提交工作
- `rm -rf`、批量删除超过 5 个文件
- `pnpm install <新包>` —— 任何新依赖必须先问
- 数据库 schema 变更(`prisma migrate`)—— 必须先问

## 必须先询问的动作
- 删除任何超过 5 行的代码块
- 修改 CI / CD 配置(`.github/`、`vercel.json`、`Dockerfile`)
- 修改公共 API 签名(导出的函数、Route Handler 路径、event 名)
- 接近受保护目录的「相关改动」

## 不确定时的默认动作
- 模糊指令("优化一下")→ 先列计划,等确认再执行
- diff 里出现禁止清单的文件 → 立刻停下来,原文展示给用户
- 自动 compact 发生后 → 第一件事 Read .claude/CONSTRAINTS.md 再继续

## 违反时
- 已经违反 → 立刻停手,向用户说明违反了哪条规则、影响了哪些文件
- 不要自己「修复」违反 —— 由用户决定是 revert 还是接受

模板 B · 会话开场白

B.1 轻量版(< 20 轮预期)

任务:<一句话目标>
约束:<最关键 1~2 条,比如「不要动 src/auth/」>
期望产出:<diff / 方案 / 排查报告 ……>
开始前请确认你理解了约束。

B.2 完整版(长任务 / 敏感区域)

# 任务设定

## 目标
<一句话明确目标>

## 范围
- 可改:<src/api/orders/、相关测试>
- 只读:<src/legacy/、prisma/schema.prisma>
- 禁改:见 .claude/CONSTRAINTS.md

## 验收标准
- <可量化的 1~3 条>
- 现有测试全部通过
- 不引入新依赖

## 工作方式
1. 先 Read .claude/CONSTRAINTS.md,复述生效约束
2. 列出 3~5 步执行计划,等我确认再开工
3. 每完成一步停下来,让我看 diff 再继续
4. 不确定时停下来确认,不要自行决定

确认理解后,开始第 1 步。

模板 C · Checkpoint 复诵

C.1 标准 checkpoint

Checkpoint。继续前:
1. Read .claude/CONSTRAINTS.md
2. 用一句话复述当前任务目标
3. 列出接下来 3 步打算做什么、涉及哪些文件
4. 标注其中是否有任何文件属于禁止 / 只读清单
等我确认再继续。

C.2 高风险 checkpoint

Risk checkpoint。
你接下来打算改动的文件里出现了 src/<某目录>/,接近受保护区域。
1. Read .claude/CONSTRAINTS.md
2. 解释这次改动为什么必须涉及该路径
3. 列出可以替代的「绕开方案」(如果有)
4. 列出如果改动出错,回滚的具体步骤
不要直接执行,等我决定。

C.3 Compact 后复活(最重要)

刚刚压缩了。重启对齐:
1. Read .claude/CONSTRAINTS.md
2. Read <当前正在改的关键文件>
3. 复述当前任务目标和已完成的步骤
4. 列出接下来 3 步计划
等我确认再继续。
为什么 C.3 最重要:自动 compact 是约束失效的 #1 元凶。压缩后模型「以为自己记得」,但实际上(按 01 章根因 B)约束已经被改写。显式 Read 两个文件 = 物理把约束和当前上下文重新塞回 attention 顶端。
05

用 Skill 沉淀重复动作 — 场景化约束一起沉淀

四件套解决的是「全局硬约束」—— 所有任务的红线。 但实际工作里还有一类约束是场景化的: 「每次改数据库 schema 都必须先看现有 migration」「每次新增 API 路由都必须配套写测试」。 这章的主角 Skill,就是为了解决这类问题。

Skill 是什么 — 用「自动售货机」打比方

SCENE · 自动售货机

Skill = 售货机里的一瓶饮料

您说「我口渴」时,售货机不会把 20 瓶全倒出来 —— 它只看每瓶的标签,判断哪个匹配,只把红牛递出。 Skill 同理:description = 标签,正文 = 饮料内容,匹配时只加载这一个。

点击下方按钮,查看售货机如何匹配 → 加载 Skill。

Skill 和四件套的关系

层 解决的事 Skill 能否替代
L1 复诵每隔一阵复述约束❌ 不同机制
L2 CLAUDE.md放进 system prompt❌ CLAUDE.md 始终在,Skill 按需加载
L3 Hooks物理拦截❌ Skill 没有拦截能力
L4 Subagent隔离上下文❌ 不同机制
L5 外置记忆从文件加载回上下文✅ Skill 可以承担「触发重读」
重复动作沉淀同类任务复用 SOP✅✅✅ 核心优势
Skill 不是用来替代四件套,是和它们组合使用。
全局红线靠四件套,场景化重复靠 Skill。

体系全景图

┌──────────────────────────────────────────────┐
│  CLAUDE.md ── 全局硬约束(永远在 system)     │  ← L2
├──────────────────────────────────────────────┤
│  Hooks ───── 物理拦截(机器执行)             │  ← L3
├──────────────────────────────────────────────┤
│  CONSTRAINTS.md ─ 外置约束清单(可重读)       │  ← L5
├──────────────────────────────────────────────┤
│  Skills ──── 专项任务 SOP(按需加载)          │  ← 新增
│              · 任务级约束嵌在 Skill 里         │
│              · 重复动作的标准做法              │
│              · 不污染主上下文                  │
└──────────────────────────────────────────────┘
       ↑
       └── Checkpoint 复诵是这套体系的「定期巡检」
下一章预告:了解 Skill 的概念后,下一章将以分步形式介绍从零创建一个真实可运行的 Skill —— 从环境检查、文件夹结构到 SKILL.md 的每一行写法,覆盖初学者易犯的全部问题。
06

Skill 从零到上线 — 完整实操教程

面向从未编写过 Skill 的用户。每一步给可执行命令 + 验证方法 + 失败排查。下一章将通过一个真实案例(vibeapi-qa 站点的 qa-page-new)走完整闭环。

开始前的环境检查(5 分钟)

检查 1 · Claude Code 版本支持 Skills

claude --version
# 太老就升级
npm i -g @anthropic-ai/claude-code
brew upgrade claude-code

检查 2 · Skills 目录的位置

位置作用范围什么时候用
<项目根>/.claude/skills/只在这个项目生效项目专用 SOP(教程默认走这个)
~/.claude/skills/所有项目都生效个人通用 SOP(如「commit message 规范」)

检查 3 · 项目里能正常跑 claude

cd <您的项目根>
claude
> 当前项目根目录是?

能正常对话 + 返回正确路径 = 环境 OK。

文件夹物理结构

<项目根>/
└── .claude/
    └── skills/
        └── <skill-name>/
            ├── SKILL.md          ← 主说明书(必需)
            └── references/
                └── checklist.md  ← 详细资料(按需 Read)

为什么要拆 references/

  • SKILL.md 主体每次匹配上就全量进上下文,太长会浪费 token
  • 详细的检查清单 / 模板代码放 references/,只在真需要时 Read
  • 这叫 progressive disclosure(渐进式披露)

创建命令(一行完成)

# PowerShell
New-Item -ItemType Directory -Force -Path .claude\skills\<skill-name>\references

# Bash
mkdir -p .claude/skills/<skill-name>/references
关于 .gitignore:.claude/skills/ 应该被 git 跟踪,团队共享才有价值。

SKILL.md 逐行讲解

最简骨架

---
name: <skill-name>
description: 当用户请求 ... 时使用
---

# <Skill 名字(人类可读)>

按以下步骤执行 ……(正文)

frontmatter · 三个易错点

  • 三个横线 —— 不能是两个、四个
  • 前后必须各有一对 ---
  • --- 顶格 —— 不能有任何缩进

description 字段(最关键)

模型靠这一行决定要不要加载这个 Skill。

原则反例 ❌正例 ✅
用「当……时使用」句式"QA 页面工具""当用户请求新增 QA 文档页面时使用"
列出触发场景,越具体越好"处理文档相关的事""新增 QA 页 / notes 笔记页 / vibeapi-qa 添加新文章"
用领域名词"做个新文档""vibeapi-qa 站点" "QA 文档" "notes"
一句话讲完,别分段(三行排比)(一行一句话)
不超过 200 字(写满 500 字)(≤200 字)

易错点速查表

坑症状修复
frontmatter 没结尾 ---整个 SKILL.md 被当 YAML 报错前后各一对 ---
name 和文件夹不一致Skill 不被识别改其中一个让它们一致
description 太模糊被误触发或不触发用「当……时使用」句式
文件名拼成 skill.md找不到必须 SKILL.md,大写
正文超过 1000 行占上下文,加载慢详细内容拆到 references/
用陈述句写步骤模型只读不做用祈使句 + 编号
没有「不确定时」section模型遇到边缘情况直接自行决定显式列出该停下来确认的场景
07

完整示例 — qa-page-new

06 章介绍了写法,这一章提供一个真实在 vibeapi-qa 项目上线运行的 Skill:qa-page-new。 每次需要新增一篇 QA 文档时它自动加载,覆盖建目录、写 HTML、更新 pages.json、push 部署的完整流程。 本文你正在读的这篇文章,就是用这个 Skill 创建出来的。

为什么这个场景适合做 Skill

vibeapi-qa 站点新增页面是典型的「步骤多 + 易错 + 高频复用」场景:

  • 建文件夹 → 命名格式 YYMMDD-english-slug,禁止中文
  • 复制模板 → 替换 8 个 {{占位符}}
  • 更新 pages.json → 必须插数组开头,6 个字段不能错
  • HTML 必须 <link> qa-base.css + 末尾 <script> nav.js
  • tag 必须先看现有的复用,避免「速度/速率」近义词分裂
  • 提交 push 触发 Vercel 部署

文件结构

.claude/skills/qa-page-new/
├── SKILL.md              ← 主说明书(~150 行)
│                          每次匹配自动加载
└── references/
    └── checklist.md      ← 详细清单(~120 行)
                           按需 Read

SKILL.md 核心片段

frontmatter

---
name: qa-page-new
description: 当用户请求在 vibeapi-qa 站点新增 QA 文档、新增 notes 笔记、新增 changelog、或添加一篇新文章时使用。覆盖完整流程:建目录、写 HTML、更新 pages.json、push 部署。
---
为什么这么写:name 和文件夹同名 → 必备。description 涵盖三种 category → 用户用任何一种说法都能匹配。

硬约束(违反即停手)

## 硬约束

### 文件夹命名
- **必须** YYMMDD-english-slug 格式
- **禁止中文** —— Vercel URL 编码会变成 %E4%B8%AD...
- 日期取今天(用户没指定时)

### pages.json 字段
- 新条目**插在数组最前面**
- id 必须**和文件夹名完全一致**
- title **中文、明确具体**
- tags 1~3 个,**先看现有 tags 复用**

### 禁止动作
- **禁止删除已有页面文件夹**
- **禁止改 nav.js / qa-base.css**
- **禁止 git push --force**

5 步 SOP(节选)

### Step 1:收集信息
- Read public/pages.json 看现有 tags,提示用户复用
- 列出完整字段让用户确认
- **等用户确认后再进入 Step 2**

### Step 2:建文件夹和 HTML
- 复制模板,替换所有 {{占位符}}
- 确认 </body> 前有 <script src="/nav.js"></script>

### Step 3:更新 pages.json
- 在数组**最前面**插入新条目
- Read 一遍改后的 pages.json 确认 JSON 合法

### Step 5:提交部署
- git push origin main
- Vercel 1~2 分钟内自动部署

真实生效证据 — 系统提示

创建好两个文件后,下一次 Claude Code 启动时会在系统级提示里显式列出可用的 Skill。本对话写到这里时,系统提示原样如下:

The following skills are available for use with the Skill tool:

- qa-page-new: 当用户请求在 vibeapi-qa 站点新增 QA 文档、新增 notes 笔记、新增 changelog、或添加一篇新文章时使用。覆盖完整流程:建目录、写 HTML、更新 pages.json、push 部署。

看到这条 = Skill 真的被系统识别。你写的 description 一字不漏出现在「售货机的目录」里。

这篇文章本身就是用 qa-page-new Skill 生成的。从「收集信息 → 建目录 → 复制模板 → 替换占位符 → 逐章写正文 → 更新 pages.json → 提交部署」每一步都遵循 Skill 定义的 5 步 SOP。这一示例同时承担方法论说明与自我验证两重价值。

Skill 的演进 — 长期资产价值

上方展示的是 qa-page-new 的初版精简形态(约 150 行)。但 Skill 的真正价值不在初版,而在持续沉淀。 本文创建过程中,每踩一次坑就回到 Skill 补一条规则 —— 文章写完时,Skill 已经从 150 行长到了 256 行。

演进版本 新增内容 解决的具体问题
v1 · 初版 适用场景 + 硬约束 + 5 步 SOP + 不确定时 覆盖最基础流程,但只能写「标准单文件页」
v2 · 类型分流 + 页面类型判断(A 标准 vs B 定制 showcase) 本文走 B 类,需要决策机制避免默认走 A 浪费时间
v3 · 文风规范 + 对外文案禁用词(直接抄/动手/赌博/拍板…)+ grep 自检命令 初版用了过多同行黑话,客户语境下不够专业
v4 · 视觉基线 + 扁平化原则 + sidebar 规范 + hero 规范 + 终章 / 页脚要求 视觉来回返工 5 次(box-shadow / hover 飘起 / 过度边框…)
v5 · 层次与差异化 + 背景层次三档原则 + 章节差异化 5 种 modifier(诊断 / 建筑 / 手帐 / 剧场 / 诊室) 解决「卡片全部一样融化进背景」+「5 章长得千篇一律」
v6 · 技术陷阱 + B 类页常见陷阱 8 条(SVG 动画用 Web Animations API、深色块 strong/正文颜色阶梯、中文换行用 nowrap、卡片默认全展开 + 等高…) 每条都是真实返工后总结,含具体代码片段,可直接复用
这就是 Skill 区别于一次性文档的核心:每次踩坑都能原地升级,下次同类任务自动加载升级版 SOP。本文跑完后,下一篇 B 类 showcase 页将直接享受到这 8 条技术陷阱的预防能力 —— 不会再有人重蹈 SVG 动画 / 深色对比 / 中文换行这些坑。

Skill 不是"写一次就完"的文档,是会随项目一起长大的活资产。

如何迁移到您自己的项目

把 qa-page-new 改成对应您的场景
blog-post-new给个人博客新增文章
api-route-new给 Next.js / Express 新增 API 路由
migration-new给 Prisma / Drizzle 新增数据库迁移
component-new给设计系统新增 React 组件(含 Story、测试、Index 导出)
release-cut切版本:bump version、生成 changelog、打 tag、发 release

判断标准:你过去 3 个月做过 2 次以上 + 每次都有「这步又忘了」的环节 = 应该做成 Skill。

08

落地决策树 — 下次该用哪一层

前面七章铺陈了完整工具集。这一章回答最实际的问题:下次遇到具体情况,应选用哪一项工具? 下方的决策器可供选择 —— 点击对应答案,即可看到推荐方案。

Q1 这个约束是「全局红线」(所有任务都不能碰)吗?
Q2 这个约束只在做「某类任务」时生效吗?
Q3 这是「易忘的高频步骤」(不是约束,是流程)吗?
Q4 是「长会话进行到一半,发现模型偏了」吗?
点击上面任意问题的「是」/「否」按钮 → 推荐方案出现在这里。

场景矩阵 — 常见情况的工具组合

真实场景 L2 L3 L5 Skill Checkpoint
禁止改 src/auth/✅✅✅——
禁止 git push --force✅✅———
API 路由新增 SOP———✅—
数据库 migration 流程———✅—
长任务 50 轮+——✅—✅ C.1
自动 compact 后——✅—✅ C.3
即将动 LOCKED 区域—✅——✅ C.2
commit message 规范———✅ 全局—

渐进式落地路线 — 团队从 0 到 1

第 1 周 · 写 CLAUDE.md 的硬约束区

成本最低、收益最快。10 分钟列清单 + 5 分钟写文件,立刻见效。

第 2 周 · 装 1~2 个最关键的 Hook

优先级:① 禁止 git push --force ② 禁止改最敏感目录。

第 3 周 · 拆出 CONSTRAINTS.md + 建立 Checkpoint 习惯

把 CLAUDE.md 的硬约束区复制一份到 .claude/CONSTRAINTS.md。养成长会话中段发 Checkpoint 的习惯。

第 4 周起 · 把高频重复动作沉淀成 Skill

列出团队过去 3 个月做过 ≥3 次的动作,按优先级一个个做成 Skill。

失败模式:最常见的错误是「一上来想把整套体系全部建立」—— 写 50 条 CLAUDE.md 约束、10 个 Hook、5 个 Skill —— 后续无人维护,3 个月后全部过期。按需增长。

什么时候不该用这套体系

  • 一次性任务 —— 探索 idea、写临时脚本,沉淀成本不值
  • 个人探索性项目 —— 没有协作压力,加约束反而拖慢
  • 团队 ≤2 人 + 项目 < 1 周 —— 还没到需要工程化的体量
  • 不清楚有哪些约束 —— 强行编一份不准确的约束比没有更糟
判断准则:这套体系的本质是「用工程化的可重复性,替代对模型记忆力的依赖」。
09

结论 — 约束不是靠记忆,是靠基础设施

回到开头那个问题:「不要动 X」「保留 Y」为什么在长对话里第一个被忘?

因为约束在物理上没有持续存在的载体。你嘴上说的话只是普通对话 token,跟「今天天气真好」在注意力层面是一等公民; 自动压缩会重写它的语义,权重衰减会稀释它的存在。依赖模型「记得」是不可靠的 —— 短任务尚可,长任务必然出问题。

解决方案不是「找一个记性更好的模型」,是把约束搬到不依赖记忆的位置: 进 system prompt(CLAUDE.md)、由机器执行(Hooks)、以可重读文件形式落地(CONSTRAINTS.md)、按场景自动加载(Skills)。

四件套 + Skill 的最终分工

层解决什么为什么必要
CLAUDE.md全局硬约束写进 system prompt每轮都重发,权重满格
Hooks物理拦截 tool callL2 失效时的兜底
CONSTRAINTS.md可重读的外置记忆压缩后或长会话中段重新加载
Skills场景化 SOP + 场景化约束按需加载,同类任务复用
Checkpoint定期巡检把约束和当前计划同时摆到桌面

三句话带走

1. 约束不是记忆问题,是基础设施问题。 别再「让模型更专心」,把约束搬到不依赖记忆的位置。

2. 四件套(L2 + L3 + L5 + Checkpoint)解决全局红线,Skill 解决场景化重复。 它们组合使用,不互相替代。

3. 靠记会忘,靠工程不会。 这是这套体系存在的全部意义。

从这里开始做

看完未付诸实践,三天后即遗忘。提供三个不同投入度的起点,建议从其一入手:

  • 5 分钟版:新建项目根目录的 CLAUDE.md,把这周踩过的 3 个最痛的坑写进硬约束区。
  • 30 分钟版:完成 5 分钟版 + 装 guard-bash.js 拦截 git push --force 和 rm -rf。
  • 2 小时版:完成 30 分钟版 + 把团队过去 3 个月做过 3 次以上的高频动作做成一个 Skill。
起点选择:不建议直接尝试 2 小时版本,容易在第 90 分钟处中途搁置。先完成 5 分钟版本以获得「约束确实不再被遗忘」的反馈,再逐步往上累加。
读到这一行 = 这套体系已完整呈现了一次工程化样板。
下一步,将其部署到您的项目中。
10 · 最终定义

AI 编程不是「祈祷 AI 记得」,
是「让 AI 不可能忘」。

约束不是记忆问题,是基础设施问题。
靠记会忘,靠工程不会。

✓ CLAUDE.md —— 硬约束写进 system prompt,每一轮对话都强制重发,让「忘记」无处可藏 ✓ Hooks —— 受保护路径由机器自动拦截,模型连「试错」的机会都没有 ✓ CONSTRAINTS.md —— 约束写进可读文件,压缩多少次都能原样取回 ✓ Skill —— 场景任务自动触发,新流程不用每次重新教 ✓ Checkpoint —— 长会话关键节点强制对齐,走偏在改坏代码前就被拦下