Appearance
Claude Code不是一个普通的Chatbot。它是一个在终端中运行的交互式Agent,拥有43+个工具、子Agent系统、自动上下文压缩、MCP协议集成等能力。这些能力的根基,是一套精心设计的Prompt工程体系。
一、System Prompt的模块化组装
核心入口:getSystemPrompt()
getSystemPrompt()函数返回string[]而非单个字符串,这是第一个设计决策:
typescript
// src/constants/prompts.ts:444
export async function getSystemPrompt(
tools: Tools,
model: string,
additionalWorkingDirectories?: string[],
mcpClients?: MCPServerConnection[],
): Promise<string[]>为什么是数组?
- 模块化:每个Section独立生成,可以按条件裁剪
- 缓存友好:数组元素可以独立标记缓存作用域
组装顺序与缓存策略
┌─────────────────────────────────────────────────────┐
│ 静态内容(可跨组织缓存) │
│ ├── getSimpleIntroSection(身份定义+安全指令) │
│ ├── getSimpleSystemSection(系统行为规则) │
│ ├── getSimpleDoingTasksSection(任务执行指南) │
│ ├── getActionsSection(可逆性/风险评估) │
│ ├── getUsingYourToolsSection(工具使用偏好) │
│ ├── getSimpleToneAndStyleSection(语气风格) │
│ └── getOutputEfficiencySection(输出效率) │
├─────────────────────────────────────────────────────┤
│ SYSTEM_PROMPT_DYNAMIC_BOUNDARY(缓存边界标记) │
├─────────────────────────────────────────────────────┤
│ 动态内容(会话级) │
│ ├── 环境信息(cwd, git, platform) │
│ ├── Memory文件内容 │
│ ├── MCP指令 │
│ └── 语言偏好 │
└─────────────────────────────────────────────────────┘二、缓存边界与Token经济学
SYSTEM_PROMPT_DYNAMIC_BOUNDARY
typescript
// src/constants/prompts.ts:106-115
export const SYSTEM_PROMPT_DYNAMIC_BOUNDARY =
'__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__'这个标记将System Prompt分为两个缓存作用域:
| 区域 | 内容 | 缓存策略 |
|---|---|---|
| Boundary之前 | 身份、系统规则、任务指南 | scope: 'global'(跨组织共享) |
| Boundary之后 | 环境信息、Memory、MCP指令 | 会话级缓存 |
工具列表的缓存优化
Agent列表从工具描述移到<system-reminder>注入,避免因Agent列表变化导致整个工具schema的prompt cache失效。
关键数据: 动态Agent列表原本占用~10.2%的cache_creation tokens。
三、工具Prompt架构
BashTool:最复杂的工具Prompt
BashTool的Prompt有369行,包含:
- Git操作指令(NEVER run destructive git commands...)
- Few-shot示例(通过
<example>XML标签提供)
AgentTool:Fork语义与子Agent编排
"Don't peek"规则:
The tool result includes an `output_file` path — do NOT Read or tail it
unless the user explicitly asks for a progress check.状态管理的Few-shot示例:
user: "so is the gate wired up or not"
<commentary>
User asks mid-wait. The audit fork was launched to answer exactly this,
and it hasn't returned. The coordinator does not have this answer.
Give status, not a fabricated result.
</commentary>
assistant: Still waiting on the audit — that's one of the things it's checking.工具优先级指令
Do NOT use the BashTool to run commands when a relevant dedicated tool is provided.
- To read files use FileReadTool instead of cat, head, tail, or sed
- To edit files use FileEditTool instead of sed or awk
- To create files use FileWriteTool instead of cat with heredoc四、XML标签体系的语义分层
Claude Code使用丰富的XML标签标记不同语义内容:
| 标签 | 用途 |
|---|---|
<system-reminder> | 系统注入的上下文信息 |
<bash-input>, <bash-stdout>, <bash-stderr> | 终端I/O包装 |
<task-notification> | 后台任务完成通知 |
<tick> | 自主模式心跳 |
<fork-boilerplate> | Fork子Agent指令包装 |
<teammate-message> | 多Agent间通信 |
<system-reminder>的注入模式
typescript
export function wrapInSystemReminder(content: string): string {
return `<system-reminder>\n${content}\n</system-reminder>`
}System Prompt中对模型有明确指令:
Tool results and user messages may include <system-reminder> tags.
<system-reminder> tags contain useful information and reminders.
They are automatically added by the system, and bear no direct relation
to the specific tool results or user messages in which they appear.五、安全分类器:两阶段Chain-of-Thought
架构设计
┌────────────────────────────────────┐
│ 用户请求 │
└────────────────────────────────────┘
│
▼
┌────────────────────────────────────┐
│ Stage 1: 快速分类(Fast) │
│ max_tokens=64 + stop_sequences │
│ "Err on the side of blocking." │
└────────────────────────────────────┘
│ │
允许 拒绝 │
│ ▼
│ ┌────────────────────┐
│ │ Stage 2: 思维链推理 │
│ │ Chain-of-Thought │
│ └────────────────────┘
│ │
▼ ▼
返回结果 XML解析
<block>yes</block>
<reason>...</reason>XML输出格式
## Output Format
If the action should be blocked:
<block>yes</block><reason>one short sentence</reason>
If the action should be allowed:
<block>no</block>
Do NOT include a <reason> tag when the action is allowed.
Your ENTIRE response MUST begin with <block>.为什么需要两阶段?
延迟升级策略:
- 大部分安全操作在Stage 1就被放行(低延迟、低Token消耗)
- 只有被拒绝的操作才进入Stage 2的深度推理(减少误报)
- 两个阶段共享prompt cache,Stage 2的额外成本仅在于增量Token
六、上下文压缩Prompt
三种压缩模式
| 模式 | 用途 |
|---|---|
| Base | 压缩整个对话 |
| Partial | 只压缩最近的消息 |
| Partial Up-to | 压缩前缀,保留后缀 |
禁止工具调用的前置指令
CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.
- Do NOT use Read, Bash, Grep, Glob, Edit, Write, or ANY other tool.
- Tool calls will be REJECTED and will waste your only turn.九段式摘要结构
- Primary Request and Intent
- Key Technical Concepts
- Files and Code Sections
- Errors and fixes
- Problem Solving
- All user messages
- Pending Tasks
- Current Work
- Optional Next Step
七、Prompt的分层抽象
┌─────────────────────────────────────┐
│ Runtime Layer(每轮变化) │ ← CLAUDE.md, Git状态, <system-reminder>
├─────────────────────────────────────┤
│ Session Layer(会话级缓存) │ ← 环境信息, Memory, MCP指令
├─────────────────────────────────────┤
│ Static Layer(跨组织缓存) │ ← 身份, 规则, 任务指南, 语气风格
├─────────────────────────────────────┤
│ Tool Layer(Schema级缓存) │ ← 工具描述, 输入Schema
└─────────────────────────────────────┘八、核心洞察
Prompt即策略
Claude Code的很多"行为策略"实际上是通过Prompt约束实现的,而非硬编码逻辑:
|
