Skip to content

Prompt Engineering 在 Claude Code 里的落地

把 Anthropic 官方的 prompt engineering 原则翻译成 Claude Code 里能直接抄的做法。

前面几章都在讲 Claude Code 本身的能力:hooks、subagent、MCP、plugin。这一节回到源头,讲一件所有能力的地基:怎么写 prompt,Claude 才愿意按你想要的方式干活。Anthropic 官方文档里有一套完整的 prompt engineering 建议,但它是从 API 视角写的。放到 Claude Code 这种带持久上下文、有 slash 命令、能引用文件的交互式场景里,落法要重新解释一遍。

官方的核心原则

Anthropic 的 prompt engineering 指南把"让 Claude 输出更好"这件事拆成了六七个可操作的原则。你不用背,但每一条都要理解成同一句话的不同侧面:让模型少猜,给它可执行的判据

说清楚目标、约束、成功标准。这是最基础也是最经常被忽视的一条。"帮我重构一下这段代码"和"把这段代码里的回调改成 async/await,保持原有的错误行为,单测别改"是两个完全不同的任务。前者会让 Claude 顺手做十件你没打算让它做的事。

提供背景和参考。你脑子里的上下文,模型是看不到的。这个函数为什么这么写、上游依赖是什么、有没有历史坑,全部写出来它才用得上。

用例子代替描述。少数几个 few-shot 样例比一大段文字规范更有效。你想让输出走某种风格,最快的方式是丢两个成品让它照着写。

用结构化标签把不同段落分开。API 场景推荐用 XML 标签 <instructions><input><context> 把不同来源的信息隔开,避免模型把用户输入当指令执行。放到 Claude Code 里,Markdown 的二级三级标题起同样的作用。

让模型显式推理。复杂任务前面加一句"先说清你的思路,再动手",或者直接进 /plan 模式。这是把 chain-of-thought 从隐式挖出来变成可审查的东西。

指定角色。给模型分配一个 persona,例如"你是一个专门做数据库迁移评审的高级工程师",会显著改变它权衡问题的口味。CLAUDE.md 里就是这个 persona 的固定住所。

预填响应模板。告诉模型"输出必须是 JSON 且只包含这三个 key",甚至给它把开头写好,能压掉一大堆格式偏差。

在 Claude Code 里怎么落

上面这些原则如果每次对话都要临时组织,成本太高。Claude Code 提供了几个把它们"沉淀住"的机制。

CLAUDE.md 就是持久 system prompt

~/.claude/CLAUDE.md 里写的东西每次都会自动带上,等于一份固化的 system prompt。这里最该放的不是"Claude 你要认真"这种废话,而是四类东西:

  • 项目背景(这是一个什么系统、用的什么语言、依赖哪些外部服务)
  • 代码风格约束(用 ES modules 不用 CommonJS、命名规范、注释风格)
  • 工作流约束(改完先 typecheck、只跑单个测试不要跑全量套件、commit 前跑 lint)
  • 已知坑位和历史决策(哪些坑踩过、为什么现在这么做)

反面例子

CLAUDE.md 不是越长越好。官方明确警告过:太长的 CLAUDE.md 会让重要规则埋没在噪音里,模型直接忽略一半。删掉那些"不写它也不会错"的条目,保留那些真的会犯错的红线。

单条 prompt 的最小结构

日常对话时,把每条重要请求都往下面这个四段结构上凑:意图 + 约束 + 验收标准 + 示例或参考。反面例子和正面例子对照一眼就看清了。

md
坏:帮我把登录改成 OAuth。

好:给 src/auth/login.ts 加一路 Google OAuth 登录(保留现有邮箱密码路径)。
    约束:session 存储沿用现在的 redis 那套,别引新依赖。
    验收:登录成功后 req.user 上带 provider 字段;跑 npm test -- auth 全绿。
    参考:@src/auth/session.ts 里已有的 session 生成模式。

再一组:

md
坏:这段代码有什么问题?

好:审 @src/api/upload.ts 的 handleUpload 函数。
    关注三件事:并发上传时的竞态、大文件的内存占用、错误路径下的文件句柄泄漏。
    输出格式:每个问题一段,先描述现象再给最小修复方案。

再一组:

md
坏:写点测试。

好:给 @src/utils/rate-limiter.ts 补 vitest 单测。
    覆盖:正常放行、超阈值拒绝、时间窗口滑动、并发场景。
    参考风格:@src/utils/__tests__/cache.test.ts,用同款 vi.useFakeTimers 模式。

三个例子共享同一个骨架:明确对象(@ 引用文件而不是描述位置)、明确约束、明确验收、明确可参照的样本。这就是 few-shot、context、clear direction 三条原则同时落地的样子。

/plan 模式就是显式推理

想让 Claude 显式推理,最直接的做法就是走 /plan:先出方案、你审一遍、再动手。这一步等于把 chain-of-thought 从模型脑子里拎出来给你看,你能在它跑偏前就把方向拧回来。官方推荐的三段式 explore → plan → implement 走的就是这个逻辑。

自定义 slash 命令 = 可复用 prompt 模板

.claude/commands/*.md 或者 .claude/skills/*/SKILL.md 里的内容,本质就是一段写好的 prompt 模板。它把"意图 + 约束 + 步骤"固化下来,用一个 /命令名 就能重放,还能塞 $ARGUMENTS 让每次调用带不同参数。

md
---
name: fix-issue
description: 按项目规范修一个 GitHub issue
---
分析并修复 GitHub issue $ARGUMENTS,遵循以下步骤:
1. 用 gh issue view 拉 issue 详情
2. 在代码库里定位相关文件
3. 实现修复并补测试
4. 跑 lint 和 typecheck
5. 生成描述性 commit message
6. 推分支并建 PR

用一次是普通 prompt,写进 skill 就是可复用的团队资产。

@file 就是 few-shot 样本

想让 Claude 按某个已有风格写代码,最省事的做法是 @ 引用一份现成文件。Claude Code 会在回答前把整份文件读进上下文,直接当 few-shot 样例。这比你描述半天"参考 XX 模式"有效得多。

Prompt caching:省 token 的隐藏杠杆

CLAUDE.md 加上项目里几个大的参考文件,加起来轻松几千 token。每次对话都重新算一遍太浪费。Claude 平台支持 prompt caching:把稳定不变的那段前缀标记为可缓存,后续对话直接命中缓存,只对新增部分计费。

Claude Code 会自动利用这个机制:CLAUDE.md 这类持续存在于每轮对话开头的内容会被缓存,你日常感受不到它的存在,但账单上的 token 会明显少。想吃满这个红利,一个隐含建议是:CLAUDE.md 内容尽量稳定。频繁改 CLAUDE.md 等于每次都让缓存失效。真正易变的内容(今天在改什么、临时的注意事项)应该放到具体的对话或者 slash 命令里,而不是塞进 CLAUDE.md。

一句话总结

Prompt engineering 在 Claude Code 里的落地不是"学一堆技巧",而是把"说清楚意图、给清楚约束、给清楚样本"这三件事,用 CLAUDE.md、slash 命令、@ 引用、/plan 模式分别固化下来。越是重复的场景,越应该把 prompt 沉淀成资产,而不是每次现敲。

参考来源

本教程为社区中文学习整理,非官方发布。Claude Code 属于 Anthropic。