第 7 章:心法层

提示词设计原则

让 Claude 准确理解你的意图

前面六章我们走完了从安装、配置、Skills 编写到典型工作流的所有实战环节。从这一节开始,本书进入心法层:不再讨论某个具体功能怎么用,而是回过头审视一个更基础也更被低估的问题——你到底应该怎么和 Claude 说话。

很多人以为提示词工程(Prompt Engineering)是某种秘籍:背一些「请你扮演资深架构师」「Let's think step by step」的口诀就能召唤出更聪明的模型。这种理解会让你长期停留在「碰运气」阶段。本书的立场是:提示词不是咒语,而是一份你和模型之间的「对话契约」(Conversation Contract)。契约写得清楚,输出就稳定;契约含糊,输出就漂移。Claude Code 的特殊之处在于,它不仅要理解你写下的那一段文字,还要把对话和文件系统、Git、Skills、CLAUDE.md 等一起编织成一个庞大的执行上下文。提示词的好坏,直接决定了它进入哪条执行路径。

本节会带你建立一套可以稳定复用的提示词写作方法论:从底层注意力机制讲起,到五大原则、Claude Code 特有模式、对话节奏、PM 与工程师的不同视角,最后是团队级的工程化沉淀。

读完本节,你应当能够回答这些问题:为什么同样一个需求,今天 Claude 写得很好、明天却不行?为什么资深工程师写出来的提示词,初级工程师照抄一遍效果会差很多?为什么有些团队用了一年 Claude Code 之后,效率不增反减?这些问题的答案,几乎都可以归结到提示词的「契约性」是否被尊重。

需要提前说明:本节讨论的所有原则,对所有 LLM 都适用,不只是 Claude。但 Claude Code 因为深度集成了文件系统、Git、Skills,提示词的物理形态(路径、@ 引用、Plan 模式)和聊天版有显著差异,因此本节会专门拆出一节讨论这些 Claude Code 独有的写法。

阅读建议:如果你是产品经理(PM),可以重点关注一、二、四、五章——它们覆盖了「不写代码也能用 Claude Code 推动项目」需要的全部要点。如果你是工程师,建议把三、六、七章作为重点——它们针对 Claude Code 特有的工作流,能立刻拿到效率提升。无论哪个角色,请不要跳过第二章「五大底层原则」,这是后面所有技巧的根基。

最后还有一个常被忽视的事实:提示词工程的进步速度,几乎完全取决于你是否愿意把每一次失败的对话拿出来复盘。不复盘的话,你会反复踩同一个坑十次还不自知。复盘的成本极低——花两分钟问自己「这次为什么 Claude 没理解我?是哪一段话写糊了?下次怎么改?」——但收益却是复利式的。本节后面给出的 checklist、回归测试、Playbook 都只是工具,真正起作用的是这种「肯回头看」的习惯。希望你读完本节后,能在自己的工作流里养出这种习惯。

补充一点行业背景:Anthropic 自己在工程团队内部就极度重视提示词的工程化。他们出版的多份技术报告和官方博客(本节延伸阅读里列出了主要篇目)都反复强调一个观点:模型的能力天花板由 Anthropic 决定,但用户实际拿到的能力上限,由你的提示词决定。这个差距比大多数人想象的要大。同一个 Claude Opus,在专业用户手里和新手手里,产出的代码质量差距可能高达数倍。这种差距的根因,几乎全部落在提示词上。

换句话说:模型已经够强了,剩下的事,由你来决定它能拿出多少能力。本节就是教你怎么提取这些能力。读完后请立刻找一个真实任务实战一遍——肌肉记忆比读再多遍都管用。也建议把本节链接收藏到团队 wiki,作为新人入职时必读的「Claude Code 提示词入门」材料;当你团队规模超过 5 人时,统一的提示词风格本身就是一种生产力,能省下大量沟通成本与返工时间。


一、为什么提示词决定了 80% 的产出质量

零基础导引:在进入具体技巧之前,先回答一个根本性问题——为什么要花这么大力气研究提示词?毕竟 Claude 已经很聪明了,随便说点什么它也能给出像样的回答。这一节会解释:为什么「随便说点什么」恰恰是浪费 Claude 能力的最快方式。

1.1 LLM 的注意力机制如何决定「它读到了什么」

零基础导引:你可以把大语言模型(Large Language Model,LLM)想象成一位记忆力惊人但注意力有限的同事。它能在一秒内读完一本几百页的代码,但真正会被它「重点关照」的,只是其中一部分。提示词的作用,就是告诉它「请重点看这里」。

技术上,Claude 这样的模型基于 Transformer 架构。每一个生成的 token(词元)都会通过注意力机制(Attention)回头看上下文里的所有 token,并按相关度加权。这意味着:

  • 越靠近问题、越具体的描述,权重越高。
  • 信息密度高的位置(比如代码块、明确的结构化指令)比散落的形容词更容易被采纳。
  • 长上下文里位于「中段」的内容,常常被弱化,这是著名的「中间迷失」(Lost in the Middle)现象。

对 PM 来说,这条原理的含义是:你必须把「最关键的约束」放在指令的开头或者最末尾,而不是埋在第三段说明里。对工程师来说,这意味着即使你贴了一千行代码,如果不主动告诉 Claude「请重点关注 validate() 函数的边界条件」,它很可能给你一个泛泛的回答。

进一步:Claude 不是「读完所有内容然后思考」,而是「边读边在每个 token 决定关注哪些前文」。这就是为什么把同一份信息以不同顺序呈现,输出会有显著差异。一条经验法则是:先放素材,后放任务——把代码、文档、数据放在前面,把「请你做什么」的指令放在最后。这样指令在生成时拥有最强的注意力权重。

另一条容易被忽视的事实是:模型对结构化标记(Markdown 标题、XML 标签、代码块)非常敏感。Anthropic 官方明确推荐使用 XML 标签包裹不同种类的素材,比如 <context>...</context><task>...</task><output_format>...</output_format>。这些标签本身没有语义魔法,它们的价值在于告诉模型「这几块内容性质不同,请分别处理」。

1.2 三类常见的提示词翻车场景

场景一:信息过载。 把整个需求文档、所有相关文件、五年来的讨论记录一股脑丢给模型,期待它「自己理解」。结果是模型把注意力均匀分散,反而抓不到重点。常见症状是:模型回答看似全面,但每一条都浅尝辄止;让它给出建议,它就给出五条都正确但都不够锋利的建议。这种「中庸输出」的根因,几乎都是上下文过载。

场景二:语义模糊。 比如「帮我优化这个函数」。优化什么?性能、可读性、内存占用、错误处理?每一个方向的改动都不一样,但提示词没有给出取舍标准。模糊提示词的另一种典型变体是「让它更好」「让它更专业」——「好」和「专业」都是高度主观的形容词,不同的模型会按训练数据里的「主流答案」来执行,于是你得到的可能是一个非常平庸的「平均答案」。

场景三:角色错位。 让 Claude 扮演「最厉害的全栈工程师」,但给的任务其实是「请帮我读这段日志找出 502 错误的原因」。前者激发的是发散性创造,后者需要的是收敛性诊断,两者风格冲突,输出会摇摆。一个简单的判断方法:如果你的任务有「唯一正确答案」(比如调试、定位 bug),就不要让模型扮演任何角色,直接陈述事实即可;如果任务是开放的(比如设计、命名),扮演角色才有意义。

场景四:隐式假设过多。 这是一类隐蔽但极其常见的翻车。比如「帮我把这个 API 接好」——你以为「接好」包括错误处理、超时、重试、日志,但模型可能只接通了 happy path(顺利路径)。任何你认为「显然应该做」的事情,对模型而言都不显然。把它显式写出来。

1.3 把「提示词」理解为「对话契约」而非「咒语」

契约的核心要素有三个:输入(你给了什么材料)、约束(不许做什么、必须做什么)、输出(期望的形态)。任何一条提示词都可以套这个三段论审视一遍。如果其中一项缺失或模糊,输出就会不稳定。

举例对比:

[咒语式提示词]
你是一个 React 大师,请帮我写一个登录组件,要好看。

[契约式提示词]
输入:我有一份 Figma 设计稿(已贴在下方),技术栈是 React 18 + TypeScript + Tailwind。
约束:必须支持邮箱+密码两种字段,必须做空值校验,禁止引入新的 UI 库。
输出:单个 .tsx 文件,导出名为 LoginForm 的默认组件,用 200 字以内说明 props 设计。

后者无论交给哪个模型、在哪一天、由谁来读,都能产出基本一致的结果。前者每次都像抽卡。

契约思维还有一个隐藏好处:它强迫你在提问之前先想清楚自己要什么。很多时候我们写不出好提示词,不是因为不会写,而是因为我们自己也没想清楚。当你被迫填写「输入是什么、约束是什么、期望输出是什么」这三栏时,那些原本模糊的需求会迅速变得清晰。这也是为什么资深工程师写提示词往往很慢——他们大部分时间花在「想清楚」上,写下来反而是最快的一步。


二、五大底层原则

零基础导引:以下五条原则是本节的核心。它们彼此独立、可单独训练、可叠加使用。建议读完后立刻挑一条在下一次和 Claude 的对话里实践。理论再好,没有肌肉记忆都是空谈。

2.1 明确输出约束(格式、长度、字段、必填项)

零基础导引:和模型沟通时,最便宜的提质方式是把你「期望看到的样子」描述清楚。模型不擅长猜测你的审美,但极其擅长按模板填空。

常见可约束的维度:

  • 格式:Markdown 表格、JSON、TypeScript 接口、Mermaid 图、纯文本。
  • 长度:词数上限、行数上限、章节数。
  • 字段:必含字段、可选字段、字段顺序。
  • 风格:正式/口语、第一人称/第三人称、是否带 emoji。
// 对话片段:让 Claude 输出严格 JSON
// User:
请把以下用户故事拆解为开发任务,输出严格 JSON:
{
  "epic": string,
  "tasks": Array<{
    "id": string,            // T-001 这样的编号
    "title": string,         // 不超过 30 字
    "estimate_hours": number, // 整数
    "depends_on": string[]   // 没有依赖时给空数组
  }>
}
不要加任何解释,不要 Markdown 包裹。

// Claude(合规输出,可直接 JSON.parse):
{"epic":"用户登录","tasks":[{"id":"T-001","title":"邮箱密码登录接口","estimate_hours":4,"depends_on":[]}, ...]}

工程上一个非常实用的小习惯:当你需要把 Claude 的输出灌进下游程序时,永远要给一个可机读的 schema,而不是「请输出 JSON 格式」这样的口头约定。

更进一步:可以在 schema 后面加一句「如果某个字段无法确定,请填写 null 而不是省略」。这条小约定能避免下游 JSON.parse 之后出现「字段时有时无」的鬼故事。对长字符串字段,还可以加上「不要包含换行符」之类的硬约束,让结果直接可用于 CSV、SQL 等下游格式。

PM 视角的应用:如果你需要 Claude 帮你产出会议纪要、用户访谈摘要、需求文档,也应当先给模板。比如:

请按以下结构输出会议纪要:

## 参会人
- ...

## 议题与决议(必填)
| 议题 | 决议 | 负责人 | Deadline |
|---|---|---|---|

## 待跟进事项
- [ ] ...

## 未达成共识的问题
- ...

模板比「请帮我写一份会议纪要」稳定十倍。

2.2 提供具体示例胜过抽象描述

少样本提示(Few-Shot Prompting)是 Anthropic 官方推荐的核心技巧之一。一条「再来一个像这样的」往往比五条「请保持专业且简洁」更有效。

[抽象描述,效果差]
请把客户反馈分类,标签要专业。

[少样本,效果稳]
请按下面的样例风格分类(标签必须从 [bug, feature_request, ux, billing, other] 五选一):

样例 1:
反馈:"登录后页面一直转圈圈,过了 30 秒才出来。"
分类:bug

样例 2:
反馈:"希望能批量导出订单到 Excel。"
分类:feature_request

现在请分类:
反馈:"找设置入口找了五分钟。"
分类:

经验法则:两到三个差异化样例通常就足够稳定。给太多反而会让模型过拟合到样例的格式细节而忽略真实输入。

样例的「差异化」非常关键。常见错误是给三个高度相似的正面样例,模型会以为「所有输入都长这样」,遇到边界情况就崩。更好的做法是覆盖典型样例 + 边界样例 + 反例

样例 1(典型):
反馈:"登录后页面一直转圈圈。"
分类:bug

样例 2(边界——表面像功能但其实是 ux):
反馈:"找设置入口找了五分钟。"
分类:ux

样例 3(反例——看似有抱怨实则无效):
反馈:"不知道说什么,先随便填一下。"
分类:other

这三个样例覆盖了「明显类」「容易被误分类的」「模糊噪声」三种典型情况,模型的鲁棒性会显著提升。

2.3 分步骤分阶段,避免一次性塞入复杂任务

零基础导引:不要把「设计、实现、测试、写文档」捆成一句话扔过去。模型在多目标任务里非常容易出现「全都做了一点但都不到位」的状况。

推荐做法是显式分阶段:

我们一起做一个新功能,分三步走:

第一步【现在做】:列出三种可行的技术方案,每种给出优缺点和大致工作量。
第二步【等我确认后做】:基于我选定的方案,输出详细设计文档。
第三步【再次确认后做】:开始编码。

请先只完成第一步,等我说"进入第二步"再继续。

这种「显式 checkpoint」可以避免模型抢跑,也方便你在中途调整方向。

分阶段还能配合「思维链」(Chain of Thought,CoT)使用。要求模型在每一步先「想」再「做」,能显著提升复杂任务的正确率:

对每一步:
1. 先用 1-2 句话说出你的思考(为什么这么做、有没有更好方案)
2. 再给出实际产出(代码 / 设计 / 决策)
3. 最后用一句话点出风险或不确定的地方

这种结构化的「思考-产出-反思」三段,对调试、设计、重构这类需要权衡的任务尤其有效。

2.4 主动暴露上下文边界(「不要做 X」「忽略 Y」)

很多人只写「请做什么」,忽略了「不要做什么」。后者在工程任务中往往更有杀伤力,因为它直接砍掉错误分支。

请重构 src/services/payment.ts。

约束:
- 不要修改对外的 export 签名
- 不要新增依赖
- 不要触碰 src/services/ 之外的文件
- 忽略 .test.ts 文件,由我自己更新测试
- 如果发现需要破坏上述约束,先停下来问我

「先停下来问我」这一句尤其重要。它把模型从「贸然修改」拉回「先沟通再行动」。

2.5 让 Claude 先复述需求再开始执行

复述(Restate)是检测理解偏差成本最低的方式。零基础导引:相当于点餐后让服务员把单子念一遍,避免做错菜。

在动手之前,请先用三段话复述:
1. 你认为我要解决的核心问题是什么?
2. 你打算采取的方案大致是什么?
3. 有哪些地方你不确定、需要我补充?

我确认后你再开始。

这一招在长任务、高风险任务里几乎是必选项。我个人的统计是,约有 30% 的复述会暴露出我自己都没意识到的需求歧义。

复述还有一个进阶变体:让 Claude 先给出反例。比如:「在动手之前,请先列举三种我可能并不想要的解读方式。」这种「主动找茬」会逼出最容易被误解的边角,比单纯复述更狠。例如你说「优化这个查询」,模型可能反问:「你说的『优化』,是指——A. 减少 SQL 执行时间,B. 减少应用层调用次数,C. 减少索引占用,D. 增强可读性?这四种我会做出完全不同的改动。」一句反问,省下半小时返工。


三、Claude Code 特有的提示词模式

零基础导引:聊天版 Claude 和 Claude Code 最大的差别在于「执行权」。前者只能产出文本,后者可以读写文件、执行命令、调用 Skills。这一节讨论的所有模式,都建立在「Claude Code 拥有执行权」这一事实之上,写法因此和聊天版有显著差异。

3.1 文件路径前缀

零基础导引:在 Claude Code 里,说清楚是哪个文件比说清楚要做什么还重要。模型一旦定位错文件,后面所有改动都白费。

[模糊]
帮我修改用户文件,加一个手机号字段。

[精确]
请修改 /src/types/user.ts,在 User 接口中新增 phone: string | null 字段,
并同步更新 /src/services/user.service.ts 里所有 new User(...) 的调用点。

绝对路径或者带项目根的相对路径都比口语化的「那个文件」可靠得多。

这条原则的延伸:行号也是一种锚点。当文件很长时,加上行号能进一步缩小注意力范围。

请在 src/utils/format.ts 的第 45-78 行(即 formatCurrency 函数)增加对 JPY 的支持,
其他函数不要动。

行号的好处是:即使模型读到了整个文件,它也知道你的兴趣区间。配合 Git diff 输出,行号还能帮助 Claude 快速定位「最近改过哪里」。

另一个 Claude Code 用户经常忽略的细节:项目根的位置。如果你打开了多个 git 仓库的工作区,Claude 默认会把当前工作目录视为根。明确写出仓库名能避免错位:

请在 frontend 仓的 src/pages/login.vue 中加一个忘记密码链接,
不要去 backend 仓里找。

3.2 使用 @ 语法引用具体文件作为上下文

Claude Code 支持在提示词中用 @ 直接引用文件,模型会自动把内容拉进上下文。这比手动复制粘贴更可靠,也省 token。

请阅读 @src/services/auth.ts 和 @docs/auth-flow.md,
找出实现与文档不一致的地方,列成表格。

进阶用法:批量引用整个目录。

请阅读 @src/components/forms/ 下的所有组件,总结它们共享的表单模式,
然后建议是否值得抽象出一个 useFormBase hook。

3.3 用 Plan 模式预审计划,避免「野蛮执行」

Claude Code 提供了 Plan Mode(计划模式,按 Shift+Tab 切换)。在这个模式下,Claude 只输出计划而不真正执行。零基础用户应当默认在所有结构性改动前进入 Plan 模式

[进入 Plan 模式]

请规划:把当前的 REST 后端迁移到 tRPC,至少给我看到:
1. 影响的文件清单
2. 改动顺序与依赖关系
3. 风险点和回滚方案

不要写任何代码,先给我计划。

Plan 模式的真实价值不是「让 Claude 慢一点」,而是强制把执行决策从模型搬回到人。在没有 Plan 模式的工具里(比如普通的 ChatGPT 网页版),模型会习惯性地一次性给出长篇代码,你要么全盘接受,要么逐行评审,没有中间地带。Plan 模式则让你可以在「方向」层面做决定,把「实现」交给模型——这才是人机分工最合理的边界。

什么时候不需要 Plan 模式?三类情况:

  • 改动范围 < 20 行且只涉及一个文件
  • 任务是查询性质(「告诉我这个变量在哪里被引用」)
  • 你已经写好了非常详细的实现指令

其他时候,进入 Plan 模式几乎都是正确选择。

3.4 对长任务使用「checkpoint」指令

长任务最常见的问题是中途偏航。可以在提示词里嵌入显式 checkpoint:

本任务分为 5 个阶段。每完成一个阶段:
1. 提交一次 git(用 conventional commits 风格的中文 message)
2. 输出一句话总结:本阶段做了什么、下一阶段要做什么
3. 等我说"继续"再进入下一阶段

这种节奏特别适合超过 30 分钟的重构任务,能极大降低重做成本。

3.5 让 Claude 引用 CLAUDE.md 与 Skills 而非重复描述

如果你已经在 CLAUDE.md 中写了项目规范,不要在每次提示词里重复,否则容易和 CLAUDE.md 冲突。正确做法是引用:

请遵循 CLAUDE.md 里关于命名约定和测试要求的部分。
本次只处理 @src/api/order.ts,其他规则照旧。

Skills 也一样。如果你有一个名为 git-commit 的 Skill,直接说「调用 git-commit skill 帮我提交」即可,不要把 Skill 的步骤再口述一遍。

这条原则可以推广为「单一信息源(Single Source of Truth)」。任何规则、约定、模板,都应该只有一份权威定义。要么在 CLAUDE.md,要么在 Skill,要么在你的提示词里——三选一,不要重复。重复定义不仅浪费 token,还会在不一致时让模型纠结到底听谁的。我见过最离谱的一次:有人在 CLAUDE.md 里写「使用 4 空格缩进」,又在提示词里写「使用 2 空格缩进」,结果 Claude 在同一个文件里混用了两种缩进。


四、对话节奏与迭代提示词

零基础导引:本节前面讨论的是「单条」提示词的写法,从这一节开始我们关心「多条」提示词如何组合成一段成功的对话。把和 Claude 的协作类比为打乒乓球——你的击球质量重要,但更重要的是你能不能维持住一个稳定的节奏。

提示词不是一锤子买卖。在 Claude Code 这种交互式环境里,你和模型之间的「节奏」往往比单条提示词的措辞更影响最终结果。

4.1 第一轮:广而粗(让 Claude 列方案)

第一轮的目标不是拿到答案,而是看清解空间。

我想给现有的电商后台加一个促销引擎。
请先不要写代码,列出至少三种架构方向(不少于:规则引擎、DSL、可视化编排),
对比它们在以下维度的表现:
- 实施成本
- 运营友好度
- 后续可扩展性
- 与我们现有 NestJS 后端的契合度

4.2 第二轮:缩小范围(人工选 + 让 Claude 详化)

选定方向二:基于 DSL。请进一步:
1. 设计这套 DSL 的语法(给 5 条样例规则)
2. 给出解释器的核心数据结构
3. 估算 MVP 的工作量(人天)

4.3 第三轮:执行 + 验证

现在开始实现。先做解释器的核心:
- 文件路径:@src/promo/interpreter.ts
- 必须有单元测试(@src/promo/interpreter.test.ts),覆盖你给出的 5 条样例规则
- 不要触碰 controller 层

4.4 何时该开新会话而不是继续旧会话

这是被严重低估的技能。常见信号:

  • 上下文里堆积了过多无关的文件读取(>100K tokens)
  • Claude 开始重复问已经回答过的问题
  • 任务方向已经发生根本变化

正确做法是:在旧会话中让 Claude 总结当前状态,然后开新会话粘贴这份总结。这是「人工压缩上下文」的最佳实践。

[在旧会话末尾]
请用 200 字以内总结本次会话的:当前进度、关键决定、未解决问题,
方便我开新会话时粘贴。

4.6 「降级」与「升级」的提示词

当模型反复给出过于复杂的方案时,你可以「降级」要求:

请给我一个最简陋但能跑的版本,明确写在注释里哪些是占位符。
我先看跑通流程,再决定哪些需要真正实现。

反过来,当模型给出的是过度简化的方案时,可以「升级」要求:

你刚才的版本只考虑了 happy path。
请增补:错误处理、超时、并发控制、日志。
每一处都说明为什么需要、能防止什么样的事故。

「降级/升级」是控制对话节奏最实用的两个操作。把它们当作单独的快捷键,而不是临时想到的描述。

4.7 「请你给我一个反对意见」

模型有讨好倾向,对用户的方案默认会先肯定再补充。当你想得到真实评判时,明确请求反对意见:

我刚才给出的设计你觉得有什么致命弱点?
请你站在「半年后维护这套代码的新同事」的视角,
列出最让人头疼的三个地方,并说明为什么。
不要先肯定我,直接进入批评。

这种「逆向 review」往往能拿到比常规 review 高得多的信息密度。

4.5 用「我现在的目标是 X」替代「你刚才做错了」

当 Claude 偏离方向时,很多人下意识写「不对,重做」。这种否定式提示词信息量极低,模型只能靠猜来调整。更高效的写法是重申目标

[低效]
你刚才那个不对,重写。

[高效]
我现在的目标是:让这个表单在 iOS Safari 下也能正确触发软键盘。
你刚才的改动专注在 Android Chrome,请重新规划,
优先验证 iOS 的 inputmode + autocomplete 组合。

五、PM 与工程师的不同提示词风格

同一个 Claude Code,PM 和工程师用起来可以判若两人。原因不在于工具本身,而在于他们带入的「锚点」(Anchor)不同。

5.1 PM 视角:从用户故事开始,让 Claude 拆解为技术任务

PM 通常没有现成的代码上下文,但有清晰的业务诉求。最适合的开局是用户故事(User Story)+ 验收标准(Acceptance Criteria)。

作为一个零售门店店长,
我希望能在每天闭店时一键导出当日销售汇总,
以便我快速核对账目并发到老板群。

验收标准:
- 一键操作(不超过 2 次点击)
- 包含:总笔数、总金额、客单价、退款笔数
- 导出 Excel,列名中文
- 失败时有明确提示

请帮我:
1. 列出涉及到的前后端模块
2. 拆解为不超过 8 小时一颗的开发任务
3. 标出需要 PM 进一步确认的点

5.2 工程师视角:从代码现状开始,让 Claude 提议变更

工程师有丰富的代码上下文,最适合的开局是「现状 + 痛点 + 期望」。

现状:@src/services/notification.ts 当前同步发送邮件,QPS 上不去。
痛点:高峰期接口 P99 从 200ms 飙升到 3s。
期望:改成异步队列,但不引入 Redis 之外的新组件。

请提议三种实现方式(基于现有 BullMQ、基于 Redis Streams、基于 PostgreSQL LISTEN/NOTIFY),
对比代码改动量和运维负担。

5.3 跨角色协作:让 Claude 充当「翻译层」

PM 和工程师沟通成本高的根因之一是术语错位。Claude 在这件事上是天然的翻译器。

请把下面这段技术决策(工程师写的)翻译成 PM 能理解的版本,
保留所有关键信息但去掉实现细节,控制在 200 字内:

"我们决定把订单状态机从 enum 切换到 XState,
原因是当前的 if-else 已经在 isCancellable 这类衍生状态上滋生了 bug,
预计可以减少 40% 的状态相关单元测试代码。"

反向翻译同理:把 PM 的需求翻译成给工程师看的接口草案。

5.4 何时让 Claude 主动发问

这是一条对所有角色都管用的元原则:当你自己也不确定时,把不确定性外包给模型

我现在脑子里这个需求还很模糊。
请你扮演一个有经验的产品经理,问我 5 个最关键的澄清问题。
我会逐条回答,然后我们再一起写需求文档。

这种「让 AI 反向访谈我」的模式,在需求阶段比任何模板都好用。

发问的质量和提问者的人设强相关。同一句话,让 Claude 「以资深 PM 视角发问」和「以质疑型架构师视角发问」会得到完全不同的问题清单。组合使用可以覆盖更全面的盲区:

请分别以三种身份审视我刚才的需求,每种身份给出 3 个最关键的疑问:
1. 资深产品经理(关心用户价值与业务可行性)
2. 后端架构师(关心数据一致性与性能)
3. QA 主管(关心边界条件与可测性)

发问后等我逐一回答。

这个「多身份发问」模式本质上是把「提示词工程」推向了「角色工程」(Role Engineering),用低成本得到了一次跨职能评审。

5.5 PM 与工程师共用的「澄清协议」

无论是 PM 还是工程师,都应该和 Claude 之间约定一个固定的澄清协议。这能极大降低误解成本。一个可推荐的协议如下:

约定:
- 当我说"先列方案",你只列方案不写代码
- 当我说"开干",你按之前确认的方案执行
- 当我说"暂停",你立刻停下并输出当前进度
- 当我说"回滚",你撤销最近一次改动并解释为什么撤销
- 任何阶段,你不确定 ≥30% 的需求时,必须主动发问而不是猜测

请确认你理解了这个协议。

把这段协议放进项目的 CLAUDE.md,整个团队就有了一致的「打招呼方式」。


六、提示词的工程化沉淀

零基础导引:好的提示词不应该只活在某个人的脑子里。它应该像代码一样被版本化、被复用、被度量。

6.1 Skills 把高频提示词模板封装为可复用资产

Claude Code 的 Skills 机制(详见第三章)本质上就是「提示词工程化」的官方答案。当你发现自己反复写类似的提示词,就是该把它升级为 Skill 的信号。

# 一个 skill 的最小骨架
# ~/.claude/skills/code-review-zh/SKILL.md

---
name: code-review-zh
description: 中文代码审查,按 [可读性, 健壮性, 性能, 安全性] 四维度打分
---

## 步骤

1. 读取 git diff
2. 按四个维度逐项打分(1-5 分)
3. 用中文输出 Markdown 报告
4. 在「严重问题」一节列出必须修复的项

## 输出模板
...

6.2 团队级「提示词手册」(Prompt Playbook)的维护

如果你的团队有超过 3 个人在用 Claude Code,强烈建议建立一份 prompts/ 目录或 wiki 页面,记录:

  • 高频任务的标准提示词
  • 反例(哪些写法翻过车)
  • 各 Skill 的使用场景
  • 团队约定的「黑名单」(比如禁止让模型自动 commit)

这份文档应当像 ESLint 配置一样进入代码评审流程,定期更新。

6.3 度量提示词效果的简易指标

你不需要搞复杂的 A/B 测试。两个简单指标就够:

  • 一次通过率:提示词发出去后,第一轮输出是否可以直接用,无需人工修订。
  • 平均轮数:完成一个任务平均往返几次。

记录一段时间后,针对一次通过率最低、平均轮数最高的提示词重点优化,往往能拿到最大收益。

更可执行的做法是把这套度量嵌入团队的周会。每周花 15 分钟,看看本周 Top 3 的「难搞提示词」,集体改进。这种轻量化的 Prompt Review,比任何花哨的 LLMOps 平台都更早能产生价值。

// 一个超轻量的本地度量脚本(伪代码)
type PromptLog = {
  promptId: string;
  passedFirstTry: boolean;
  totalRounds: number;
  date: string;
};

function summarize(logs: PromptLog[]) {
  const byId = new Map<string, PromptLog[]>();
  for (const log of logs) {
    const arr = byId.get(log.promptId) ?? [];
    arr.push(log);
    byId.set(log.promptId, arr);
  }
  return [...byId.entries()].map(([id, arr]) => ({
    id,
    samples: arr.length,
    firstTryRate: arr.filter(l => l.passedFirstTry).length / arr.length,
    avgRounds: arr.reduce((s, l) => s + l.totalRounds, 0) / arr.length,
  }));
}

6.4 反模式:把提示词写成「咒语收藏夹」

最后一个警告。网上流传着大量「神级提示词大全」,鼓吹「一句话让 GPT 变身十倍工程师」之类。请保持警惕:

  • 这些咒语大多是在某个特定模型版本、特定任务上的偶然观察。
  • 它们违反了本节强调的「契约思维」——把不可解释性当作护城河。
  • 跨模型、跨版本、跨任务时,咒语的有效性极不稳定。

更可持续的策略是:理解原理 + 沉淀团队 Playbook + 定期度量。这三件事做好,比背一千条咒语都管用。

最后给你一个识别「咒语收藏夹」的简易检测器:如果一条提示词技巧的卖点是「不告诉模型理由就能让它表现更好」,多半是噪声;如果一条技巧能用注意力机制、训练数据分布、对齐目标这类原理解释清楚,多半是真知识。带着这个尺子去看互联网上的提示词分享,你会过滤掉 80% 的水分。

6.5 提示词的版本化与回归测试

零基础导引:当一条提示词被多个团队成员复用、又在线上跑了几个月之后,你会发现修改它变得非常危险——谁也说不准微调一句话会不会让某些边界 case 翻车。这时就需要把提示词当作代码来管理。

实践要点:

  • 存进 Git 仓库。建立一个 prompts/ 目录,每个提示词一个文件,文件名带版本号(例如 code-review.v3.md)。Diff 历史就是改进史。
  • 建立小型回归集。挑 10-20 个有代表性的输入,每次改提示词时跑一遍,比较新旧输出。可以人工评审,也可以让另一个模型做评审员(LLM-as-a-Judge)。
  • 写 changelog。每次改提示词,写一行「为什么改 + 预期改善」。三个月后回头看,你会感谢自己。
// 一个最小的提示词回归测试结构
type PromptCase = {
  id: string;
  input: string;
  mustContain?: string[];   // 输出必须包含的关键词
  mustNotContain?: string[]; // 输出必须不包含的关键词
};

const cases: PromptCase[] = [
  {
    id: 'jpy-currency',
    input: '把 1234 转成日元显示',
    mustContain: ['¥', '1,234'],
    mustNotContain: ['$', 'USD'],
  },
  // ...更多 case
];

async function runRegression(prompt: string, cases: PromptCase[]) {
  const failed: PromptCase[] = [];
  for (const c of cases) {
    const out = await callClaude(prompt + '\n\n输入:' + c.input);
    const passContain = (c.mustContain ?? []).every(s => out.includes(s));
    const passExclude = (c.mustNotContain ?? []).every(s => !out.includes(s));
    if (!passContain || !passExclude) failed.push(c);
  }
  return failed;
}

这套机制不需要复杂的 LLMOps 平台,一份 Markdown 测试样本 + 50 行脚本就能跑起来。早期低门槛,后期再考虑专业工具。

6.6 提示词的「可解释性」检查

最后一条工程化原则:每条进入团队 Playbook 的提示词,都应当能用一句话解释「为什么这么写」。如果你写下一条提示词却说不清楚每一段约束的目的,那这条提示词大概率是抄来的、没有内化的。

写一个简单的 review checklist:

  • 输入素材是否齐全?(少了什么会让 Claude 瞎猜?)
  • 约束是否覆盖了「不要做什么」?
  • 输出格式是否能被下游程序消费?
  • 是否给了至少一个样例?
  • 是否埋了 checkpoint?
  • 是否冗余了 CLAUDE.md / Skill 的内容?

把这份 checklist 写进团队的 Code Review 模板里,每次新增 Skill 或 Playbook 条目时走一遍,团队的提示词水平会以肉眼可见的速度提升。


七、综合演练:把一个糟糕提示词改造成契约式提示词

零基础导引:理论讲再多,不如手把手改一次。这一节我们拿一个真实场景里典型的糟糕提示词,按本节方法论一步步重写,看看每一步能拿掉哪些不确定性。

原始提示词(典型用户写法):

帮我把那个登录功能改一下,最近老有人反映登不上,
你看着办,搞得专业点。

这段话至少踩中了七个雷:「那个」(指代不明)、「登录功能」(哪个文件)、「老有人反映」(多少人?什么时间?什么环境?)、「登不上」(症状是什么)、「你看着办」(无约束)、「专业点」(无标准)、缺少输出形态约定。

第一轮改造:补输入

我们的登录组件在 @src/components/Login.tsx,使用邮箱+密码登录,
后端走 @src/api/auth.ts 的 POST /api/login。

最近一周客服收到 12 条投诉,都是 iOS Safari 用户,
现象是点击登录按钮后无反应,控制台报 net::ERR_FAILED。
桌面端和 Android 都正常。

仅这一步,问题已经从「玄学故障」收敛到「iOS Safari 上的网络层问题」。

第二轮改造:补约束

约束:
- 不要触碰后端代码(auth.ts 不动)
- 不要引入新的 npm 依赖
- 兼容性目标:iOS Safari 14+
- 如果你怀疑根因在后端,停下来告诉我,不要改前端代码绕过

这一步把「乱改」「滥改」「绕过本质问题」的可能性都封死了。

第三轮改造:补输出与节奏

请按以下节奏推进:

第一步:复述你对问题的理解(3 段话内)。
第二步:列出 3-5 个最可能的原因,按概率排序,每条说明排查方法。
第三步:等我确认排查方向后,再给出代码改动建议。

每一步结束都停下,等我说"继续"。

完整版(三步合一):

<context>
登录组件:@src/components/Login.tsx(邮箱+密码)
登录接口:@src/api/auth.ts 中的 POST /api/login
故障范围:iOS Safari 14+,桌面与 Android 正常
症状:点击登录按钮无反应,console: net::ERR_FAILED
反馈量:一周 12 例
</context>

<constraints>
- 不修改后端代码
- 不引入新依赖
- 怀疑根因在后端时停下来沟通
</constraints>

<task>
分三步推进:
1) 复述理解(≤3 段)
2) 排序列出 3-5 个最可能的原因 + 排查方法
3) 等我确认后再给代码建议
每步结束停下等"继续"。
</task>

对比最初的「你看着办」,这版提示词在以下维度全部具备可预测性:

  • 范围确定:只看两个文件
  • 症状清晰:iOS Safari + ERR_FAILED + 12 例
  • 失败模式有兜底:怀疑后端会停下来
  • 节奏可控:分三步,可以中途纠偏
  • 结构化标记:用 XML 标签把上下文、约束、任务分开

你会发现,整个改造过程其实就是「把脑子里所有的隐式假设显式化」。这不是「写得啰嗦」,而是「把契约写完整」。一旦养成这个习惯,你会反过来发现:和模型的沟通效率,倒逼你把和人沟通时也变得更结构化、更准确。这是提示词工程最被低估的副作用。


八、常见问答(FAQ)

零基础导引:本节最后整理了在内部分享和读者来信中被反复问到的疑问。如果你刚学完前面的原则,先扫一眼这些问答,能帮你避开 80% 的初学者坑。

Q1:英文提示词是不是比中文提示词效果好?

不绝对。Claude 在中英双语上的能力都很强。Anthropic 训练数据中英文比例较高,严肃技术文档与论文场景用英文确实可能更稳;但日常工作流、和中文代码库结合的任务,用中文反而更顺。建议是:术语用英文(接口名、库名),叙述用中文,混合使用即可。本书全部范例都用中文写作,就是这个理由。

Q2:提示词越长越好吗?

不。提示词长度和质量没有正相关。一份 2000 字的提示词如果信息密度低、结构混乱,效果远不如一份 300 字、契约清晰的提示词。检验标准是:每删一句话,看输出会不会变差。如果删了没影响,就该删。

Q3:要不要给 Claude 加「请你深呼吸」「这关系到我的职业生涯」这类情绪化前缀?

早期一些研究确实发现某些情绪化前缀能轻微提升表现,但这种效应在新模型上越来越弱,且非常不稳定。在 Claude 这种已经做了大量对齐训练的模型上,这种「情感勒索式提示词」收益极低,还会污染你的提示词风格。不推荐。

Q4:用 Claude Code 时该不该给「请检查并修正」这类指令?

应该,但要具体。「请自检」太空泛,模型会做表面功夫。改成「请用 pnpm lint && pnpm test 验证你的改动,并把输出贴回来」,效果立竿见影。把「自检」转化为「可执行的自检命令」,是 Claude Code 提示词最重要的进阶。

Q5:长会话越来越笨怎么办?

这是上下文管理问题,下一节 7.2 会专门讲。短答:在旧会话里让 Claude 输出「状态总结」,开新会话粘贴。

Q6:和 Claude 沟通时,是用「你」还是「请」更好?

无显著差异。Claude 对礼貌程度并不敏感(这一点和早期 GPT-3 略有不同)。重要的是指令清晰度。本书风格倾向用祈使语气直陈,因为这更接近「写代码注释」的状态——你不会在注释里写「请这个函数返回布尔值」,对模型也一样。

Q7:可以让 Claude 直接读 PDF / 图片吗?

可以。Claude Code 支持图片和 PDF 输入。但需要注意:图片里的文字识别(OCR)质量会受图片分辨率影响,复杂表格容易错位。重要素材建议先转 Markdown 或 CSV 再交给 Claude 处理。

Q8:长提示词会被「截断」吗?

Claude 系列模型有上下文窗口限制(具体大小随版本而定)。超过窗口的部分会被丢弃,丢弃顺序通常是「最早的优先丢」。但实际工作中,你远在窗口物理限制之前就已经面临「中间迷失」——也就是说,性能下降比硬性截断早得多。所以「能塞就塞」是错误策略,「精炼后塞」才对。

Q9:当 Claude 给出明显错误的代码时,最好的纠正方式是什么?

不是骂它「错了」,而是贴出错误证据。比如:「我跑了一下,控制台报 TypeError: Cannot read property 'id' of undefined,发生在第 17 行。请定位原因并修。」证据越具体,模型修复越准。

Q10:能不能让 Claude 直接帮我写提示词?

能,而且效果不错。一个常用 meta-prompt 是:「我想让 Claude 帮我做 X 任务。请你以提示词工程师的身份,写一份高质量提示词,包含输入、约束、输出格式、样例。」这种「让 AI 写给 AI」的元提示词,往往比人手写更结构化。前提是你能讲清楚 X 是什么。

九、写在最后:把提示词当作一项可训练的肌肉

零基础导引:技巧和原则都讲完了,最后想留给你一段「心法」。

提示词工程不是一次性掌握的知识,更不是某种考过就完事的技能。它更像跑步、写作或者弹琴——你每天都能用,但每天都还能再进步一点。

我个人对自己的要求是:每周至少回头审视三条本周用过的提示词,问自己:

  • 这条提示词的输入、约束、输出哪一段最弱?
  • 如果让一个完全陌生的同事按这条提示词去做,他能复现我的结果吗?
  • 哪些地方依赖了我隐式的偏好?这些偏好能不能变成 CLAUDE.md 里的一行规则?

这种「一周一回顾」的习惯,能让你在三个月后回看自己的提示词,发现它们已经从「碰运气」进化到「工程艺术品」。这种进步是肉眼可见的,也是真实可复用的。

最后留下一道作业。请挑出你最近一周里最不满意的一条和 Claude 的对话,按本节方法论重写一次提示词,然后把新旧版本并列贴在团队 wiki 上。如果有同事看了之后说「啊,原来还能这么写」,那本节就达成了它的目的。


提示词是你和 Claude 之间的对话契约。明确输入、约束、输出三段,结合 Claude Code 特有的 @ 引用、Plan 模式、CLAUDE.md/Skills 引用,再配合「先复述、分阶段、显式 checkpoint」的对话节奏,你能把一次性碰运气式的交互,变成可复制、可度量、可团队化的工程实践。

回顾本节的核心要点:

  1. 注意力机制决定一切——把关键信息放在开头或结尾,结构化标记比形容词管用。
  2. 契约思维——任何提示词都应明确输入、约束、输出三段。
  3. 五大原则——明确输出、给样例、分阶段、暴露边界、强制复述。
  4. Claude Code 特色——文件路径前缀、@ 引用、Plan 模式、checkpoint、引用 CLAUDE.md。
  5. 对话节奏——广而粗 → 缩范围 → 执行验证;该开新会话时果断开。
  6. 角色差异——PM 从用户故事出发,工程师从代码现状出发,Claude 可以做翻译层。
  7. 工程化沉淀——Skills、Playbook、度量、版本化、回归测试、可解释性 checklist。

如果你只能从本节带走一句话,请带走这一句:把和 Claude 的每一次对话,当作在写一份会被自己一年后阅读的契约。 只要你能做到这一点,其他所有技巧都会自然落地。

提示词只是基础设施的第一层。下一节 7.2,我们会把视角从「单条提示词」放大到「整段对话的上下文」,讨论上下文管理(Context Management)策略:什么时候该清空、什么时候该压缩、什么时候该开新会话,以及如何用 CLAUDE.md 与 Memory 工具构建跨会话的长期记忆。

延伸阅读