Appearance
代理循环 — 概念
Agent Loop 执行流程
Agent Loop 是 Codex 的核心执行引擎,由 Codex struct(core/src/session/mod.rs)驱动,采用事件驱动的队列对架构:
代理循环的核心迭代过程:
- 提交操作:
Codex::submit(Op)通过tx_sub发送Submission到事件循环 - 上下文构建:
build_initial_context()拼装 system prompt、对话历史(ConversationHistory)、工具声明和 Context Management 信息 - 模型调用:
ModelClientSession::stream()向 LLM 后端发起流式请求,返回ResponseStream - 响应解析:从流中解析
ResponseEvent,识别文本输出和工具调用(function call) - 工具执行:若包含工具调用,通过 Sandbox 执行命令或通过 Apply Patch 应用代码修改
- 循环迭代:将工具执行结果追加到上下文,回到步骤 3,直到模型不再发起工具调用
- 事件通知:每个状态变化通过
rx_event发送Event通知消费者
Codex struct 的核心字段定义(core/src/session/mod.rs):
rust
pub struct Codex {
tx_sub: Sender<Submission>, // 操作提交通道
rx_event: Receiver<Event>, // 事件接收通道
agent_status: watch::Receiver<AgentStatus>, // 状态广播
session: Arc<Session>, // 会话状态(Arc 共享)
}Context Management 上下文管理
Context Management 负责在 LLM 的上下文窗口限制内高效管理输入:
上下文管理的关键机制:
- 对话历史:每个 turn 产生
TurnItem(文本输出、工具调用、工具结果),存储在ConversationHistory中 - 压缩策略:当历史超过上下文窗口时,调用
compact_conversation_history()使用 LLM 生成摘要替换早期历史 - 工具声明:包括内置工具(
shell、apply_patch)和 MCP 注册的外部工具,tool_is_model_visible()过滤模型可见的工具 - 系统提示:包含角色定义、安全规则、workspace 信息,通过
build_prompt_input()构建
Session 中的关键上下文管理方法:
| 方法 | 功能 | 调用时机 |
|---|---|---|
build_initial_context() | 组装完整上下文 | 每个 turn 开始时 |
record_conversation_items() | 记录对话条目 | 工具执行完成后 |
replace_compacted_history() | 替换压缩后的历史 | 压缩完成后 |
update_token_usage_info() | 更新 token 用量 | 每次模型响应后 |
recompute_token_usage() | 重算 token 总量 | 历史变更后 |
Rollout 执行策略
Rollout 控制代理循环的执行行为和终止条件:
Rollout 的核心控制维度:
- 迭代次数限制:通过
max_turns控制单个 turn 内的最多工具调用轮次,防止无限循环 - 执行策略(ExecPolicy):通过
Policy和Rule定义每个命令的权限等级(ExecPolicy:Allow/Prompt/Forbidden) - Rollout 记录器:
RolloutRecorder记录完整的执行轨迹,用于回放、调试和训练 - 中断机制:
steer_input()允许在 turn 执行过程中插入新的用户指令或中断当前操作
rust
// RolloutRecorder 记录参数
pub struct RolloutRecorderParams {
pub cursor: Cursor,
pub session_meta: SessionMeta,
// ... 路径和配置
}Apply Patch 补丁应用
Apply Patch 是 Codex 自定义的代码修改应用机制,解析 LLM 生成的 *** Begin Patch 格式补丁:
补丁格式解析流程(apply-patch/src/lib.rs):
- 触发:LLM 调用
apply_patch工具,参数为*** Begin Patch格式的补丁文本 - 解析:
StreamingPatchParser流式解析补丁文本,生成Hunk列表(每个 Hunk 描述一个文件的增/删/改操作) - 验证:
verify_apply_patch_args()校验补丁格式和目标文件状态 - 应用:将验证通过的 Hunk 原子应用到文件系统
rust
// 补丁解析核心类型
pub struct Hunk {
// 描述对单个文件的修改操作
}
pub fn parse_patch(patch: &str) -> Result<Vec<Hunk>, ParseError> {
// 解析 *** Begin Patch ... *** End Patch 格式
}Apply Patch 与标准 diff/patch 的区别:Codex 使用自定义格式而非 unified diff,因为 LLM 更容易生成这种格式,且支持更灵活的上下文匹配。
相关概念
- Agent Loop — 代理循环的迭代机制和状态机
- Context Management — 上下文窗口管理策略
- Rollout — 执行策略和轨迹记录
- Apply Patch — 代码补丁的解析与应用
- Backend Client — LLM 后端的连接管理