news 2026/10/19 2:13:27

从 OpenAI Codex 源码看 Agent 工程化:7 个值得借鉴的设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从 OpenAI Codex 源码看 Agent 工程化:7 个值得借鉴的设计

一、为什么要研究 Codex 源码?

最近在研究 OpenAI 开源的 Codex 项目:

GitHub:https://github.com/openai/codex

Codex 不只是一个 AI 代码生成工具。它更像是一个能够理解代码、操作文件、执行命令、运行测试,并根据执行结果继续调整的代码 Agent。

如果只从产品角度看,我们看到的是:告诉 AI 一个开发任务,它就能帮我们修改代码。

但从工程角度看,真正值得研究的是另一个问题:

当 Agent 需要持续工作、调用工具、处理异常、管理上下文时,系统应该如何组织这些能力?

结合 Codex 的 Rust 源码,我重点关注了以下模块:

  • codex-rs/core/src/session/turn.rs:核心回合执行。
  • codex-rs/core/src/tasks/regular.rs:常规任务调度。
  • codex-rs/core/src/agents_md.rs:项目指令发现与加载。
  • codex-rs/core/src/tools/mod.rs:工具系统组织。
  • codex-rs/core/src/tools/sandboxing.rs:沙箱与执行限制。
  • codex-rs/core/src/tools/handlers/multi_agents.rs:多 Agent 协作。
  • codex-rs/app-server/:客户端与核心能力之间的服务接入层。

源码会持续演进,以上路径以仓库当前版本为准。本文重点讨论这些设计背后的工程思想,不把 Codex 的具体实现直接等同于所有 Agent 都必须采用的标准架构。

二、启示一:Agent 不只是一次模型调用,而是一个持续运行的控制循环

很多初级 Agent 项目,结构大致如下:

response=llm.invoke(user_input)ifresponse.tool_calls:result=execute_tools(response.tool_calls)response=llm.invoke(result)

这个实现可以验证工具调用的基本原理,但距离工程化还有一段距离。

真实任务通常需要经历多个步骤:

  1. 理解用户目标。
  2. 检查当前环境。
  3. 选择下一步行动。
  4. 调用工具执行。
  5. 观察执行结果。
  6. 根据结果决定继续、修复还是结束。

例如,让 Agent 修复一个 FastAPI 项目的测试失败问题。

它可能先读取测试报告,再检查相关代码,修改实现,运行测试,然后根据新的错误信息继续调整。

这不是一次模型调用就能完成的事情,而是一个持续迭代的过程。

Codex 的run_turn正是理解这一机制的重要入口。它负责协调模型采样、工具反馈、上下文状态和回合结束条件;RegularTask::run则承担更外层的任务调度职责。

这里有一个值得注意的区别:

  • Task:管理一项工作及其生命周期。
  • Turn:管理当前一轮模型交互与工具执行。
  • Tool Call:执行某个具体操作。

它们不是同一个概念。

对我们开发 Agent 的启示

不要把所有逻辑都塞进一个Agent.run()方法。

至少应该在设计上区分任务管理、回合调度和工具执行。

一个简化的控制循环可以这样表达:

whilenottask.is_finished():context=prepare_context(task)response=call_model(context)ifresponse.has_tool_calls:results=execute_tools(response.tool_calls)record_results(task,results)continueifshould_stop(response,task):break

这只是用于说明控制流的伪代码,并不是 Codex 源码。

真正的实现还需要补充取消机制、错误分类、上下文压缩、权限检查和待处理输入管理。

核心观点:Agent 的工程价值,不只在于模型能够思考,更在于系统能够可靠地组织多轮思考与实际执行。

三、启示二:任务调度与 Agent Loop 应该分层

研究 Codex 源码时,一个容易忽略的细节是:外层任务循环与内层回合循环并不是一回事。

RegularTask::run调用run_turn,并在回合结束后检查终止状态和待处理输入。

run_turn则负责当前回合内部的模型采样、工具反馈和继续执行条件。

为什么要这样设计?

假设一个 Agent 正在生成企业标书。

当前回合中,它可能需要检索历史项目资料、提取技术参数、生成章节草稿并检查引用证据。

与此同时,用户可能追加要求:

“把项目实施周期调整为六个月,并重新检查相关章节。”

如果任务管理和模型回合完全混在一起,系统很容易出现输入覆盖、状态混乱或者重复执行的问题。

把两者分开,可以更清晰地管理:

  • 当前任务是否结束。
  • 当前回合是否结束。
  • 是否存在新的待处理输入。
  • 是否出现终止性错误。
  • 是否需要重新准备上下文。

对我们开发 Agent 的启示

对于复杂业务 Agent,可以建立三个层次:

层次主要职责
Task Manager管理任务生命周期、取消和待处理输入
Agent Runtime管理模型交互、工具调用和回合循环
Tool Executor执行具体工具并返回结构化结果

对于短小的原型,可以暂时合并部分模块;但随着功能增加,应该避免让任务生命周期、模型推理和工具执行互相纠缠。

四、启示三:上下文工程不等于 RAG

我们经常把企业 Agent 的上下文问题理解为 RAG 问题。

例如:

用户提出问题 → 向量检索 → 召回文档 → 拼接 Prompt → 调用模型。

这只是上下文管理的一部分。

研究 Codex 的turn.rs,可以看到它还需要处理会话历史、模型输入格式、上下文窗口、采样前压缩以及采样后的 token 状态。

与此同时,agents_md.rs负责项目指令的发现与加载,让 Agent 能够遵循与当前工作目录相关的开发规则。

这意味着,Agent 的上下文至少包括以下几类:

上下文类型示例解决的问题
任务上下文用户目标、验收条件当前要完成什么
历史上下文之前的推理和工具结果已经做了什么
项目上下文项目规则、目录结构、接口约束应该遵循什么
外部知识企业知识库、合同、业务文档可以依据什么事实
执行上下文当前配置、工作目录、权限状态当前允许如何执行

这些信息并不适合全部采用同一种检索方式。

例如,长期有效的项目开发规则可以通过AGENTS.md管理;大量企业文档适合使用 RAG;当前任务状态则更适合由任务对象显式维护。

对我们开发 Agent 的启示

不要试图通过不断增加向量数据库和 Prompt 长度解决所有上下文问题。

更好的思路是:

先区分上下文的来源、生命周期和用途,再决定如何存储、检索、注入和更新。

这对于 RAG、文档处理和多步骤业务 Agent 都很重要。

五、启示四:工具调用必须有独立的执行与权限边界

在很多 Agent Demo 中,工具调用只是一个函数映射:

tools={"search_documents":search_documents,"calculate":calculate,"update_record":update_record,}

模型生成工具调用,程序直接执行。

这种方式适合快速验证,但在企业环境中存在明显风险。

假设 Agent 可以操作合同、客户资料和订单数据库。

检索一份合同,与修改正式合同,不应该拥有相同的权限要求。

同样,生成退款建议与实际执行退款,也应该被视为不同级别的操作。

Codex 的工具模块将工具注册、路由、处理器、审批和沙箱等职责组织为不同部分。具体执行规则取决于工具类型、配置和运行环境。

它体现出的一个重要原则是:

模型可以提出行动,但模型提出行动不等于系统必须执行。

我们可以将工具执行设计成以下流程:

模型提出工具调用 ↓ 检查工具名称与参数 ↓ 检查用户权限和业务规则 ↓ 判断是否需要审批 ↓ 在受控环境中执行 ↓ 记录结果与副作用 ↓ 将结果返回 Agent

例如,企业标书 Agent 可以自动读取资料、提取参数、生成草稿,但正式发布文件之前仍然可以要求人工审核。

业务数据修改、资金操作、合同签署等高风险操作,则应该设置更严格的授权与审计机制。

对我们开发 Agent 的启示

不要把安全机制写成系统提示词中的一句“请勿执行危险操作”。

应该在工具执行层建立真正的权限边界。

提示词可以影响模型的行为,但不能替代服务端权限检查。

六、启示五:异常处理是 Agent 工程化的重要组成部分

一个简单的 Agent Demo,往往只考虑成功路径:

调用模型 → 执行工具 → 返回结果。

真实系统还需要考虑:

  • 模型请求超时。
  • 工具执行失败。
  • 输入参数不合法。
  • 用户取消任务。
  • 上下文超限。
  • 外部服务不可用。
  • 同一工具调用被重复触发。
  • 任务执行过程中出现新的用户输入。

Codex 的turn.rs和regular.rs展示了对取消、上下文压缩失败、终止错误和待处理输入等不同状态的处理。

这里最值得借鉴的不是某一种具体异常处理代码,而是设计理念:

不同类型的失败应该拥有不同的恢复策略。

例如:

异常可考虑的策略
参数错误返回明确错误,让模型修正参数
临时网络错误有条件地重试
权限不足终止该操作或请求授权
上下文超限压缩历史或减少输入
用户取消停止后续工作,并处理正在运行的操作
外部写操作超时先核实执行结果,再决定是否重试
不可恢复错误终止任务并保留诊断信息

特别需要注意:对有副作用的工具,不能简单地遇到超时就重试。

例如,支付请求超时并不意味着支付失败。系统应先查询交易状态,或者使用可靠的幂等机制,再决定是否继续操作。

这类问题与模型能力无关,却直接决定 Agent 能否安全地进入生产环境。

七、启示六:项目规则应该独立于具体任务

Codex 的AGENTS.md机制,是另一个很值得借鉴的设计。

一个项目通常有很多长期有效的约束:

  • 使用什么语言和框架。
  • 代码放在哪些目录。
  • 如何运行测试。
  • 哪些文件不允许随意修改。
  • API 设计遵循什么规范。
  • 修改完成后需要执行哪些检查。

如果每次开发任务都重新把这些规则写进提示词,不仅效率低,也容易产生不一致。

项目指令文件可以集中管理这些长期规则,让 Agent 在相关工作目录下发现并使用它们。

但要注意:项目指令并不等于真正的安全边界。禁止访问某个文件的要求,仍然需要在工具和执行环境中落实。

结合 Spec 编程,可以怎样组织?

我更倾向于把项目开发资料分为五类:

文档主要职责
AGENTS.md长期项目规则
PRD.md业务目标和需求范围
SPEC.md技术约束和验收条件
PLAN.md具体实施步骤
Git 历史实际变更与回滚依据

这样做的好处是:

  • 项目规则不必在每次任务中重复编写。
  • 需求变化可以通过文档和版本历史追踪。
  • Agent 能够根据明确的验收条件执行任务。
  • 代码审查可以检查实现是否符合 SPEC,而不是只看模型是否认为自己完成了工作。

需要强调,这是一种与 Codex 项目指令机制相结合的工程实践,并不是 Codex 强制采用的文档体系。

八、启示七:多 Agent 不等于多开几个模型

Codex 的multi_agents.rs展示了子 Agent 创建、发送输入、恢复、等待和关闭等协作操作。

这说明多 Agent 系统不仅要解决任务拆分,还要管理子任务的生命周期和通信。

假设我们开发一个企业 AI 文档分析系统。

可以考虑将工作拆分为:

  • 文档结构分析 Agent。
  • 事实与证据检索 Agent。
  • 内容生成 Agent。
  • 质量审核 Agent。

但并不是所有任务都适合这样拆分。

如果多个 Agent 同时修改同一份文档,可能出现冲突;如果每个 Agent 都重复读取大量资料,也会增加成本;如果子 Agent 的结果缺乏统一格式,主 Agent 就很难可靠地整合它们。

因此,多 Agent 设计至少要明确:

  1. 任务如何拆分。
  2. 子任务如何分配。
  3. 状态和结果如何传递。
  4. 执行权限如何控制。
  5. 失败如何恢复。
  6. 最终结果由谁验收。

对我们开发 Agent 的启示

先把单 Agent 的工具执行、状态管理和错误处理做好,再考虑引入多 Agent。

只有当任务具有明确的可分解性,且并行执行确实能够提升效率或质量时,多 Agent 才值得引入。

架构越复杂,不代表 Agent 越先进。

九、把这些设计应用到企业 Agent,应该怎么做?

结合上述分析,我认为可以将 Agent 工程分为三个阶段。

第一阶段:构建可靠的单 Agent

优先实现:

  • 清晰的任务与回合状态。
  • 可控的工具调用。
  • 结构化的执行日志。
  • 超时、取消和异常处理。
  • 可重复运行的测试。

此时不必急于引入复杂的多 Agent 架构。

第二阶段:完善上下文与业务约束

根据实际业务补充:

  • RAG 检索和证据引用。
  • 项目规则与业务规则。
  • 上下文预算控制。
  • 结构化输出与验收条件。
  • 权限检查与人工审批。

例如,AI 标书生成系统不仅要生成内容,还应该能够追溯关键技术参数来自哪份原始文件,并在缺乏证据时明确提示。

第三阶段:引入任务编排与多 Agent

当单 Agent 已经能够稳定完成明确任务后,再考虑:

  • 长任务编排。
  • 子任务并行执行。
  • 持久化任务状态。
  • 失败恢复。
  • 自动评测与回归测试。
  • 多 Agent 结果合并和质量验收。

这样可以避免在基础执行机制尚不可靠时,就引入更难调试的协作结构。

十、总结:Agent 工程的核心是把不确定性控制在系统边界内

研究 OpenAI Codex 源码后,我认为有七点值得记住:

  1. Agent 是持续运行的执行系统,而不只是一次模型调用。
  2. 任务调度、回合循环和工具执行应该有清晰边界。
  3. 上下文工程不仅包括 RAG,还包括项目规则、任务状态和历史管理。
  4. 工具调用必须受到独立的权限与执行策略约束。
  5. 取消、异常和恢复机制是生产级 Agent 的基础能力。
  6. 项目规则、需求规范、实施计划和代码历史应该各司其职。
  7. 多 Agent 应该由真实的任务分解需求驱动,而不是为了追求架构复杂度。

最后,用一句话概括:

模型决定下一步做什么,Agent Runtime 负责组织执行,工具层落实权限与操作,验证机制判断结果是否真的满足要求。

对于正在从 Demo 走向企业应用的 Agent 开发者来说,这比单纯追求更强的模型或更复杂的 Prompt 更值得投入精力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 2:13:17

Temporal Cues CVPR 2025

文章目录1 论文信息2 论文主要贡献3 论文创新点4 方法4.1 整体框架4.2 具体模块(1)正反向伪标签生成与集成(2)2D–3D Hungarian Matching 伪标签筛选(3)3D 跟踪与标签传播(4)目标查询…

作者头像 李华
网站建设 2026/10/19 2:13:15

仍可外挂实现:给solomd添加标签管理相关功能

主要是打开标签太多的时候,当前关闭是一个难题!需要逐个确认弹窗!! 所以我增加了全部关闭(保存或不保存)选项 此外,对在资源管理器中显示当前文件的标签命令,做了强化:显…

作者头像 李华
网站建设 2026/10/19 2:12:19

40篇短文串联高考英语3500词:附词汇表、音频视频与语法专项汇总

资源概览 这份资料是一套针对高考英语词汇的记忆资源合集,围绕「高中英语3500词」这一核心主题整理而成。资料的核心记忆方法是通过40篇短文将全部3500个词汇串联起来,帮助学习者在语境中理解和记忆单词,而非孤立背诵词表。 相关资料 查看文…

作者头像 李华
网站建设 2026/10/19 2:12:16

质序:完全离线的 GJB 质量体系助手技术方案

质序:完全离线的 GJB 质量体系助手技术方案 前言 军工质量体系工作经常被三个约束包围:标准条款多、材料链条长、运行环境经常断网或隔离。云端大模型在这种场景里并不总是可用,也不一定适合直接处理专业判断。 质序是我们围绕这些约束做的本…

作者头像 李华