Skip to content

System prompt

源码版本rust-v0.145.0

codex descompone «lo que se le dice al modelo» en varios fragmentos de texto estático, plantillas y piezas de contexto que se ensamblan. El crate prompts aporta constantes y plantillas; core elige al arranque de la sesión las base instructions del modelo correspondiente y luego apila AGENTS.md, permissions instructions y fragmentos de personality para componer el system prompt final. Esta página explica esa cadena de ensamblado.

Responsabilidades

  1. Mantener las base instructions por defecto y las plantillas de personality de cada modelo, seleccionando y rellenando según el slug del modelo: codex-rs/protocol/src/openai_models.rs:478-500
  2. Exponer constantes de prompt relacionadas con herramientas/aprobación (apply_patch, compaction, review, permissions, realtime): codex-rs/prompts/src/lib.rs:1-27
  3. Componer las developer instructions a nivel de proyecto a partir de AGENTS.md y de las instrucciones de usuario: codex-rs/core/src/agents_md.rs:53-80
  4. Renderizar sandbox/approval policy como permissions instructions visibles para el modelo: codex-rs/prompts/src/permissions_instructions.rs:62-117
  5. Fijar base_instructions al arranque de la sesión y en los cambios de turn, dejándolo disponible para client/compact: codex-rs/core/src/session/mod.rs:615-631

Motivación de diseño

Las base instructions no pueden quedar hardcodeadas en core. Los modelos distintos (gpt-5.1, gpt-5.2-codex, etc.) tienen personalidades por defecto y descripciones de herramienta diferentes; además, un mismo modelo puede cambiar personality (friendly/pragmatic/none). Las plantillas se colocan en models-manager y core/templates/; ModelMessages.instructions_template reemplaza en runtime el placeholder , de modo que añadir un modelo solo exige añadir un markdown nuevo y core no se toca.

Otra motivación es el provenance (trazabilidad de origen). AGENTS.md puede venir de nivel de usuario, raíz de proyecto o subdirectorio; al apilar varias capas, LoadedAgentsMd conserva la fuente de cada entrada y, si es necesario, etiqueta la salida por environment, para que el modelo sepa qué instrucción viene de qué directorio. Las permission instructions funcionan igual: no son una cadena cualquiera, sino un ContextualUserFragment con marker <permissions instructions>, para que el context manager las identifique y separe al compactar o reproducir.

Archivos clave

El fallback de tres niveles para base_instructions: primero la config del usuario; si no, se recupera del conversation history; por último, el por defecto del modelo.

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

Reemplazo de plantilla de personality: si el modelo tiene instructions_template, siempre se reemplaza con la plantilla; si no, se retrocede a 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()
    }
}

Las permissions instructions no son una cadena cualquiera, sino un ContextualUserFragment con marker, para que el context manager las identifique y separe al compactar o reproducir.

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

Flujo de datos

Bordes y fallos

Resumen

El system prompt en codex no es una cadena hardcodeada, sino el fallback de tres niveles «por defecto del modelo → override de config → snapshot del historial» más fragmentos con marker como AGENTS.md, permissions instructions y personality. El crate prompts solo aporta constantes y plantillas; el ensamblaje ocurre todo en core, y el BaseInstructions que recibe el llamador ya es una cadena fijada. Entender esta cadena es clave para depurar tanto «por qué el modelo responde así» en Bucle principal del Agent como «qué fragmentos se pelan y se reinyectan al compactar» en Compaction.