14. System Prompt

System Prompt 的装配流程

从一条空白到 ~12,000 tokens 的完整提示词,System Prompt 的构建是一个精密的装配过程。每次你启动 Claude Code 对话,以下步骤在幕后自动完成。

第一层:核心指令

getSystemPrompt()src/constants/prompts.ts 中生成。包含身份声明、行为准则、输出规范。这是不变的基础层。

第二层:工具提示词

50+ 个工具各自贡献自己的描述。每个工具都有一个 description() 异步方法,返回该工具的使用说明和参数格式。工具提示词是 System Prompt 中占比最大的部分。

第三层:Skill 指令

已注册的 Skills(斜杠命令)的名称和描述被注入。注意:只是名称和描述,不是完整内容——完整内容通过 ToolSearch 延迟加载。

第四层:CLAUDE.md 注入

从多个位置发现和合并 CLAUDE.md 文件:~/.claude/CLAUDE.md(全局)、CLAUDE.md(项目根)、.claude/CLAUDE.md(项目配置)。由 src/utils/claudemd.ts 负责加载。

第五层:记忆注入

MEMORY.md 和相关记忆文件由 src/memdir/memdir.ts:loadMemoryPrompt() 加载。限制:最多 200 行 / 25KB。

第六层:用户上下文

prependUserContext()src/utils/api.ts 中注入 Git 分支、最近提交、工作区状态。这让我了解你当前的开发状态。

装配与缓存

最终的 System Prompt 在 QueryEngine.ts:321 中拼接:

[customPrompt || defaultSystemPrompt, memoryMechanicsPrompt, appendSystemPrompt]

Anthropic API 的 cache_control 机制确保相同的 System Prompt 在多个用户之间共享缓存,大幅降低成本。

源码探秘

装配入口——src/utils/queryContext.ts 中的 fetchSystemPromptParts() 是整个装配过程的入口。它依次收集核心指令、工具描述、技能指令、CLAUDE.md 和记忆文件,最终返回一个字符串数组。

工具描述生成——每个工具实例都有 .description() 方法(定义在 src/tools.ts 的各工具类中),返回该工具的 JSON Schema 和使用说明。getAllBaseTools() 返回 50+ 个工具实例。

CLAUDE.md 发现——src/utils/claudemd.ts 从多个路径搜索 CLAUDE.md 文件:用户主目录、项目根目录、.claude/ 目录,并将所有找到的内容合并注入。

记忆加载——src/memdir/memdir.ts 中的 loadMemoryPrompt() 加载 MEMORY.md,截断到 200 行 / 25KB 上限。

缓存优化——在 API 请求中,System Prompt 的前缀标记了 cache_control,使得相同内容在不同用户间共享缓存,将 ~12K tokens 的处理成本降到几乎为零。

How the System Prompt Is Assembled

From a blank slate to a complete ~12,000 token prompt, the System Prompt construction is a precise assembly process. Every time you start a Claude Code conversation, the following steps happen automatically behind the scenes.

Layer 1: Core Instructions

Generated by getSystemPrompt() in src/constants/prompts.ts. Contains identity declaration, behavioral rules, and output format specifications. This is the immutable foundation layer.

Layer 2: Tool Prompts

50+ tools each contribute their own description. Every tool has an async description() method that returns usage instructions and parameter format. Tool prompts are the largest portion of the System Prompt.

Layer 3: Skill Instructions

Registered Skills (slash commands) have their names and descriptions injected. Note: only names and descriptions, not full content — full content is lazy-loaded via ToolSearch.

Layer 4: CLAUDE.md Injection

CLAUDE.md files are discovered and merged from multiple locations: ~/.claude/CLAUDE.md (global), CLAUDE.md (project root), .claude/CLAUDE.md (project config). Loaded by src/utils/claudemd.ts.

Layer 5: Memory Injection

MEMORY.md and related memory files are loaded by src/memdir/memdir.ts:loadMemoryPrompt(). Limit: maximum 200 lines / 25KB.

Layer 6: User Context

prependUserContext() in src/utils/api.ts injects Git branch, recent commits, and workspace status. This gives me awareness of your current development state.

Assembly and Caching

The final System Prompt is concatenated in QueryEngine.ts:321:

[customPrompt || defaultSystemPrompt, memoryMechanicsPrompt, appendSystemPrompt]

The Anthropic API’s cache_control mechanism ensures identical System Prompts share cache across users, dramatically reducing costs.

Source Code Deep Dive

Assembly entry pointfetchSystemPromptParts() in src/utils/queryContext.ts is the entry point for the entire assembly process. It sequentially collects core instructions, tool descriptions, skill instructions, CLAUDE.md, and memory files, returning a string array.

Tool description generation — Each tool instance has a .description() method (defined in the respective tool classes in src/tools.ts), returning the tool’s JSON Schema and usage instructions. getAllBaseTools() returns 50+ tool instances.

CLAUDE.md discoverysrc/utils/claudemd.ts searches for CLAUDE.md files across multiple paths: user home directory, project root, .claude/ directory, and merges all discovered contents for injection.

Memory loadingloadMemoryPrompt() in src/memdir/memdir.ts loads MEMORY.md, truncating to a 200-line / 25KB ceiling.

Cache optimization — In the API request, the System Prompt prefix is marked with cache_control, enabling identical content to share cache across users and reducing the ~12K token processing cost to nearly zero.

PreviousPromptNextContext