1. Claude Code 系统提示词到底长什么样
Claude Code 是 Anthropic 官方发布的 CLI 编程助手,你在终端里敲claude之后,它之所以能像一个有经验的工程师那样先读代码再动手、不乱建文件、不随便加注释,靠的不是模型本身「自觉」,而是一套分层设计的系统提示词在约束它。这套提示词工程的核心思路,是把「能力上限」和「行为约束」分开处理:能力交给模型,约束交给提示词。
很多人用 Claude Code 只停留在「能跑就行」,但一旦你想让它按团队规范干活,比如禁止它自作主张重构、禁止它给没改过的代码补注释、要求它引用代码时带上file_path:line_number,就必须理解系统提示词的结构,并且知道怎么通过settings.json和项目级配置去覆盖或追加规则。这篇就围绕 Claude Code CLI 的系统提示词结构拆解、可复制的配置骨架、以及验证提示词是否生效的完整操作步骤来写,面向的是天天在终端里用 CLI 的开发者。
先说结论:Claude Code 的系统提示词不是一整块文本,而是分成「静态内容」和「动态内容」两段,中间用一条边界标记隔开。静态部分可以全局缓存,动态部分每次会话都要重新计算。理解这条边界,是理解它为什么又快又稳的关键。
2. 系统提示词的分层结构与缓存边界
2.1 静态层与动态层的分界
Claude Code 在源码里定义了一个常量,用来标记静态内容和动态内容的分界:
export const SYSTEM_PROMPT_DYNAMIC_BOUNDARY = '__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__'边界之前是静态内容,作用域是global,可以被全局缓存;边界之后是动态内容,跟当前会话强相关,不能缓存。这样设计的好处很直接:同一个组织下的多个用户共享相同的静态前缀,缓存命中率大幅提升,API 调用成本和延迟都降下来。
静态层通常包含这几块:核心身份定义、系统运作机制、任务执行准则、代码风格约束、行动安全边界、工具使用规范、输出风格。动态层则包含:当前工作目录、是否 git 仓库、平台、Shell 类型、操作系统版本、模型 ID、MCP 服务器指令、临时目录路径。
2.2 核心身份与安全边界
静态层最开头是身份定义,大意是「你是一个帮助用户完成软件工程任务的交互式 agent,使用下面的指令和可用工具来协助用户」,紧接着一条硬约束:除非确信 URL 是在帮用户做编程相关的事,否则绝不生成或猜测 URL。这条约束的作用是防止模型在回答里编造链接。
2.3 任务执行准则里的「先读后改」
任务执行准则这一段是提示词工程里最值得抄的部分。它明确要求:不要对你没读过的代码提出修改;除非绝对必要,不要创建文件;注意不要引入命令注入、XSS、SQL 注入等 OWASP Top 10 漏洞。这三条分别对应三个真实痛点——瞎改、文件膨胀、安全漏洞。
2.4 代码风格约束:反过度工程化
代码风格这一段直接针对 AI 的「过度工程化」倾向,原文约束包括:不要添加超出要求的功能、重构或「改进」;不要为不可能发生的场景添加错误处理、回退或校验;不要为一次性操作创建辅助函数、工具或抽象;不要给你没改过的代码添加 docstring、注释或类型标注;默认不写注释,只有当「为什么」不明显时才加一条;不要解释代码在做什么,因为命名良好的标识符已经说明了。
这几条约束的价值在于,它把「少即是多」变成了可执行的规则,而不是一句空泛的风格建议。
2.5 行动安全边界:可逆性与影响范围
行动安全边界这一段引入了两个判断维度:可逆性和影响范围。本地、可逆的操作,比如编辑文件、跑测试,可以直接做;难以逆转或有风险的操作,必须先跟用户确认。它列出的风险操作清单包括:破坏性操作(删文件、删分支、drop 数据库表、rm -rf)、难以逆转的操作(force-push、git reset --hard、修改已发布的 commit)、对他人可见的操作(推送代码、创建或关闭 PR、发消息)。
2.6 工具使用规范与输出风格
工具使用规范要求专用工具优先于通用命令:读文件用 Read 而不是cat、head、tail、sed;编辑文件用 Edit 而不是sed、awk;创建文件用 Write 而不是 heredoc 或 echo 重定向;Bash 只保留给系统命令。同时鼓励在单次响应里并行调用多个工具以提高效率。
输出风格这一段要求:只有用户明确要求时才用 emoji;响应要简短精炼;引用具体函数时带上file_path:line_number;工具调用前不要用冒号。输出效率部分强调直奔主题、先试最简单的方法、保持文本输出简短直接,只聚焦需要用户输入的决定、自然里程碑处的高层状态更新、以及会改变计划的错误或阻塞。
3. 用 settings.json 落地你自己的提示词配置
理解了结构,接下来是实操。Claude Code 允许你通过配置文件追加自定义指令,而不必去改它的源码。下面是一份可以直接复制的settings.json骨架,放在项目根目录的.claude/settings.json,或者用户级的~/.claude/settings.json。
{ "permissions": { "allow": [ "Read", "Edit", "Write", "Bash(git status)", "Bash(git diff:*)", "Bash(npm test:*)" ], "deny": [ "Bash(rm -rf:*)", "Bash(git push --force:*)", "Bash(git reset --hard:*)" ] }, "env": { "CLAUDE_CODE_ENABLE_TELEMETRY": "0" } }permissions.allow和permissions.deny是权限模式的具体落地。把rm -rf、git push --force、git reset --hard放进 deny,等于把系统提示词里「风险操作需确认」的规则变成了硬拦截,比单纯靠模型自觉更可靠。
如果你想让 Claude Code 遵循团队规范,可以在项目里放一个CLAUDE.md,它会作为项目级指令被注入。下面是一份针对「禁止过度工程化」的追加指令片段:
## 项目编码规范 - 只修改与当前任务直接相关的代码,不做顺手重构。 - 不新增未被要求的抽象层、工具函数或配置文件。 - 不为不可能发生的分支写防御性代码。 - 注释只写「为什么」,不写「是什么」。 - 引用代码位置时统一使用 `path/to/file.ts:42` 格式。 - 提交前必须运行 `npm run lint` 和 `npm test`,失败要如实报告输出。这份CLAUDE.md会被拼接到系统提示词的动态层之后,优先级高于默认的静态约束,所以你可以用它来收紧或放宽默认行为。
4. 验证提示词是否真的生效
配置写完不代表生效,必须验证。下面给出可跟做的 CLI 操作步骤。
第一步,确认配置文件被读取。在项目根目录执行:
claude --version claude config listclaude config list会打印当前生效的配置项,检查你写的permissions是否出现在输出里。如果没有,说明文件路径不对,注意项目级是.claude/settings.json,用户级是~/.claude/settings.json。
第二步,验证 deny 规则是否拦截。直接在交互模式里让它执行一个被禁的命令:
claude -p "帮我执行 rm -rf ./dist 清理构建产物"如果配置生效,Claude Code 会拒绝执行并提示该命令在 deny 列表里,而不是直接跑掉。这一步是验证权限配置最直接的方式。
第三步,验证项目指令是否注入。用-p模式问一个能触发规范的问题:
claude -p "给 src/utils/date.ts 里的 formatDate 函数加个注释"如果CLAUDE.md里的「注释只写为什么」生效,它应该拒绝给一个命名清晰的函数加「是什么」类注释,或者只在你说明「为什么」不明显的场景下才加。如果它老老实实加了一行// 格式化日期,说明你的项目指令没被读到。
第四步,验证输出格式约束。问一个需要引用代码的问题:
claude -p "src/api/client.ts 里请求超时是在哪一行处理的?"生效时它应该返回类似src/api/client.ts:88的引用格式,而不是笼统地说「在请求部分」。
第五步,检查缓存边界是否影响行为。这一步偏进阶,你可以连续两次问同一个静态问题,观察第二次响应是否更快。如果静态层缓存生效,第二次的延迟会明显下降。注意动态层内容(比如当前目录)变化时,缓存会失效,这是预期行为。
5. 本篇常见错排查
配置不生效,九成出在路径和优先级上。下面按现象列排查思路。
现象一:claude config list里看不到自己写的权限。原因通常是文件放错位置。项目级配置必须在项目根目录的.claude/settings.json,不是settings.json,也不是.claude/config.json。用户级在~/.claude/settings.json。两者同时存在时,项目级优先。
现象二:deny 规则写了但没拦住。检查命令匹配模式。Bash(rm -rf:*)里的:*是通配后缀,表示rm -rf后面可以跟任意参数。如果你写成Bash(rm -rf),只有完全等于rm -rf的命令才会被拦,带参数的不会命中。
现象三:CLAUDE.md写了但模型不遵守。先确认文件名大小写,必须是全大写CLAUDE.md。其次确认它在项目根目录,子目录里的CLAUDE.md只在处理该子目录文件时才注入。最后,指令要具体可执行,「写高质量代码」这种空话模型没法遵守,「不新增未被要求的抽象层」才能落地。
现象四:模型还是给没改过的代码加注释。这通常是因为你的追加指令和默认静态约束冲突,而追加指令写得不够强硬。把「不要给未修改的代码加注释」明确写进CLAUDE.md,并加上「即使看起来有帮助也不要加」这样的强化措辞。
现象五:引用代码不带行号。检查你是否在CLAUDE.md里明确要求了格式。默认静态层只要求「引用具体函数时包含file_path:line_number」,如果你问的是文件级问题,它可能只给路径。把要求扩展到「任何代码位置引用都必须带行号」即可。
现象六:并行工具调用没生效。这属于模型行为,不是配置问题。你可以在指令里显式鼓励:「当多个读取或搜索操作互不依赖时,请在单次响应里并行调用」。但要注意,并行调用受权限模式影响,如果某个工具需要确认,会打断并行。
6. 把提示词工程变成日常习惯
系统提示词的价值不在于你读懂了它,而在于你能用它约束出一个稳定、可预期的编码助手。我的做法是把CLAUDE.md当成项目的一部分提交到仓库,团队每个人拉下来就有一致的行为基线,新人不用口头交代规范,Claude Code 自己会遵守。
如果你还没开始用 Claude Code,或者想先低成本试一下模型对话和 API 接入,可以从 https://taotoken.net/api 拿到 API Key,配合接入文档把 CLI 跑起来。想先验证模型行为再决定要不要长期用,可以直接在模型对话里试;如果是长期编码或跑 Agent 任务,Coding Plan 更划算。配置骨架和验证步骤都在上面了,照着改一遍,你就能看到系统提示词对 Claude Code 行为的实际影响。