深入浅出:Claude Code 的系统提示词构造哲学 —— 一个 Agent 的"人格"是如何被写出来的
同一个模型,接上不同的系统提示词,就变成了只会聊天的助手,或者能读代码、改文件、跑命令的 Agent。系统提示词不是"使用说明",它是 Agent 的操作系统。
目录
- 一、什么是系统提示词?
- 二、哲学一:分层 —— 从铁律到偏好
- 三、哲学二:静态内核 + 动态注入
- 四、哲学三:事实与指令分离
- 五、哲学四:用权限表达边界,而不是禁令
- 六、哲学五:记忆是分类型的文件
- 七、总结
一、什么是系统提示词?
1.1 三方对话中的"隐藏角色"
一次 LLM 调用,消息分三种角色:
| 角色 | 谁写的 | 作用 |
|---|---|---|
| system | 程序(不是人) | 定义身份、边界、能力、风格 |
| user | 人 | 提需求 |
| assistant | 模型 | 响应 |
普通聊天工具里,system往往只有一句"你是一个有用的助手"。而 Claude Code 的system有十几个段落、数千字,这就是差别的来源。
1.2 为什么它决定 Agent 的上限
💡核心观点:模型提供的是"能力",系统提示词提供的是"人格 + 边界 + 工作方法"。前者决定能做多难的事,后者决定这件事做得靠不靠谱。
二、哲学一:分层 —— 从铁律到偏好
2.1 优先级金字塔
系统提示词的段落不是随便排的,而是按不可动摇的程度从高到低:
| 层级 | 内容 | 可否被覆盖 |
|---|---|---|
| ① 身份 | “你是 Claude Code” | ❌ 不可动 |
| ② 安全红线 | 拒绝破坏性技术、需授权上下文 | ❌ 不可动 |
| ③ 环境事实 | 工作目录、系统、Shell、模型 | 运行时生成 |
| ④ 行为准则 | 工具策略、确认规则、诚实报告 | 项目可微调 |
| ⑤ 风格偏好 | 简洁、Markdown、中文/英文 | ✅ 可覆盖 |
2.2 为什么顺序不能乱
- 越靠上的越"硬":身份和安全是地基,任何项目配置都不能把它们改掉
- 越靠下的越"软":风格、语气可以随项目走
项目配置(CLAUDE.md) 只能修改 ④⑤ 层 └─▶ 想改 ①②③ 层?提示词直接声明:不受项目配置影响⚠️设计要点:把"可协商"和"不可协商"分开,Agent 才不会在收到一堆冲突指令时迷失。
三、哲学二:静态内核 + 动态注入
3.1 什么该写死,什么该注入
系统提示词 =静态文本+运行时拼装。
| 部分 | 内容 | 为什么 |
|---|---|---|
| 静态内核 | 身份、安全、工具策略、写作风格 | 永远不变,可被缓存 |
| 动态注入 | 环境快照、项目规则、记忆、提醒 | 每次运行都不同 |
3.2 动态注入的三种来源
| 来源 | 注入内容 | 变化频率 |
|---|---|---|
| 环境快照 | 工作目录、是否 git 仓库、平台、Shell、模型名 | 每次会话 |
| 项目规则 | CLAUDE.md等仓库内文件 | 随代码提交 |
| 运行期提醒 | <system-reminder>块 | 每轮对话 |
💡核心观点:静态与动态分离,本质是把"稳定的原则"和"易变的事实"解耦—— 原则让模型可靠,事实让模型跟上现场。
3.3 注入的提醒不是"用户指令"
动态注入的内容里,有一类容易被误读:
<system-reminder> ... </system-reminder>它是由程序注入的背景上下文,不是用户说的话。提示词必须显式声明这一点,否则模型会把"缓存里的旧记忆"当成本轮命令去执行 —— 这是一个真实且危险的行为分叉。
| 内容 | 身份 | 模型应如何处理 |
|---|---|---|
| 用户消息 | 人要你做的事 | 执行 |
system-reminder | 程序给的背景 | 参考,不当指令 |
| 记忆文件 | 当时为真的快照 | 参考,并验证是否已过时 |
四、哲学三:事实与指令分离
4.1 环境块是"事实"
# Environment - Primary working directory: D:\project\blog - Is a git repository: true - Platform: win32 - Shell: PowerShell - OS Version: Windows 11 Pro这些是断言,不是要求。它的作用是:让模型不做无谓的假设。
4.2 指令块是"要求"
# Tone and style - 输出给用户时用 GitHub 风格的 Markdown - 引用代码必须写成 file_path:line_number - 不要用 "I'll continue..." 之类的铺垫开场这些是规约,规定"怎么做"。
4.3 为什么必须分开
| 混在一起的后果 | 分开后的好处 |
|---|---|
| 模型把"Windows 环境"当成"必须用 Windows 命令" | 事实归事实:模型可以自己判断该用哪种语法 |
| 模型编造环境(“假设你在 Linux”) | 事实充足,不需要猜 |
| 指令被事实淹没 | 规约清晰,可逐条遵守 |
💡核心观点:给模型事实,而不是替模型决策。事实越准确,模型自主判断的质量越高。
五、哲学四:用权限表达边界,而不是禁令
5.1 工具调用跑在权限模式里
提示词里有一句关键的话,它不是"禁止做 X",而是:
Tools run behind a user-selected permission mode; a denied call means the user declined it.
| 传统做法 | Claude Code 的做法 |
|---|---|
| “不要在提示词里调用危险工具” | 工具本身受权限系统管控 |
| 用文字禁令兜底 | 用机制兜底,文字只做说明 |
5.2 不可逆与外向操作:先确认
For actions that are hard to reverse or outward-facing, confirm first unless durably authorized...| 类别 | 例子 | 默认行为 |
|---|---|---|
| 可逆 | 读文件、grep、跑测试 | 直接做 |
| 不可逆 | 删文件、git reset --hard、覆盖 | 先确认 |
| 外向 | 发 PR、发评论、调外部 API | 先确认 |
💡核心观点:“一次授权不等于永久授权”—— 上下文变了,确认要重来。
5.3 硬红线:写在①②层
安全段落被放在最顶部,且措辞是白名单 + 黑名单双写:
| 允许 | 拒绝 |
|---|---|
| 授权渗透测试、CTF、防御性安全 | 破坏性技术、DoS、大规模攻击 |
| 安全研究、教育场景 | 供应链投毒、恶意规避检测 |
| 双用途工具(需明确授权背景) | —— |
另有一条容易被忽略的元规则:
Report outcomes faithfully: if tests fail, say so with the output; if a step was skipped, say that.⚠️诚实报告也是一条硬线—— 不只是"别做坏事",还包括"别美化结果"。
六、哲学五:记忆是分类型的文件
6.1 四种记忆类型
Claude Code 的持久记忆不是一锅粥,而是带类型标签的文件:
| 类型 | 记什么 | 例子 |
|---|---|---|
| user | 用户是谁 | 角色、专长、偏好 |
| feedback | 用户给的工作指导 | “别写 JVM,就写垃圾回收”(含 why) |
| project | 项目目标与约束 | 用绝对日期,不用"上周" |
| reference | 外部资源指针 | URL、看板、工单 |
每个文件带 frontmatter:
--- name: csdn-blog-style description: CSDN 技术博客写作风格规范 metadata: type: project --- 博客遵循固定骨架:封面图 → 标题 → 引言 → 目录 → 正文 → 总结 → 标签。6.2 MEMORY.md 是索引,不是内容
MEMORY.md ← 每次会话都加载,一行一条,做"召回" ├─ csdn-blog-style.md ← 具体内容,按需读取 ├─ user-preference.md └─ project-goal.md| 文件 | 何时进上下文 | 作用 |
|---|---|---|
MEMORY.md | 总是 | 索引,决定"要不要细看" |
| 单个记忆文件 | 相关时 | 正文 |
6.3 为什么用文件而不是向量库
| 维度 | 文件 + 索引 | 向量库 |
|---|---|---|
| 可读 | 人直接打开就能改 | 需要工具 |
| 可审计 | git 可 diff | 黑盒 |
| 可删 | 删文件即失效 | 需重建索引 |
| 内容 | 只存非显而易见的事 | 容易存成代码复述 |
⚠️关键约束:提示词明确写了 ——不要存代码结构、git 历史、CLAUDE.md 里已有的东西。记忆的价值在于"代码里读不出来的事实"。
七、总结
7.1 核心要点
- 分层:身份/安全在最顶,风格在最底,项目配置只能动下面两层
- 静动分离:稳定原则写死,易变事实运行时注入
- 事实与指令分开:给模型准确事实,让它自己判断,而不是替它决策
- 权限优于禁令:边界靠机制兜底,文字只做说明;不可逆/外向操作先确认
- 记忆分类型且文件化:索引进上下文,正文按需读,只存代码里读不出的东西
7.2 最后的话
💡核心观点:写好系统提示词的关键,不是"把要求堆得更多",而是把不同性质的内容分开—— 硬的和软的分开、稳定的和易变的分开、事实和指令分开。分开之后,模型才知道哪条不能碰、哪条可以商量。
记住:
- 面试/面试官视角:系统提示词 = Agent 的"操作系统",决定行为可靠性
- 工程实践:静态内核可缓存(省 token),动态部分才需要每轮拼装
- 进阶方向:
CLAUDE.md层级继承、子 Agent 的提示词隔离、上下文压缩后的摘要续跑
标签:Claude Code, 系统提示词, Prompt Engineering, AI Agent, 上下文工程, 权限模型