提示写得好不好,80% 取决于输入准备,而不是措辞技巧。这篇文章解释提示的写法原则,以及如何把提示文件、Claude Code Skill 和 CLAUDE.md 三者结合起来,让好的提示模式真正在日常工作中生效。
写好提示的原则
输入比措辞更重要
“你是一名经验丰富的工程师,请帮我实现这个功能” ← 这句话本身没有问题,但它掩盖了真正的问题:AI 拿着什么输入在工作?
给 AI 一个接口定义 + 一段类似实现示例 + 具体的验收标准,用普通的话说”实现这个函数”,效果远好于精心设计的提示词但输入模糊。
实践方式:写提示前先问自己:如果我把这些信息交给一个刚入职的工程师,他能完成任务吗?能 → 输入够了。不能 → 还需要补充什么。
约束要显式,包括”不做什么”
AI 的默认行为是”有帮助地把能做的都做了”。如果你不说不要什么,它会:
– 加你没要求的功能(”顺手”把相关逻辑一起做了)
– 引入新的依赖
– 改动不相关的代码
“不添加超出验收标准的功能”、”不引入新依赖”、”不修改接口签名”——这类负向约束和正向指令一样重要,要明确写出来。
指定输出格式
不指定格式时,AI 会选择它认为”最完整”的格式,通常是大量解释文字 + 代码。大多数场景你只需要代码 + 简短决策说明。
常用的格式约束:
– “只输出代码,代码后面简述关键决策”
– “先列清单,确认后再生成代码”
– “给出 2-3 个方案,每个方案说明优势和劣势”
– “不需要解释每行的含义”
一次只做一件事
“帮我重构这个函数,同时补上测试,顺便检查一下有没有安全问题” → 三件事合在一起,每件事的质量都会下降。
拆开:先重构,验证没有行为变化,再生成测试,再做安全检查。每步的输入更干净,输出更可靠。
提示通过迭代打磨,不靠一次设计完美
第一版提示几乎都不够好。有效的提示来自:用了几次 → 发现某类输出总是差 → 找出原因(通常是某个输入没给或某个约束没写)→ 更新提示文件。
这就是为什么提示文件需要版本历史:不是为了形式,而是记录”因为输出总是过度实现,所以加了这条约束”这类原因。下次看到这条约束时,你知道它不是多余的。
三层使用结构
提示文件(04-prompt/)、Skill、CLAUDE.md 不是同一种东西的三个版本,而是三个不同的层次,各自解决不同的问题。
CLAUDE.md 每次对话都生效,写通用规则和上下文
↓ 引用
04-prompt/ 文件 按需引用,写特定任务的操作模式
↓ 演进
Skill 命令触发自动激活,封装完整工作流
CLAUDE.md:总是生效的基础层
CLAUDE.md 在每次会话开始时自动加载。适合放:
– 工作流规则:直接推到 main,不开 PR
– 项目约束:使用的技术栈,禁止的操作
– Prompt 文件入口:告诉 AI 做某类任务时去哪里找详细操作模式
CLAUDE.md 里引用提示文件的写法:
## 代码生成
实现新函数或模块前,按 04-prompt/code/code-generation.md 的输入清单确认上下文齐全。
## PR 合并前
运行 /code-review 或参考 04-prompt/review/pr-review.md。
这样做的效果:CLAUDE.md 保持简洁(规则层),具体操作细节在提示文件里(知识层),两者不互相污染。
不适合放进 CLAUDE.md 的:具体的提示文本、详细的操作步骤——这些随任务变化,放进 CLAUDE.md 会让它越来越难维护。
04-prompt/ 文件:按需引用的知识层
这些文件是任务操作手册,不是脚本。你在做某类任务前读它,或者告诉 Claude Code “先读这个文件再操作”。
核心价值:准备清单。每个文件最重要的部分是”准备什么”——在触发 AI 之前,你需要收集哪些输入。遗漏关键输入是 AI 输出质量差的最常见原因。
直接引用的方式:
先读 04-prompt/code/code-generation.md,
然后实现 [函数名],接口定义在 [路径]。
Claude Code 会读取那个文件,按里面描述的模式工作。你不需要复制粘贴任何内容。
Skill:命令触发的自动化层
Skill 是 Claude Code 插件里的指令文件,在特定命令(如 /req:dev、/code-review)运行时自动激活。它们本质上也是 Markdown 文件,但由工具自动注入,不需要你手动传递。
Skill 和提示文件的区别:
| 提示文件(04-prompt/) | Skill | |
|---|---|---|
| 触发方式 | 手动引用 | 命令自动激活 |
| 适合的任务 | 需要判断和准备的任务 | 流程固定、高频的任务 |
| 包含内容 | 输入清单 + 操作模式 | 完整工作流 + 决策树 |
| 修改方式 | 直接编辑 Markdown | 需要维护插件 |
什么时候用哪个:
- 需求开发流程 →
/req:dev(已有 Skill,流程固定) - PR 审查 →
/code-review(已有 Skill,流程固定) - 实现一个具体函数 → 引用
04-prompt/code/code-generation.md(每次输入不同,需要判断) - 错误诊断 → 引用
04-prompt/code/error-diagnosis.md(每次情况不同)
从提示文件演进到 Skill 的时机:当某个任务足够高频、流程足够固定、每次的输入结构都差不多,考虑把提示文件的内容封装成 Skill。没到这一步时,提示文件已经够用。
实际操作流程
开始一个新任务
1. 判断是否有对应 Skill(/req:dev、/code-review 等)
有 → 直接用命令,Skill 自动处理
没有 → 找对应的提示文件
2. 打开提示文件,检查「准备什么」
把需要的输入收集好
3. 触发:
对话里说"先读 04-prompt/[路径]/[文件].md,然后[任务]"
4. 判断输出质量
参考提示文件里的「好的输出是什么样的」和「常见失败模式」
发现某类输出反复质量差
1. 找到对应的提示文件
2. 对照「常见失败模式」找原因
3. 没有匹配的失败模式 → 这是新情况,记录下来
4. 更新提示文件:补充失败模式,或在「准备什么」里增加一项必要输入
5. 提交时说明改动原因
写一个新提示文件
适合沉淀为文件的条件:
– 这类任务至少重复了 3 次
– 每次都需要类似的准备步骤
– 遇到过至少一次输出质量差的情况(说明坑已经踩过)
复制 templates/prompt-template.md,按格式填写。重点写清楚:
– 什么时候用(明确边界,不是”随时可以用”)
– 准备什么(具体的输入清单)
– 常见失败模式(踩过的坑)
一个完整示例
假设要实现一个支付退款接口:
第一步:判断是否有对应 Skill → 没有专门的退款 Skill,用提示文件
第二步:打开 04-prompt/code/code-generation.md,检查准备什么:
– 接口定义 → 找到 PaymentService.Refund(ctx, req) 的签名
– 类似实现示例 → 找到已有的 PaymentService.Charge() 实现
– 约束 → 不能直接调用外部支付 API,必须通过内部 gateway
– 验收标准 → 打开 docs/requirements/active/REQ-042.md
第三步:触发
先读 04-prompt/code/code-generation.md,
接口定义:[PaymentService.Refund 签名],
类似实现参考 internal/payment/charge.go,
约束:不直接调用外部 API,通过 internal/gateway,
验收标准参考 docs/requirements/active/REQ-042.md。
请实现退款功能。
第四步:检查输出 → 代码风格是否和 charge.go 一致,是否有多余功能,错误处理是否完整
这个流程的每一步都有据可查,下次类似任务复用同样的流程。