☰
Codex CLI 本地 Agent 配置全攻略:从 TOML 到 AGENTS.md 的优先级实践
2026/9/29 7:33:42 网站建设 项目流程

如果你最近在折腾 Codex CLI,想把它从“开箱即用”的玩具改造成一个真正按你的规矩办事的本地 Agent,那这篇文章应该能帮你省掉不少弯路。我花了两天时间,把 TOML 配置、AGENTS.md 规则书写、模型供应商切换这三块彻底理了一遍,中间踩了不少坑——cc switch 报 local proxy failed、agent execution terminated due to error、auth token is unavailable,这些经典报错我全都遇到过一遍。这篇文章就从最基础的配置结构讲起,把优先级规则和实际排查经验一次性说清楚,适合刚装好 Codex 不知道怎么配模型、以及想让 Agent 更听话的开发者参考。

1. 项目概述与整体配置思路

先聊聊 Codex 是什么。它是 OpenAI 开源的终端 AI Agent,核心形态是一个命令行工具(codex CLI),你可以在终端里直接跟它对话,让它读取项目代码、执行命令、改动文件、跑测试。它跟 ChatGPT 那种一次性问答最大的区别是,它有“手”,能在你的项目里实际干活。而“本地自定义 Agent”这个词,核心含义是:你可以不依赖 Codex 默认的云端配置,在本地完全控制这个 Agent 的身份、行为规则和数据模型连接。

为什么需要自定义?我遇到的实际场景是:默认配置只指向 OpenAI 官方接口,但我手里的模型资源和团队基建不是这样。一个是接入 DeepSeek 这类兼容 OpenAI 协议的第三方服务,一个是让 Agent 遵循团队既有规范——比如禁止直接改某个目录、必须跑哪条测试命令。这些需求,光靠默认安装一个都用不了,必须动两个东西:TOML 配置文件管“资源”,AGENTS.md 管“行为”。

先说整体架构,它其实是清晰的两层:

第一层是连接层,记录在~/.codex/config.toml里。这个文件决定 Agent 的大脑从哪里来:模型名称、API 地址、鉴权方式、超时参数等。它解决的问题是“Agent 用什么模型思考”。

第二层是行为层,记录在 AGENTS.md 里。这个文件决定 Agent 的做事规则:项目背景、允许/禁止操作、常用命令、代码风格要求等。它解决的问题是“Agent 按什么规矩干活”。

这两层一旦理清,你遇到的所有配置难题都有一个明确的归因方向:连接不出结果,去查 TOML;行为不符合预期,去查 AGENTS.md。后面几章我会把这两层的细节全部展开。

2. 安装、登录与基本验证

安装 Codex CLI 很简单,官方推荐是 npm 方式:

npm install -g @openai/codex

装完先跑codex --version确认安装成功。另外也可以下载桌面版或原生二进制安装包,方式不同但配置目录是一样的,都落在~/.codex下。Codex 有桌面版也有纯 CLI 版。桌面版本质上是在 CLI 外面包了一层图形界面,配置目录和 AGENTS.md 的逻辑完全相通。哪怕你主力用桌面版,也值得学会直接改 TOML,因为 GUI 能暴露的选项永远是有限的,很多自定义 provider 必须手写配置。

登录是绕不过的第一道坎。装完跑codex login,会走浏览器 OAuth 拿到一个 token,然后保存在本地。如果你遇到过codex auth token is unavailable这个报错,基本就是这一步没完成,或者 token 读取异常。我建议的办法是先把~/.codex目录下的 auth 文件删掉重新登录,避免残留的坏 token 干扰。如果是在 CI/CD 这种无头环境,可以走环境变量方式提供 API key,前提是你把 provider 的env_key指过去,这个第四章细说。

登录完先做一个最小验证:找个临时目录,跑codex "1+1等于几"这样最简单的对话。如果这一步就报错,先别急着配模型,大概率是认证或网络层面的问题。排到能正常对话了,再开始折腾自定义配置。

注意:不要一上来就改 config.toml。我见过太多人,配置没生效先怀疑网络,结果花了半小时发现是 TOML 语法写错了一个括号。先把基础链路跑通,再做自定义,排查效率能高一个量级。

3. AGENTS.md:让 Agent 按规矩干活

3.1 AGENTS.md 到底是什么

AGENTS.md 是 Codex 的规则文件,你可以把它理解成给 AI Agent 看的“员工手册”。它用 Markdown 编写,Agent 每次开始干活之前会先读它,然后按照里面的规则决定怎么做。它跟项目里的 README.md 的区别是:README 是给人看的说明书,AGENTS.md 是给 Agent 看的操作守则。这个区分很重要,很多人习惯把技术栈介绍、架构图都塞进 AGENTS.md,结果 Agent 真正需要的行为约束反而淹没在背景信息里。

那 AGENTS.md 具体能约束什么?我归纳成三类:项目信息和约束、常用命令、硬性规则。项目信息帮助 Agent 快速理解上下文;常用命令让 Agent 不用猜该怎么构建和测试;硬性规则则是“红线”,比如不能动哪个目录、必须走哪个流程。三层写清楚,Agent 的行为就基本可控了。

3.2 AGENTS.md 的位置与优先级

Codex 按“从全局到项目再到子目录”的层级读取 AGENTS.md:

  • 全局级:~/.codex/AGENTS.md,对所有项目生效。适合放个人通用的偏好,比如“代码注释用中文”、“禁止删除未确认的文件”。
  • 项目级:<项目根目录>/AGENTS.md,对当前项目生效。适合放项目独有的构建命令、架构约束、文件组织约定。
  • 子目录级:<子目录>/AGENTS.md,对子目录内的操作生效。适合对特定模块做额外约束。

优先级规则是“越靠近当前正在处理的文件,规则越优先”。也就是说,子目录的规则可以覆盖项目级规则,项目级可以覆盖全局规则。这个设计跟很多配置系统一样,就近覆盖。后面我会专门有一章讲优先级实测,这里先记住这个“就近覆盖”原则就够了。

3.3 怎么写 AGENTS.md

我推荐的结构是三段式:

  1. 项目背景说明:两三句话告诉 Agent 这是什么项目、技术栈是什么、有没有特殊的架构限制。
  2. 常用命令:构建、测试、格式化、lint 等,按“命令名: 具体命令”的格式列清楚。
  3. 规则清单:用简短条目写死规则,比如“不得修改 migrations 目录下的文件”。

下面是我项目里实际用过的例子:

# 项目规则 ## 项目概述 这是一个基于 FastAPI 的订单服务,核心目录结构是 app/(业务代码)、tests/(测试)、migrations/(数据库迁移)。数据库迁移文件只能手动管理,不能由 Agent 自动修改。 ## 常用命令 - 安装依赖: poetry install - 运行测试: poetry run pytest tests/ - 代码格式化: poetry run ruff format . - 静态检查: poetry run ruff check . ## 规则 - 在动手修改代码之前,必须先阅读 app/ 目录下相关的模块文件。 - 新增接口必须补测试,测试要用 pytest 风格。 - 禁止直接修改 migrations/ 下的任何文件。 - 删除文件前必须向用户确认。 - 所有输出日志使用英文,代码注释使用中文。

写 AGENTS.md 有几个技巧。第一,命令要写绝对精确的命令行,别写“运行测试”这种模糊指令。第二,规则条目要短,一条只约束一件事,太长 Agent 会抓不住重点。第三,规则之间不要互相矛盾,比如一条说“禁止修改 migrations”、另一条又说“必要时可以修改 migrations 以修正错误”,这种矛盾会让 Agent 执行结果不稳定,实测很看运气。第四,不要把 AGENTS.md 写成百科全书,规则文件越长,模型越容易在关键点上“迷路”,上下文窗口也被白白占用。

3.4 一个容易被忽略的细节

AGENTS.md 的修改对当前会话不是即时生效的。Codex 通常在每个会话开始时或用户显式要求时重新读取规则文件。如果你改了 AGENTS.md 但 Agent 还是按旧规则干活,先新开一个会话或重启 codex,再验证。这个坑不算大,但能卡住你十分钟。

4. config.toml:连接层配置实战

4.1 配置文件的位置与结构

新版 Codex CLI 的主配置是~/.codex/config.toml。TOML 这种格式对人类很友好:键值对清晰、支持嵌套 table(用方括号语法)、注释用 #。相比旧版的 YAML,TOML 在解析上更严格,写错了更容易发现,社区整体迁移到这个格式之后也少了很多“缩进不对就报错”的破事。

配置文件核心分三段:

model = "gpt-5" model_provider = "openai" [model_providers.openai] name = "OpenAI" base_url = "https://api.openai.com/v1" env_key = "OPENAI_API_KEY" wire_api = "responses"

逐行解释一下:

  • model是默认模型名。Codex 会对这个字符串做“智能补全”,比如你写deepseek-chat,它可能在内部拼接成deepseek/deepseek-chat之类,不同 provider 行为不同,注意看实际日志。
  • model_provider是当前生效的 provider 标识,它必须对应下面某个[model_providers.xxx]table 的 xxx。
  • base_url是 API 地址。
  • env_key是从哪个环境变量读取 API key。
  • wire_api是请求协议格式,两个值:responses(OpenAI 新版 Responses API)和chat(传统的 Chat Completions API)。

4.2 接入 DeepSeek 的完整示例

我整理了社区传得最多的一份 DeepSeek 接入方式,可直接参考:

model = "deepseek-chat" model_provider = "deepseek" [model_providers.deepseek] name = "DeepSeek" base_url = "https://api.deepseek.com/v1" env_key = "DEEPSEEK_API_KEY" wire_api = "chat"

配置好后在~/.bashrc或~/.zshrc里加一行export DEEPSEEK_API_KEY="sk-xxx",然后新开终端,跑codex验证。这里有个关键坑:DeepSeek 目前提供的是 Chat Completions 兼容接口,不是 Responses API,所以wire_api必须写成chat,否则请求发过去会报错或行为异常。这也是很多人接入失败的第一原因。

我实测下来,DeepSeek 的响应速度在代码生成场景下表现不错,而且它对中文指令的理解比很多同价位模型更自然。如果你团队的 API 预算有限,把 Codex 接到 DeepSeek 上做日常的代码审查、重构建议,是很划算的方案。不过要注意,DeepSeek 的上下文窗口相比旗舰模型有差距,超大仓库场景下要主动缩小 Agent 的工作范围。

4.3 本地模型的接入方式

如果你想接本地跑的模型(比如 Ollama、vLLM、LM Studio 这类),核心就是把base_url指向本地端口。以 Ollama 为例:

model = "qwen2.5-coder:14b" model_provider = "ollama" [model_providers.ollama] name = "Ollama" base_url = "http://localhost:11434/v1" env_key = "OLLAMA_API_KEY" wire_api = "chat"

本地模型的优势是数据不出机器,适合调试敏感代码;劣势是上下文窗口和推理速度受硬件限制,大项目容易把内存吃满。如果你的本机没有 GPU,建议先用 7B 参数级别的模型做测试,14B 以上纯 CPU 推理会很慢,体验打折。另外,本地模型服务偶尔会不按 OpenAI 兼容格式响应,遇到agent execution terminated due to error时,先去本地模型服务的日志里确认是不是它自己返回了异常结构。

4.4 如何正确配置本地网关与 base_url

这节说一下cc switch local proxy failed这类报错背后的真实场景。很多人不满足于直连官方 API,会把请求转发到一个本地网关做日志记录、流量控制或重试分发,这时候base_url会指向 localhost 或内网地址的某个端口。配置本身很简单:

[model_providers.gateway] name = "Local Gateway" base_url = "http://localhost:8080/v1" env_key = "GATEWAY_API_KEY" wire_api = "chat"

但报错往往出在转发链路的匹配上。我遇到过的常见失败组合是:本地网关服务只实现了 Chat Completions 端点,而配置里wire_api写的却是responses,Codex 向/responses发请求,网关自然处理不了,于是出现local proxy failed while handling codex endpoint /responses这种报错。排查思路就两条:检查网关服务日志确认请求是否到了,检查wire_api与网关能力是否匹配。不要把“代理”两个字想复杂,它就是一台普通 HTTP 服务,Codex 按base_url发请求,服务按协议返回,仅此而已。

4.5 命令行参数与配置优先级

config.toml 不是唯一的配置来源,Codex 还支持命令行参数临时覆盖。比如:

codex --config ~/.codex/prod.toml

可以显式指定另一份配置文件。此外,运行时还可以用codex --model xxx --model-provider yyy临时切换模型。临时用的优先级永远高于配置文件里的默认值。这个设计对运维场景很有用:同一份规则(AGENTS.md),跑不同模型做对比实验,不用改文件。

5. 优先级规则:当配置冲突时谁说了算

5.1 一条主线:就近覆盖

前面其实已经零散提过优先级,这章把它收拢成一张完整的表。Codex 的配置优先级可以用一句话概括:越具体、越靠后加载的配置越优先。

配置类型默认值配置来源优先级
模型选择内置默认模型config.toml / 命令行命令行 > config.toml > 内置
AGENTS.md 规则无全局 / 项目 / 子目录子目录 > 项目 > 全局
API key无环境变量(env_key指定)环境变量直接读取,不参与叠加

这里要特别强调的是:model_provider和model是配对关系,当你切换model_provider时如果不改model,Codex 可能报“模型不存在”或请求发到错误的 provider。实测中我建议每次切换 provider 都把这两个字段一起改,避免出现半配状态。

5.2 实测:AGENTS.md 覆盖效果复现

为了验证“就近覆盖”,我专门做了个实验。全局 AGENTS.md 里写“所有 Python 文件必须使用单引号字符串”,项目 AGENTS.md 里写“本项目的字符串统一使用双引号”,然后让 Codex 在一个测试文件里写一段 Python 代码。结果 Codex 生成的是双引号风格,项目级规则赢了。接着我在子目录加了 AGENTS.md 写“本目录使用单引号”,让 Codex 修改该目录下的文件,它又切回了单引号。这说明覆盖链路是真实生效的,而且作用范围精确到目录级。

这个实验的意义在于:你可以在全局放一套“底线规则”(比如禁止删除文件、禁止 push),在项目里放“具体规则”(比如测试命令),在子目录放“特例规则”(比如某目录允许临时生成文件)。三层各管各的,互不干扰。团队协作时,全局规则通常由技术负责人维护,项目规则由仓库 owner 维护,子目录规则则留给模块负责人自己微调,权限边界非常清晰。

5.3 优先级带来的排查经验

当你发现 Agent 的行为跟预期不一致时,按优先级从高到低排查:先看子目录有没有 AGENTS.md 写了相反规则,再看项目级,最后看全局。很多时候“Agent 不听话”不是模型笨,是你的规则文件自己打架了。

同理,当你发现请求的模型不对时,先确认是不是命令行参数里残留了旧的--model,再看 config.toml 的model_provider是否指向了正确 provider。这个排查顺序看似乎简单,但实际工作中绝大多数人都是反着来的——先去怀疑网络,再去怀疑模型,最后才想到配置文件。

6. 常见问题与排查技巧实录

6.1 报错速查表

报错关键词可能原因排查方向
auth token is unavailable未登录或 token 失效重新codex login,或清理~/.codex/auth*后重登
local proxy failed while handling codex endpoint /responsesbase_url 指向的服务不支持/responses端点,或服务未启动检查网关服务状态、对齐wire_api
agent execution terminated due to error沙盒阻止命令执行、或命令执行超时、或子进程返回非零查看 codex 日志、检查沙盒权限、缩小执行范围
无法发送消息网络不通、认证过期、对话上下文损坏先测试简单对话,再逐层排查认证与网络
显示更新 agent 沙盒沙盒版本有更新,或目录权限导致重建失败按提示确认更新,必要时重置沙盒目录

6.2 几个值得单聊的坑

第一个坑是wire_api匹配问题。前面说过,第三方兼容接口绝大多数是chat协议,Responses API 目前主要是 OpenAI 自家在推。如果你对接的是自建网关或国内可直接访问的模型服务,先确认服务商文档写的是/v1/responses还是/v1/chat/completions,再决定wire_api。这一步错了,报错信息往往还不是“协议不匹配”,而是莫名其妙的 404 或者解析失败,很容易绕远路。

第二个坑是上下文超长。本地模型内存有限,项目代码一多,发给模型的内容一旦超过上下文窗口,Codex 可能在安静一阵后直接报agent execution terminated due to error。处理办法是给 Codex 划小工作范围,或者精简 AGENTS.md 规则,别把整本手册的细节都塞进去。规则文件太长,一方面占 token,另一方面模型反而容易抓不住重点。

第三个坑是 API key 的环境变量名冲突。如果你同时配了多个 provider,注意env_key必须各自对应不同的环境变量名,别两个 provider 都写OPENAI_API_KEY然后指望 Codex 自动区分。这样只会导致所有请求都用同一个 key 发出,权限混乱。我踩过一次之后,现在的习惯是DEEPSEEK_API_KEY、OLLAMA_API_KEY、GATEWAY_API_KEY泾渭分明,一个 provider 一个变量。

第四个坑是 ccswitch 这类第三方切换工具。社区里流通的 ccswitch 本质上是帮你维护和管理多份 codex 配置,方便在不同 provider 之间快速切换。它本身不复杂,但切换后一定要确认 config.toml 被正确改写,最好用codex --version或跑一句对话验证。我见过有人用工具切换后,TOML 里的 table 名出现拼写错误,导致 provider 找不到,报错信息又只显示一半,排查起来特别耗时。

6.3 排查的基本功:看日志

Codex 的大部分报错,日志里都有更详细的原因。默认日志级别可能不够细,可以手动打开详细日志再复现一次问题。关键日志字段包括:请求发往的 URL、HTTP 状态码、返回体里的错误消息。看到 404 大概率是base_url路径写错(比如少了/v1),看到 401 大概率是 API key 无效,看到 400 大概率是请求体结构不匹配(wire_api选错)。

日志还有一个容易被忽略的用途:确认 Codex 实际加载了哪份 AGENTS.md。有时候你以为全局规则生效了,实际项目根目录早有一份残留的 AGENTS.md 在“作祟”。日志里会打印规则文件的加载路径,扫一眼就能定位。

7. 经验总结与后续扩展

如果你只记住一件事,那就是:Codex 的本地自定义本质上是“两个文件加一套优先级”——TOML 管连接,AGENTS.md 管行为,就近原则管冲突。把这个模型记在脑子里,遇到任何问题你都能快速定位到某个层面,而不是在全局里瞎试。

第二件事,配置一定要版本化管理。把 AGENTS.md 和示例 config.toml 都提交到 Git 仓库,团队里每个人 clone 下来就能复现同样的 Agent 行为。我建议在 config.toml 里只提交不含密钥的模板,真实 key 统一放环境变量,这样既安全又方便。新同事入职配环境时,给他一份模板加两句说明,比让他自己看官方文档高效太多。

最后说一下我后续打算做的扩展。一个方向是把 AGENTS.md 拆得更细,按模块拆出子目录规则,让大型项目的 Agent 只关注当前模块上下文,减少 token 浪费;另一个方向是写一套自己的配置文件切换脚本,在多种 provider 之间一键切换,避免每次手动改 TOML。这些思路都是从“两个文件加一套优先级”这个基础框架上生长出来的,先把地基打牢,剩下的都可以慢慢折腾。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询