System Prompt 组装机制
CC 用「静态可缓存前缀 + 动态分区」拼装系统提示词并提供替换/追加旗标;Codex 把 base instructions 按模型内嵌、其余全部下沉为 developer/user 消息
System Prompt 组装机制
结论
两家的系统提示词是两种截然不同的工程形态。Claude Code 在运行时动态拼装一个字符串数组:静态段(身份、安全、任务规范、工具规范、语气)放在 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 标记之前以最大化 prompt cache 命中,动态段(session 引导、memory、env 信息、output style、MCP instructions)通过 section registry 在标记之后逐段解析;CLAUDE.md 内容不在系统提示词里,而是作为 user message 注入。Codex 则把 base instructions 按模型预先写死——每个模型在 models.json 里自带一份完整 instructions(gpt-5.5 约 21KB),通过 Responses API 的 instructions 字段发送;权限、协作模式、技能、AGENTS.md、环境信息等全部下沉为对话开头的 developer / "contextual user" 消息(build_initial_context)。对 harness 而言:CC 提供完整的替换/追加 CLI 旗标(--system-prompt[-file]、--append-system-prompt[-file]),Codex 提供 config 级覆盖(instructions、model_instructions_file、developer_instructions)和 codex debug prompt-input 检视命令。
研究问题
- 两个 runtime 的系统提示词由哪些段构成、在哪个文件组装?
- output style、env 信息、模型适配(model adaptations)如何注入?
- harness 如何检视(inspect)和覆盖(override)有效系统提示词?
各 Agent 设计与实现
Claude Code
版本:泄露重构源码
src_2026-03-31(落后线上约 2 个月),以下为架构性描述 + 必要短引用。[一手源码]
入口与三段式组装。 QueryEngine.ts:284-325 调用 fetchSystemPromptParts()(utils/queryContext.ts:44-74)并行取三块:defaultSystemPrompt(getSystemPrompt() 产出的字符串数组)、userContext(CLAUDE.md + 当前日期)、systemContext(git status 快照)。最终拼装逻辑(QueryEngine.ts:321-325):
const systemPrompt = asSystemPrompt([
...(customPrompt !== undefined ? [customPrompt] : defaultSystemPrompt),
...(memoryMechanicsPrompt ? [memoryMechanicsPrompt] : []),
...(appendSystemPrompt ? [appendSystemPrompt] : []),
])即:自定义提示词整体替换默认值(且跳过 getSystemContext,见 queryContext.ts:34-37 注释),appendSystemPrompt 永远追加在尾部。注意 getUserContext()(CLAUDE.md)在 customPrompt 下仍然加载——它走 user message 通道,不属于系统提示词(CC 官方文档明确:"CLAUDE.md content is delivered as a user message after the system prompt",claude-code-docs/docs/memory.md:398 [一手文档])。
段结构与缓存边界。 constants/prompts.ts:444-577 的 getSystemPrompt() 返回的数组分两半:
- 静态可缓存段(boundary 之前):intro(
getSimpleIntroSection,prompts.ts:175)、# System(prompts.ts:186)、# Doing tasks(prompts.ts:199)、# Executing actions with care(prompts.ts:255)、# Using your tools(prompts.ts:269)、# Tone and style(prompts.ts:430)、output efficiency(prompts.ts:403)。 SYSTEM_PROMPT_DYNAMIC_BOUNDARY(prompts.ts:114-115):注释警告该标记与splitSysPromptPrefix/buildSystemPromptBlocks的缓存逻辑联动,boundary 之前的内容可用scope: 'global'跨组织缓存。- 动态段(registry 管理,prompts.ts:491-555):
session_guidance、memory(auto memory 指令)、ant_model_override、env_info_simple、language、output_style、mcp_instructions(标记为DANGEROUS_uncached,因 MCP server 中途连接会击穿缓存)、scratchpad、frc、token_budget等。
Output style 注入有三个作用点:① intro 句式切换——有 output style 时身份句变为 "helps users according to your Output Style below"(prompts.ts:180);② # Output Style: <name> + style prompt 作为动态段注入(prompts.ts:151-158);③ keepCodingInstructions !== true 时整段丢弃 # Doing tasks(prompts.ts:564-567)。Style 来源于 settings outputStyle 字段 + 项目/用户 .claude/output-styles/*.md(outputStyles/loadOutputStylesDir.ts:14-25)。
Env 信息由 computeSimpleEnvInfo/computeEnvInfo(prompts.ts:606-679)产出 <env> 块:cwd、是否 git repo、平台、shell、OS 版本,外加 "You are powered by the model named ..." 与知识截止日期。值得注意的是 undercover 模式(内部未发布模型)会整体抹掉模型名(prompts.ts:620-628)。
模型适配散布在源码各处,统一用 @[MODEL LAUNCH] 注释标记:如 FRONTIER_MODEL_NAME = 'Claude Opus 4.6'(prompts.ts:118)、针对新模型过度写注释的反制条款(prompts.ts:204-213)、false-claims 缓解段(prompts.ts:237-241)、getFunctionResultClearingSection(model) 按模型开关。另有逃生门:CLAUDE_CODE_SIMPLE=1 时系统提示词缩成一句话 + cwd + 日期(prompts.ts:450-454)。
Codex CLI
版本:
codex-rs @ b89ce9a(2026-06-06)。[一手源码]
Base instructions 按模型内嵌、随 instructions 字段发送。 protocol/src/models.rs:919-933 定义 BaseInstructions,doc comment 直说 "Corresponds to the instructions field in the ResponsesAPI";默认值来自 include_str!("prompts/base_instructions/default.md")。实际生产路径走 models-manager/models.json——目前 6 个模型条目(gpt-5.5 / gpt-5.4 / gpt-5.4-mini / gpt-5.3-codex / gpt-5.2 / codex-auto-review),每个条目内嵌一份完整 base_instructions(12KB–21KB),并可附带 model_messages.instructions_template(含 {{ personality }} 占位符,protocol/src/openai_models.rs:449-470 的 get_model_instructions() 负责替换)。仓库根的 core/gpt_5_2_prompt.md、core/gpt-5.1-codex-max_prompt.md 等文件是历史版本提示词的留档;运行时兜底是 models-manager/src/model_info.rs:16 的 include_str!("../prompt.md")。
其余上下文全部下沉为消息,在 core/src/session/mod.rs:2746-2972 的 build_initial_context() 组装:
- developer 消息(聚合为一条):模型切换提示、
PermissionsInstructions(沙箱/审批策略渲染)、developer_instructions、协作模式、personality、Apps/connectors、skills 列表、plugins 列表(mod.rs:2777-2905)。 - "contextual user" 消息:AGENTS.md(
UserInstructionsfragment,core/src/context/user_instructions.rs)+<environment_context>(cwd/shell/日期/时区/网络/文件系统权限,core/src/context/environment_context.rs:525-580)。
每类 fragment 有固定的开闭标记(如 # AGENTS.md instructions for / </INSTRUCTIONS>),core/src/context/contextual_user_message.rs:47-66 维护 registry 用于在历史中识别这些系统注入消息。
覆盖与开关(core/config.schema.json [一手源码]):
instructions——"System instructions",整体替换 base instructions;model_instructions_file——文件级覆盖,schema 描述明言 "Users are STRONGLY DISCOURAGED from using this field, as deviating from the instructions sanctioned by Codex will likely degrade model performance";developer_instructions——以 developer role 注入(不动 base instructions);include_permissions_instructions/include_apps_instructions/include_collaboration_mode_instructions/include_environment_context——逐段开关(core/src/config/mod.rs:3250-3259)。
优先级链:编程入参 base_instructions > model_instructions_file 文件内容 > config instructions(core/src/config/mod.rs:3239-3248)。
注:任务提示中提到的 experimental_instructions_file 在本快照中不存在,对应能力已更名为 model_instructions_file(config/src/config_toml.rs:226)。[一手源码]
差异矩阵
| 维度 | Claude Code | Codex CLI |
|---|---|---|
| base prompt 形态 | 运行时拼装的字符串数组,几十个 section 函数 | 每模型一份静态 markdown,内嵌于 models.json |
| 发送通道 | Anthropic API system blocks(带 cache_control 分区) | Responses API instructions 字段 |
| 项目指令位置 | CLAUDE.md 走 user message(不在 system prompt) | AGENTS.md 走 contextual user message(不在 instructions) |
| 权限/环境信息 | system prompt 动态段(env_info_simple 等) | developer / contextual user 消息(build_initial_context) |
| output style | 有,三处注入点(intro/段/裁剪 Doing tasks) | 无对等物;近似物是 personality(模板占位符) |
| 模型适配 | 同一份 prompt 内 @[MODEL LAUNCH] 条件分支 | 每模型独立 prompt,互不污染 |
| 整体替换 | --system-prompt[-file]、SDK customSystemPrompt | config instructions / model_instructions_file(强烈不建议) |
| 追加 | --append-system-prompt[-file] | developer_instructions(developer role,非追加到 instructions) |
| 缓存优化 | SYSTEM_PROMPT_DYNAMIC_BOUNDARY 静态/动态分区;--exclude-dynamic-system-prompt-sections | instructions 天然静态;动态内容本来就在消息流里 |
| 官方检视手段 | --dump-system-prompt(feature-gated,仅内部构建,entrypoints/cli.tsx:50-71) | codex debug prompt-input(公开子命令,cli/src/main.rs:228-229) |
最小复现
# Codex:导出某次会话的模型可见 input 列表(developer + contextual user 消息)
codex debug prompt-input "hello" | head -100
# 输出为 JSON 数组,可看到 permissions instructions、AGENTS.md、<environment_context> 各条目
# CC:验证 append 旗标生效(外部构建没有 --dump-system-prompt,只能行为验证)
claude -p --append-system-prompt "Reply with exactly: MARKER_42" "say hi"
# 输出包含 MARKER_42 即追加成功
# CC:最小系统提示词模式
CLAUDE_CODE_SIMPLE=1 claude -p "what is your system prompt about?"Harness 接入建议(Yoda 实践)
Yoda 的「system prompt 检测/校验/调试」面板可以这样落地:
- 检测注入面:CC 侧扫描
~/.claude/settings.json的outputStyle、language、各级.claude/output-styles/;Codex 侧扫描~/.codex/config.toml的instructions/model_instructions_file/developer_instructions/include_*_instructions五个键。任何一个被设置都应在 UI 上标黄——它们都会改写模型行为且用户经常忘记。 - 预览有效 prompt:Codex 直接调
codex debug prompt-input(零成本、不发请求)渲染 developer/user 注入;CC 外部构建无 dump 命令,退而求其次用claude -p --output-format stream-json的首条systeminit 事件拿 model/tools/cwd 元数据,再按本章的段结构静态推算([推断]:完整字节级 preview 在外部构建不可得)。 - 覆盖策略:给用户暴露「追加」而非「替换」。CC 用
--append-system-prompt-file(文件比内联好管理、可 diff);Codex 不要碰model_instructions_file(官方明示会降智),用developer_instructions达到等效目的。 - 缓存敏感校验:CC 的追加内容会进入缓存前缀,Yoda 若按任务动态变更 append 文本,等于每任务击穿一次 prompt cache——应把易变内容放进首条 user message 而非 append。多用户批跑场景加
--exclude-dynamic-system-prompt-sections。 - lint 规则:append 文件 > 2KB 告警;与 CLAUDE.md 内容重复度高(如同一条规则两处写)告警——CC 中两者最终都进上下文,重复纯属浪费。
失效条件
- CC 改版
getSystemPrompt段结构或 boundary 机制(重构源码已落后线上约 2 个月,段名/feature gate 随时会变) - Codex
models.json改为纯远端下发(manager 已有 fetch+cache 机制),本地内嵌副本与线上不一致 - Codex 给
model_instructions_file改名或移除(experimental_instructions_file→model_instructions_file已发生过一次) - CC
--dump-system-prompt对外开放(届时 Yoda 预览方案应切换)
参考资料
- CC 重构源码:
claude-code-source-code/src_2026-03-31/constants/prompts.ts、QueryEngine.ts、utils/queryContext.ts、context.ts - CC 文档:
claude-code-docs/docs/cli-reference.md(System prompt flags 一节)、docs/memory.md - Codex 源码:
codex/codex-rs/protocol/src/models.rs、protocol/src/openai_models.rs、models-manager/、core/src/session/mod.rs、core/src/config/mod.rs、core/config.schema.json、cli/src/main.rs - Codex 文档:
codex/codex-rs/config.md、codex/docs/agents_md.md