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 の三段フォールバック——ユーザ 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 上書き → 履歴 snapshot の三段フォールバックに AGENTS.mdpermissions instructionspersonality といった marker 付き断片を重ねたものだ。prompts crate は定数とテンプレートだけを置き、組み立てロジックは全て core にあり、呼び出し側が受け取る BaseInstructions はすでに確定した文字列だ。このリンクの理解は Agent メインループ で「モデルがなぜそう答えたか」をデバッグするのと、圧縮 (compaction) で「どの段が剥がされて再再生されるか」を追うのに重要だ。