# 给 AI 写一本法典——从“向它许愿”到“让它守规矩”


先讲一件真实发生的事。

2025 年初，我给内部系统加一个功能：导出 Excel。需求很小，我甚至没写文档，直接在对话框里打了句"给列表页加个导出按钮"。

AI 十分钟内搞定了。改前端、加接口、写 SQL，一气呵成。PR 打开的时候我挺高兴，直到 review 发现：导出列和列表页对不上、十万行数据直接卡死服务、没有权限校验、测试只覆盖了最理想的路径。

代码能跑，测试全绿，AI 说完成了。交付是失败的。

后来我又试了一次。同一个需求，这次先确认导出哪些列、大数据量怎么处理、谁有权限，写成文档再动手，拆成三个能独立验收的小任务，最后让人对照原始需求 review 一遍。第一次确实慢一些，但后续维护和换人接手都稳得多。

两次用的是同一个模型。差距不在模型。

{{< admonition type=info title="核心观点" >}}
同一个需求，两条路径，同一个模型。差的是你有没有一套**可执行的规矩**。
{{< /admonition >}}

<!-- more -->

## 模糊的愿望，AI 补上默认答案

早期我犯过的错误，很多人应该都犯过。

"帮我把这个模块重构一下。"结果 AI 把原来能看懂的代码，改成了连自己都看不懂的样子。

"加个测试。"它写了一堆测试，测的都是理想路径。边界条件？异常情况？没人问，它也不问。

"这个 bug 修一下。"它确实修了，但没动根本原因，换个输入就再犯。

最离谱的一次：我让 AI "优化一下这个函数"，它把 30 行代码压缩成 8 行，"简洁多了"。简洁是简洁了，可读性归零。后来换人接手，花了半天才搞明白那 8 行在干什么。

共同点：我给了一个模糊的愿望，AI 补上了所有默认答案。默认答案错得很有礼貌——代码能编译，测试通过，没有任何报错。

{{< admonition type=danger title="能跑的陷阱" >}}
"能跑"比报错更危险。报错会逼你停下来想，能跑让你以为自己已经想过了。
{{< /admonition >}}

## 流程文章没回答的问题：谁来执行

后来我读到一篇讲 AI 工作流的文章，[《从 AI 写代码到 AI 工作流》](https://czm15053.github.io/ai-workflow-six-stages/)。

文章说：同一个需求，"直接让 AI 写"和"先对齐再动手"两条路径，用的是同一个模型。差距在于流程：需求对齐、设计决策、任务拆分、逐步实现、独立评审、知识交接，六个阶段，少一个就出岔子。

我同意。但读完心里有个疑问：文章说"要有六个阶段"，然后呢？谁来执行？

靠自觉？靠每天早上开工前默念一遍"今天我要走六个阶段"？还是靠一份没人会认真读的内部文档？

我把这个问题推到底：流程如果不变成某种"可执行的东西"，它就只是一份愿望清单。AI 不需要愿望清单，AI 需要的是明确到每一行的指令。

## dev-skills：把阶段变成可加载的规矩

所以我写了 [ByronFinn/dev-skills](https://github.com/ByronFinn/dev-skills)——一套遵循标准 skill 规范的技能集，加载到 AI 之后，它就知道规矩了。

功能清单和安装方式我不重复了，之前的[一篇盘点]({{< ref "posts/2026-07-06-ai-agent-skills-mcp-review" >}})写过。这里只说设计上的三个决定：

**第一，每个技能都是纯文本。** `SKILL.md` 是入口指令，`REFERENCE.md` 是详细流程，格式模板另放一个文件。没有运行时，没有脚手架，没有额外依赖。规矩本身是文本，加载机制是平台的事——[Skill 的加载和执行机制]({{< ref "posts/2026-06-22-claude-code-skills-system" >}}) 那篇拆过。

**第二，每个技能补一个具体的洞。** 12 个技能覆盖从构思到发布，每个都单独成立。挑六个核心的说：

- `/think` 发散构思，收敛成决策完备的 PRD：目标、方案、验收标准、技术决策，以及明确不做什么。
- `/grill` 对抗性审读，把每个未决问题、模糊假设、没定义好的术语逐个逼到墙角，不解决完不放行。
- `/story` 垂直切片，把方案拆成能独立执行、独立验收的小任务。水平切写出来的用例，测的是想象出来的行为。
- `/tdd` 子代理编排的测试驱动开发，每个验收标准一个周期。
- `/review` 三方并行评审：测试、代码、影响各由一个子代理独立审，报告合并后矛盾不自动消解，交给真人裁。
- `/research` 从权威信源（官方文档、源码、规范）取经，写成版本化、不可变的记录，大版本更新就开新档案，旧档永久冻结。

**第三，规矩不是写给人的，是写给 AI 加载器的。** 有人可能会说，这不过是把"好的工程实践"写成了文档。是的，关键不在"写好"，在加载之后 AI 就守这个规矩。

## 同一个需求，规矩加载前后各走一遍

{{< image src="/pictures/posts/give-ai-a-rulebook-workflow.svg" caption="同一条愿望，两条路径：左边靠许愿，右边靠规矩" width="800" class="center" >}}

回到开头的"导出 Excel"。

技能加载之后，我不再说"加个导出按钮"。`/think` 开工，AI 开始问：导出哪些列？大数据量怎么处置？权限？并发？`/grill` 上来审读，"大数据量"这种词过不了关：十万？一百万？一千？不定义清楚不放行。`/story` 切成三个任务：小数据量基础导出、大数据量异步导出加下载链接、权限校验，每个都能独立验收。`/tdd` 里，权限校验缺失会被自己的用例抓住，不是靠运气。最后 `/review` 三方并行，矛盾交给真人判。

同样的"导出 Excel"，两次都是 AI 写的代码。第一次靠许愿，第二次靠规矩。

{{< admonition type=tip title="关键区别" >}}
AI 本来就聪明，聪明到能把你没想清楚的地方补成看起来很完美的样子。规矩的作用不是放大 AI 的能力，而是挡住它的默认答案——让你的判断有机会落地。
{{< /admonition >}}

## 隔离靠进程边界，不靠子代理自觉

{{< image src="/pictures/posts/give-ai-a-rulebook-subagents.svg" caption="/tdd 的两道人工门与两个独立进程" width="800" class="center" >}}

`/tdd` 和 `/review` 的核心设计是子代理编排：测试子代理和开发子代理是两个独立进程，各自从零开始，各自从磁盘重读所有上下文。测试子代理不知道代码会怎么写，开发子代理必须真正读懂用例才能让测试变绿。

子代理为什么该独立——上下文隔离、防止污染、无状态行为可推理——这些在[多代理架构那篇]({{< ref "posts/2026-06-24-claude-code-multi-agent" >}})已经论证过，不重复。这里补两个"独立"落实在流程上的细节：

**第一，两道人工门。** 场景设计完，人审一遍；用例写完，再审一遍；然后开发子代理才动手。审不出问题就重来，人不能缺席。

**第二，记忆不共享。** 测试子代理和开发子代理在同一个编排进程下，但没有任何共享的对话记忆。开发子代理只能从用例本身理解行为，不能从"测试子代理刚才说过的话"里猜。

## 技能不是银弹

这句话可能让你失望，但我说的是实话：技能解决不了所有问题。

它能解决的是"AI 忘了规矩"。解决不了"规矩本身是错的"。PRD 的质量取决于人的判断。`/grill` 审读再狠，如果初始需求就是错的，也只是把错误的方向执行得更彻底。`/tdd` 的测试再全面，如果测的是错误的行为，那也只是错误地做对了事情。

有没有银弹？没有。

{{< admonition type=quote title="没有银弹" >}}
技能只是让"没有银弹"这个事实变得不那么痛苦。它不能替你思考，但它能确保你思考过的东西有机会变成代码，而不是被一个看似聪明实则懒惰的默认答案覆盖掉。
{{< /admonition >}}

## 结尾：指着一个文件说，看那儿

我做 dev-skills 的时候，脑子里一直有一个画面：

某个深夜，你写了个功能，第二天早上来了个新同事接手。他不需要问你"这个设计为什么这么搞""那个边界条件当时怎么考虑的"——他打开 PRD，看 ADR，翻 research 记录，全在那儿。

无非是想要：下次有人问"为什么这么做"的时候，你可以指着文件说，看那儿。

