Skip to content

Claude code prompt构建规则


请求参数构建全流程

整个请求参数的构建分散在 3 个层级,最终在 claude.tsqueryModel() 中汇总为一个完整的 API 请求。


一、System Prompt 的构建(4 层管线)

System Prompt 的构建是最复杂的部分,经历了 4 层处理

第 1 层:原始内容生成 — constants/prompts.tsgetSystemPrompt()

claude-code-sourcemap/restored-src/src/constants/prompts.tsL444–L449
typescript
export async function getSystemPrompt(
  tools: Tools,
  model: string,
  additionalWorkingDirectories?: string[],
  mcpClients?: MCPServerConnection[],
): Promise<string[]> {

这个函数返回一个 string[] 数组,每个元素是 system prompt 的一个段落。其内部组装了两大区域:

静态内容(可跨组织缓存):

段落函数内容
IntrogetSimpleIntroSection()"You are an interactive agent..." + 安全风险指令
SystemgetSimpleSystemSection()工具权限模式、system-reminder 标签说明、Hook 机制
Doing TasksgetSimpleDoingTasksSection()软件工程任务指南、代码风格、安全要求
ActionsgetActionsSection()操作谨慎性指导(可逆/不可逆操作分级确认)
Using ToolsgetUsingYourToolsSection()各工具的使用指导(Bash/FileEdit/Agent/Search 等)
Tone & StylegetSimpleToneAndStyleSection()语气风格指导
Output EfficiencygetOutputEfficiencySection()输出效率要求

Boundary Marker(分割线):

claude-code-sourcemap/restored-src/src/constants/prompts.tsL572–L573
typescript
    // === BOUNDARY MARKER - DO NOT MOVE OR REMOVE ===
    ...(shouldUseGlobalCacheScope() ? [SYSTEM_PROMPT_DYNAMIC_BOUNDARY] : []),

这是关键的缓存优化标记 '__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__',将静态和动态内容分隔开。

动态内容(每次计算或缓存):

通过 systemPromptSection 注册表机制管理(见 systemPromptSections.ts):

claude-code-sourcemap/restored-src/src/constants/prompts.tsL491–L555
typescript
  const dynamicSections = [
    systemPromptSection('session_guidance', () =>
      getSessionSpecificGuidanceSection(enabledTools, skillToolCommands),
    ),
    systemPromptSection('memory', () => loadMemoryPrompt()),
    systemPromptSection('env_info_simple', () =>
      computeSimpleEnvInfo(model, additionalWorkingDirectories),
    ),
    systemPromptSection('language', () =>
      getLanguageSection(settings.language),
    ),
    systemPromptSection('output_style', () =>
      getOutputStyleSection(outputStyleConfig),
    ),
    DANGEROUS_uncachedSystemPromptSection(
      'mcp_instructions', () => getMcpInstructionsSection(mcpClients),
      'MCP servers connect/disconnect between turns',
    ),
    systemPromptSection('scratchpad', () => getScratchpadInstructions()),
    systemPromptSection('frc', () => getFunctionResultClearingSection(model)),
    // ...
  ]

其中 systemPromptSection()计算一次后缓存(直到 /clear/compact),而 DANGEROUS_uncachedSystemPromptSection()每轮重新计算(会打破 prompt cache):

claude-code-sourcemap/restored-src/src/constants/systemPromptSections.tsL20–L38
typescript
export function systemPromptSection(
  name: string,
  compute: ComputeFn,
): SystemPromptSection {
  return { name, compute, cacheBreak: false }
}

export function DANGEROUS_uncachedSystemPromptSection(
  name: string,
  compute: ComputeFn,
  _reason: string,
): SystemPromptSection {
  return { name, compute, cacheBreak: true }
}

第 2 层:Prompt 选择策略 — utils/systemPrompt.tsbuildEffectiveSystemPrompt()

这一层决定 用哪个 system prompt

claude-code-sourcemap/restored-src/src/utils/systemPrompt.tsL41–L123
typescript
export function buildEffectiveSystemPrompt({
  mainThreadAgentDefinition,
  toolUseContext,
  customSystemPrompt,
  defaultSystemPrompt,
  appendSystemPrompt,
  overrideSystemPrompt,
}: { ... }): SystemPrompt {

优先级从高到低:

1. overrideSystemPrompt → 完全替换(如 loop mode 设置的)
2. Coordinator 模式 prompt → 协调者专用
3. Agent 自定义 prompt → 如果有 mainThreadAgentDefinition
   - Proactive 模式:agent prompt 追加到 default 后面
   - 普通模式:agent prompt 替换 default
4. customSystemPrompt → 用户通过 --system-prompt 指定的
5. defaultSystemPrompt → 上面第 1 层生成的标准 prompt

最后 appendSystemPrompt 总是追加到末尾(除 override 模式外)。

第 3 层:上下文注入 — query.tsqueryLoop()

queryLoop() 中,system prompt 被附加上 系统上下文

claude-code-sourcemap/restored-src/src/query.tsL449–L451
typescript
    const fullSystemPrompt = asSystemPrompt(
      appendSystemContext(systemPrompt, systemContext),
    )

appendSystemContext()systemContext(如 git status、cache breaker)作为键值对追加到 prompt 数组末尾:

claude-code-sourcemap/restored-src/src/utils/api.tsL437–L447
typescript
export function appendSystemContext(
  systemPrompt: SystemPrompt,
  context: { [k: string]: string },
): string[] {
  return [
    ...systemPrompt,
    Object.entries(context)
      .map(([key, value]) => `${key}: ${value}`)
      .join('\n'),
  ].filter(Boolean)
}

systemContext 来自 context.tsgetSystemContext()(memoized),包含:

  • gitStatus:当前分支、状态、最近 5 次提交
  • cacheBreaker:调试用缓存打破注入

同时,用户上下文userContext)不注入 system prompt,而是作为消息前置:

claude-code-sourcemap/restored-src/src/utils/api.tsL449–L474
typescript
export function prependUserContext(
  messages: Message[],
  context: { [k: string]: string },
): Message[] {
  return [
    createUserMessage({
      content: `<system-reminder>\n...\n# claudeMd\n...\n# currentDate\n...\n</system-reminder>`,
      isMeta: true,
    }),
    ...messages,
  ]
}

userContext 来自 context.tsgetUserContext(),包含:

  • claudeMd:所有 CLAUDE.md 文件内容
  • currentDate:当前日期

第 4 层:最终封装 — claude.tsqueryModel()

queryModel() 内部,system prompt 被做最后的 包装和格式化

claude-code-sourcemap/restored-src/src/services/api/claude.tsL1358–L1369
typescript
  systemPrompt = asSystemPrompt(
    [
      getAttributionHeader(fingerprint),        // ① 归因头
      getCLISyspromptPrefix({                   // ② CLI 前缀
        isNonInteractive: options.isNonInteractiveSession,
        hasAppendSystemPrompt: options.hasAppendSystemPrompt,
      }),
      ...systemPrompt,                          // ③ 上面 3 层构建的完整内容
      ...(advisorModel ? [ADVISOR_TOOL_INSTRUCTIONS] : []),  // ④ Advisor 指令
      ...(injectChromeHere ? [CHROME_TOOL_SEARCH_INSTRUCTIONS] : []),  // ⑤ Chrome 工具搜索
    ].filter(Boolean),
  )

其中:

① 归因头 getAttributionHeader(fingerprint) — 来自 constants/system.ts

claude-code-sourcemap/restored-src/src/constants/system.tsL73–L95
typescript
export function getAttributionHeader(fingerprint: string): string {
  // ...
  const version = `${MACRO.VERSION}.${fingerprint}`
  const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? 'unknown'
  const header = `x-anthropic-billing-header: cc_version=${version}; cc_entrypoint=${entrypoint};${cch}${workloadPair}`
  return header
}

② CLI 前缀 getCLISyspromptPrefix() — 一句话身份声明:

claude-code-sourcemap/restored-src/src/constants/system.tsL30–L46
typescript
export function getCLISyspromptPrefix(options?: { ... }): CLISyspromptPrefix {
  // Vertex → "You are Claude Code, Anthropic's official CLI for Claude."
  // 非交互 + 有 append → "...running within the Claude Agent SDK."
  // 非交互 → "You are a Claude agent, built on Anthropic's Claude Agent SDK."
  // 默认 → "You are Claude Code, Anthropic's official CLI for Claude."
}

然后通过 buildSystemPromptBlocks() 将 string 数组转为 TextBlockParam[]

claude-code-sourcemap/restored-src/src/services/api/claude.tsL3213–L3237
typescript
export function buildSystemPromptBlocks(
  systemPrompt: SystemPrompt,
  enablePromptCaching: boolean,
  options?: { ... },
): TextBlockParam[] {
  return splitSysPromptPrefix(systemPrompt, { ... }).map(block => {
    return {
      type: 'text' as const,
      text: block.text,
      ...(enablePromptCaching && block.cacheScope !== null && {
        cache_control: getCacheControl({ scope: block.cacheScope, ... }),
      }),
    }
  })
}

splitSysPromptPrefix() 将 prompt 数组拆分为最多 4 个 block,按缓存策略分组:

Block内容Cache Scope
1归因头 x-anthropic-billing-header:...null(不缓存)
2CLI 前缀 "You are Claude Code..."null'org'
3Boundary 之前的静态内容'global'(跨组织共享缓存)
4Boundary 之后的动态内容null(不缓存)

二、其他请求参数的构建

全部在 claude.tsparamsFromContext() 函数(第 1538-1729 行)中完成:

Messages 构建

claude-code-sourcemap/restored-src/src/services/api/claude.tsL1701–L1709
typescript
      messages: addCacheBreakpoints(
        messagesForAPI,
        enablePromptCaching,
        options.querySource,
        useCachedMC,
        consumedCacheEdits,
        consumedPinnedEdits,
        options.skipCacheWrite,
      ),

消息处理链:

  1. normalizeMessagesForAPI() — 将内部消息格式规范化为 API MessageParam
  2. 工具搜索相关消息处理(strip/keep tool_reference
  3. ensureToolResultPairing() — 修复 tool_use/tool_result 配对
  4. stripExcessMediaItems() — 限制 ≤100 个媒体项
  5. addCacheBreakpoints() — 在合适位置添加 cache_control

Tools 构建

claude-code-sourcemap/restored-src/src/services/api/claude.tsL1235–L1246
typescript
  const toolSchemas = await Promise.all(
    filteredTools.map(tool =>
      toolToAPISchema(tool, {
        getToolPermissionContext: options.getToolPermissionContext,
        tools,
        agents: options.agents,
        allowedAgentTypes: options.allowedAgentTypes,
        model: options.model,
        deferLoading: willDefer(tool),
      }),
    ),
  )

工具列表 = 内建工具 schema + extraToolSchemas(如 advisor server tool)+ MCP 工具。支持 defer_loading 特性,延迟加载的工具不立即发送 schema。

Thinking 配置

claude-code-sourcemap/restored-src/src/services/api/claude.tsL1604–L1630
typescript
    if (hasThinking && modelSupportsThinking(options.model)) {
      if (
        !isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING) &&
        modelSupportsAdaptiveThinking(options.model)
      ) {
        thinking = { type: 'adaptive' }    // 自适应思考
      } else {
        let thinkingBudget = getMaxThinkingTokensForModel(options.model)
        // ...
        thinking = {
          budget_tokens: thinkingBudget,
          type: 'enabled',
        }
      }
    }

三种模式:adaptive(自适应)、enabled + budget_tokens(固定预算)、disabled(关闭)。

Betas 构建

Betas 是一组 feature flag 头,决定 API 端启用哪些实验特性。在多处累积:

claude-code-sourcemap/restored-src/src/services/api/claude.tsL1071–L1078
typescript
  const betas = getMergedBetas(options.model, { isAgenticQuery })
  if (isAdvisorEnabled()) {
    betas.push(ADVISOR_BETA_HEADER)
  }

后续还可能追加:FAST_MODE_BETA_HEADERAFK_MODE_BETA_HEADERCACHE_EDITING_BETA_HEADERCONTEXT_1M_BETA_HEADERSTRUCTURED_OUTPUTS_BETA_HEADERPROMPT_CACHING_SCOPE_BETA_HEADER 等。使用 "Sticky-on latch" 策略——一旦某个 beta 被首次发送,整个会话都会继续发送,避免缓存 key 变化。

最终请求对象

claude-code-sourcemap/restored-src/src/services/api/claude.tsL1699–L1729
typescript
    return {
      model: normalizeModelStringForAPI(options.model),
      messages: addCacheBreakpoints(...),
      system,                              // TextBlockParam[]
      tools: allTools,                     // BetaToolUnion[]
      tool_choice: options.toolChoice,
      ...(useBetas && { betas: betasParams }),
      metadata: getAPIMetadata(),          // { user_id: JSON字符串 }
      max_tokens: maxOutputTokens,
      thinking,                            // adaptive/enabled/disabled
      ...(temperature !== undefined && { temperature }),
      ...(contextManagement && { context_management }),
      ...extraBodyParams,
      ...(Object.keys(outputConfig).length > 0 && { output_config }),
      ...(speed !== undefined && { speed }),  // 'fast' for fast mode
    }

三、System Prompt 完整结构示意图

最终发送给 API 的 system 参数 (TextBlockParam[]):
┌────────────────────────────────────────────────────────────┐
│ Block 1 (cacheScope=null):                                  │
│   "x-anthropic-billing-header: cc_version=1.x.x.xxx;       │
│    cc_entrypoint=cli;"                                      │
├────────────────────────────────────────────────────────────┤
│ Block 2 (cacheScope=null):                                  │
│   "You are Claude Code, Anthropic's official CLI for Claude."│
├────────────────────────────────────────────────────────────┤
│ Block 3 (cacheScope='global'):   ← 静态内容                 │
│   ┌──── getSimpleIntroSection() ────┐                       │
│   │  身份说明 + 安全风险指令           │                       │
│   ├──── getSimpleSystemSection() ───┤                       │
│   │  工具权限、system-reminder 说明   │                       │
│   ├──── getSimpleDoingTasksSection() ┤                      │
│   │  软件工程任务指南、代码风格        │                       │
│   ├──── getActionsSection() ────────┤                       │
│   │  操作谨慎性分级指导               │                       │
│   ├──── getUsingYourToolsSection() ─┤                       │
│   │  各工具使用说明                   │                       │
│   ├──── getSimpleToneAndStyleSection()│                     │
│   │  语气风格                         │                      │
│   └──── getOutputEfficiencySection()─┘                      │
│   __SYSTEM_PROMPT_DYNAMIC_BOUNDARY__                        │
├────────────────────────────────────────────────────────────┤
│ Block 4 (cacheScope=null):   ← 动态内容                     │
│   ┌──── session_guidance ───────────┐                       │
│   │  会话特定指导                     │                       │
│   ├──── memory (CLAUDE.md recall) ──┤                       │
│   ├──── env_info_simple ────────────┤                       │
│   │  模型信息、CWD、OS、日期          │                       │
│   ├──── language ───────────────────┤                       │
│   │  语言偏好(如 "中文")              │                       │
│   ├──── output_style ──────────────┤                        │
│   ├──── mcp_instructions ──────────┤                        │
│   │  MCP 服务器指令                   │                       │
│   ├──── scratchpad ────────────────┤                        │
│   ├──── frc (function result clear)┤                        │
│   ├──── summarize_tool_results ────┤                        │
│   ├──── gitStatus (from systemContext)│                     │
│   └──── advisor / chrome (可选) ───┘                        │
└────────────────────────────────────────────────────────────┘

核心设计思想:静态内容尽量用 global scope 缓存(跨组织共享),动态内容不缓存或用 org scope,以最大限度利用 Anthropic API 的 prompt caching 机制,降低 token 消耗。