指令编写的心法
同一条规则,两种写法,效果天壤之别。
看这两条 code review 指令:
写法 A:
Check error handling.
写法 B:
检查所有 async 函数的错误处理,因为我们的 Sentry 只能捕获被 catch 的异常,漏掉的 Promise rejection 会变成线上的沉默故障。
写法 A 扔给 AI,它会敷衍地扫一遍,告诉你”error handling looks fine”。写法 B 扔给它,它会逐个 async 函数检查有没有 try-catch 或 .catch(),还会特别关注 Promise.all 里是不是有未包裹的调用。
区别不在于字数多少,在于你有没有把”为什么查这个”讲清楚。写 Skill 指令不是写规则文档,是在给一个聪明但缺乏上下文的同事做 briefing。他能力很强,但他今天第一天来,对你们项目的历史事故、技术债、团队惯例一无所知。
祈使句 + Why
一条好指令的格式:做什么 + 因为为什么。
三个对比:
❌ “Check error handling” ✅ “检查所有 async 函数的错误处理,因为我们的 Sentry 只能捕获被 catch 的异常,漏掉的 Promise rejection 会变成线上的沉默故障”
❌ “Use TypeScript strict mode” ✅ “确保 tsconfig 开启了 strict 模式,因为团队去年有两次事故是 any 类型导致的运行时错误”
❌ “Follow naming conventions” ✅ “组件用 PascalCase,hooks 用 use 前缀,工具函数用 camelCase——和项目现有代码保持一致,降低新人的认知负担”
“因为”后面的部分才是关键。它让 AI 理解这条规则的权重和边界。知道了”Sentry 只捕获被 catch 的异常”,AI 就不会把”顶层 main 函数没有 try-catch”标记成问题——因为那个通常由框架兜底。
输出格式约束
自由文本的 review 结果,每次格式都不一样,没法被后续流程消费。定义一个固定模板:
## 审查结果
### 问题列表
| # | 文件 | 行号 | 严重度 | 问题描述 | 修复建议 |
|---|------|------|--------|----------|----------|
### 总结
- 总体评分:X/10
- 主要风险:...
- 亮点:...把这个模板直接写进 SKILL.md,AI 就会按表格格式输出。输出一致意味着你可以写脚本解析它——比如统计每周各仓库的审查评分趋势,或者自动把 Critical 问题同步到 Issue tracker。第 11 章会实现这个统计脚本。
严重度分级
所有问题同等对待是 review 工具最常见的毛病。开发者打开一看,20 条建议,分不清哪些必须改、哪些随便看看,索性全部忽略。
定义三个等级:
- 🔴 Critical:必须修,不修不能合并。安全漏洞、数据丢失风险、线上必崩的 bug。
- 🟡 Warning:建议修,影响可维护性。命名不清、逻辑过于复杂、缺少关键注释。
- 🔵 Suggestion:可以考虑,锦上添花。更优雅的写法、性能微优化、代码风格统一。
终端兼容性提示:如果你的终端或 CI 环境不支持 emoji 显示,可以用
[C][W][S]或[Critical][Warning][Suggestion]替代。脚本解析时也更方便用正则匹配。
在指令里明确告诉 AI 每个等级的判断标准。不然它会把”变量名不太好”也标成 Critical。
指令的”减法”
回到第 2 章的精益原则:指令不是越多越好。
每加一条指令,都在消耗 AI 的注意力预算。20 条指令和 5 条指令,AI 对每条的遵守程度是不一样的。指令越多,每条被忽略的概率越高。
检查方法:把某条指令删掉,跑几次看看输出有没有变化。如果没变——这是死指令,AI 本来就会这么做,你写了等于没写。
保留标准很简单:这条指令让 AI 做了它原本不会做的事。
比如”代码要有良好的可读性”——废话,AI 默认就会关注可读性,删掉。但”所有金额计算必须用 Decimal 库而不是浮点数”——这个必须留,因为 AI 默认不知道你们的精度要求。
实战:code-review v2 — 结构化输出
在 v1 的基础上加入输出模板和严重度分级。完整的 .claude/skills/code-review/SKILL.md:
---
name: code-review
description: "审查代码的质量、安全性和可维护性。当用户说'review 这段代码'、'帮我看看这个 PR'、'检查一下代码质量'时使用。"
---
你是一个严格但友善的代码审查者。
## 审查关注点
1. **Bug 风险**:空指针、未处理异常、边界条件、竞态条件
2. **安全问题**:XSS、SQL 注入、敏感信息硬编码、不安全的反序列化
3. **错误处理**:所有 async 函数必须有明确的错误处理路径,因为未捕获的 Promise rejection 在生产环境中表现为沉默故障
4. **可维护性**:函数超过 50 行要标记,嵌套超过 3 层要标记,重复代码要标记
## 严重度定义
- 🔴 Critical:必须修复才能合并。判断标准:会导致数据丢失、安全漏洞、或线上崩溃
- 🟡 Warning:建议修复。判断标准:不修会增加未来维护成本或 bug 风险
- 🔵 Suggestion:可选优化。判断标准:有更好的写法,但现有代码不会出问题
拿不准严重度时,宁可往低标。开发者更信任不乱报 Critical 的审查者。
## 输出格式
严格按照以下格式输出,不要改变表格结构:
### 问题列表
| # | 文件 | 行号 | 严重度 | 问题描述 | 修复建议 |
|---|------|------|--------|----------|----------|
如果没有发现问题,写"未发现问题",不要硬凑。
### 总结
- 总体评分:X/10
- 主要风险:(一句话概括最大的风险点,没有就写"无")
- 亮点:(代码中做得好的地方,至少写一条)对比 v1,变化不大——加了输出模板、严重度定义、几条带 “因为” 的审查规则。但 AI 的输出质量会有明显提升:格式稳定、优先级清晰、不再胡乱标 Critical。
对应快照目录 skills/code-review-snapshots/v2-structured/。