系統提示詞 (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) 裡「哪些段被剝掉再重放」都很關鍵。