Skip to content

系統提示詞 (System Prompt)

源码版本rust-v0.145.0

codex 把「對模型說的話」拆成幾段靜態文字、模板和上下文片段拼裝而成。prompts crate 提供常數與模板,core 在 session 啟動時挑出對應模型的 base instructions,再疊加 AGENTS.mdpermissions instructions、personality 片段,組成最終的 system prompt。本頁講這套組裝鏈路。

職責

  1. 維護各模型預設 base instructions 與 personality 模板,按模型 slug 選擇填入:codex-rs/protocol/src/openai_models.rs:478-500
  2. 暴露工具/審批相關的常數提示(apply_patch、compaction、review、permissions、realtime):codex-rs/prompts/src/lib.rs:1-27
  3. AGENTS.md 與使用者指令拼出專案級 developer instructions:codex-rs/core/src/agents_md.rs:53-80
  4. 把 sandbox/approval policy 渲染成模型可見的 permissions instructions:codex-rs/prompts/src/permissions_instructions.rs:62-117
  5. 在 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-managercore/templates/,由 ModelMessages.instructions_template 在執行時替換 占位符,讓新增模型只需要新增一份 markdown,core 不用動。

另一層動機是 provenance(來源可追溯)。AGENTS.md 可能來自使用者級、專案根、子目錄;多層疊加時 LoadedAgentsMd 保留每條 entry 的來源,必要時按 environment 加標籤輸出,讓模型知道哪段指令來自哪個目錄。permission instructions 同理——它不是普通字串,而是帶 <permissions instructions> marker 的 ContextualUserFragment,便於上下文管理器在壓縮或回放時識別和剝離。

關鍵檔案

base_instructions 三級 fallback——優先使用者 config,其次從 conversation history 恢復,最後才用模型預設。

rust
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

rust
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,便於上下文管理器在壓縮或回放時識別和剝離。

rust
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) }
}

資料流

邊界與失敗

小結

系統提示詞在 codex 裡不是一段寫死的字串,而是 模型預設 → config 覆蓋 → 歷史快照 的三級 fallback 加上 AGENTS.mdpermissions instructionspersonality 等帶 marker 的片段疊加。prompts crate 只放常數與模板,組裝邏輯都在 core 裡,呼叫方拿到的 BaseInstructions 已經是落定的字串。理解這條鏈路對除錯 Agent 主迴圈 裡「模型為什麼這麼回答」和 壓縮 (compaction) 裡「哪些段被剝掉再重放」都很關鍵。