Claude Code 的 Prompt 工程:从静态分离到缓存优化的深度解析
Claude Code 的 Prompt 工程从静态分离到缓存优化的深度解析揭秘一个 AI 编程助手如何在每次请求都发送完整提示词的情况下依然保持惊人的响应速度和低廉的成本作为一款基于 Claude 模型的命令行编程助手Claude Code 在效率与成本控制上的表现令人印象深刻。它能够在每次 API 调用都发送完整系统提示词的前提下依然保持极快的响应速度和较低的使用成本。这背后的秘密是一套精心设计的 Prompt 工程体系。本文将深入解析 Claude Code 的提示词管理系统从架构设计到缓存策略带你看懂这套“既要又要”的精妙机制。一、核心设计思想静态与动态的分离Claude Code 最核心的设计理念是将系统提示词切分为静态段与动态段。在源码中二者通过一个特殊的标记SYSTEM_PROMPT_DYNAMIC_BOUNDARY明确分隔。 静态段不变的“宪法”静态段位于边界之上定义的是 AI 的核心身份、基本能力、安全准则和通用工作流。关键特征✅ 内容稳定不变✅ 对所有用户、所有会话保持一致✅ 可以被全局缓存具体包含的模块包括模块名作用身份介绍“你是 Claude CodeAnthropic 的官方 CLI…”系统能力说明具备读写文件、执行命令等能力任务执行指南“先读代码再修改”、“找到根本原因”等原则安全与操作规范强调操作的可逆性高风险操作需确认工具使用指南建议使用 FileRead 而非 cat 等技巧语气与风格“不使用 emoji”、保持专业 动态段灵活的“任务书”动态段位于边界之下包含与当前会话、项目和用户强相关的实时信息。关键特征 因会话而异 可能每轮变化 无法被全局缓存具体包括模块名加载时机说明会话特定指南会话级子代理合约等项目记忆CLAUDE.md会话级启动时加载逐层加载并拼接环境信息每轮更新当前目录、操作系统、日期时间等Git 状态每轮更新git status输出通过特殊机制加载MCP 指令会话级来自 MCP 服务器的指令语言设置会话级指定回复语言Token 预算按需大上下文模式下的 500k 指令二、动态段如何加载用户指令用户指令主要通过以下方式进入动态段1.CLAUDE.md— 最主要的用户入口加载机制会话启动时从根目录向下遍历到当前目录沿途加载所有CLAUDE.md、CLAUDE.local.md和.claude/CLAUDE.md内容处理原样拼接verbatim无摘要或截断层级覆盖子目录配置与父目录共同生效形成配置层叠2.settings.json— 用户/项目级配置配置文件中的设置内容也会作为用户指令的一部分加载到动态段。3. 启动参数 — 一次性指令通过--system-prompt或--append-system-prompt参数追加自定义指令。4. 输出风格Output Styles通过修改系统提示词改变回复风格自定义指令会被追加到系统提示词末尾。⚠️ 重要提示静态段Anthropic 官方指令拥有最高优先级。如果用户指令与官方指令冲突官方指令会优先生效。三、每次调用都完整发送但依然飞快是的Claude Code 每次 API 调用都会发送完整的系统提示词。然而它之所以仍能保持低延迟和低成本全靠提示词缓存Prompt Caching机制。缓存的工作原理基于“严格前缀匹配”原则API 会缓存请求的“前缀”部分只要新请求的开头与缓存内容匹配就能复用处理结果只有新增或变化的部分需要全新处理三层内容的缓存策略层级内容变更频率缓存策略System Prompt核心指令、工具定义很少变更✅ 高缓存命中静态部分全局缓存Project ContextCLAUDE.md、项目规则会话级✅ 会话内缓存Conversation用户消息、对话历史每轮都变❌ 不被缓存每次全新处理缓存命中率的实际效果这种设计可节省约80%的 Token 成本并显著降低响应延迟。你可以通过 API 返回头中的anthropic-organization-cache-creation或anthropic-organization-cache-read字段来确认缓存命中情况。四、DANGEROUS_uncachedSystemPromptSection一场“主动牺牲”的缓存博弈在 Claude Code 源码中有一个命名极为直白的函数DANGEROUS_uncachedSystemPromptSection。它的设计初衷“与其让一个易变的内容破坏掉整个巨大的缓存前缀不如主动将它标记为‘不缓存’从而牺牲小我保全大我。”典型应用场景MCP 指令内容随服务器连接状态变化Git 状态git status随文件改动频繁变化环境信息CWD、时间戳等每轮可能不同同级的其他部分与DANGEROUS_uncachedSystemPromptSection同级的是systemPromptSection()。二者的核心区别systemPromptSection()DANGEROUS_uncachedSystemPromptSection()缓存策略内容可缓存❌ 不缓存每轮重新计算变更频率稳定或低频变化⚡ 频繁变化典型用途会话级指令、项目记忆MCP 指令、Git 状态设计目的最大化缓存复用保护主缓存不被破坏 Git 状态会被加载吗会的。Git 状态正是通过DANGEROUS_uncachedSystemPromptSection来加载的。由于git status的输出会随每次文件修改、暂存或提交而变化将其放入可缓存部分会导致整个 Prompt Cache 频繁失效。因此通过“不缓存”机制加载是一种务实的工程选择。你也可以通过settings.json中的includeGitInstructions: false来控制是否包含 Git 状态指令。五、缓存失效陷阱开发者需要注意什么以下操作会破坏前缀匹配导致缓存失效操作影响切换模型不同模型的缓存相互独立修改effort级别每个级别独立缓存升级 Claude Code 版本系统提示词变化缓存全部失效工具集变化工具定义属于缓存前缀的一部分提示词中的动态时间戳时间戳每轮变化会破坏前缀匹配⚠️常见误解中途修改CLAUDE.md会立即生效。实际上出于缓存考量CLAUDE.md的变更只会在新会话中生效。六、完整组装顺序一切如何串联最终的系统提示词按以下顺序组装由getSystemPrompt()驱动[静态段] 1. Intro (身份介绍) 2. Output style (输出风格) 3. System rules (系统规则) 4. Doing tasks (任务执行指南) 5. Actions (安全规范) ─── __SYSTEM_PROMPT_DYNAMIC_BOUNDARY__ ─── [动态段] 6. Environment (环境信息) 7. Git status (Git 状态) 8. Project context (项目上下文) 9. CLAUDE.md (用户指令) 10. Runtime config (运行时配置)最终示例简化You are Claude Code, Anthropics official CLI... # Your capabilities... # Doing tasks - In general, do not propose changes... # Executing actions with care... __SYSTEM_PROMPT_DYNAMIC_BOUNDARY__ - Model: claude-3-opus-20240229 - CWD: /Users/me/my-project - Date: 2026-07-07 - Git status: On branch main, nothing to commit... - From CLAUDE.md: Always use ES modules...七、总结设计的哲学Claude Code 的 Prompt 系统体现了三种核心设计哲学静态与动态分离稳定的“骨架”与灵活的“血肉”各司其职缓存优先通过精细的缓存策略在功能完整性与运行效率之间取得平衡可观测性通过 API 头和源码设计让开发者能清晰理解系统行为这套体系不仅让 Claude Code 能在每次请求都发送完整上下文的前提下保持高性能也为其他 AI 应用的 Prompt 工程提供了优秀的参考范式。