第四十三课:Hooks 生命周期
3.9K字·10分钟·
Hook注册事件类型自定义工作流
学习目标
- 了解 Hooks 的概念和作用
- 掌握 Hook 注册方法
- 了解事件类型和使用场景
- 学会开发自定义 Hooks
一、什么是 Hooks
Hooks 是 Codex 的生命周期钩子,让你可以在特定事件发生时执行自定义逻辑。它就像是代理的"中间件",可以在关键节点插入自定义行为。
1.1 Hooks 的价值
Hooks 的核心价值在于自动化和扩展性:
- 自动化:在特定事件时自动执行操作,无需人工干预
- 扩展性:无需修改核心代码即可扩展功能
- 灵活性:可以根据需要配置不同的 Hooks
- 可维护性:将自定义逻辑与核心代码分离
1.2 工作原理
代理执行过程中会触发各种事件,Hooks 监听这些事件并在事件发生时执行注册的处理函数。
执行流程:
- 用户输入任务
- 代理开始执行
- 触发 pre-run 事件
- 执行任务
- 调用工具时触发 pre-tool 事件
- 工具执行完成触发 post-tool 事件
- 任务完成触发 post-run 事件
二、事件类型
2.1 任务事件
- pre-run:任务开始前触发,用于准备工作
- post-run:任务结束后触发,用于清理工作
- on-error:任务出错时触发,用于错误处理
2.2 工具事件
- pre-tool:工具调用前触发,用于参数验证
- post-tool:工具调用后触发,用于结果处理
- on-tool-error:工具调用出错时触发,用于错误恢复
2.3 会话事件
- on-message:收到消息时触发,用于消息预处理
- on-response:生成响应时触发,用于响应后处理
2.4 事件参数
每个事件都携带上下文信息:
- 任务描述
- 工具名称和参数
- 执行结果
- 时间戳
- 错误信息
三、注册方法
3.1 配置文件
在配置文件中定义 Hooks:
hooks:
pre-run:
- command: "echo 'Starting task'"
- script: "scripts/pre-run.sh"
post-run:
- command: "echo 'Task completed'"
- script: "scripts/post-run.sh"
pre-tool:
- match: "apply_patch"
command: "echo 'Applying patch'"
3.2 编程方式
import { Codex } from '@openai/codex-sdk';
const codex = new Codex({ apiKey: process.env.OPENAI_API_KEY });
// 注册 pre-run hook
codex.hook('pre-run', async (context) => {
console.log('Starting task:', context.task);
// 执行准备工作
});
// 注册 post-tool hook
codex.hook('post-tool', async (context) => {
console.log('Tool called:', context.tool.name);
console.log('Result:', context.result);
// 处理工具结果
});
// 注册 on-error hook
codex.hook('on-error', async (context) => {
console.error('Error:', context.error.message);
// 错误处理
});
3.3 条件匹配
可以为特定工具注册 Hook:
hooks:
pre-tool:
- match: "shell"
command: "echo 'Running shell command'"
- match: "apply_patch"
command: "echo 'Applying patch'"
四、使用场景
4.1 代码格式化
在文件修改后自动运行格式化:
hooks:
post-tool:
- match: "apply_patch"
command: "prettier --write $FILE"
4.2 测试运行
在任务完成后自动运行测试:
hooks:
post-run:
- command: "npm test"
4.3 日志记录
记录所有工具调用:
hooks:
post-tool:
- command: "echo '$(date): $TOOL_NAME called' >> codex.log"
4.4 通知发送
在任务完成时发送通知:
hooks:
post-run:
- command: "notify-send 'Codex' 'Task completed'"
4.5 代码审查
在代码修改后自动运行审查:
hooks:
post-tool:
- match: "apply_patch"
command: "eslint $FILE"
4.6 备份
在修改文件前自动备份:
hooks:
pre-tool:
- match: "apply_patch"
command: "cp $FILE $FILE.bak"
五、Hook 上下文
5.1 可用信息
Hook 可以访问以下信息:
- task:任务描述
- tool:工具信息(名称、参数)
- result:执行结果
- error:错误信息
- timestamp:时间戳
- session:会话信息
5.2 环境变量
Hook 执行时会设置以下环境变量:
- CODEX_HOOK_EVENT:事件类型
- CODEX_TOOL_NAME:工具名称
- CODEX_TASK_ID:任务 ID
- CODEX_SESSION_ID:会话 ID
- CODEX_FILE:当前文件路径
5.3 返回值
Hook 可以返回值来影响后续执行:
- 返回 true:继续执行
- 返回 false:阻止执行
- 返回修改后的参数:替换原始参数
六、最佳实践
6.1 性能考虑
- Hook 应该快速执行,避免阻塞主流程
- 避免在 Hook 中执行耗时操作
- 使用异步执行避免阻塞
- 设置合理的超时时间
6.2 错误处理
- Hook 应该处理可能的错误
- 避免 Hook 失败影响主任务
- 记录 Hook 执行日志
- 提供错误恢复机制
6.3 安全性
- 验证 Hook 输入
- 限制 Hook 权限
- 避免执行危险命令
- 审计 Hook 执行
6.4 可维护性
- 保持 Hook 简单
- 提供清晰的文档
- 版本控制 Hook 配置
- 定期审查和更新
七、调试技巧
7.1 日志记录
在 Hook 中添加日志,便于调试:
codex.hook('pre-tool', async (context) => {
console.log('[Hook] pre-tool:', JSON.stringify(context, null, 2));
});
7.2 测试 Hook
单独测试 Hook,确保正确工作:
# 测试 pre-run hook
codex hook test pre-run "test task"
7.3 查看 Hook 列表
codex hook list
八、本课小结
| 要点 | 说明 |
|---|---|
| Hooks | 生命周期钩子,插入自定义逻辑 |
| 事件类型 | 任务事件、工具事件、会话事件 |
| 注册方式 | 配置文件、编程方式 |
| 使用场景 | 格式化、测试、日志、通知、审查、备份 |
| 上下文 | 任务、工具、结果、错误、时间戳 |
下一步
下一课我们将进入实战环节。