让 Agent 不再是玄学——我用 Codex 源码当教材手把手拆给你看怎么从零构建一个真正能干活的 AI Agent。这两年 AI Agent 从概念火到了各种技术群里但真到自己动手写的时候很多人其实一头雾水网上教程张口闭口都是 ReAct、多智能体、记忆机制、MCP听着很唬人落地却两眼一抹黑。我自己带团队做 Agent 项目踩了不少坑最后发现一个特别好的学习路径——直接啃 OpenAI Codex 的源码。它不是那种一上来就甩给你几百个文件的巨型框架而是把 Agent 最核心的骨架模型调用、工具注册、上下文管理、任务循环用非常工程化的方式摆在你面前。这篇文章我就以 Codex 源码为教材从概念到实操带你把“Agent 到底是什么、代码长什么样、自己怎么搭一个能跑的出来”这三件事彻底搞明白。开始之前先回答一个很多人纠结的问题Agent、LLM、AI 模型到底是什么关系拿 DeepSeek 举例它就是典型的 LLM大语言模型是一个脑子能理解语言、生成文本但它不会主动用工具也不会自己规划多步任务。而 Agent 是“脑子 手 记忆 规划能力”的完整个体LLM 是它的核心引擎Agent 则是在这个引擎外面套了一层能感知环境、调用工具、迭代执行的壳。你可以把 LLM 想成一个特别聪明但没手没脚的专家Agent 就是给这个专家配了电脑、扳手、记事本还帮他列干活清单的助理。今天要拆的 Codex就是“配好手脚后的专家”的一个优秀参考实现。1. 内容整体设计与思路拆解1.1 先搞明白我们要学的是什么Codex 的整体架构Codex 在源码层面的设计其实就干了几件事接受用户用自然语言描述的目标然后把目标拆解成一系列可执行的动作通过调用各种工具比如执行 shell 命令、读写文件、搜代码一步步逼近结果最后把过程与结论汇报给用户。这个循环听起来不复杂但工程实现上有几个非常关键的设计决策决定了 Agent 能不能真正稳定地干活。从源码目录结构来看Codex 的代码组织很有教学价值。它把代码分成了核心运行时runtime、会话管理层session、工具层tools、配置层config几个大块。其中最值得学习的是它的运行时设计每一条消息进来内部都会经历“解析用户输入 - 组装上下文 - 调用模型 - 解析模型输出 - 执行工具调用 - 将执行结果再喂给模型”这样一条完整闭环。这个闭环就是 Agent 的生命线也是我在自己项目里反复打磨的核心逻辑。我自己在带新人时有个体会很多人一上来就想写一个通用的 Agent 框架觉得越抽象越高级结果半个月过去连一个能稳定完成“查天气并写进文件存下来”这种简单任务的 Agent 都跑不通。Codex 给我们最大的启发恰恰相反——它先把具体场景做扎实再把可复用的部分抽象出来。它里面大量用到了“策略模式”不同的工具执行策略、不同的模型适配策略全都通过接口定义然后在配置里自由切换。所以当你要构建自己的 Agent 时第一原则是先别急着写抽象层先把具体的一条链路跑通再回头抽公用代码。1.2 为什么选 Codex 源码当教材三个别人没告诉你的理由市面上讲 Agent 的资料很多有纯概念的科普文有照搬 LangChain 的教程有学术论文的复现解读但 Codex 源码有它不可替代的教学价值。第一它是“真实产品级”的代码不是 demo。很多教学项目为了演示方便把错误处理、超时重试、配置校验这些“麻烦事”全部砍掉你学完写出来的东西一上生产就崩。Codex 不一样它是真正跑在成千上万人终端里的产品所以在源码里能看到很多极其实战的处理细节模型返回不符合格式时怎么纠偏、并发执行工具时怎么控制、上下文超长时怎么裁剪。这些才是真金白银的经验普通教程根本不会写。第二它的边界划分特别干净适合当解剖样本。Codex 严格区分了“模型的思考”和“Agent 的行动”。模型输出一律是大段自然语言加结构化的工具调用指令Agent 则只负责解析这些指令并调度执行。很多人写 Agent 容易犯一个错误把业务逻辑直接塞进模型 prompt 里或者把工具执行的细节暴露给了模型结果模型输出动不动就乱来。看 Codex 源码你能清晰地学到怎么画这条“模型与应用之间的边界线”。第三它支撑了“以源码为教材”的完整学习闭环。学概念 - 看代码实现 - 自己改代码跑通 - 遇到问题回源码找答案这个循环里每一步都能从 Codex 源码里找到对应内容。不像某些黑盒框架出了问题你只能去发 issue 等回复Codex 的代码结构足够清晰自己就能定位问题。1.3 在学习之前先树立正确的心智模型我想强调一件比看代码更重要的事Agent 不是某一项具体技术而是一种工程架构思想。它没有一个标准答案不是说必须用 LangChain、必须用 MCP、必须有记忆和规划才算 Agent。你在终端里敲一个命令让 AI 帮你改代码这已经是 Agent 的雏形了。以我个人的理解Agent 要解决的核心矛盾是把 LLM 这种“概率性的、不可控的”大脑嵌入到一套“确定性的、可预期的”工程系统里。所以构建 Agent 最核心的能力反而在工程侧——你如何将模型输出的非结构化内容与你的系统安全地对接如何做好错误处理如何设计工具让模型更容易正确调用。这些能力都得靠动手写代码、踩坑来积累单纯看文章是学不会的。我建议的学习路径是先有几天时间快速过一遍代码结构不要深入每一行然后盯住一个具体流程比如让 Agent 执行一条 shell 命令并解释结果从头跟到尾最后再尝试自己扩展一个工具或者换一个模型后端比如把默认模型改成 DeepSeek 的 API在这个过程中你会碰到大量实际问题解决它们的能力就是构建 Agent 的真正功底。2. 核心细节解析与实操要点2.1 Agent 的核心组成结构一个能干活的大脑需要哪些部件在深入代码前我们先从更高的视角捋一下一个完整的 AI Agent 需要哪些组成部件。按我的工程实践拆解必要的部件包括模型接入层、提示词与上下文管理、工具系统、任务规划循环、记忆系统、安全与权限控制以及日志与可观测性。模型接入层负责与 LLM 通信。这一层要考虑的远不止“调一下 API”那么简单不同的模型OpenAI 的、DeepSeek 的、本地跑的在接口格式、参数支持、输出风格上有差异你需要做一层适配还要处理超时、重试、限流、token 统计等问题。Codex 里这一层就是核心运行时的一部分它把模型的请求和响应都做了规范化包装上层逻辑完全不需要关心背后是哪个模型。提示词与上下文管理是很多人忽略的重头戏。Agent 每轮对话都要把系统提示词、历史对话、工具定义、工具执行结果拼装成一个上下文这件事实测下来是 Agent 稳定性的分水岭。上下文拼得太长容易超限拼得太短模型容易失忆工具定义描述不清楚模型就会产生幻觉乱调参数历史对话不裁剪几轮之后整个上下文就乱套了。Codex 的代码里对上下文管理有非常细致的处理这也是我推荐读它源码的一个核心原因。工具系统是 Agent 的“手脚”。一个 Agent 能干什么完全取决于你给它接了什么工具。工具系统的设计有几个关键点工具的描述信息要能被模型理解、参数定义要结构化一般用 JSON Schema、执行结果要能合理地返回给模型。Codex 支持调用 shell 执行命令、读写文件、搜索代码等工具每个工具都封装成了模型可调用的函数形式。任务规划循环是 Agent 区别于普通聊天机器人的根本特征。聊天机器人是“一问一答”Agent 则在一个任务上反复迭代思考下一步做什么、调用某个工具、观察结果、再思考、再行动直到任务完成或达到终止条件。这就是经典的 Agentic Loop。Codex 源码里对这个循环的实现非常清晰模型输出里可以直接包含多个内部思考步骤和多个工具调用请求Agent 逐个执行这些请求把结果收集起来再一次交给模型判断。2.2 Agent 与 LLM 和 AI 模型的原理解读DeepSeek 在哪个位置结合前面的概念我再用更具象的方式解释一下热搜词里那个高频问题“Agent、LLM、AI 模型有什么区别DeepSeek 属于哪个”大多数人对 AI 的认知是“有一个智能的东西你跟它说话它回答你”。但实际上这个链条是分层的。最底层是 AI 模型指经过训练、能以某种形式处理输入的参数化系统可以是语言模型、视觉模型、多模态模型往上一层是大语言模型LLM专指基于 Transformer 架构、在大规模文本上预训练的语言模型DeepSeek、GPT、Claude、Qwen 都属于这一类再往上是 Agent它不是一个模型而是一个用 LLM 做引擎的完整应用系统包含规划、记忆、工具调用等能力。用一个类比来说LLM 相当于一个应届 PhD 的大脑——知识丰富、推理能力强但你给他一个“帮我整理桌面文件”的任务他只会跟你讲应该怎么整理却不会自己动手。Agent 就好比给这个 PhD 配了一双手、一套工具、一个日程本让他不仅知道怎么做还能真正动手去做、做完还能总结经验。所以在技术选型上要特别搞清楚一件事如果你只是想做一个聊天机器人用 LLM 就够了但如果你要做的是让 AI 自动完成某个业务流程比如自动部署代码、自动分析数据报表、自动回复客户邮件那你就需要 Agent。DeepSeek 本身是 LLM但你可以基于它来构建 Agent 系统——这也是“codex 接入 deepseek”这种需求火爆的原因Codex 原本默认调用 OpenAI 的模型但通过修改配置和适配层可以让它的 Agent 骨架配上 DeepSeek 这个国产 LLM 大脑。2.3 方案选型怎么选择合适的 Agent 构建路径理解了概念和部件之后接下来面临一个很现实的问题我该用什么方式构建自己的 Agent目前市面上有三条主流路径我分别说说它们的优缺点。第一条路径是使用现成的 Agent 框架比如 LangChain、LlamaIndex、AutoGPT 这类。优点是上手快、生态全、内置大量工具和集成缺点是抽象层次太高出了问题很难定位而且框架更新频繁今天学的东西明天可能就被 deprecated 了。我见过太多团队把 LangChain 用成了“黑盒子胶水”最后遇到一个诡异的 bug 无从下手被迫读它的源码读了两天放弃。第二条路径是使用平台型产品比如字节的 Coze扣子、Dify、阿里百炼这些。它们提供可视化编排不用写代码就能搭出简单的 Agent 工作流。这条路径很适合快速验证想法和非技术背景的人但如果你的业务场景比较复杂或者需要在本地环境做深度集成可视化平台往往力不从心。第三条路径就是我从 Codex 源码里领悟到也是目前我最推荐进阶者走的路基于 LLM API 自己动手写一个轻量级的 Agent 核心。不要怕“重复造轮子”对于一个 Agent 来说最核心的循环逻辑其实不到 500 行代码就能写清楚。自己写过一遍你对 Agent 的理解深度和用框架的人完全不是一个量级。而且这个核心写完后你完全可以再去用它来理解 LangChain 之类的框架这时候读框架源码会有一种“原来如此”的豁然开朗感。2.4 为什么“工具”是 Agent 的灵魂一个实践案例说了这么多我举一个我实际项目里的例子来加深理解。之前我帮客户做一个代码仓库自动梳理的 Agent要求是给它一个仓库地址它自动分析项目结构、找出核心模块、生成 README。如果用一个“裸” DeepSeek 模型你让它“分析这个仓库”它会直接拒绝因为它根本访问不了文件系统。但是当我给它接上“读取文件”“列出目录”“搜索代码”这几个工具后同样一个模型就能自己一步步去看目录结构、逐个阅读关键文件、总结出项目脉络。这中间的差别就是工具的威力。而且工具的威力不仅在于“能访问文件”更在于给了模型一个“行动的抓手”。人在面对一个复杂任务时如果只有脑子没有手会陷入空想模型也一样工具的调用输出不断给模型提供新的信息输入让它的推理链能够持续推进下去。从这个案例也能看出Agent 开发的一个核心工作就是想清楚你的业务场景里Agent 需要哪些手。3. 实操过程与核心环节实现3.1 环境准备搭建一个最简 Agent 开发环境理论讲再多不如亲手跑起来一个最小闭环。我这里给出一套经过我反复验证的、最轻量的 Agent 开发环境搭建方案。在开始之前请你确认自己的电脑能跑 Python 3.10 以上版本并准备好了至少一个大模型 API 的访问密钥OpenAI、DeepSeek 或其他任意兼容 OpenAI 格式的 API 都可以。我的建议是直接用 DeepSeek 的 API 来学习一方面国内访问稳定、价格便宜另一方面它兼容 OpenAI 的接口格式后续你切换到 OpenAI 或其他模型只需要改 base_url 和 api_key 两处配置。独立开发环境下建议先做一个 Python 虚拟环境避免依赖冲突mkdir my-agent cd my-agent python3 -m venv venv source venv/bin/activate pip install openai python-dotenv这里只安装两个核心库。openai官方 SDK 其实可以用来调用任何兼容 OpenAI 协议的模型接口python-dotenv用来管理环境变量。装好后创建一个.env文件填入你的 API 密钥和模型接入地址OPENAI_API_KEYsk-你的key OPENAI_BASE_URLhttps://api.deepseek.com MODEL_NAMEdeepseek-chat为什么要用.env文件而不是直接把密钥写在代码里因为密钥一旦硬编码进代码想改成环境配置就得改代码而且不小心把代码分享出去就会泄露密钥。用环境变量管理密钥是我在所有项目里都坚持的底线习惯。3.2 核心代码实现用不到 300 行写一个能自主决策的 Agent下面是我亲手整理、精简过的一个最简 Agent 核心实现。它不依赖任何 Agent 框架只有一个循环把消息发给模型 - 模型决定调用什么工具 - 程序执行工具 - 把结果交回给模型 - 重复直到模型不再调用工具。这里我实现了两个工具一个用来模拟“获取当前时间”一个用来模拟“执行 shell 命令”生产环境请务必谨慎授权。import json import os import subprocess from datetime import datetime from dotenv import load_dotenv from openai import OpenAI load_dotenv() client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) TOOLS [ { type: function, function: { name: get_current_time, description: 获取当前的日期和时间返回字符串, parameters: { type: object, properties: {}, required: [] } } }, { type: function, function: { name: run_shell_command, description: 在本地环境执行一条 shell 命令。仅在必要时使用。, parameters: { type: object, properties: { command: { type: string, description: 要执行的 shell 命令 } }, required: [command] } } } ] def execute_tool(name: str, arguments: dict) - str: if name get_current_time: return datetime.now().strftime(%Y-%m-%d %H:%M:%S) if name run_shell_command: try: result subprocess.run( arguments[command], shellTrue, capture_outputTrue, textTrue, timeout10, ) return freturn code: {result.returncode}\nstdout: {result.stdout}\nstderr: {result.stderr} except subprocess.TimeoutExpired: return 命令执行超时(10秒) except Exception as e: return f执行出错: {str(e)} return f未知工具: {name} def agent_loop(prompt: str, max_iters: int 8): messages [ {role: system, content: 你是一个能调用工具的智能助手。请根据用户的问题合理调用工具并在确认完成后给出最终答复。}, {role: user, content: prompt} ] for i in range(max_iters): print(f--- 第 {i 1} 轮思考 ---) response client.chat.completions.create( modelos.getenv(MODEL_NAME), messagesmessages, toolsTOOLS, tool_choiceauto, ) message response.choices[0].message messages.append({ role: assistant, content: message.content, tool_calls: getattr(message, tool_calls, None), }) if not message.tool_calls: print(Agent 最终回复:, message.content) return message.content for tool_call in message.tool_calls: print(f调用工具: {tool_call.function.name} {tool_call.function.arguments}) result execute_tool( tool_call.function.name, json.loads(tool_call.function.arguments or {}), ) messages.append({ role: tool, tool_call_id: tool_call.id, content: result, }) print(达到最大迭代次数强制终止) return None if __name__ __main__: user_input input(请输入你的任务: ) agent_loop(user_input)这段代码就是整个 Agent 的核心骨架我来逐步拆解每个环节为什么这么写。代码的核心是agent_loop函数。它维护了一个messages列表这个列表就是 Agent 整个生命周期里的“对话记忆”。在这个列表里既有模型的思考过程assistant 角色的内容也有工具执行的结果tool 角色。把工具执行结果也拼接到 messages 里是 Agent 能持续推理的关键因为模型每多一个工具结果就多了一条上下文证据它的下一步决策就有更充分的依据。再看tool_choiceauto这个参数它告诉模型你可以根据对话内容自主决定是否调用某个工具以及调用哪个工具也可以不调用工具直接给出最终回答。这是模型侧“自主决策”的实现方式。当模型的返回里不包含tool_calls字段时就说明它认为不需要再调用工具了这时我们就认为任务已经完成把它的话作为最终结果输出。execute_tool函数是工具层的实现。它接收模型输出中关于工具名称和参数的解析结果然后分发给对应的处理函数执行。这里面最关键的设计是无论工具成功还是失败都要把结果以字符串形式返回给模型。很多初学者会把工具执行放在 try/except 外面一报错整个 Agent 就崩了其实工具执行失败本身也是一条重要信息模型看了之后可以调整策略重试。3.3 运行测试让 Agent 完成一个真实任务代码写好后我们在终端里跑一个测试看效果。我故意设计了一个需要调两次工具的任务“先查看当前系统时间再执行echo hello-agent命令最后告诉我两个命令分别的结果。”python agent.pyAgent 的输出大致是这样的不同模型的回复措辞会有差异但流程一致--- 第 1 轮思考 --- 调用工具: get_current_time {} --- 第 2 轮思考 --- 调用工具: run_shell_command {command: echo hello-agent} --- 第 3 轮思考 --- Agent 最终回复: 当前时间是 2025-06-11 20:30:15执行 echo hello-agent 的结果是return code 0stdout 为 hello-agent。这个过程完整展示了 Agent 的核心工作方式它不是一次性给出结果而是分多轮决策每一步都会结合前面的工具返回结果来规划下一步行动。第一次调用时间工具获取时间第二次调用 shell 工具执行命令第三次发现所有信息都齐了就不再调用工具直接组织自然语言回答。这就是 Agent 和普通 LLM 对话最本质的区别——它不是“我问你答”而是“我发指令你执行并反馈直到任务完成”。3.4 工具的安全边界与实际落地改造前面给的示例可以在学习阶段安全运行但如果你要把它用到真实工作里有几个工程化改造必须做否则会出事。最危险的就是那个run_shell_command它让模型可以直接在终端执行任意命令。如果模型被恶意提示词诱导或者它自己产生了偏差运行了rm -rf /之类的命令后果不堪设想。我自己的工程实践里对工具权限控制做了三层限制。第一层是命令白名单只允许模型执行预设好的那几条命令比如git status、ls、cat等只读命令第二层是参数校验即使命令在白名单里也要对参数做正则校验防止cat /etc/passwd这种越权读取第三层是全部命令用沙箱用户运行不给它宿主机完整权限。这三层下来Agent 的安全性基本可控。另外真实场景里工具结果往往不是简单字符串可能是大段日志、表格数据、图片路径等。这时候你需要考虑“结果摘要”策略把海量结果先做一个局部摘要再放回模型上下文防止 token 爆炸。我在处理日志分析类 Agent 时就经常用这个策略——工具先取出日志文件的前 N 行让模型决定是继续看更多行还是基于当前信息分析避免一次性把所有日志都塞给模型。3.5 上下文管理与记忆机制从会话级到持久级很多 Agent 聊到十几轮就开始“失忆”根源在于上下文管理没做好。LLM 的输入窗口有限你不可能把所有历史对话和工具结果都无限塞进去。Codex 源码的处理方式是对旧的对话做摘要压缩把“完整的历史信息”压缩成“保留了关键信息的小体积摘要”再与最近的对话内容拼接起来一起送给模型。对于自己的 Agent我建议从简单到复杂逐步升级记忆方案。最简单的是滑动窗口只保留最近 N 轮对话超过的丢弃进阶一点的是摘要记忆每过几轮让模型把前面的核心信息总结成一段文字后续用这段摘要替代原始对话再进阶是外部向量库记忆把关键信息存入向量数据库需要时按相关性检索出来加入上下文。这几种方案各自的适用场景不同。滑动窗口适合任务型 Agent做完一个任务就结束摘要记忆适合长对话的咨询场景向量库记忆适合需要长期存储用户偏好的场景比如购物助手。刚开始做 Agent 别想着一上来就上向量库先试试滑动窗口和摘要记忆效果不一定差而且代码量小一个数量级。3.6 Codex 源码中的高级设计Agent 工程化必须掌握的范式读完 Codex 源码后我提炼出几个设计上的亮点它们对任何 Agent 项目都有直接的借鉴意义。第一个是“结构化工具调用”的设计。Codex 要求模型输出的工具调用必须符合严格的 JSON 结构凡是格式不正确的Agent 会反馈一个“解析错误”给模型并要求它重新生成。这种做法保证了解析层的稳定性。对比一些用正则表达式从自然语言里提取函数参数的方案结构化调用无论从准确率还是扩展性上都完胜。这就是为什么现在 OpenAI 推出了 function calling、MCP 等标准协议它们本质都是在推进结构化工具调用的标准化。第二个是“分步骤可观测”。Codex 在每一步工具调用时都会输出日志记录模型说了什么、调用了哪个工具、返回了什么结果。这个简单的“日志输出”习惯在 Agent 出问题时就是救命稻草。我看过太多团队搭的 Agent 像黑盒一样每次出问题只能靠猜而 Codex 源码里就可以看到它把日志工程做得非常完善从配置加载到请求发出到响应接收每一步都有迹可循。第三个是“可重试与容错设计”。模型 API 调用失败是常态限流、超时、网络波动、模型接口返回异常都需要 Agent 自己处理。Codex 源码的请求层针对不同类型的错误做了差异化处理瞬时错误网络超时、503自动重试永久错误401、403直接放弃并告知用户限流错误429则等待一段时间后重试。这个设计思路值得直接抄进自己的 Agent 项目里。4. 常见问题与排查技巧实录4.1 模型输出的 Tool Call 解析失败这是我在开发中最常遇到的问题现象是模型明明说了要调用某个工具但代码却解析不到tool_calls字段。排查下来发现原因通常有两种。第一种是模型不支持 function calling 或 tools 参数。像一些非 OpenAI 协议的本地模型可能只支持纯文本输出这时候你需要通过显式要求在 prompt 里让模型输出一个固定的 JSON 格式然后再用json.loads去解析。这个方法虽然“土”但在某些场景下是唯一方案。codex 接入 deepseek 时用的还是兼容协议所以没有这个问题但你如果换一些不兼容的模型就得走 prompt 解析这条路。第二种是 API 返回结构差异。如果你用了某个中转 API 或者框架的 SDK它可能没有把tool_calls字段透传出来。遇到这类问题我的排查习惯是先把 API 原始返回的 JSON 完整打印出来看一眼确认字段结构再写解析代码千万别想当然。4.2 上下文长度超限Token LimitAgent 跑着跑着突然报错“context length exceeded”,这是第二个高频问题。原因是我们的messages列表无脑累积历史对话加工具结果越来越多撑爆了窗口。解决方案就是我前面提到的记忆管理策略加一个简单的滑动窗口只保留最近 8 轮的 messages或者做完一轮工具调用后调用一次摘要把摘要塞回 messages清掉旧消息。我实测下来有一个经验数据一个工具执行结果动辄几百上千 token如果 Agent 循环里频繁调用工具5 到 10 轮就可能撑爆 8k 的上下文窗口。所以在设计 Agent 时就该提前规划好上下文预算——给系统提示词预留多少、给工具定义预留多少、给历史对话预留多少、给模型输出预留多少心里要有数。4.3 Agent 陷入无意义循环或死循环有时候 Agent 会一直调同一个工具得到相同的结果然后接着再调似乎“忘了”自己已经试过一次。这是 Agent 开发里常见的“无限循环”问题。我在本地跑示例时就遇到过一次Agent 检查某个文件不存在后仍然是反复调用“列出目录工具”尝试寻找每次结果都一样。排查到根因是工具返回的信息在高频轮次之后被挤出了上下文窗口模型“失忆”了。解决方法是调整上下文保留策略确保最近的工具结果一定不被裁剪另一个兜底方案是设置最大迭代次数我前面代码里就设置了max_iters8到次数直接强制终止防止 Agent 把 API 费用烧光。4.4 Codex 自身安装与使用中的典型报错很多同学在自己安装和使用 Codex 时也会碰到问题。我根据社区高频反馈总结了两个最常见的错误。第一个是codex auth token is unavailable这代表无法正常读取登录凭证。通常是基于 Codex 改造后没有正确登录或者环境变量没设置。解决方法很简单查看官方文档确认环境变量的变量名检查注入方式终端、CI、IDE 环境确保变量名没有拼写错误。第二个是cc switch local proxy failed while handling codex endpoint /responses. provi...这类报错一般出现在网络代理配置不当时。本地开发代理无法正常处理 Codex 的 HTTPS 请求地址导致请求被拦截或错误转发。解决办法是检查本地代理是否支持 HTTPS 证书把 Codex 的域名加入代理的白名单NO_PROXY 白名单或者临时关闭代理直连试一下。这类问题十有八九是网络层的问题排查时先确认好“当前 Agent 进程能不能直接访问到模型 API 地址”。4.5 常见问题速查表我把开发 Agent 时的高频问题整理成了一张速查表方便你对照排查。现象大概率原因排查/解决方向模型不调用工具直接给话工具描述不清 / 模型不支持 tools优化工具 description加示例换兼容模型tool_calls 老是解析失败API 返回结构不标准打印原始返回结构确认字段名上下文长度超限messages 无限累积加滑动窗口对旧对话做摘要压缩Agent 重复调用同个工具近期上下文被裁剪 / 状态未记录确保最近工具结果写入上下文维护外部状态表API 限流 429并发太多或额度过低指数退避重试策略降低并发数代码能运行但结果不理想prompt 描述不够具体细化工具说明增加 few-shot 示例可达性异常连接超时、代理报错网络层拦截 / 代理没配好检查 base_url 可达性确认代理白名单配置5. 从 Codex 源码到你自己的 Agent一个可复制的进阶路线5.1 第一周的目标读懂模型接入层的秘密很多人拿到 Codex 源码第一反应是“从 main 函数开始读”但一个大项目从头读很容易劝退。我的建议是第一周只盯一个目标把“请求是如何发给模型响应又是怎么被处理的”这条链路彻底读透。打开源码找到模型调用的接口实现从“构建请求体 - 配置请求参数model、temperature、tools- 发送请求 - 接收流式或非流式响应 - 解析 response - 根据响应决定下一步动作”这一整条链路上每一个方法你都溯源去看它做了什么。读的时候建议配合打印日志或者加断点跑一遍真实任务观察每一步的请求和响应结构。这周结束你就能回答一个问题Agent 的“思考”在工程上到底是怎么发生和被捕获的。5.2 第二周的目标读懂工具定义并自己加一个新工具第二周开始动手修改基于你第一周读通的链路在 Codex 或你自己的 Agent 方案里新增一个定制工具。比如一个“获取系统 CPU 使用率”的工具这需要做三件事定义好工具的 JSON Schema描述、参数、返回类型、编写实际的函数体、把工具注册到代码里。加完后给它一个任务“获取当前 CPU 使用率如果超过 80% 提醒我注意。”观察模型能不能正确调用你的新工具。如果失败了大概率是描述信息写得不够清晰这能帮你理解工具描述与模型调用准确率之间的强关联。5.3 第三周及以后向多工具、多模型、持久记忆迈进从第三周开始可以尝试做这些升级给 Agent 接上多轮记忆用数据库存历史对话摘要支持多个模型之间切换比如 OpenAI 处理推理任务、DeepSeek 处理日常问答把 Agent 暴露成 HTTP 服务接口给前端页面调用。这些升级每一样都会碰到新问题但核心的 Agent 骨架已经稳定了你的所有工作都是在骨架之上做扩展。我见过太多人一周想学会 Agent结果什么都没学深。Agent 开发是一个需要长期积累才能精进的工程领域按周定好目标慢慢打磨才是正路。这段从零构建 AI Agent 的实操旅程本质上是一场“脑与手结合”的工程实践。Codex 源码的价值不在于让你背下每一行代码而在于它像一本优秀的教材把 Agent 最核心的设计范式模型、工具、上下文、安全边界以近乎标准答案的形式展示在你面前。以它为起点先跑通最小闭环再有意识地去扩展工具、管理记忆、控制权限你会发现自己对 Agent 的理解远超那些只刷概念的人。我个人这段时间做得最有效的一件事是坚持给每一个 Agent 项目都留一份“失败记录”文档什么场景下模型开始答非所问了、什么 prompt 会诱导它乱调工具、什么上下文结构让它准确率飙升全部记录在案。时间长了你会发现Agent 开发的真正门槛并不在模型而在于你有没有把自己当成工程师去认真打磨 System Prompt、上下文管理、工具定义这些周边工程。接下来动起来哪怕从复制我上面那段最小代码开始你也会很快体会到自己动手构建 Agent 的真正乐趣。