Skip to content

System Prompt

源码版本rust-v0.145.0

codex éclate « ce qu'on dit au modèle » en plusieurs morceaux : texte statique, templates et fragments de contexte assemblés. Le crate prompts fournit constantes et templates ; au démarrage de la session, core choisit le base instructions du modèle, puis empile AGENTS.md, permissions instructions et fragments de personality pour composer le system prompt final. Cette page décrit cette chaîne d'assemblage.

Responsabilités

  1. Maintenir les base instructions par défaut et les templates de personality de chaque modèle, et sélectionner selon le slug du modèle : codex-rs/protocol/src/openai_models.rs:478-500
  2. Exposer les prompts constants liés aux outils/approval (apply_patch, compaction, review, permissions, realtime) : codex-rs/prompts/src/lib.rs:1-27
  3. Composer les developer instructions projet à partir d'AGENTS.md et des instructions utilisateur : codex-rs/core/src/agents_md.rs:53-80
  4. Rendre la sandbox/approval policy en permissions instructions visibles du modèle : codex-rs/prompts/src/permissions_instructions.rs:62-117
  5. Déterminer base_instructions au démarrage de session et au changement de turn, et l'exposer à client/compact : codex-rs/core/src/session/mod.rs:615-631

Motivations de conception

Les base instructions ne peuvent pas être codées en dur dans core. Différents modèles (gpt-5.1, gpt-5.2-codex, etc.) ont des personality par défaut et des descriptions d'outils différentes ; un même modèle peut aussi basculer de personality (friendly/pragmatic/none). Placer les templates dans models-manager et core/templates/, et faire remplacer à l'exécution le placeholder par ModelMessages.instructions_template, permet d'ajouter un modèle en ajoutant juste un markdown, sans toucher à core.

Une autre motivation est la provenance (traçabilité de la source). AGENTS.md peut venir d'un niveau utilisateur, de la racine projet, d'un sous-répertoire ; en cas d'empilement, LoadedAgentsMd conserve la source de chaque entry, et peut taguer par environment si besoin, pour que le modèle sache quel répertoire a émis quelle instruction. Même chose pour les permissions instructions — ce ne sont pas des chaînes ordinaires, mais des ContextualUserFragment avec marker <permissions instructions>, pour que le gestionnaire de contexte puisse les identifier et les détacher lors d'une compaction ou d'un replay.

Fichiers clés

Le fallback trois niveaux de base_instructions — config utilisateur d'abord, puis récupération depuis l'historique de conversation, puis défaut du modèle.

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));

Remplacement du template de personality : si le modèle a instructions_template, on remplace toujours via le template ; sans template, on retombe sur 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()
    }
}

Les permissions instructions ne sont pas une simple chaîne : c'est un ContextualUserFragment avec marker, pour que le gestionnaire de contexte puisse l'identifier et le détacher en cas de compaction ou de replay.

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

Flux de données

Limites et échecs

Récapitulatif

Le system prompt dans codex n'est pas une chaîne codée en dur, mais un fallback trois niveaux défaut modèle → override config → snapshot historique auquel s'ajoutent des fragments à marker — AGENTS.md, permissions instructions, personality. Le crate prompts ne contient que constantes et templates ; l'assemblage est dans core, et le BaseInstructions obtenu par l'appelant est déjà une chaîne fixée. Comprendre cette chaîne est clé pour déboguer dans Boucle principale de l'Agent « pourquoi le modèle répond comme ça » et dans Compaction du contexte « quels segments sont détachés puis rejoués ».