犀牛鸟 2026 研究笔记 estelledc.github.io

Codex Prompt 工程与上下文管理精读

调研时间:2026-06-22 源码 commit:98845e4 本地 CLI:codex-cli 0.125.0

一句话定位

Codex 的 prompt 系统是一个多层注入架构:base instructions(模型模板 + 人格)作为 system prompt,AGENTS.md / Skills / Plugins / Context 作为 user-role 消息注入 conversation history,最终形成每次 API 调用的完整 Prompt 结构体。上下文管理通过 auto-compaction 机制自动维护,在达到 token 阈值时触发摘要压缩。


日常类比

把 Codex 的 prompt 组装想象成一个演出的后台准备:

类比边界:真实演出中演员有自主判断,Codex 的 prompt 注入是确定性的——相同输入必然产生相同的 Prompt 结构。


Prompt 全景架构

flowchart TD
    subgraph Config["配置层级(低→高优先级)"]
        ADM[admin] --> SYS[system]
        SYS --> CLOUD[cloud]
        CLOUD --> USR[user]
        USR --> PROF[profile]
        PROF --> PROJ[project tree]
        PROJ --> REPO[repo]
        REPO --> CLI[runtime/CLI]
    end
    
    subgraph Assembly["Prompt 组装"]
        BI[Base Instructions<br/>模板 + 人格]
        AM[AGENTS.md<br/>项目指引]
        SK[Skills<br/>按需注入]
        PL[Plugins]
        CTX[Context Updates<br/>env/permissions/realtime]
        HIST[Conversation History]
        TOOLS[Tool Specs]
    end
    
    Config -->|base_instructions<br/>developer_instructions| BI
    Config -->|personality| BI
    
    BI --> PROMPT[Prompt 结构体]
    AM --> PROMPT
    SK --> PROMPT
    PL --> PROMPT
    CTX --> PROMPT
    HIST --> PROMPT
    TOOLS --> PROMPT
    
    PROMPT --> API[API 调用]

一、Base Instructions(系统指令)

模板与人格分离

Codex 将系统指令拆为两部分:

模板中包含一个占位符,运行时被人格内容替换:

// codex-rs/protocol/src/openai_models.rs:452
pub fn get_model_instructions(&self, personality: Option<Personality>) -> String {
    if let Some(template) = &model_messages.instructions_template {
        template.replace(PERSONALITY_PLACEHOLDER, personality_message)
    } else {
        self.base_instructions.clone()  // fallback to legacy prompt
    }
}

[源码] 旧版 fallback:codex-rs/core/gpt_5_codex_prompt.mdcodex-rs/core/prompt_with_apply_patch_instructions.md

模板内容概要(gpt-5.2 版)

模板覆盖以下内容:

Session 初始化

// SessionConfiguration 确定最终 base_instructions
base_instructions: config.base_instructions
    .clone()
    .unwrap_or_else(|| model_info.get_model_instructions(config.personality)),

[源码] config 中的 base_instructions 字段可直接覆盖模板——完全旁路模型默认指令。


二、AGENTS.md 加载机制

发现逻辑

核心实现:codex-rs/core/src/agents_md.rs

project_root (由 .git 等标记确定)
  ├── AGENTS.override.md   ← 最高优先级
  ├── AGENTS.md            ← 标准
  ├── subdir/
  │   ├── AGENTS.override.md
  │   └── AGENTS.md
  └── ... (遍历直到 cwd)

加载规则:

渲染为 Conversation History

// codex-rs/core/src/context/user_instructions.rs
impl ContextualUserFragment for UserInstructions {
    fn type_markers() -> (&'static str, &'static str) {
        ("# AGENTS.md instructions", "</INSTRUCTIONS>")
    }
    fn body(&self) -> String {
        format!("{directory}\n\n<INSTRUCTIONS>\n{}\n", self.text)
    }
}

最终在 history 中表现为一条 user-role 消息:

# AGENTS.md instructions
[directory path]

<INSTRUCTIONS>
[AGENTS.md 文件内容]
</INSTRUCTIONS>

[源码] AGENTS.md 不进 system prompt——而是作为 user 消息注入 conversation history。这意味着模型将其视为”用户提供的项目指引”而非”系统级身份”。


三、Skills 注入

触发与加载

sequenceDiagram
    participant U as User Input
    participant T as turn.rs
    participant SK as core-skills
    participant H as History
    
    U->>T: 消息包含 $skill-name
    T->>T: collect_explicit_skill_mentions()
    T->>SK: build_skill_injections()
    SK->>SK: 读取 SKILL.md 文件内容
    SK-->>T: Vec<SkillInjection>
    T->>T: 转换为 SkillInstructions
    T->>H: 作为 user-role 消息插入

渲染格式

// codex-rs/core-skills/src/skill_instructions.rs
impl ContextualUserFragment for SkillInstructions {
    fn type_markers() -> (&'static str, &'static str) {
        ("<skill>", "</skill>")
    }
    fn body(&self) -> String {
        format!("\n<name>{}</name>\n<path>{}</path>\n{}\n",
            self.name, self.path, self.contents)
    }
}

在 history 中的最终形态:

<skill>
<name>database</name>
<path>/project/.codex/skills/database/SKILL.md</path>
[SKILL.md 完整内容]
</skill>

[源码] Skills 按需注入:只有用户消息中显式提及 $skill-name 才加载对应 SKILL.md。不使用的 skill 不消耗 token。


四、Tools 注入

构建流程

// turn.rs:1211 → built_tools()
fn built_tools(&self) -> ToolRouter {
    // 收集所有工具规格:
    // - 内置工具:shell, apply_patch, plan
    // - MCP tools:从 MCP server 连接获取
    // - Dynamic tools:运行时注册的工具
    let router = ToolRouter::new(...);
    router
}

最终通过 router.model_visible_specs() 提取 Vec<ToolSpec> 放入 Prompt。

Tool 可见性控制

不是所有注册的工具都对模型可见——model_visible_specs() 过滤掉内部工具(如 escalation 相关的),只暴露模型应该调用的工具。


五、Config 层级体系

加载优先级(低到高)

admin → system → cloud → user → profile → project(tree) → repo → runtime/CLI

[源码] codex-rs/config/src/loader/mod.rs

安全门控

项目级 config 有信任级别门控机制:

影响 Prompt 的关键 Config 字段

字段 作用 注入位置
base_instructions 完全覆盖模型模板 system prompt
developer_instructions 开发者附加指令 developer role 消息
personality 选择 friendly/pragmatic 人格 模板占位符替换
project_doc_max_bytes AGENTS.md 最大读取字节数 影响 AGENTS.md 截断
auto_compact_token_limit 压缩触发阈值 影响 compaction 时机

六、Context Window 管理

Token 估计

// codex-rs/core/src/context_manager/history.rs
fn estimate_token_count_with_base_instructions() -> usize {
    base_instructions_tokens + history_items.iter().map(|i| i.token_count()).sum()
}

Auto-Compaction 触发

两种评估 scope:

默认阈值:context_window 的 90%。

Compaction 时机

flowchart TD
    PT[Pre-turn check] -->|token > 90%| COMPACT
    MT[Mid-turn check<br/>sampling 返回后] -->|token_limit_reached<br/>+ needs_follow_up| COMPACT
    DS[Model downshift] -->|切换到小 context 模型| COMPACT
    
    COMPACT --> LOCAL[Local summarization]
    COMPACT --> REMOTE[Remote compaction V1]
    COMPACT --> REMOTEV2[Remote compaction V2]

Compaction Prompt

You are performing a CONTEXT CHECKPOINT COMPACTION. Create a handoff summary
for another LLM that will resume the task.

Include:
- Current progress and key decisions made
- Important context, constraints, or user preferences
- What remains to be done (clear next steps)
- Any critical data, examples, or references needed to continue

[源码] codex-rs/prompts/templates/compact/prompt.md

压缩后的 History 结构

compaction 完成后,原始 history 被替换为一条 compaction summary 消息 + 后续新消息。AGENTS.md 和 Skills 注入会在新 turn 重新加载(不依赖 compaction 保留)。


完整 Per-Turn 组装流程

Session Init
├── Config loading (admin→...→runtime)
├── Model info → get_model_instructions(personality) → base_instructions
├── AGENTS.md discovered → stored in SessionConfiguration
└── SessionConfiguration finalized

Per-Turn Execution (run_turn)
├── 1. Pre-sampling compaction (if token_limit reached)
├── 2. record_context_updates_and_set_reference_context_item()
│     └── Diffs: environment, permissions, personality, collab mode
├── 3. build_skills_and_plugins()
│     ├── Collect $skill mentions from user input
│     ├── Read SKILL.md → SkillInjection → SkillInstructions
│     ├── Read plugins → PluginInjection
│     └── Insert as user-role messages into history
├── 4. Sampling loop:
│     ├── Clone history → input items
│     ├── built_tools() → ToolRouter → model_visible_specs()
│     ├── get_base_instructions() → BaseInstructions
│     ├── build_prompt(input, tools, base_instructions) → Prompt
│     ├── Send to API
│     ├── Process response
│     └── If token_limit_reached && needs_follow_up → compact → loop
└── Turn complete: model returns assistant-only message

Prompt 结构体

pub struct Prompt {
    pub input: Vec<ResponseItem>,          // conversation history
    pub tools: Vec<ToolSpec>,              // 模型可见工具定义
    pub parallel_tool_calls: bool,
    pub base_instructions: BaseInstructions, // system prompt
    pub output_schema: Option<Value>,
}

input 中消息的时序排列:

  1. AGENTS.md instructions(user role,<INSTRUCTIONS> 标签)
  2. Environment context updates(user role)
  3. Permissions instructions(developer role)
  4. Skill injections(user role,<skill> 标签)
  5. Plugin injections
  6. User messages + tool call/result pairs
  7. Compaction summary(如有压缩历史)

与 Claude Code 的差异(待 Agent A 核对)

维度 Codex Claude Code(推测)
项目指引文件 AGENTS.md / AGENTS.override.md CLAUDE.md
注入角色 user role 消息 推测为 system prompt 或 user role
层级遍历 project root → cwd 逐级合并 推测有类似层级
Skill 触发 显式 $skill-name 提及 推测基于自然语言匹配
人格系统 模板 + 可选人格文件(friendly/pragmatic) 无公开人格切换机制
上下文压缩 Auto-compaction(local/remote/V2),90% 阈值触发 推测有类似机制,细节未知
Config 安全 项目级 config 有信任门控 + denylist 推测无分级信任机制
Tool 可见性 model_visible_specs 过滤内部工具 推测类似(部分工具对用户不可见)
Override 机制 AGENTS.override.md 最高优先级 无对应公开机制

关键差异洞察:


设计洞察

为什么 AGENTS.md 是 user role 而非 system role

  1. 安全性:system prompt 被模型视为最高权限;将项目指引降为 user role 减少了通过恶意 AGENTS.md 越狱的风险
  2. 可覆盖性:system prompt(base_instructions)由平台控制,项目级指引不应覆盖平台策略
  3. 清晰分层:system = 身份 + 能力,user = 上下文 + 指引

Skills 按需加载的优势

Auto-Compaction 的 trade-off


局限性


证据等级汇总

结论 来源
AGENTS.md 作为 user role 注入,非 system prompt [源码] core/src/context/user_instructions.rs
模板 + 人格文件分离设计 [源码] protocol/src/openai_models.rs:452
Skills 通过 $skill-name 显式触发 [源码] core-skills/src/injection.rs
Config 8 层优先级 admin→runtime [源码] config/src/loader/mod.rs
Auto-compaction 90% 阈值 [源码] core/src/context_manager/history.rs
Compaction prompt 使用 handoff summary 格式 [源码] prompts/templates/compact/prompt.md
项目 config 有信任门控 + denylist [源码] config/src/loader/mod.rs
ToolRouter 过滤内部工具 [源码] turn.rs:1211 built_tools()