Codex 使用教程:从项目规则、Skills、Rules 到 Hooks
摘要
Codex 不只是一个临时聊天窗口。更准确地说,它是一个可以读取项目规则、调用技能、执行工具、触发自动化脚本的 AI 编程代理。
如果你只是每次打开 Codex 后重新告诉它"这个项目是做什么的""文档放哪里""回答结束后记得记录问答",那么 Codex 的能力会被浪费。真正适合长期使用的方式,是把不同类型的规则放到不同位置:
text
AGENTS.md:项目级长期规则
Skills:可复用任务流程
.rules:命令权限和审批规则
Hooks:生命周期中的自动脚本
每日记录:把学习过程沉淀成文档
这篇文章按初学者视角,从零讲清楚这些概念分别是什么、放在哪里、什么时候用、容易误解在哪里。
先建立一个整体模型
可以把 Codex 的工作过程理解成下面这条链路:
用户提出任务
Codex 读取项目规则 AGENTS.md
判断是否需要 Skills
执行文件读取、代码修改、文档生成等工具操作
受 .rules 和审批策略约束
Hooks 在关键生命周期节点运行脚本
输出结果并写入每日记录
这张图里最重要的不是"工具很多",而是分工清楚:
AGENTS.md解决"Codex 应该知道什么项目规则"。Skills解决"某类任务应该按什么流程做"。.rules解决"哪些命令允许、哪些命令要确认、哪些命令禁止"。Hooks解决"在固定时机自动运行什么脚本"。- 每日记录解决"如何把问答和学习过程保存下来"。
Codex 项目规则是什么
Codex 项目规则通常写在项目根目录的 AGENTS.md 中。
在当前学习项目里,项目级规则文件是:
text
D:\your_project\AGENTS.md
它的目的不是写一篇长文档,而是告诉 Codex:在这个仓库里工作时应该遵守哪些基本约定。
一个典型的 AGENTS.md 可以包含:
markdown
# Codex Project Rules
This file defines the project-level instructions Codex should follow when working in this repository.
## Purpose
This repository is a learning workspace for understanding how Codex project rules, workflows, and skills are organized.
## General Rules
- Read the existing project structure before changing files.
- Keep examples small, explicit, and easy to study.
- Prefer Markdown documentation for learning notes.
- Do not add external dependencies unless the task clearly requires them.
- Keep generated examples in ASCII unless a Chinese learning document benefits from Chinese text.
## Workflow
1. Understand the request and inspect the relevant files.
2. Pick the smallest useful change.
3. Explain the planned edit before modifying files.
4. Create or update files using the existing project style.
5. Verify the resulting structure or behavior.
6. Summarize what changed and how to use it.
## Skill Usage
Project-local skills live under:
```text
.agents/skills/<skill-name>/SKILL.md
Use a project-local skill when the user's request matches its description field. Keep each skill focused on one reusable workflow.
Completion Criteria
- The requested files or behavior exist.
- The project structure is still easy to understand.
- Any important next steps are documented.
这份规则包含五类信息:
| 部分 | 作用 |
|---|---|
Purpose |
告诉 Codex 这个仓库为什么存在 |
General Rules |
告诉 Codex 一般工作约束 |
Workflow |
告诉 Codex 做任务的步骤 |
Skill Usage |
告诉 Codex 本地 skill 放在哪里 |
Completion Criteria |
告诉 Codex 什么叫完成 |
AGENTS.md 应该写什么
初学者最容易犯的错误,是把 AGENTS.md 当成"什么都往里塞的项目百科"。
更合理的原则是:
text
AGENTS.md 只放始终相关的信息。
适合写进 AGENTS.md 的内容:
text
项目目的
目录结构
开发流程
代码风格
文档位置
测试命令
不允许做的事
完成标准
项目本地 skills 的位置
不适合写进 AGENTS.md 的内容:
text
某次对话的完整历史
某个 bug 的全部排查过程
某个模块几十页实现细节
一次性临时约定
大量会议记录
原因很简单:Codex 每次进入项目时都会读取这些项目说明。如果 AGENTS.md 写得太长,就会浪费上下文空间,还会让真正关键的规则被淹没。
所以 AGENTS.md 要短、明确、可执行。
全局规则和项目规则
Codex 可以同时读取全局规则和项目规则。
常见位置是:
text
C:\Users\your_username\.codex\AGENTS.md
项目根目录\AGENTS.md
二者区别如下:
| 文件 | 范围 | 适合写什么 |
|---|---|---|
C:\Users\your_username\.codex\AGENTS.md |
当前 Windows 用户的所有 Codex 项目 | 个人工作习惯 |
项目根目录\AGENTS.md |
当前仓库 | 仓库规则、目录结构、验证方式 |
例如,全局规则可以写:
markdown
## Working agreements
- Prefer Markdown for learning notes.
- Ask before adding large dependencies.
- Keep explanations beginner-friendly when the user is studying a concept.
项目规则可以写:
markdown
## Repository expectations
- Keep examples small.
- Put daily notes under `技术文档/每日记录/`.
- Put generated blog drafts under `技术文档/博客/`.
一句话区分:
text
全局 AGENTS.md:我的通用工作习惯
项目 AGENTS.md:这个仓库的具体规则
Codex 如何按层级读取规则
Codex 不是只读取一个文件,而是会建立一条"指令链"。
顺序大致是:
text
全局规则
↓
项目根目录规则
↓
当前子目录规则
例如存在这些文件:
text
~/.codex/AGENTS.md
项目根目录/AGENTS.md
services/payments/AGENTS.override.md
如果你在项目根目录启动 Codex,它通常只读取:
text
1. ~/.codex/AGENTS.md
2. 项目根目录/AGENTS.md
它不会继续扫描:
text
services/payments/AGENTS.override.md
因为 Codex 只会从项目根目录一路查到当前工作目录。
如果你从支付目录启动:
bash
codex --cd services/payments
或者当前工作目录就是:
text
项目根目录/services/payments/
Codex 才会读取:
text
1. ~/.codex/AGENTS.md
2. 项目根目录/AGENTS.md
3. services/payments/AGENTS.override.md
这里的关键点是:
text
Codex 读取的是"项目根目录到当前目录"这条路径上的规则,不会扫描所有子目录。
AGENTS.override.md 是什么
AGENTS.override.md 是覆盖文件。
在同一个目录里,Codex 会优先读取:
text
AGENTS.override.md
如果它存在,就不会再读取同目录下的:
text
AGENTS.md
它适合用在"某个子目录需要特殊规则"的场景。
例如支付服务目录:
markdown
# services/payments/AGENTS.override.md
## Payments service rules
- Use `make test-payments` instead of `npm test`.
- Never rotate API keys without notifying the security channel.
这种规则不应该写到整个项目根目录,因为它只适用于支付服务。
fallback 文件名是什么
Codex 默认认识两个项目说明文件名:
text
AGENTS.override.md
AGENTS.md
如果你的项目已经有自己的规则文件,例如:
text
TEAM_GUIDE.md
PROJECT_RULES.md
CONTEXT.md
.agents.md
Codex 默认不会把它们当成项目规则文件读取。
这时可以在配置中加入 fallback 文件名:
toml
project_doc_fallback_filenames = ["TEAM_GUIDE.md", ".agents.md"]
project_doc_max_bytes = 65536
配置后,Codex 在每个目录里会按顺序找:
text
1. AGENTS.override.md
2. AGENTS.md
3. TEAM_GUIDE.md
4. .agents.md
注意:每个目录最多只读取一个文件。
如果某个目录里同时有:
text
AGENTS.md
TEAM_GUIDE.md
Codex 会读取:
text
AGENTS.md
不会继续读取:
text
TEAM_GUIDE.md
如果某个目录没有 AGENTS.md,但有:
text
TEAM_GUIDE.md
并且你配置了:
toml
project_doc_fallback_filenames = ["TEAM_GUIDE.md"]
Codex 才会读取 TEAM_GUIDE.md。
所以 fallback 文件名的本质是:
text
Codex 默认文件不存在时,允许使用的备用规则文件名。
它不是"让 Codex 读取所有文档"的机制。
项目说明文件大小限制
Codex 不会无限读取所有项目说明。
默认情况下,合并后的项目说明有大小限制。文档中提到默认是:
text
32 KiB
可以通过配置调整:
toml
project_doc_max_bytes = 65536
但更好的做法不是一味调大,而是拆分内容:
text
始终相关的规则 -> AGENTS.md
模块专属规则 -> 子目录 AGENTS.md 或 AGENTS.override.md
任务流程 -> Skills
历史记录 -> 技术文档/每日记录
如何验证 Codex 加载了哪些规则
可以用命令让 Codex 总结当前指令:
bash
codex --ask-for-approval never "Summarize the current instructions."
也可以在子目录中验证:
bash
codex --cd services/payments --ask-for-approval never "List the instruction sources you loaded."
如果规则没有生效,可以检查:
text
是否在正确的仓库目录启动 Codex
AGENTS.md 是否为空
是否有 AGENTS.override.md 覆盖了普通 AGENTS.md
fallback 文件名是否配置正确
是否重启了 Codex
CODEX_HOME 是否指向了别的目录
规则文件是否超过 project_doc_max_bytes
CODEX_HOME 很重要。它会改变 Codex 的 home 目录。
例如:
bash
CODEX_HOME=$(pwd)/.codex codex exec "List active instruction sources"
如果你修改的是:
text
C:\Users\your_username\.codex\AGENTS.md
但运行 Codex 时 CODEX_HOME 指向了别的目录,就会出现"我明明写了规则但没生效"的情况。
Skills 是什么
Codex Skill 可以理解成:
text
给 AI 编程代理预设的一套专业能力模块。
它可以包含:
- 工作流。
- 最佳实践。
- 项目规则。
- 输出格式。
- 示例。
- 自动化脚本。
- 专项知识。
Skill 的典型结构是:
text
.agents/skills/<skill-name>/SKILL.md
当前项目的本地 skills 包括:
text
.agents/skills/codex-project-setup/SKILL.md
.agents/skills/code-review-checklist/SKILL.md
.agents/skills/svn-commit-message/SKILL.md
.agents/skills/daily-qa-log/SKILL.md
每个 skill 应该只解决一个可复用工作流。
例如:
| Skill | 适合做什么 |
|---|---|
codex-project-setup |
创建或检查 Codex 项目结构 |
code-review-checklist |
做代码审查清单 |
svn-commit-message |
生成 SVN 提交说明 |
daily-qa-log |
把问答记录写入每日 Markdown |
Skill 如何触发
Skill 有两种触发方式。
第一种是显式调用。
推荐写法是:
text
$skill-name 你的任务
例如:
text
$svn-commit-message 帮我根据当前修改生成 SVN 提交说明
$daily-qa-log 今天的问答记录整理一下
在这套使用习惯里,/daily-qa-log 不是调用 skill 的主要方式;斜杠命令更像 Codex 内置命令或插件命令。
第二种是隐式触发。
Codex 会根据 SKILL.md frontmatter 里的 description 判断是否应该使用某个 skill。
所以写 skill 时,description 非常重要。它不是普通简介,而是触发条件。
Skill 不是 Prompt
很多人会误解:
text
Skill = Prompt
这个理解太浅了。
真正有用的 Skill 应该有:
text
name
description
workflow
output format
examples
references
scripts
Prompt 是一次性提示词;Skill 是可重复使用的工作流。
例如写博客可以拆成不同 skill:
text
blog-writer:生成博客、调整结构、补充摘要
technical-writing:把技术概念解释清楚
markdown-publisher:生成 Markdown、frontmatter、标签和分类
screenshot-explainer:把 WinDbg/WPA/Trace 截图解释成图注
reverse-engineering-blog:写逆向、驱动、EDR、Hook、IO 路径分析
create-diagram:生成 Mermaid 架构图、调用链、流程图
seo-blog-optimizer:生成 SEO 标题、description、slug
windows-performance-blogger:写 WPA、ETW、WinDbg 性能分析文章
这些 skill 曾被安装到全局目录:
text
C:\Users\your_username\.agents\skills
后来又被删除。这个过程说明一个实践原则:Skill 可以按需创建、验证、调整,也可以删除。它不是越多越好,而是要保持真正有用。
AGENTS.md 和 Skills 的分工
不要把所有规则都塞进 AGENTS.md。
更好的拆分是:
text
AGENTS.md:始终相关的项目规则
SKILL.md:某类任务的具体流程
例如:
text
项目文档放在哪里 -> AGENTS.md
每日问答怎么记录 -> daily-qa-log skill
SVN 提交说明怎么写 -> svn-commit-message skill
代码审查检查哪些风险 -> code-review-checklist skill
这样 AGENTS.md 可以保持简洁,复杂流程也不会丢失。
.rules 是什么
.rules 是 Codex 官方命令权限规则文件,不是普通业务规则。
它控制的是:
text
哪些命令可以在 sandbox 外运行
哪些命令需要确认
哪些命令禁止
常见用户级位置:
text
C:\Users\your_username\.codex\rules\default.rules
常见项目级位置:
text
<repo>\.codex\rules\default.rules
项目级 .rules 需要项目 .codex/ 配置层被信任才会加载。
常见 decision 包括:
text
allow
prompt
forbidden
可以这样理解:
| 机制 | 作用 |
|---|---|
AGENTS.md |
告诉 Codex 项目规则 |
Skills |
告诉 Codex 某类任务怎么做 |
.rules |
控制命令权限 |
Hooks |
在生命周期节点运行脚本 |
Hooks 是什么
Hooks 是 Codex 的生命周期脚本机制。
简单说:
text
Hooks = 在 Codex 工作流程的某些时间点,自动运行你自己的脚本。
它可以做这些事:
- 会话开始时加载备注。
- 用户提交 prompt 前检查是否误贴 API key。
- Codex 执行 Bash 命令前阻止危险命令。
- Codex 执行命令后分析输出。
- 一轮回答结束后自动记录问答。
- 如果测试没跑,让 Codex 继续完成验证。
Hooks 和 AGENTS.md 的区别是:
text
AGENTS.md:软规则,告诉 Codex 应该怎么做。
Hooks:可执行规则,直接运行脚本检查或处理。
例如:
markdown
# AGENTS.md
- 不要运行危险删除命令。
这是提示。
而 Hook 可以真正检查命令:
text
如果 command 包含 rm -rf,就拒绝执行。
所以 Hooks 更适合确定性规则、审计和安全控制。
如何启用 Hooks
Hooks 需要在 config.toml 中开启:
toml
[features]
codex_hooks = true
常见配置位置有:
text
~/.codex/hooks.json
~/.codex/config.toml
<repo>/.codex/hooks.json
<repo>/.codex/config.toml
全局 hooks:
text
~/.codex/...
对当前用户下的所有 Codex 项目生效。
项目 hooks:
text
<repo>/.codex/...
只对当前仓库生效,并且项目 .codex/ 配置层需要被信任。
Hooks 和 AGENTS.md 的加载差异
这是一个非常重要的区别。
AGENTS.md 更像:
text
越靠近当前目录,优先级越高。
Hooks 更像:
text
只要匹配,全部都会运行。
也就是说,多个地方的 hooks 会合并执行,不是覆盖。
如果用户级配置里有一个 Stop hook,项目级配置里也有一个 Stop hook,只要它们都匹配,就都会运行。
Hook 配置的三层结构
Hooks 配置一般有三层:
text
事件 event
匹配器 matcher
处理脚本 hooks
示例:
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 .codex/hooks/pre_tool_use_policy.py",
"statusMessage": "Checking Bash command"
}
]
}
]
}
}
意思是:
text
当 Codex 准备使用 Bash 工具时
运行 pre_tool_use_policy.py
界面显示 Checking Bash command
常见 Hook 事件
| 事件 | 触发时机 | 适合做什么 |
|---|---|---|
SessionStart |
会话开始 | 加载会话备注、注入额外上下文 |
UserPromptSubmit |
用户提交 prompt 时 | 检查是否粘贴密钥、补充上下文 |
PreToolUse |
工具执行前 | 阻止危险 Bash、apply_patch、MCP 工具调用 |
PermissionRequest |
Codex 准备请求权限时 | 自动允许、拒绝或交给正常审批 |
PostToolUse |
工具执行后 | 检查命令输出、测试失败后提醒 |
Stop |
一轮回答结束时 | 自动记录、检查是否需要继续 |
PreToolUse 最像安全闸门,因为它发生在工具执行之前。
PostToolUse 发生在工具执行之后,所以它不能撤销已经发生的副作用,只能影响后续处理。
Stop 很特殊:它可以让 Codex 在准备结束时继续一轮,比如"测试还没跑,再跑一次"。
matcher 是什么
matcher 是触发条件,通常是正则表达式。
示例:
text
Bash
^apply_patch$
Edit|Write
mcp__filesystem__.*
startup|resume|clear
支持 matcher 的事件包括:
text
SessionStart
PreToolUse
PermissionRequest
PostToolUse
不支持 matcher 的事件包括:
text
UserPromptSubmit
Stop
也就是说,UserPromptSubmit 和 Stop 即使写了 matcher,目前也会被忽略。
Hook 脚本如何接收数据
每个 command hook 都会从标准输入 stdin 收到一个 JSON 对象。
常见字段包括:
text
session_id
transcript_path
cwd
hook_event_name
model
工具相关事件还会有:
text
turn_id
tool_name
tool_input
tool_response
例如 PreToolUse 拦截 Bash 时,可以从:
text
tool_input.command
读取 Codex 准备执行的命令。
Hook 脚本如何影响 Codex
Hook 可以通过 stdout 输出 JSON 告诉 Codex 怎么处理。
例如,在 PreToolUse 中阻止危险 Bash 命令:
json
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Destructive command blocked by hook."
}
}
也可以使用旧写法:
json
{
"decision": "block",
"reason": "Destructive command blocked by hook."
}
也可以用退出码 2,并把原因写到 stderr。
示例:每轮回答结束后自动记录问答
当前学习记录里配置过一个用户级 Stop hook。
配置位置:
text
C:\Users\your_username\.codex\config.toml
C:\Users\your_username\.codex\hooks\daily_qa_log.py
配置内容类似:
toml
[features]
codex_hooks = true
[[hooks.Stop]]
[[hooks.Stop.hooks]]
type = "command"
command = 'python C:\Users\your_username\.codex\hooks\daily_qa_log.py'
timeout = 30
statusMessage = "Recording daily Q&A"
脚本逻辑是:
- 在
Stophook 触发时运行。 - 读取 hook 输入里的
transcript_path和cwd。 - 从 transcript 中提取最近一轮可见的
user/assistant消息。 - 跳过隐藏推理、工具调用、工具输出、系统/开发者指令。
- 写入当前项目的
技术文档/每日记录/YYYY年M月D日.md。 - 用状态文件去重,避免同一轮重复写入。
这个 hook 不能"直接调用 $daily-qa-log 让模型再跑一次 skill"。
原因是:
text
Hook 执行的是脚本,不是模型指令。
正确做法是把 daily-qa-log skill 的记录规则固化到 hook 脚本里。
用户级 Hook 和项目级 Hook 的区别
刚才这个 daily log hook 是用户级 hook,不是项目级 hook。
因为它放在:
text
C:\Users\your_username\.codex\config.toml
C:\Users\your_username\.codex\hooks\daily_qa_log.py
所以理论上会对当前 Windows 用户下的所有 Codex 项目生效。
但日志写入位置是按当前项目 cwd 动态决定的:
text
<当前项目>\技术文档\每日记录\YYYY年M月D日.md
也就是说:
text
hook 本身:用户级,跨项目可用
日志文件:写到当前项目目录下
如果只想让它对当前项目生效,应该放到项目级:
text
D:\your_project\.codex\config.toml
D:\your_project\.codex\hooks\daily_qa_log.py
并确保项目 .codex/ 配置层被信任。
配置 Hook 后如何验证
可以做这些检查:
- 检查
config.toml是否包含:
toml
[features]
codex_hooks = true
- 检查脚本是否存在:
text
C:\Users\your_username\.codex\hooks\daily_qa_log.py
- 运行语法检查:
bash
python -m py_compile C:\Users\your_username\.codex\hooks\daily_qa_log.py
-
用临时 transcript 模拟
Stophook。 -
删除临时测试文件和测试日志内容。
-
重新打开或重启 Codex 会话,让新的
config.toml被加载。
推荐的 Codex 学习项目结构
一个适合长期学习的项目可以这样组织:
text
codex_study/
├── AGENTS.md
├── docs/
│ └── plans/
├── 技术文档/
│ ├── 每日记录/
│ └── 博客/
└── .agents/
└── skills/
├── codex-project-setup/
├── code-review-checklist/
├── svn-commit-message/
└── daily-qa-log/
这样每一层都有明确用途:
| 路径 | 用途 |
|---|---|
AGENTS.md |
项目级规则 |
docs/plans/ |
计划和设计文档 |
技术文档/每日记录/ |
每日问答记录 |
技术文档/博客/ |
从学习记录整理出的博客 |
.agents/skills/ |
项目本地可复用技能 |
常见误区
误区一:把所有内容写进 AGENTS.md
AGENTS.md 应该保持简洁。复杂流程放到 Skills,确定动作放到 Hooks,历史记录放到文档。
误区二:把 .rules 当成业务规则
.rules 不是普通项目说明,它控制命令权限。
误区三:以为 Hook 可以直接调用 Skill
Hook 运行脚本,不运行模型。它可以实现 skill 的规则,但不是直接调用 $skill-name。
误区四:以为项目 Hook 会自动跨项目生效
项目 hook 只对当前仓库生效。用户级 hook 才更适合跨项目使用。
误区五:以为多个 Hooks 会互相覆盖
Hooks 是合并执行,不是覆盖。只要匹配,多个 hook 都会运行。
一套推荐使用流程
如果你是初学者,可以按这个顺序使用 Codex:
- 在项目根目录写
AGENTS.md。 - 把重复任务拆成
.agents/skills/<skill-name>/SKILL.md。 - 用
$skill-name显式调用重要 skill。 - 配置
.rules控制命令权限。 - 配置
Stophook 自动记录问答。 - 把每日记录整理成博客或教程。
- 定期清理
AGENTS.md,避免它变成知识垃圾桶。
总结
Codex 的真正用法,不是不断写更长的 prompt。
更好的方式是分层:
text
项目长期规则 -> AGENTS.md
可复用任务流程 -> Skills
命令权限控制 -> .rules
生命周期自动化 -> Hooks
学习过程沉淀 -> 每日记录和博客
当这些机制配合起来时,Codex 才不只是"会回答问题的 AI",而是一个能够理解项目规则、执行工作流、自动记录过程、持续沉淀知识的开发协作系统。