这篇不是源码逆向,也不是把本地缓存当成绝对真相。更准确地说,它是一种“运行时考古”:观察 $CODEX_HOME 下由 Codex 内核管理的目录、SQLite schema、缓存和官方文档之间的对应关系,反推出 Codex 的核心抽象和工程哲学。
结论先放前面:.codex 不是普通配置目录。它更像一个本地 agent runtime home,里面同时放着控制面、状态面、执行面、扩展面、安全面、后台任务和长期记忆。Codex 也不只是一个“会调用模型的 CLI”,而是一个围绕线程、工具、权限、扩展和可恢复执行组织起来的轻量 agent OS。
1. 先把 .codex 看成 CODEX_HOME
如果只看目录名,很容易把 .codex 理解成:
config.toml
sessions
cache
plugins
skills
worktrees
logs
但换一个视角,它其实更像一个运行时根目录:
CODEX_HOME
├── control plane
├── state plane
├── execution plane
├── extension plane
├── isolation plane
├── audit plane
└── memory plane
这个视角比“按目录逐个解释”更有用,因为 Codex 的内核不是围绕文件夹命名组织的,而是围绕 agent 工作流组织的:
- 用户发起一个线程。
- 线程里产生 turn 和 item。
- item 可以是消息、工具调用、命令、文件变化、浏览器动作或 agent 输出。
- 执行过程受 sandbox、approval、project trust、hooks、rules 控制。
- 能力通过 skills、plugins、MCP servers、apps 注入。
- 长任务、后台任务和并行任务通过 worktrees、automations、subagents 隔离。
- 结果被写入 sessions、SQLite、logs、history、snapshots,方便恢复、索引、审计和继续执行。
所以 .codex 透露出的第一条内核原则是:
Codex 把 agent 工作当成可恢复、可审计、可扩展的本地运行时,而不是一次性 prompt-response。
2. 控制面:config.toml 是本地内核的装配表
config.toml 暴露出 Codex 的控制面。它不是只有模型名,而是把几个关键维度放在同一个配置层里:
model / model_provider / reasoning_effort
sandbox_mode / approval_policy
features
mcp_servers
plugins
projects.*.trust_level
skills.config
这说明 Codex 的默认行为不是写死在某个客户端里,而是由配置层叠加出来的。Config basics 也明确说,Codex 会从 CLI overrides、项目 .codex/config.toml、profile、用户级 config.toml、系统级配置和内置默认值里解析最终配置。
这背后有一个很重要的工程判断:不同工作区的风险边界不同。一个 Git 项目、一个下载目录、一个临时目录、一个企业托管环境,不应该共享同一套权限和工具策略。
所以 projects.*.trust_level 很关键。项目被信任之后,Codex 才会加载项目级 .codex 配置、hooks、rules。否则用户级和系统级配置仍然生效,但项目本地的可执行控制面不会自动进入运行时。
这是一种典型的 agent 安全设计:能力可以分层注入,但项目本地能力必须先过 trust boundary。
3. 状态面:Thread 是 Codex 的第一公民
.codex/sessions 和 state_*.sqlite 暴露了 Codex 的状态模型。App Server 文档把核心原语定义成:
Thread:一段用户和 Codex agent 的对话
Turn:一个用户请求和随后的 agent 工作
Item:输入或输出单元,例如消息、命令、工具调用、文件变化
本地状态也正好围绕这个模型展开:
sessions/ 原始会话与 rollout
session_index 会话索引
history 历史事件
state.sqlite thread 元数据、动态工具、远程控制、agent jobs
logs.sqlite 本地运行日志
goals.sqlite thread goal 与预算状态
memories.sqlite memory 生成流水线状态
这透露出第二条原则:
Codex 不只保存聊天记录,它保存 agent 工作的结构化索引。
普通聊天产品只需要按时间存 message。Codex 需要更多维度:
这个 thread 在哪个 cwd 里?
使用了哪个模型和 provider?
当时 sandbox / approval 是什么?
关联哪个 git branch / sha?
有没有动态工具?
有没有子 agent 派生关系?
有没有 goal budget?
是否已归档?
能不能从本地、worktree 或远程恢复?
这些字段不是 UI 装饰,而是 agent runtime 的必要状态。因为 Codex 要支持恢复线程、fork 线程、handoff、后台执行、远程控制、自动化和审计,就必须把“对话”升级成“可管理的任务实体”。
4. 执行面:Shell、Browser、Computer Use 是不同等级的现实接口
.codex 里有几类执行相关目录:
shell_snapshots
node_repl
process_manager
browser/sessions
computer-use
generated_images
attachments
它们代表 Codex 接触现实世界的不同层级。
第一层是 shell。Codex 可以执行命令、读写文件、跑测试、启动服务。shell_snapshots 说明它会缓存 shell 环境,用来加速或复现重复命令。
第二层是浏览器。内置浏览器适合本地开发服务器、file-backed preview、公开页面检查。官方文档强调它和用户常用浏览器不同:不共享登录态、扩展、已有 cookies。这个边界很重要,因为浏览器页面是高风险 prompt-injection 来源。
第三层是 Computer Use。它不是代码工具,而是 GUI 操作层:看屏幕、点窗口、输入、跨 app 操作。官方文档也把它定位为命令行和结构化集成不够时的补充,并且强调需要 macOS Screen Recording / Accessibility 这样的系统权限。
这三层共同说明:
Codex 的执行面不是单一工具,而是从文件系统、进程、网页到桌面 GUI 的分层现实接口。
这也解释了为什么 Codex 需要强权限模型。只要 agent 能从“改 repo 文件”扩展到“点浏览器里的按钮”和“操作桌面 app”,它就不再只是代码助手,而是在用户机器上运行的自治工作流系统。
5. 扩展面:Skill、Plugin、MCP 是三种不同抽象
.codex/skills、.codex/plugins/cache、.codex/vendor_imports、cache/remote_plugin_catalog、cache/codex_apps_tools 暴露出 Codex 的扩展面。
这几个概念容易混在一起,但职责其实不同:
Skill 复用工作流,主要是说明、参考资料、脚本
Plugin 可安装分发单元,可以打包 skills、apps、MCP servers、assets
MCP 工具和上下文协议,让模型接入外部系统或本地工具
App 更高层的连接器或产品集成
Skills 文档里有一句很关键:skills 使用 progressive disclosure。也就是说,Codex 一开始只看 skill 的名称、描述和路径;只有决定使用某个 skill 时,才读取完整 SKILL.md。
这是一种面向大上下文系统的工程优化:能力很多,但不能把所有说明都塞进 prompt。先用短描述做路由,再按需加载完整说明。
Plugins 则是分发层。一个 plugin 可以带 skills、app integrations、MCP servers。用户可以安装、启用、禁用插件;插件也可以提供自己的 MCP server 和 lifecycle hooks。
MCP 是工具协议层。Codex 可以通过 stdio 或 HTTP MCP server 获取工具、资源和 server instructions。配置里还支持 tool allowlist、denylist、approval mode、startup timeout、tool timeout。
所以 Codex 的扩展哲学不是“给模型更多 prompt”,而是:
把能力包装成可发现、可路由、可启用、可禁用、可授权、可审计的 runtime component。
这和传统 IDE 插件有相似之处,但更强调模型如何选择工具、如何遵循 workflow、如何受权限约束。
6. 安全面:Sandbox 和 Approval 分工明确
Codex 的安全模型可以用一句话概括:
sandbox 决定技术上能做什么;
approval 决定越界时要不要问人。
Agent approvals & security 把两者分得很清楚。sandbox 是 OS 层或运行时层边界,比如能否写文件、能否访问网络、能否写工作区之外。approval policy 是决策层边界,比如什么时候暂停并请求用户许可。
常见组合大致是:
read-only + on-request
workspace-write + on-request
danger-full-access + never
这背后的哲学不是“默认不信任 agent”,也不是“默认完全信任 agent”。更准确地说:
Codex 试图把低风险重复动作放进边界内自动完成,把高风险动作推到边界上显式审查。
这也解释了 hooks、rules、project trust 的位置。
hooks 是生命周期控制:在 tool use 前后、permission request、compact、session start、stop 等事件上挂检查或自动化。rules 更像命令级策略:允许、提示或禁止某些命令前缀。project trust 则决定项目本地配置和 hooks 是否能被加载。
安全不是一个单点开关,而是多层组合:
project trust
config precedence
sandbox
approval policy
auto-review
rules
hooks
MCP tool approval modes
plugin enablement
computer-use app approvals
这是一套适合 agent 的安全模型,因为 agent 的风险不是单一来源。风险可能来自命令、文件、网络、浏览器页面、MCP tool、插件、项目本地 hooks,甚至来自桌面 GUI 操作。
7. 并行面:Worktree、Automation、Subagent 解决不同并行问题
.codex/worktrees 和 .codex/automations 暴露出 Codex 对后台工作的设计。
Worktrees 解决的是代码隔离。官方文档说 Codex-managed worktree 默认放在 $CODEX_HOME/worktrees,通常处于 detached HEAD,用来让后台线程或 automation 不污染用户当前 checkout。
Automations 解决的是时间维度。它可以定时启动独立任务,也可以作为 thread automation 在同一个线程里周期性唤醒。官方文档还特别提醒,automation 会使用默认 sandbox settings;如果在 full access 下运行无人值守任务,风险更高。
Subagent 解决的是任务分解和上下文污染问题。官方文档说 Codex 只有在用户显式要求时才会 spawn subagents。它们适合并行探索、测试、日志分析、总结,把噪声留在子线程里,主线程只接收蒸馏后的结果。
这三个机制看起来都叫“并行”,但其实解决的是三类不同问题:
worktree 文件系统隔离
automation 时间调度和无人值守
subagent 认知分工和上下文隔离
这透露出一个很成熟的工程判断:agent 的并行不只是多开几个模型。并行必须同时考虑代码冲突、权限继承、上下文污染、后台任务生命周期和结果汇总。
8. Memory:有用的本地回忆,但不是规则源
memories 和 memories_*.sqlite 代表 Codex 的长期记忆面。
Memories 文档对 memory 的定位很克制:它可以记住稳定偏好、常见工作流、技术栈、项目约定、已知坑;但团队必须遵守的规则仍应放在 AGENTS.md 或项目文档里。
这一区分很重要:
AGENTS.md 是显式规则和团队约定
config 是运行时控制面
memory 是本地经验回忆层
sessions 是历史事实
如果把 memory 当规则源,就会让系统变得不可预测。因为 memory 是生成态、延迟更新、可能被跳过、也可能被 redaction 或 rate limit 影响。它适合“帮我少重复背景”,不适合“必须永远执行某条安全规则”。
这也反映 Codex 的另一条工程哲学:
生成出来的经验可以辅助,但确定性控制必须留在显式配置、文档和策略里。
9. 这些目录合起来像什么
把所有面合在一起,.codex 可以这样理解:
config.toml
控制面:模型、权限、功能开关、MCP、插件、项目信任
sessions / state.sqlite / history / logs
状态面:线程、turn、item、索引、日志、目标、审计
packages / app-server-daemon / app-server-control
本地 runtime:standalone binary、daemon、rich client control
skills / plugins / vendor_imports / cache
扩展面:能力包、插件市场、工具目录、按需加载
shell_snapshots / process_manager / node_repl
命令执行面:进程、shell 环境、交互式执行
browser / computer-use / attachments / generated_images
多模态执行面:网页、GUI、附件、图片
worktrees / automations
后台和隔离面:定时任务、独立 checkout、任务恢复
memories
长期经验面:偏好、稳定上下文、历史总结
这就是我说它像本地 agent OS 的原因。它不是完整操作系统,但它具备 OS-like 的几个特征:
有进程和任务生命周期
有权限边界
有扩展和驱动
有本地状态数据库
有日志和审计
有后台任务
有隔离工作区
有跨客户端控制协议
有长期记忆
如果用一句话概括 Codex 内核的工程哲学,我会写成:
让模型在清晰边界内自治,把能力做成可组合组件,把每次工作保存成可恢复的结构化状态。
10. 对我们使用 Codex 的启发
这个视角对日常使用很有帮助。
第一,不要把 AGENTS.md、skills、memory、config 混用。
一次性约束 放 prompt
团队规则 放 AGENTS.md
运行时默认 放 config.toml
可复用工作流 做 skill
可安装能力包 做 plugin
外部系统工具 接 MCP / app
定时或巡检 用 automation
本地经验 交给 memory
强制安全控制 用 sandbox / approval / rules / hooks
第二,给 Codex 更多权限之前,先想清楚边界。
很多时候不需要 danger-full-access。如果只是需要多写几个目录,可以扩展 writable roots;如果只是某个命令需要例外,可以用 rules;如果只是项目长期约定,可以写进 AGENTS.md;如果只是一次任务,可以留在当前 prompt。
第三,把复杂工作拆成不同隔离层。
代码修改适合 worktree;定时检查适合 automation;读很多材料适合 subagents;固定流程适合 skill;外部系统访问适合 MCP;视觉验证适合 in-app browser;桌面软件才需要 Computer Use。
第四,定期清理 runtime home。
sessions、logs、worktrees、plugins/cache、packages/releases、generated_images 都可能增长很快。清理时不要粗暴删除正在关联的 worktree 或会话,最好通过 Codex app 的归档、清理和设置入口处理。这个目录承载的不只是缓存,还有恢复和审计状态。
结语
从 .codex 这个目录看 Codex,最有意思的地方不是“它藏了哪些文件”,而是它把 agent 产品的工程边界显露出来了。
一个真正可用的 coding agent,不能只靠一个强模型。它需要本地控制面、结构化状态、工具协议、权限系统、扩展市场、可恢复会话、后台工作区、日志审计和长期记忆。
模型是推理核心,但 .codex 才让这种推理落到一台真实机器、一组真实项目和一套真实工作流里。
这就是 Codex 目录透露出的内核原理:agent 的能力不是一次回答,而是一套可以被配置、执行、约束、扩展、恢复和审计的运行系统。