系统提示词 (System Prompt)
codex 把"对模型说的话"拆成几段静态文本、模板和上下文片段拼装而成。prompts crate 提供常量与模板,core 在 session 启动时挑出对应模型的 base instructions,再叠加 AGENTS.md、permissions instructions、personality 片段,组成最终的 system prompt。本页讲这套组装链路。
职责
- 维护各模型默认 base instructions 与 personality 模板,按模型 slug 选择填充:
codex-rs/protocol/src/openai_models.rs:478-500 - 暴露工具/审批相关的常量提示(apply_patch、compaction、review、permissions、realtime):
codex-rs/prompts/src/lib.rs:1-27 - 从
AGENTS.md与用户指令拼出项目级 developer instructions:codex-rs/core/src/agents_md.rs:53-80 - 把 sandbox/approval policy 渲染成模型可见的 permissions instructions:
codex-rs/prompts/src/permissions_instructions.rs:62-117 - 在 session 启动与 turn 切换时落定
base_instructions,并供 client/compact 读取:codex-rs/core/src/session/mod.rs:615-631
设计动机
base instructions 不能写死在 core 里。不同模型(gpt-5.1、gpt-5.2-codex 等)有不同的默认人格与工具描述;同模型还可能切换 personality(friendly/pragmatic/none)。把模板放进 models-manager 与 core/templates/,由 ModelMessages.instructions_template 在运行时替换 占位符,让新增模型只需要新增一份 markdown,core 不用动。
另一层动机是 provenance(来源可追溯)。AGENTS.md 可能来自用户级、项目根、子目录;多层叠加时 LoadedAgentsMd 保留每条 entry 的来源,必要时按 environment 加标签输出,让模型知道哪段指令来自哪个目录。permission instructions 同理——它不是普通字符串,而是带 <permissions instructions> marker 的 ContextualUserFragment,便于上下文管理器在压缩或回放时识别和剥离。
关键文件
codex-rs/prompts/src/lib.rs:1-27—promptscrate 入口,re-exportAPPLY_PATCH_TOOL_INSTRUCTIONS、SUMMARIZATION_PROMPT、REVIEW_PROMPT、BACKEND_PROMPT等。codex-rs/prompts/src/permissions_instructions.rs:62-117—PermissionsInstructions把PermissionProfile+Policy渲染成模型可见的 developer 段。codex-rs/core/src/agents_md.rs:253-345—LoadedAgentsMd与legacy_text()实现项目指令的有序拼接。codex-rs/core/src/session/mod.rs:615-631— base_instructions 三级 fallback:config 覆盖 → 历史快照 → 模型默认。codex-rs/core/src/session/mod.rs:1224-1229—get_base_instructions在 turn 处理与 compaction 时被反复调用。codex-rs/protocol/src/openai_models.rs:478-500—get_model_instructions优先用模板替换 personality 占位符。codex-rs/models-manager/src/model_info.rs:17-22—BASE_INSTRUCTIONS常量,以及 personality section header/placeholder。codex-rs/core/src/client.rs:849-864— client 在构造请求时把 base_instructions 与 tools 拼到 messages。
base_instructions 三级 fallback——优先用户 config,其次从 conversation history 恢复,最后才用模型默认。
let base_instructions = config
.base_instructions
.clone()
.or_else(|| conversation_history.get_base_instructions().map(|s| s.text))
.unwrap_or_else(|| model_info.get_model_instructions(config.personality));personality 模板替换:如果模型有 instructions_template,总是用模板替换 ;没有模板就退回 base_instructions。
pub fn get_model_instructions(&self, personality: Option<Personality>) -> String {
if let Some(model_messages) = &self.model_messages
&& let Some(template) = &model_messages.instructions_template
{
let personality_message = model_messages
.get_personality_message(personality)
.unwrap_or_default();
template.replace(PERSONALITY_PLACEHOLDER, personality_message.as_str())
} else {
// ...
self.base_instructions.clone()
}
}permissions instructions 不是普通字符串,而是带 marker 的 ContextualUserFragment,便于上下文管理器在压缩或回放时识别和剥离。
impl ContextualUserFragment for PermissionsInstructions {
fn role(&self) -> &'static str { "developer" }
fn markers(&self) -> (&'static str, &'static str) { Self::type_markers() }
fn type_markers() -> (&'static str, &'static str) {
("<permissions instructions>", "</permissions instructions>")
}
fn body(&self) -> String { PermissionsInstructions::body(self) }
}数据流
边界与失败
- 模型没有
instructions_template但请求了 friendly/pragmatic personality 时,会退回到 base instructions 并打 trace 日志:codex-rs/protocol/src/openai_models.rs:488-498 config.personality == None时with_config_overrides会清空model_messages,避免 personality 段被错误注入:codex-rs/models-manager/src/model_info.rs:56-70PermissionsInstructions.from_permission_profile必须接收execpolicy::Policy引用——policy 缺失会让审批说明与实际拦截不一致:codex-rs/prompts/src/permissions_instructions.rs:89-117- turn 切换时若 base_instructions 与模型默认 personality 模板一致,会跳过重复注入 personality 消息:
codex-rs/core/src/session/mod.rs:3244-3257 - 多 environment 下
LoadedAgentsMd.text走environment_labeled_text分支而非legacy_text,避免不同 cwd 的指令被合并成不可区分的一坨:codex-rs/core/src/agents_md.rs:311-345
小结
系统提示词在 codex 里不是一段写死的字符串,而是 模型默认 → config 覆盖 → 历史快照 的三级 fallback 加上 AGENTS.md、permissions instructions、personality 等带 marker 的片段叠加。prompts crate 只放常量与模板,组装逻辑都在 core 里,调用方拿到的 BaseInstructions 已经是落定的字符串。理解这条链路对调试 Agent 主循环 里"模型为什么这么回答"和 压缩 (compaction) 里"哪些段被剥掉再重放"都很关键。