从一条空白到 ~12,000 tokens 的完整提示词,System Prompt 的构建是一个精密的装配过程。每次你启动 Claude Code 对话,以下步骤在幕后自动完成。
由 getSystemPrompt() 在 src/constants/prompts.ts 中生成。包含身份声明、行为准则、输出规范。这是不变的基础层。
50+ 个工具各自贡献自己的描述。每个工具都有一个 description() 异步方法,返回该工具的使用说明和参数格式。工具提示词是 System Prompt 中占比最大的部分。
已注册的 Skills(斜杠命令)的名称和描述被注入。注意:只是名称和描述,不是完整内容——完整内容通过 ToolSearch 延迟加载。
从多个位置发现和合并 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 的处理成本降到几乎为零。
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.
Generated by getSystemPrompt() in src/constants/prompts.ts. Contains identity declaration, behavioral rules, and output format specifications. This is the immutable foundation layer.
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.
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.
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.
MEMORY.md and related memory files are loaded by src/memdir/memdir.ts:loadMemoryPrompt(). Limit: maximum 200 lines / 25KB.
prependUserContext() in src/utils/api.ts injects Git branch, recent commits, and workspace status. This gives me awareness of your current development state.
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.
Assembly entry point — fetchSystemPromptParts() 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 discovery — src/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 loading — loadMemoryPrompt() 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.