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 没?
在工作区根目录按顺序跑这三条。哪一行报问题就停在哪一行。
| 步骤 | 命令 | 健康输出 |
|---|---|---|
| 1 | codex --version | 0.138.0 或更高 |
| 2 | codex --ask-for-approval never "Summarize the current instructions." | Codex 按优先级把你预期的 AGENTS.md 全列出来 |
| 3 | realpath "$(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/skills。Issue #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 文档:
- 全局:
~/.codex/AGENTS.override.md然后~/.codex/AGENTS.md。第一个非空文件胜出。 - 项目:从 Git 根目录走到当前工作目录,每一层依次查
AGENTS.override.md、AGENTS.md,再查project_doc_fallback_filenames列出的备选名。 - 合并:从根目录到 cwd 顺序拼接。离 cwd 越近的内容覆盖前面的规则。
- 上限:总内容受
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 | 是 |
| 3 | Git 根的 AGENTS.override.md | 是 |
| 4 | Git 根的 AGENTS.md | 是 |
| 5 | Git 根到 cwd 之间每个目录:override → main → fallback 名 | 每层一个 |
| 6 | cwd:同第 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(或它解析到的物理路径)。如果没出现,按顺序查三个点:
- 文件非空。
wc -c AGENTS.md至少返回 1 字节。空文件静默跳过。最近刚touch AGENTS.md然后编辑器崩了,留下零字节空壳的频率比你想象的高。 - 没有 override 在覆盖。
find ~/.codex ~/work -name 'AGENTS.override.md' 2>/dev/null。上层任何非空命中都会赢你的项目文件。 $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.md 和 AGENTS.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 文件赢了你基础文件这件事立刻露馅。
验证 3:symlink round-trip 测试
第三步专门抓 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 还指着上一个项目的 profile | unset 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 | 上报时间 | 状态 | 内容 |
|---|---|---|---|
| #8759 | 2025 年底 | Closed(已修) | CLI 默认情况下读不到全局 ~/.codex 里的 AGENTS.md |
| #8943 | 2025 年 11 月 | Closed(not planned) | ~/.codex/skills/public 下的软链目录被跳过 |
| #9898 | 2026 年 1 月 | Closed(not planned) | 相对路径 symlink 从 cwd 解析,而不是从 symlink 所在目录 |
| #10470 | 2026 年 2 月 | Closed(not planned) | 软链的 SKILL.md 不读 |
| #11314 | 2026 年 3 月 | Closed(not planned) | .agents/skills 本身是 symlink:没有 skills 被发现 |
| #13288 | 2026 年 5 月 | Closed(v0.138 修复) | monorepo 子目录嵌套 AGENTS.md 被忽略 |
| #24770 | 2026 年 6 月 | Open | Plugin 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,支付宝/微信都行。
2. 钉真目录,扔掉 symlink
不想换模型的话,务实的补丁就是 cp -r 代替 ln -s。真目录在所有 Codex 版本上都工作,包括 pre-v0.91。issues #9898、#10470、#11314 的 reviewer 已经把立场摊明:symlink 在 skills 树上不是一等公民,将来也不是。把这当事实,绕着它设计你的项目结构。
之前靠软链 .agents/skills 的共享库工作流,可以换成签入子树或 git submodule。两种都落在真目录上,每个 Codex 版本都加载。
3. symlink 重度工作流:Claude Code 或 Cursor
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,测过再调上界。
写完这次的核对源
- OpenAI Codex Changelog(2026 年 6 月)(2026-06-10 复核)
- Codex AGENTS.md 发现指南(2026-06-10 复核)
- openai/codex Release v0.138.0(2026-06-10 复核,2026-06-08 23:00 UTC 发布)
- GitHub Issues:#8759、#9898、#11314、#13288
- ofox GPT-5.3-Codex 模型页(2026-06-10 复核,$1.49/M input / $11.90/M output / $0.153/M cache read 为 ofox 折扣价;原价 $1.75/M input)
- 相关阅读:Codex CLI 装完报 “command not found” 的 7 个修法
一整年 symlink 报告堆下来的结论是:Codex 把 AGENTS.md 当一等概念,把 .agents/skills 当未文档化的行为。如果你的工作流靠后者,别等 v0.139——换工具,那个版本不会来。


