ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Codex本地配置实战:config.toml、AGENTS.md与优先级机制

Codex本地配置实战:config.toml、AGENTS.md与优先级机制 先声明一点这篇不是科普文档是我自己把 Codex 从“装好就不管”到“按自己项目习惯调教”折腾了一遍之后把 config.toml、AGENTS.md 和优先级这套东西理顺的经验记录。如果你正准备用 Codex 做本地自定义 Agent或者想接非默认模型这篇文章能帮你少走很多弯路。我最初的需求很简单不想每次开新项目都反复交代背景也不希望 Codex 用自己的默认模型跑不合适的任务。折腾完才发现这背后其实是三件事——TOML 配置文件管“模型从哪来、权限给多少”AGENTS.md 管“Agent 知不知道你的规矩”优先级机制管“你写的配置和默认行为发生冲突时听谁的”。三件事搞明白Codex 才真正从“别人的工具”变成“自己的 Agent”。1. 先搞清楚要改什么Codex 本地三条配置主线1.1 一个真实场景假设你刚装好 Codex CLI打开终端执行codex它跑起来了用的却是官方默认模型。你想让它接入公司内部的推理服务或者试一下地跑的 OpenAI 兼容接口这时候你大概率会先搜“Codex 怎么换模型”。搜到的教程各说各话有人让你改config.toml有人让你写AGENTS.md有人让你传环境变量。要是分不清这些文件在干什么就会陷入改一个、报错一个、再改一个的死循环。我当时踩的坑是改了config.toml里的model字段却发现 Codex 还是不动然后再去翻文档发现model只是“选择用哪个模型”真正的模型来源是model_provider。没有把 Provider 指对你填什么模型名都白搭。这个经历让我意识到Codex 的本地配置不是“一个文件搞定所有事”而是三条主线互相配合缺一条都会出问题。1.2 三块配置的职责分工先给这三条主线画个分工图config.toml负责“运行时行为”。包括默认模型、Provider 定义、API 地址、环境变量引用、沙盒模式、命令审批策略、存储路径等。它决定 Codex 进程跑起来之后到底怎么跟推理服务说话、有多大权限动手。AGENTS.md负责“行为约定”。它是给 Agent 看的说明文档告诉它在当前项目里应该遵守什么技术栈、用什么命令、遵循什么编码习惯、避免哪类操作。它不决定模型是谁但决定模型在你的项目里怎么干活。优先级机制负责“冲突裁决”。Codex 有一套固定的配置优先级命令行参数 环境变量/特定配置 全局配置文件 默认值。AGENTS.md 在不同层级全局 vs 项目也会被覆盖或合并。搞不清这条你会遇到“明明配了却不生效”或“生效了但不是你想要的那个生效”。我把它类比成装修房子config.toml 是水电图决定管线怎么走AGENTS.md 是给工人看的施工规范决定窗户开多大、瓷砖贴多高优先级是监理制度决定图纸、规范和工人随手改的细节哪个说了算。装修不乱这三样必须各司其职。1.3 我的原则配置文件不是越复杂越好很多人容易走进另一个误区——把配置写得特别满。Provider 配三四个AGENTS.md 写得比需求文档还长结果 Codex 每次加载都要消化大量无用信息反而表现得“弱智”了。我的原则是能用默认配置满足的场景绝不自定义。每写一条配置都要能说出“解决了我实际遇到的哪个问题”。保持配置可读定期删掉不再使用的 Provider 和过时指令。后面所有实操内容都是基于这个原则展开的。2. TOML 配置实战config.toml 从零到可用2.1 配置文件位置与基础骨架Codex 的全局配置文件在用户的.codex目录下具体路径取决于系统。Linux 和 macOS 一般看~/.codex/config.tomlWindows 在%USERPROFILE%\.codex\config.toml。如果你不确定直接在终端执行codex config这条命令会把当前生效的配置路径和关键字段打印出来比我对着系统挨个找目录快得多。如果你想直接打开配置文件编辑可以用codex config edit它会调用系统默认编辑器打开配置文件。这个命令省事但有个坑执行完不会自动校验语法改错了要等下次启动才暴露。一份最基础、能正常跑起来的最小config.toml长这样model gpt-4.1-mini model_provider openai [providers.openai] name openai base_url https://api.openai.com/v1 env_key OPENAI_API_KEY注意model和model_provider在文件顶部全局生效[providers.openai]是定义一个名为openai的 Provider。Codex 默认自带 OpenAI Provider所以哪怕不写这段它也能用你真正需要写[providers.xxx]的时机是你要接一个非默认来源的时候。2.2 自定义 Provider接入第三方 OpenAI 兼容接口Codex 有个很实用的设计它把“模型来源”抽象成了 Provider。你不需要魔改客户端只需定义一个 Provider指向 OpenAI 兼容的 base_url并配置好环境变量名就能把模型来源切换到别的推理服务。这里我用两个常见例子说明。第一个例子是接入本地推理服务比如 Ollama。Ollama 暴露了 OpenAI 兼容接口默认地址是http://localhost:11434/v1。配置如下model qwen2.5:7b model_provider ollama [providers.ollama] name ollama base_url http://localhost:11434/v1 env_key OLLAMA_API_KEY这里有个细节本地服务通常不校验 API Key但你依然要给env_key设一个值Codex 要求 Provider 引用一个环境变量。实际操作中我在终端里随便export OLLAMA_API_KEYlocal就能跑通。直接把这个环境变量写进config.toml是不行的TOML 里不应保存密钥也用明文写死的方式会污染配置。第二个例子是接入国内服务商的 OpenAI 兼容 API。你只需要把 base_url 和 env_key 换成服务商提供的值model_provider deepseek [providers.deepseek] name deepseek base_url https://api.deepseek.com/v1 env_key DEEPSEEK_API_KEY需要提醒的是第三方服务的模型 ID 不一定是gpt-4o这种名字你要先查清楚服务商发布的模型标识再填进全局的model字段。填错的最典型反应是请求发出去了服务商返回 404 或 “model not found”。还有一类 Provider 需要你同时指定 API 版本路径例如 Azure OpenAI 的格式是https://{resource}.openai.azure.com/openai/deployments/{deployment}Codex 社区有不少人踩过这个坑。我的建议是先到 Provider 官方文档确认 base_url 的完整路径协议再写进配置。不确定时先把 base_url 配成“裸域名”执行一次codex exec hello看报错里提示的期望路径再反过来修正。这招在排查 endpoint 问题时特别有效。2.3 沙盒与审批让 Agent 安全地动手模型来源搞定后下一步是考虑 Codex 在本地跑命令时的安全边界。Codex 有沙盒机制默认配置对你的文件系统、网络、进程都有访问限制。我之前图省事直接把sandbox_mode关掉结果 Codex 在一次重构任务里把我的缓存目录给清了。从那以后我老老实实研究这个字段。sandbox_mode通常有三种形态read-only只读沙盒Agent 可以随便读文件但写操作需要审批。workspace-write允许写当前工作区但工作区之外的操作受限。danger-full-access完全访问。这个命名本身就是在警告你别乱开。更细粒度的控制靠[sandbox_workspace_write]这类字段。比如我想让 Codex 能写当前项目目录、能执行 npm 和 git 命令但其他写操作都要弹确认配置可以这样写sandbox_mode workspace-write approval_policy on-request [sandbox_workspace_write] allows [ npm install, npm run build, git status, git diff, ]approval_policy是另一个容易忽视的点。它的取值大致是on-request每次命令执行前询问你。auto自动放行允许列表里的命令其他命令再询问。never任何非只读操作都拒绝适合你想纯聊天式使用的时候。这份配置花费了我最多时间。一开始我以为allows列表是“只允许这些命令”后来才发现它只是“这些命令无需审批自动执行”不在列表里的命令只要策略允许仍会在询问后执行。理解了这一点配置才真正顺手。2.4 验证配置是否生效的排查手段改完config.toml不要直接开交互模式先用一句简单指令验证codex exec hi --model qwen2.5:7b如果返回正常说明 Provider、base_url、env_key 三个环节都通了。如果报错优先看日志tail -f ~/.codex/log/codex.log日志是定位配置问题的最好工具很多 endpoint 和鉴权错误在日志里比在终端里详细得多。我还习惯用codex config查看实际生效值确认自己没有改错文件——有时候你改了 A 目录下的配置文件Codex 加载的却是 B 目录那份。3. AGENTS.md 配置实战让 Agent 听懂项目规矩3.1 两级 AGENTS.md 与加载规则如果说config.toml是让 Codex“跑得起来”那AGENTS.md就是让它“跑得对”。它是码给 Agent 看的自然语言说明文件。Codex 会按层级加载它全局级~/.codex/AGENTS.md对所有项目生效。项目级项目根目录./AGENTS.md只对当前项目生效。更细层级子目录也可以放AGENTS.md只在该目录及其子目录内生效。层级的优先级是离当前工作目录越近的AGENTS.md覆盖越远的那一级。也就是说项目根目录的规则会覆盖全局规则子目录的规则又能进一步补充或调整项目根目录的规则。这里有个关键点Codex 对多个层级文件的处理不是“二选一”而是“合并”。它会把各层内容按优先级拼在一起。如果上级说“不要修改 package-lock.json”项目级又说“可以改 package-lock.json”最终结果往往是就近原则生效而不是全局规则压住项目规则。这个特性让我养成了一个习惯——全局 AGENTS.md 只写“任何人任何项目都得遵守的底线”项目相关细节一律放项目级文件里避免互相打架。3.2 怎么写出会被执行的项目指令AGENTS.md 写不好Codex 会像没听到你说话的实习生点头说“明白”转头就按自己习惯干。我总结了几个让它真正“听到”的要领第一用命令式短句少用希望式描述。“不要提交 node_modules”比“建议不要将依赖目录纳入版本控制以防仓库体积膨胀”有效得多。Agent 的上下文窗口有限冗长的背景故事会稀释掉真正的指令。第二把能验证的约束写成“清单式”例如“所有 Python 代码用ruff检查后再提交”“所有对外接口必须写类型注解”。这些约束 Codex 可以在执行时自行验证而不是靠猜。第三给关键操作写明具体命令不要让 Agent 自由发挥。写“使用 pnpm 安装依赖”好过写“按项目需要安装依赖”后者它可能真给你用 npm 装一遍然后留下一堆锁文件差异。第四负面约束要写得具体。单写“不要乱删文件”没用要写“不要删除 public/ 目录下未在assets-manifest.json中登记的静态资源”。我还遇到过指令太多太杂导致 Codex “抓不住重点”的情况。后来把 AGENTS.md 分成了几个区块项目概览、技术栈、常用命令、编码规范、红线行为。这样一来长上下文里 Codex 查找规则时更高效。3.3 一份可直接套用的 AGENTS.md 模板下面这份模板是我从实际项目里整理出来的你可以按需改动不要照抄# 项目指令 ## 项目概览 这是一个基于 TypeScript 的后端服务提供任务调度能力。 关键目录 - src/services业务逻辑所有接口实现放在这里 - src/routes路由定义禁止包含业务逻辑 - tests单元测试与集成测试 ## 常用命令 - 安装依赖pnpm install - 本地启动pnpm dev - 检查类型pnpm typecheck - 运行测试pnpm test ## 编码规范 - TypeScript 启用严格模式禁止使用 any - 模块导入统一使用 ESM 语法 - 所有错误处理必须走 domain/errors.ts 中定义的错误类型 - 提交前必须通过 pnpm typecheck 和 pnpm test ## 红线行为 - 禁止直接修改 package.json 中的依赖版本 - 禁止删除 tests 目录下的测试文件 - 禁止绕过 src/services 层直接访问数据库 - 修改 src/routes 下的路由时必须在 tests 目录补充对应测试写好后把项目根目录的 AGENTS.md 替换成以上内容然后在项目里执行codex exec 现在项目的测试怎么跑它会回答pnpm test而且是在读完你给的文件之后得出的结论这说明指令已经生效。如果它还在按自己“常识”回答八成是没加载到这份文件或者有更高优先级的同级文件覆盖了它。4. 优先级机制三个层级到底谁说了算4.1 配置项的优先级秩序配置改多了之后“到底谁覆盖谁”会成为唯一萦绕在脑子里的问题。Codex 的优先级大体是最高命令行参数比如codex exec --model xxx。次高具体配置项例如config.toml顶部写的model/model_provider。再次 Providers 内部的配置[providers.xxx]里的 base_url、env_key 等。最低内置默认值。光看这个排序你会觉得很简单实际坑在于不同“层级”的优先级在不同配置项上并不一致。比如你命令行指定--model a但model_provider没有指定那么 Codex 会用默认 provider 来解析--model a。也就是说“最高优先级”的命令行参数也得接受 Provider 解析规则约束。我见过有人执行codex exec --model qwen2.5:7b报错因为默认 Provider 是 OpenAIOpenAI 服务端根本不知道qwen2.5:7b是什么模型。这时候正确姿势是同时指定--model_provider ollama或者在 config.toml 里把默认 Provider 设成目标服务。另一个容易被忽略的是env_key的引用优先级。同样的环境变量如果在[providers.xxx]里指定了env_key MY_KEY那 Codex 只会去读MY_KEY这个变量不会自动 fallback 到通用变量名。你的 shell 里明明 export 过API_KEY但 Key 取不到原因就是字段名不匹配。4.2 model 与 model_provider 的耦合关系model与model_provider的关系是 Codex 优先级机制里最值得单独拿出来讲的。简单说model只管“用什么模型”model_provider管“去哪里找这个模型”。两者必须同时成立请求才能成功。我建议这样理解model_provider是地图model是目的地坐标。地图错了坐标识别不了地图对了但坐标不存在还是到不了。所以排查配置问题时第一步永远是回答两个问题Codex 当前用的 Provider 是谁该 Provider 认不认识我填的 model ID调试代码如下# 查看当前默认 Provider 和模型 codex config # 指定 Provider 和模型做一次最小请求 codex exec ping --model_provider ollama --model qwen2.5:7b如果这条能通说明配置文件的“Provider 主体”没问题剩下的是默认值设置问题如果这条也不通问题多半出在 base_url 或 env_key 上。4.3 优先级实战中容易翻车的三个场景场景一你改了config.toml顶部的model_provider但 Codex 还是走默认行为。大概率是你改了文件但没有重新启动已经运行的 Codex 会话。Codex 的交互式会话在启动时读一次配置过程中改配置不会热更新。我踩过这个坑开着codex会话心里想着“改完配置再试试”结果还是旧行为。正确做法是退出会话重新进入。场景二项目里有多个AGENTS.md但 Codex 只认了其中一份。要检查实际加载了哪些文件可以打开 verbose 日志或直接给 Codex 提一个问题“你读到了哪些 AGENTS.md请列出路径和优先级结论。”它会告诉你实际命中的文件列表。这个方法比盲目反复改文件高效得多。场景三approval_policy设置成never然后代码执行类请求全部被拦截你以为是沙盒坏了。其实这是优先级生效的正常表现——策略字段权限高于沙盒细节。你把sandbox_mode danger-full-access和approval_policy never放一起最后仍是拒绝执行因为 approval_policy 拦截发生在更上层。理解这个排序才能避免“我明明给了全权限为什么还是不行”的困惑。5. 本地化部署的高频问题与排查实录5.1 endpoint 报错与 base_url 拼接坑我见过最多的报错就是cc switch local proxy failed while handling codex endpoint /responses.这一类 endpoint 相关错误以及各种请求 404、路径不存在。多数情况下不是网络问题而是 base_url 拼错了。Codex 发起请求时会在你给的 base_url 后面追加实际接口路径比如/{model}/responses。如果你把 base_url 写成了https://api.xxx.com/v1/responsesCodex 就会拼出https://api.xxx.com/v1/responses/model/responses自然 404。我在自己的测试里把 base_url 写成“根路径版本号”的形态最稳比如https://api.deepseek.com/v1后面的路径交给 Codex 自己补全。排查方法很简单先确定“标准 prompt 路径”到底是什么然后临时构造一个请求看完整 URL 是否合理。如果你不想手写请求可以开 verbose 日志观察 Codex 实际发出的请求地址。日志比报错文案更能说明问题。5.2 auth token unavailable 与 env_key 引用问题报auth token unavailable或者是鉴权失败时先不要怪网络检查三点Provider 配置里的env_key是否是真实存在的环境变量名。该环境变量是否注入到了 Codex 进程所在的环境。尤其用 Docker 跑 Codex 时宿主机 export 的变量不会自动进入容器。环境变量是否为空值。很多 shell 配置文件里export XXX写着值是空字符串Codex 读到之后等于没有。我的做法是先在终端里确认echo $DEEPSEEK_API_KEY返回值不是空再跑 Codex。还有一个细节Codex 可能对 Key 有格式要求比如 key 必须带Bearer前缀。如果服务商要求这种格式但 Codex 只把环境变量原样放入请求头你可能需要在服务商侧配置不带前缀的 Key或者在 Provider 配置里使用支持注入的字段方案。5.3 AGENTS.md 被无视的原因AGENTS.md 写了但 Codex 像没看到这个问题我也困扰了很久。后来总结出几个高频原因文件不在项目根目录而在上一级或无关目录。Codex 是按当前工作目录搜索 AGENTS.md 的你在/home/user/myapp里执行codex exec它找的就是/home/user/myapp/AGENTS.md。文件命名不匹配。有些版本只认AGENTS.md不认AGENTS.txt。内容格式问题。此前有人图方便把所有规则压缩成一句话Codex 没能从这句话里提取出可执行约束。这不叫“被无视”而是“读了等于没读”。多个 AGENTS.md 存在更高优先级覆盖。子目录里如果还有一个 AGENTS.md且内容只写了更少规则Codex 在子目录场景下会因为近端覆盖而忽略部分根目录规则。处理方式很简单执行codex exec 列出你看到的 AGENTS.md 文件路径并总结每条规则。这一步能直接确认加载情况比翻日志快。如果确认加载了还是“不听话”那就是指令写得不够具体回到 3.2 节调整写法。5.4 命令审批与沙盒拦截最后聊一下沙盒和命令审批的体验问题。Codex 在沙盒模式下执行命令可能被拦截表现为“命令需要审批”或直接失败。这里有三个实用配置思路把频繁使用的安全命令放入allows白名单减少打断频率。把确实不需要动命令的任务比如纯代码重构、文本处理放 read-only 沙盒里跑避免误操作。偶尔短时间开danger-full-access来跑一次性任务时务必确认当前目录是项目目录而非家目录或系统目录。家目录下的全权限操作可能引发灾难性后果。日志路径~/.codex/log/codex.log是定位沙盒拦截原因的最佳工具。它会明确告诉你是哪条命令、哪个目录、被什么策略拦下。根据日志逐条调整allows你就能得到一个“既不频繁打扰你又能安全操作”的平衡配置。6. 按调试经验走的最终检查清单写到最后我把自己每次配新环境都会过一遍的检查清单贴出来希望能帮你省点时间用codex config确认实际加载的配置路径和生效值。先用codex exec单次命令验证模型链路再进交互模式。修改配置后务必重启会话确认加载新值。base_url 只写到“根路径版本号”接口路径由 Codex 自动拼接。所有密钥通过环境变量注入不在 TOML 里明文保存。AGENTS.md 采用命令式短句按区块组织重点项目放“红线行为”区。项目规则写在项目根目录别随手丢到子目录。沙盒权限按“最小够用”原则配置安全优先。日志永远比报错文案更接近真相排查问题先从日志入手。这套流程的最终体验是配置好之后我很少再去动 config.toml日常维护主要花在更新 AGENTS.md 上。因为模型能不能跑通是一次性工作而 Agent 是否持续按项目规范执行靠的是 AGENTS.md 这个“说明书”不断迭代。我个人最深的体会是Codex 这类工具的可配置性是把双刃剑。配置得当它能变成完全贴合你工作流的智能伙伴配置随意它就会在各种默认值和你的个人习惯之间摇摆不定。理解 TOML、AGENTS.md 和优先级这三者的分工比记住任何单一字段更重要。以后再遇到“Codex 行为不符合预期”先问自己一句是模型来源的问题、指令表达的问题还是配置覆盖的问题定位准确了一半的故障已经解决了。
返回列表