Codex AGENTS.md 在 symlink 工作区不加载?v0.138 修了(2026)
(updated )

Codex AGENTS.md 在 symlink 工作区不加载?v0.138 修了(2026)

如果你在一个 symlink 工作区里跑 Codex CLI,模型却装作 AGENTS.md 不存在——你不是疯了,你还在 v0.137 或更早。2026-06-08 发布的 v0.138.0 修的就是这个,背后两个 PR 悄悄重写了 Codex 解析指令路径的方式。

故障模式很一致:你 cd 进项目,往上一两层有个完全合法的 AGENTS.md,Codex 起来后模型把里面的规则全当不存在,你花一小时怀疑自己是不是名字打错了。锅基本不在文件上,在 Codex 用的那条路径。

想直接绕过 CLI 的发现链?把 OpenAI SDK 的 base_url 指到 https://api.ofox.ai/v1,直接调 openai/gpt-5.3-codex——ofox 折扣价 $1.49/M input(原价 $1.75/M),Token 计费、支付宝/微信付,ofox.ai 注册 几分钟搞定。下文会讲什么情况下这条路比折腾 CLI 划算。

30 秒确诊:Codex 到底加载了你的 AGENTS.md 没?

在工作区根目录按顺序跑这三条。哪一行报问题就停在哪一行。

步骤命令健康输出
1codex --version0.138.0 或更高
2codex --ask-for-approval never "Summarize the current instructions."Codex 按优先级把你预期的 AGENTS.md 全列出来
3realpath "$(pwd)" vs. pwd要么一致,要么解析出的路径里仍然有你的 AGENTS.md

第 1 步打出 0.137.x 或更老、并且工作区路径里有 symlink——不管是 ~/work 软链到外置 SSD、Docker bind mount,还是 SSHFS 挂载——别再往下看,直接 npm install -g @openai/codex@latest,再跑一次第 2 步。从 Codex issues 跟踪记录 看,光这一次升级就解掉了绝大多数静默跳过案例。

第 1 步已经是 v0.138+ 但第 2 步还是不报你的项目文件,说明要么文件被覆盖,要么发现链路被遮挡了。直接跳到下文 “常见错误对照表” 章节。

什么时候在 CLI 里修,什么时候直接换运行时

不是所有 “AGENTS.md 不加载” 都该在 Codex 里解。有些场景从一开始就不匹配 Codex 的发现模型,硬修一天就没了。

就地升级修复,适用于:

  • 你还在 v0.137 或更早,AGENTS.md 在 symlink、NFS 挂载或 bind mount 后面。
  • monorepo 切到 worktree 后,嵌套的 AGENTS.md 全部停止加载。
  • Remote Codex 在沙箱 VM 里看不到你项目的 AGENTS.md

别再折腾 CLI、换运行时或模型,适用于:

  • 你维护的是 pre-v0.91 工作流,依赖相对路径 symlink 指向 .agents/skillsIssue #9898 已被 closed as not planned。这条解析规则不会回来。把 symlink 换成真目录,或者换一个原生跟 symlink 的 CLI。
  • 合并后的 AGENTS.md 超过 32 KiB。project_doc_max_bytes 上限会静默截断离 cwd 最远的内容。先精简文档,再考虑动工具。
  • 你本来只想要 Codex 调优过的推理能力,CLI 是顺手用的。把 OpenAI SDK 的 base_url 指到 https://api.ofox.ai/v1,直接调 openai/gpt-5.3-codex 就行。模型本身就训过 codebase 导航,跟 AGENTS.md 发现机制完全无关。

止损线: 升到了 v0.138、codex doctor 报告安装一切正常、文件还是不加载,立刻停止 debug Codex 的发现代码。bug 已经搬到你的文件系统了——权限错、空文件,或者上层有 override 把你的覆盖。直接跳到下一节的验证步骤。

内部原理:v0.137 错在哪、v0.138 怎么修的

官方 AGENTS.md 发现规则其实很短,来自 Codex AGENTS.md 文档

  1. 全局~/.codex/AGENTS.override.md 然后 ~/.codex/AGENTS.md。第一个非空文件胜出。
  2. 项目:从 Git 根目录走到当前工作目录,每一层依次查 AGENTS.override.mdAGENTS.md,再查 project_doc_fallback_filenames 列出的备选名。
  3. 合并:从根目录到 cwd 顺序拼接。离 cwd 越近的内容覆盖前面的规则。
  4. 上限:总内容受 project_doc_max_bytes(默认 32 KiB)限制。离 cwd 最远的字节先被截断。

v0.137 错在第 2、3 步里。原来的 walk 直接用 host 系统调用拿到的物理路径,工作区根目录一旦穿过 symlink,walk 走过的那些段就跟用户脑子里的目录树对不上了。

issues 板上反复出现的两种翻车模式:

软链的工作区根目录。 ~/work/proj 是个软链,指向 /Volumes/ssd/proj。你把 AGENTS.md 放在 ~/work/proj/AGENTS.md。物理解析落在 /Volumes/ssd/proj/AGENTS.md,但 Git 根检测器认住的是 ~/work,从没跟着 symlink 跨过去。最后 walk 跑在 [~/work, ~/work/proj] 上,找物理位置在别的盘上的文件。

TUI 连远端的工作区。 沙箱 VM 的文件系统是个快照挂载,驱动跟 host 不一样。v0.137 从 host shell 环境里读出路径,扔到 VM 里去解析,部分段直接 ENOENT 静默返回。walk 把这些段丢掉继续往下,结果就是没你的文件。

v0.138.0 用两个 PR 同时修:

  • PR #26205 — “Route AGENTS.md loading through environment filesystems.” 引入 environment filesystem 抽象。walk 改成问工作区自己的 fs 驱动(local、remote VM、NFS)去解析每一段,而不是直接调 host 层 syscall。
  • PR #26465 — “Preserve logical paths during AGENTS.md discovery.” 在 walk 过程里保留用户视角的路径(比如 ~/work/proj),让 symlink 透明地路由到物理目的地,又不丢掉 Git 根检测器依赖的那一段逻辑名。

官方 changelog 里这条只写了一句:“Workspace instruction loading is more accurate for remote and symlinked workspaces, so the right AGENTS.md files are picked up consistently.” 这两个 PR 就是这句话背后的真东西。

v0.138 之后的发现流程

flowchart TD
    A[codex 在 cwd 启动] --> B{$CODEX_HOME 设了吗?}
    B -- 是 --> C[用 $CODEX_HOME 作全局根]
    B -- 否 --> D[用 ~/.codex 作全局根]
    C --> E[读 全局 AGENTS.override.md,再读 AGENTS.md]
    D --> E
    E --> F[通过 env filesystem 检测 Git 根]
    F --> G[Git 根 → cwd 逐层 walk]
    G --> H{当前层有 override?}
    H -- 是 --> I[override.md 加入合并 buffer]
    H -- 否 --> J{有 AGENTS.md?}
    J -- 是 --> K[AGENTS.md 加入合并 buffer]
    J -- 否 --> L[尝试 project_doc_fallback_filenames]
    I --> M{到达 cwd?}
    K --> M
    L --> M
    M -- 否 --> G
    M -- 是 --> N[拼接后截到 32 KiB]
    N --> O[作为系统指令注入]

发现顺序与优先级

顺序检查路径当层只取第一个匹配
1$CODEX_HOME/AGENTS.override.md(默认 ~/.codex/AGENTS.override.md
2$CODEX_HOME/AGENTS.md
3Git 根的 AGENTS.override.md
4Git 根的 AGENTS.md
5Git 根到 cwd 之间每个目录:override → main → fallback 名每层一个
6cwd:同第 5 行

所有非空匹配都会被拼接进来,总字节封顶 32 KiB,离 cwd 近的内容在截断时存活。

各种典型场景怎么修

场景 1:本地软链工作区

最常见就是 Mac 把 ~/work 软链到外置 SSD,或者 Linux 工作站把 ~/dev 软链到一块更快的 NVMe 分区。升到 v0.138 之后:

npm install -g @openai/codex@latest
codex --version    # 期望 0.138.0 或更高
cd ~/work/proj
codex --ask-for-approval never "Summarize the current instructions."

输出的摘要里应该出现 ~/work/proj/AGENTS.md(或它解析到的物理路径)。如果没出现,按顺序查三个点:

  1. 文件非空。 wc -c AGENTS.md 至少返回 1 字节。空文件静默跳过。最近刚 touch AGENTS.md 然后编辑器崩了,留下零字节空壳的频率比你想象的高。
  2. 没有 override 在覆盖。 find ~/.codex ~/work -name 'AGENTS.override.md' 2>/dev/null。上层任何非空命中都会赢你的项目文件。
  3. $CODEX_HOME 没被改向。 echo $CODEX_HOME 应该是空或者 ~/.codex。如果你在实验时把它指到了项目本地的某个 profile,全局 override 会在那个 profile 里找,而不是 ~/.codex

场景 2:Remote 工作区(Remote TUI / 云沙箱)

Remote Codex 把模型端跑在沙箱 VM 里,TUI 通过 WebSocket 发命令。v0.137 把 host 解析出来的路径转发过去,VM 经常没法重解。v0.138 的 environment filesystem 抽象改成在工作区进程里解析。

codex --remote ws://your-remote-endpoint
# 进 TUI 后:
/status

/status 会报告当前模型、approval 策略、可写根、token 用量;TUI 是远端连接时还会报远程地址和服务器版本。如果 /status 报的工作区根不对,或者模型表现得像没加载 AGENTS.md,问题在你的 WebSocket 会话或工作区挂载,不在发现 walk 上。退出 TUI 用 codex --remote ws://... 重连,重新建立会话。

场景 3:monorepo 嵌套 AGENTS.md

pre-v0.138 的 monorepo 嵌套文件全丢。Issue #13288 抓的就是这种规范布局:

~/monorepo
├── AGENTS.md           # 仓库级规则
├── java/
│   └── AGENTS.md       # Java 服务规则
├── go/
│   └── AGENTS.md       # Go 服务规则
└── packages/web/
    └── AGENTS.md       # 前端规则

v0.137 里从 ~/monorepo 启动 Codex 让它改 java/UserService.java,只会加载根 AGENTS.md。v0.138 的 walk 会走 ~/monorepo → java,按顺序把两份文件拼起来。规则冲突时,离 cwd 近的赢。

真实 monorepo 里 32 KiB 上限会咬你。根文件 28 KiB 公司规范,留给 java/AGENTS.md 的就只剩 4 KiB。先精简根,或者按”根只放根能管的、叶节点写自己的”原则拆。

要知道 Codex 实际挑了哪份,最快的办法是在每个 AGENTS.md 顶部放一行独一无二的 marker——比如 <!-- agents-marker:java -->——然后让模型重复它看到的 marker。离 cwd 最近的那个应该回来。

v0.138 升完之后必跑的 3 步验证

升级本身一条命令。难的是让自己相信升级真的在你这台机器、这个工作区上生效——尤其是你跟静默跳过共存好几周、已经不敢信任 Codex 的输出。这三步加起来跑不到两分钟,覆盖了 issues 板上升级后问题的大多数。

验证 1:让 Codex 把指令链回显出来

官方 AGENTS.md 文档主推的验证命令就是一条非交互 prompt。从你实际启 Codex 的最深目录跑,Codex 会按优先级把所有 AGENTS.mdAGENTS.override.md 列出来。

cd ~/monorepo/java
codex --ask-for-approval never "Summarize the current instructions. List each AGENTS.md path you loaded and the order they were merged."

输出里读三个信号。第一,文件数:你期望某个嵌套文件加载,但摘要里没出现,说明 walk 在那一层断了(经常是因为那个目录跟父目录不在同一文件系统上)。第二,大致内容:叶节点规则在摘要里缺,可能是 32 KiB 上限截断了——这种情况 Codex 在注入前就丢了,根本不报错。第三,顺序:Codex 是从根目录到 cwd 拼接的,离 cwd 近的赢冲突。顺序反了基本上就是上一次会话残留的 $CODEX_HOME

要再清点一次工作区根和配置状态,可以跑 codex doctor(或 codex doctor --json 拿机器可解析输出),它会打出安装/认证/运行时/配置的诊断信息——排除掉 Codex 自己配置问题再去怀疑发现 walk。

验证 2:把 sentinel marker 在模型里走一圈

验证 1 的摘要确认了 Codex 报出哪些文件,但不保证每个字节都活到了模型那一端。两者会偏离:要么 32 KiB 截了一段,要么你 harness 里某个 hook 把系统 prompt 剥了。

在合并链上每份 AGENTS.md 顶部放一个独一无二 sentinel:

<!-- agents-marker:java-leaf -->

然后在新会话里让模型:“把你系统指令里所有 agents-marker:* 注释一字不差地重复一遍。” 全部回来就说明合并活下来了。只回根 marker、缺叶节点的,那就是撞 32 KiB——在叶节点被截前先精简根。

同样的 trick 也抓 override 遮蔽。AGENTS.override.md 里塞一个 agents-marker:override,你忘了的 override 文件赢了你基础文件这件事立刻露馅。

第三步专门抓 v0.138 修过、但很容易意外退回去的那个回归——Codex 跑在一条路径本身就是 symlink 的目录上,不只是工作区里有 symlink。

mkdir -p /tmp/codex-sym-test/real
echo "<!-- agents-marker:symtest -->" > /tmp/codex-sym-test/real/AGENTS.md
ln -s /tmp/codex-sym-test/real /tmp/codex-sym-test/linked
cd /tmp/codex-sym-test/linked
codex --ask-for-approval never "Repeat every agents-marker comment you see in your system instructions verbatim."

摘要回 <!-- agents-marker:symtest -->,说明 environment filesystem 抽象在你这台机上工作正常。回不来的话,要么升级没真的落(重看 codex --version),要么你的 shell realpath 解析出的物理路径跟工作区进程看到的不一样。把测试目录搬到 home 目录再试一次,再去开 issue。

这三步同样适合写进团队 runbook,三个月后别人撞同样问题时直接照着跑。验证流程跟触发源是 symlink 工作区、Remote 沙箱还是 monorepo 子树无关——底层问题永远是 “Codex 是不是看到了我预期它看到的文件”。

常见 AGENTS.md 加载报错对照表

现象可能原因修法
指令摘要里一份 AGENTS.md 都没有pre-v0.138 CLI + symlink 工作区根升级到 v0.138.0 或更高
摘要里有文件但显示指令为空文件是 touch 出来的、从没写过内容至少写一行非空白;wc -c 验证
只在某个分支上模型表现像没加载规则之前实验留下的 AGENTS.override.md 还在find . -name 'AGENTS.override.md',复核后删除
monorepo 子目录里嵌套 AGENTS.md 被忽略pre-v0.138 walk 只看启动目录升级到 v0.138.0 或更高
Remote TUI 在工作区改完后还加载旧 AGENTS.md沙箱 VM 快照缓存退出 TUI 用 codex --remote ws://... 重连,再 /status
切项目 cd 后加载到错的 AGENTS.md$CODEX_HOME 还指着上一个项目的 profileunset CODEX_HOME 或按 shell 限定作用域
.agents/skills/SKILL.md 走 symlink 不被加载Issue #11314 closed as not planned把 symlink 换成真目录;用 cp -r,别用 ln -s

如果你卡在的不是发现机制而是 codex 命令本身找不到,看 Codex CLI 装完报 “command not found” 的 7 个修法;常见运行时报错(429、context too long、stream 中断)汇总见 Codex CLI 常见报错排查

Codex AGENTS.md 史:2026 真实 issues

v0.138 不是一个 bug fix 修出来的,是一串相似报告堆出来的,其中好几个在工作区抽象落地前被驳回。这个分布很说明项目实际投资在哪。

Issue上报时间状态内容
#87592025 年底Closed(已修)CLI 默认情况下读不到全局 ~/.codex 里的 AGENTS.md
#89432025 年 11 月Closed(not planned)~/.codex/skills/public 下的软链目录被跳过
#98982026 年 1 月Closed(not planned)相对路径 symlink 从 cwd 解析,而不是从 symlink 所在目录
#104702026 年 2 月Closed(not planned)软链的 SKILL.md 不读
#113142026 年 3 月Closed(not planned).agents/skills 本身是 symlink:没有 skills 被发现
#132882026 年 5 月Closed(v0.138 修复)monorepo 子目录嵌套 AGENTS.md 被忽略
#247702026 年 6 月OpenPlugin install:跨 agent marketplace 契约里的 symlink

分裂很清晰。所有针对 SKILL.md.agents/skills 树的 symlink 报告都被 closed as not planned,只有 AGENTS.md 和工作区根解析被判定值得做抽象。如果你的工作流靠软链 skills 目录本身,v0.138 帮不上你——换成真目录,或者选一个把 symlink 当一等公民的 CLI。

Codex 装不下你的指令:现在能用的几条替代路径

绝大多数团队的正解还是 “升 v0.138”。下面这些是给那些 Codex 发现模型确实兜不住的边角场景。

一览

路径适合谁摩擦成本
升 Codex 到 v0.138本地 symlink、Remote TUI、monorepo一条 npm install 之外没了免费
通过 ofox 直接调 openai/gpt-5.3-codex想完全跳过 CLI 发现的人自己在 harness 里实现读文件按 token 计费,ofox 折扣价 $1.49/M input(原价 $1.75/M)
把 symlink 换成真目录钉死在某个 CLI 版本、没法升级一次性拷贝 + 新同步流程免费,吃硬盘
换到 Claude Code 或 Cursor.agents 树重度 symlink、当共享库用团队要学新工具后端可以走同一个 ofox

1. 用 ofox 直接调 GPT-5.3-Codex

如果你用 Codex 的原因是 GPT-5.3-Codex 模型的代码能力——512K 上下文、agentic 工具调用、codebase 导航——绕开 CLI 完全可行。模型本身就在 ofox 的 OpenAI 兼容端点 上提供。在你自己的 harness 里读 AGENTS.md,作为 system prompt 传进去就行:

from openai import OpenAI
client = OpenAI(base_url="https://api.ofox.ai/v1", api_key="ofox-...")
with open("AGENTS.md") as f:
    house_rules = f.read()
resp = client.chat.completions.create(
    model="openai/gpt-5.3-codex",
    messages=[{"role": "system", "content": house_rules},
              {"role": "user", "content": "Refactor UserService.java to async."}],
)
print(resp.choices[0].message.content)

这条路径完全跳过发现 walk。代价是你得在 harness 里自己实现读文件、多层合并、override 语义——但你也不用再跟 symlink 解析较劲了。ofox 定价:折扣价 $1.49/M input、$11.90/M output、cache read $0.153/M(原价 $1.75/M input)。注册和支付走 ofox.ai,支付宝/微信都行。

不想换模型的话,务实的补丁就是 cp -r 代替 ln -s。真目录在所有 Codex 版本上都工作,包括 pre-v0.91。issues #9898#10470#11314 的 reviewer 已经把立场摊明:symlink 在 skills 树上不是一等公民,将来也不是。把这当事实,绕着它设计你的项目结构。

之前靠软链 .agents/skills 的共享库工作流,可以换成签入子树或 git submodule。两种都落在真目录上,每个 Codex 版本都加载。

Claude Code 和 Cursor 都从物理文件系统路径读项目规则,默认跟 symlink。如果你团队的 .agents/skills 是跨多仓库软链的共享规则库,这两个工具都不会跟你打架。两边都设 OPENAI_BASE_URL=https://api.ofox.ai/v1 就能路由到 Codex 用的同一后端,模型选择跟 CLI 选择脱钩。

注意这是换工具,不是换模型。两个 CLI 里都能继续调 openai/gpt-5.3-codex。想批量管理这种多 CLI 切换,看 cc-switch 多 CLI 配置

4. 留在 v0.137 用 workaround

今天升不了——CI 锁了、binary 是 vendored 的、Docker 镜像冻结——绕路是把解析后的 AGENTS.md 复制到 v0.137 walk 实际访问的目录:

cp "$(realpath ~/work/proj/AGENTS.md)" ~/work/proj/AGENTS.md.physical
mv ~/work/proj/AGENTS.md.physical ~/work/proj/AGENTS.md

不优雅。每次源文件变更都得手工再同步一次。冻结一解除立刻升。

AGENTS.md 加载的监控与告警

v0.138 之后仍可能静默失败:有人在父目录加了个 AGENTS.override.md,盖掉了你维护的文件,模型行为变了但没有报错。两个实际能用的护栏,能在你下次开 debug session 之前抓到这种事。

sentinel-marker pre-flight 脚本

可以用非交互方式让 sentinel 在模型里跑一圈,回不来就让 CI 失败。在项目 AGENTS.md 顶部加一行 <!-- agents-marker:repo-root -->,然后:

#!/bin/bash
# scripts/preflight-codex.sh
marker="agents-marker:repo-root"
out="$(codex --ask-for-approval never exec \
  "Repeat every agents-marker comment you see in your system instructions verbatim.")"
echo "$out" | grep -q "$marker" || {
  echo "AGENTS.md 未加载:响应里缺 marker '$marker'"; exit 1; }

注意参数顺序:--ask-for-approval 是全局 flag,必须放在 exec 子命令前面。codex exec --ask-for-approval never 会被当作未知 exec flag 拒掉。

挂进 npm run codex 或团队约定的入口。CI 在有人发现 “模型怎么把 style guide 忘了” 之前就抓 override 遮蔽和截断。

在仓库层面盯 override 文件

**/AGENTS.override.md 加进 .gitignore。同事实验留下的新 override 文件 git status 会立刻标出来,gitignore 也防止意外 commit。配一条 Renovate 或 Dependabot 规则升 @openai/codex,团队就能自动拿到后续发现机制的修复,不用人工跟。

package.json 里钉 Codex 版本

{
  "engines": {
    "codex": ">=0.138.0 <0.140.0"
  }
}

工作区发现的改动不带 feature flag,v0.137 → v0.138 就是最近的例子。在 engines(或对应的工具注册表)里钉一个范围,能防止 latest 把你的团队漂移到一个还没审过的行为变化上。订阅 Codex releases feed,测过再调上界。

写完这次的核对源

一整年 symlink 报告堆下来的结论是:Codex 把 AGENTS.md 当一等概念,把 .agents/skills 当未文档化的行为。如果你的工作流靠后者,别等 v0.139——换工具,那个版本不会来。