AI Code With · Codex 自动化架构与安全实践
Codex 真正进入日常工作以后,很多人会很快碰到四个功能:AGENTS.md、Hooks、Automations 和 Playwright MCP。
它们看起来都和“自动化”有关,但不是同一层。AGENTS.md 是长期项目规则;Hook 是生命周期事件发生时执行确定性脚本;Automation 决定任务什么时候在后台运行;Playwright MCP 则把可执行能力扩展到浏览器。
如果把四个东西混着配,常见结果是:规则越来越长,Hook 重复执行,定时任务在没人看着时改了本地文件,浏览器自动化又拿着登录态一路点到“发布”。真正应该做的,是先给每一层分工,再逐步增加风险。
自动化不是功能越多越成熟,而是规则、触发、执行和外部动作的边界都能解释。
1. 先看懂四层:它们解决的不是同一个问题
| 层 | 工具 | 负责什么 | 典型问题 |
| 规则层 | AGENTS.md | 长期告诉 Codex 项目约束、测试和交付要求 | “以后处理这个仓库都要遵守什么?” |
| 生命周期层 | Hooks | 特定事件发生时执行确定性脚本 | “每次工具调用后记录审计信息” |
| 调度层 | Automations / Scheduled tasks | 按时间或支持的事件后台执行任务 | “每天 9:30 检查项目有没有阻塞” |
| 外部执行层 | Playwright MCP | 让 Codex 操作浏览器页面 | “读取网页、填表、保存草稿” |
这四层可以组合,但不是必须全部使用。一个只需要长期项目规范的仓库,只写 AGENTS.md 就够;一个简单定时摘要可能只需要 Automation;只有任务真的需要浏览器动作时,才应该引入 Playwright MCP。
2. AGENTS.md:先把“长期规则”写成可验收的东西
AGENTS.md 最像给 Codex 的项目说明书。真正好用的规则不是“请写高质量代码”,而是能观察、能执行、能失败。
# Project instructions
## Tests
- 修改 Python 文件后运行:python3 -m unittest discover -s tests -v
- 如果测试不能运行,说明原因,不得写“测试通过”
## Editing
- 不修改 generated/ 目录
- 保留用户已有未提交改动
## Response
- 完成后列出修改文件、测试命令和真实结果
这样的规则能直接判断有没有生效。以后无论是手工会话、定时任务还是更复杂的自动化,都不用反复在 Prompt 里重新解释基础规范。
AGENTS.md 的覆盖顺序:同一目录只取一份
当前 OpenAI 文档说明,Codex Home 默认在 ~/.codex。全局层如果存在 AGENTS.override.md,会优先使用它;否则读取 AGENTS.md。
项目层则从项目根目录一路走到当前工作目录。在每个目录里按 AGENTS.override.md → AGENTS.md → 自定义 fallback 文件名的顺序查找,同一目录最多加载一个。
repo/
├── AGENTS.md
└── frontend/
├── AGENTS.override.md
└── src/
根目录可以放仓库通用测试要求,frontend 下的 override 放前端专属要求。越靠近当前工作目录的规则越具体,可以覆盖上层冲突项。
32 KiB 是合并后的默认上限,不是每个文件 32 KiB
当前文档明确:项目指令合并后达到 project_doc_max_bytes 就会停止继续加入,默认是 32 KiB。
所以不要把 AGENTS.md 写成第二份公司制度。遇到越来越长的规则,优先做三件事:删除重复、把子目录规则下沉、把一次性流程改成 Skill。
怎么验证 AGENTS.md 真的被读到了
在临时项目里放一个非常明显但无害的测试规则,例如“回答第一行必须写 PROJECT_RULE_ACTIVE”,子目录 override 再换一个标记。分别从根目录和子目录发起只读请求。
验证结束后把测试标记删掉,不要把这种“为了测试而测试”的规则永久留在正式仓库。
如果规则不生效,先查:当前工作目录是不是你以为的目录;有没有更近的 override;规则总量是否过大或互相矛盾。
3. Hooks:不是定时器,而是“某个生命周期事件发生就跑脚本”
Hook 很适合做确定性的事情:记录审计信息、检查某个工具调用、在会话结束时写状态。但它也是最不适合“复制一段配置就上生产”的功能之一,因为 Hook 真会执行脚本。
OpenAI 当前 Hooks 文档把常见位置列得很清楚:
• ~/.codex/hooks.json
• ~/.codex/config.toml
• <repo>/.codex/hooks.json
• <repo>/.codex/config.toml
同一层如果同时出现 hooks.json 和 config.toml 内联 [hooks],Codex 会合并并在启动时警告。第一次最好只选一种写法。
很多人漏掉的不是配置,而是“信任”
当前非托管 Hook 必须先审查并信任,Codex 会按 Hook 当前定义的哈希记录信任状态。Hook 内容变化后,需要重新审查。
/hooks
用 /hooks 查看来源、待审查配置、信任状态和禁用项。文章如果只写“配置完就会自动跑”,其实少了最关键的一步。
第一个 Hook:只写一个无害时间戳
第一次不要自动格式化、不要 git commit、不要碰生产文件。先做一个只往系统临时目录写时间戳的脚本:
• 不读取凭证。
• 不访问网络。
• 不修改项目。
• 不执行 Git。
• 明确返回退出码。
先确认事件能触发,再故意让脚本失败一次,观察 Codex 怎么提示。这样你才能真正理解 Hook 的事件、输入和错误传播。
多个 Hook 可能并发,别自己脑补顺序
当前官方文档明确:同一事件上多个匹配的 command hook 可能并发启动,后台 Hook 也可能以不同顺序完成。
因此不要写出这种隐式依赖:Hook A 先生成文件,Hook B 立刻读取它。除非你自己实现同步,否则这个顺序没有保证。
4. Automations:先从只读巡检开始,不要第一天就自动改代码
Scheduled tasks 适合把重复任务放到后台,但第一次任务越无聊越好。你需要先验证它有没有按时运行、上下文从哪里来、产物在哪、权限有没有越界。
每个工作日 09:30 检查当前项目:
1. 读取 git 状态和最近一次测试结果;
2. 不修改文件,不提交,不发送外部消息;
3. 输出未提交变更、失败测试和需要人工处理的事项;
4. 没有异常时写“无新增阻塞”;
5. 失败时保留错误摘要,不自动连续重试。
OpenAI 当前文档建议先在普通 Chat 里手工测试 Prompt,再放进 Scheduled。前几次 Run 也要人工检查,确认范围和输出可复核。
Web、桌面本地项目、CLI / IDE 不是一种运行方式
当前 Scheduled 管理界面主要在 ChatGPT Web 和桌面应用。CLI 和 IDE extension 可以帮你先跑顺 Prompt、Skill 或项目改动,但没有同样的 Scheduled 管理界面。
Web 任务可以使用上传内容、连接工具、Skills 和 Plugins,但不会在两次 Run 之间保留你电脑上的本地目录。
如果 Scheduled task 要读本机项目,机器需要保持开机、桌面 App 保持运行,并且项目路径到执行时间仍然存在。
可能改代码时,worktree 比直接碰本地 checkout 更稳
Git 项目里的 Scheduled task 可以选择在本地项目运行,也可以使用独立 worktree。worktree 的价值是把自动任务的改动和你手头正在编辑的代码分开。
只读巡检没有必要为了形式强制用 worktree;一旦任务可能改代码,我更倾向先隔离。频繁任务也要记得清理不用的 worktree 和旧 Run。
5. AGENTS.md、Hook 和 Automation 应该怎么配合
它们不是一个严格的流水线,但可以形成清晰分工:
| 事情 | 放在哪里更合适 | 不要放在哪里 |
| 长期测试 / 编辑规则 | AGENTS.md | 不要每次重复塞进定时 Prompt |
| 到了某个时间执行任务 | Automation | 不要用 Hook 伪装定时器 |
| 工具调用后记录状态 / 做确定性检查 | Hook | 不要让模型自由发挥脚本逻辑 |
| 一次性复杂工作流 | Skill | 不要无限膨胀 AGENTS.md |
如果同一个本地执行环境同时加载了项目规则和 Hook,任务运行时是否真正读取了预期规则、触发了预期 Hook,都应该通过 Run history、/hooks 状态和实际日志验证,而不是默认“配了就一定串起来”。
6. Playwright MCP:只有任务真的需要浏览器,才把它加进来
浏览器是自动化风险明显升高的一层。公开页面读取、后台填表、发布内容、删除记录,这些不能只用“浏览器自动化”四个字概括。
Microsoft 官方 Playwright MCP 当前给 Codex 的添加命令是:
codex mcp add playwright npx "@playwright/mcp@latest"
也可以配置:
[mcp_servers.playwright]
command = "npx"
args = ["@playwright/mcp@latest"]
第一次只做一件无聊的小事:打开公开页面、读取标题、返回 URL。先证明 Server 能启动、浏览器能导航、结果能回到 Codex,再讨论登录后台。
Playwright MCP 不是安全边界
Microsoft README 明确写明:Playwright MCP 本身不是安全边界。allowed-origins、blocked-origins 等参数是护栏,但不能替代真正隔离,也不能覆盖重定向等全部风险。
默认文件访问会受 workspace roots 或当前目录限制,打开 unrestricted file access 会扩大范围。浏览器登录态和存储状态也可能包含 Cookie、账号信息和内部数据。
浏览器任务拆成三段:读取、准备、提交
| 阶段 | 动作 | 自动化建议 |
| 读取 | 打开页面、读取信息 | 可自动,优先只读 |
| 准备 | 填表、上传、生成草稿 | 允许编辑,但不触发最终动作 |
| 提交 | 发布、支付、发送、删除、改权限 | 单独确认,必要时人工执行 |
“帮我把流程跑完”对浏览器来说太宽。更好的 Prompt 要明确允许域名、页面范围、可输入的数据、不能点的按钮,以及任务完成后要返回什么证据。
7. 一个完整现实案例:每天巡检内容,并把合格文章填成 CMS 草稿
下面这套例子把四层放在同一套工作流里,但每层职责仍然分开。
AGENTS.md
→ 规定:只处理已审核文章、不得跳过测试/审核标记、完成后输出证据
Automation
→ 每个工作日固定时间检查“待发布”目录,只读汇总新增文章
Hook
→ 在关键生命周期节点记录任务 ID、退出码和时间,不自动改业务内容
Playwright MCP
→ 仅当文章状态满足条件时,打开 CMS,填写标题/正文/分类并保存草稿
人工确认
→ 检查草稿页面后,再决定是否正式发布
这套设计故意把“发布”留在人类确认点。因为保存草稿和正式发布的后果不同,自动化不应该因为前面都成功了,就默认最后一步也必须无人值守。
8. 自动化一旦调用模型,预算规则也要进入设计
手工一天调用一次时,成本变化不明显;Scheduled task 如果每小时运行、每次又带很长上下文,费用会在没人盯着的时候累积。
更耐用的预算规则是写行为,而不是把价格写死:
• 每次只读取最近一段时间新增内容。
• 单次失败最多重试有限次数。
• 不在失败时自动升级到更贵模型。
• 超过预设预算就停止并报告。
• 不在 AGENTS.md、Hook 或定时 Prompt 里硬编码长期折扣。
如果这套任务本来通过 AI Code With 调用模型,可以把模型页、渠道页和真实调用记录当成验收三件套:实际用了什么模型、走了哪条渠道、发生了多少调用与费用。
AI Code With 在这里负责的是 API Key、模型、渠道和用量管理;它不提供 Playwright MCP,也不会替 Codex 决定本地 Hook 是否可信、自动任务该不该发布内容。
9. Hook 或 Automation 不工作时,按层排查
| 问题 | 先查什么 | 不要先做 |
| Hook 完全不触发 | 脚本能否独立运行、事件名、matcher、/hooks 信任状态 | 直接开更高 Codex 权限 |
| Hook 行为顺序异常 | 是否有多个匹配 Hook 并发 | 假设 A 一定先于 B |
| Scheduled task 没跑 | 任务是否启用、时间、机器、电源、桌面 App、项目路径、Run history | 直接重建任务 |
| Scheduled task 改错文件 | local project 还是 worktree、AGENTS.md 规则、Prompt 范围 | 扩大权限掩盖问题 |
| Playwright 打不开页面 | Server、浏览器依赖、页面可达性、工具调用拒绝 | 直接登录生产后台 |
| 浏览器处于未知提交状态 | 当前页面、最后工具调用、Server 日志 | 自动重复点击 |
10. 上线前的 14 项清单
□ AGENTS.md 里的规则可以被验收,不是空泛口号。
□ 同一目录的 AGENTS.override.md / AGENTS.md 覆盖关系已经理解。
□ 项目指令没有无限膨胀,必要流程已经拆成 Skill。
□ Hook 使用了明确事件和 matcher。
□ 非托管 Hook 已经通过 /hooks 审查并信任。
□ 第一个 Hook 不读 Secret、不联网、不改仓库。
□ 多个 Hook 没有依赖隐式执行顺序。
□ Automation 的 Prompt 已经手工运行验证。
□ 第一次 Scheduled task 从只读任务开始。
□ 可能改代码的后台任务考虑了 worktree 隔离。
□ 模型调用有失败重试上限和预算边界。
□ Playwright MCP 第一次只访问公开页面。
□ 浏览器“提交”类高风险动作保留独立确认点。
□ 任何自动化失败都有日志、Run history 或可见证据可追。
11. 最后:把自动化做成四个可单独关闭的层
一套真正可维护的 Codex 自动化,不应该只有一个“大 Prompt”。
AGENTS.md 负责长期规则;Hooks 负责确定性的生命周期动作;Automations 负责调度;Playwright MCP 负责浏览器能力。它们可以组合,但每一层都应该有自己的最小权限、验证方法和关闭方式。
规则可解释,触发可追踪,执行可审计,高风险动作可暂停。
做到这一点以后,自动化才不是一个越来越难碰的黑盒,而是一套可以逐层扩展、逐层回滚的工作流。
资料来源与核对说明
本文由《Codex AGENTS.md 怎么写?》《Codex Hooks 怎么配置?》《Codex Automations 怎么用?》和《Codex Playwright MCP,能打开浏览器只是第一步》四篇原稿合并重写,并核对了当前 OpenAI AGENTS.md、Hooks、Scheduled tasks 与 Microsoft Playwright MCP 文档。Hooks、Scheduled tasks 和 Playwright MCP 都可能继续更新,正式落地时应以当天文档、当前客户端状态和真实测试结果为准。
OpenAI AGENTS.md:https://developers.openai.com/codex/guides/agents-md
OpenAI Hooks:https://developers.openai.com/codex/hooks
OpenAI Scheduled tasks:https://developers.openai.com/codex/automations
Microsoft Playwright MCP:https://github.com/microsoft/playwright-mcp
AI Code With 模型列表:https://aicodewith.ai/zh/dashboard/pricing
AI Code With 渠道管理:https://aicodewith.ai/zh/dashboard/channels


