Hooks 是 Codex 的事件驱动扩展机制。在 AI 执行的各个生命周期节点,你可以注入自定义脚本——验证命令安全性、记录日志、触发通知、执行自动化检查。
Codex 暴露了以下生命周期节点:
| 事件 | 触发时机 | 用途 |
|------|---------|------|
| pre_exec | 命令执行前 | 安全校验、环境检查 |
| post_exec | 命令执行后 | 日志记录、结果通知 |
| pre_edit | 文件修改前 | 备份文件、格式检查 |
| post_edit | 文件修改后 | 触发 lint、格式化 |
| pre_agent | Agent 启动前 | 初始化环境变量 |
| post_agent | Agent 结束后 | 清理临时文件 |
| on_error | 发生错误时 | 错误上报、回滚 |
hooks:
pre_exec:
- echo "[$(date)] 即将执行: {{.command}}" >> .codex/history.log
- bash .codex/safety-check.sh "{{.command}}"
post_exec:
- echo "[$(date)] 执行完成: exit={{.exit_code}}" >> .codex/history.log
pre_edit:
- cp "{{.file}}" "{{.file}}.codex-backup"
post_edit:
- npx prettier --write "{{.file}}"
on_error:
- echo "错误: {{.error}}" >> .codex/errors.log
Hooks 中使用双花括号传递上下文变量:
| 变量 | 说明 | 适用事件 |
|------|------|----------|
| {{.command}} | 即将执行的命令 | pre_exec, post_exec |
| {{.exit_code}} | 命令退出码 | post_exec |
| {{.file}} | 被修改的文件路径 | pre_edit, post_edit |
| {{.error}} | 错误信息 | on_error |
| {{.agent_id}} | 当前 Agent ID | pre_agent, post_agent |
| {{.model}} | 当前使用的模型名称 | 全部 |
| {{.timestamp}} | Unix 时间戳 | 全部 |
hooks:
pre_exec:
- |
DANGEROUS_PATTERNS=("rm -rf /" "sudo " "chmod 777" "> /dev/sda" "DROP TABLE" "shutdown")
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if [[ "{{.command}}" == *"$pattern"* ]]; then
echo "⛔ 危险命令被阻止: {{.command}}"
exit 1
fi
done
hooks:
pre_edit:
- |
BACKUP_DIR=".codex/backups/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
if [ -f "{{.file}}" ]; then
cp "{{.file}}" "$BACKUP_DIR/$(basename {{.file}})-{{.timestamp}}"
echo "📦 已备份: {{.file}}"
fi
hooks:
post_edit:
- |
FILE="{{.file}}"
# TypeScript / JavaScript
if [[ "$FILE" == *.ts ]] || [[ "$FILE" == *.tsx ]]; then
npx eslint "$FILE" --fix && echo "✅ ESLint: $FILE"
fi
# Python
if [[ "$FILE" == *.py ]]; then
black "$FILE" && ruff check "$FILE" --fix && echo "✅ Format: $FILE"
fi
# Go
if [[ "$FILE" == *.go ]]; then
gofmt -w "$FILE" && echo "✅ gofmt: $FILE"
fi
hooks:
post_edit:
- |
FILE="{{.file}}"
if [[ "$FILE" == *.test.* ]] || [[ "$FILE" == *__tests__* ]]; then
echo "🧪 已修改测试文件,自动运行..."
npm test -- "$FILE"
fi
hooks:
post_exec:
- |
curl -X POST https://hooks.slack.com/services/XXX \
-H "Content-Type: application/json" \
-d "{\"text\": \"Codex 执行完成: {{.command}} (exit={{.exit_code}})\"}"
hooks:
post_edit:
- |
FILE="{{.file}}"
if git diff --quiet "$FILE"; then
echo "无变更: $FILE"
else
git add "$FILE"
echo "📝 已暂存: $FILE"
fi
有时你只想在特定条件下触发 Hook:
hooks:
pre_exec:
- name: "安全审核"
when: "execution.policy != 'always'"
run: bash .codex/safety-check.sh "{{.command}}"
- name: "debug 日志"
when: "env.CODEX_DEBUG == 'true'"
run: echo "[DEBUG] {{.command}}" >> debug.log
例如:
#!/bin/bash
# .codex/pre-exec-check.sh
if [[ "$1" == *"rm"* ]] && [[ "$1" != *"rm -rf node_modules"* ]]; then
echo "⛔ rm 命令被阻止(除非删除 node_modules)"
exit 1 # 阻止执行
fi
exit 0 # 放行
在 codex.yaml 中开启详细日志:
hooks: debug: true # 显示每个 Hook 的执行详情 continue_on_error: false # Hook 失败时是否继续
将复杂 Hook 放在独立脚本文件:hooks/pre-exec.sh 比 yaml 中的多行字符串好维护
**pre_* hooks 做校验**,post_* hooks 做收尾
不要同步调用慢速外部服务(如短信网关)——会阻塞 Codex
使用 .codex/ 目录统一管理 Hook 脚本,并加入 .gitignore
Hook 脚本本身加入版本控制,让团队成员共享相同的行为规则
Hooks 让 Codex 从工具升级为平台。通过生命周期节点,你可以将团队的编码规范、安全策略和质量标准硬编码为自动执行的检查规则。AI 生成代码 + Hooks 自动质检 + 沙箱安全隔离——这三者结合,构建了一个既高效又安全的 AI 编程工作台。