7

Hook 系统

生命周期事件 — 在关键时刻插入自定义逻辑

什么是 Hook?

Hook(钩子)是一种编程模式:在程序执行到特定时刻时,自动触发预设的操作。 在 OpenHarness 中,Hook 系统提供了 4 个时机: • SESSION_START:会话开始时触发 • SESSION_END:会话结束时触发 • PRE_TOOL_USE:工具执行之前触发 • POST_TOOL_USE:工具执行之后触发 其中 PRE_TOOL_USE 和 POST_TOOL_USE 是最常用的,它们让你能在每次工具执行的前后插入自定义逻辑。

Hook 能做什么?

Hook 的常见用途包括: 📝 日志记录 记录每次工具调用的参数和结果,用于审计和调试。 🛡️ 额外安全检查 比如检查 Bash 命令是否包含危险操作,在权限系统之上增加一层防护。 🔄 自动格式化 在文件写入后自动运行代码格式化工具。 📊 统计分析 统计工具使用频率、执行时间等数据。 🚫 拦截操作 PreToolUse Hook 可以阻止工具执行,比如在工作时间外禁止部署操作。

Hook 的执行流程

openharness/hooks/executor.py
1async def execute_tool_with_hooks(tool_call, context):
2 # 第 1 步:执行 PreToolUse 钩子
3 pre_result = await run_hooks("pre_tool_use", {
4 "tool_name": tool_call.name,
5 "tool_params": tool_call.params,
6 })
7
8 # 如果钩子要求阻止,直接返回
9 if pre_result.should_block:
10 return ToolResult("操作被 Hook 阻止", is_error=True)
11
12 # 第 2 步:权限检查(在 Hook 之后)
13 permission = await check_permission(tool_call)
14 if not permission.allowed:
15 return ToolResult("权限不足", is_error=True)
16
17 # 第 3 步:真正执行工具
18 result = await tool.execute(tool_call.params)
19
20 # 第 4 步:执行 PostToolUse 钩子
21 await run_hooks("post_tool_use", {
22 "tool_name": tool_call.name,
23 "result": result,
24 })
25
26 return result

每次工具调用时,Hook 的执行顺序是这样的:

四种 Hook 类型

OpenHarness 支持四种不同类型的 Hook 实现: 1. Command Hook(命令钩子) 执行一个 Shell 命令。最简单直接的方式。 2. HTTP Hook 发送一个 HTTP 请求到指定 URL。适合与外部服务集成。 3. Prompt Hook 让 Agent 自己处理一段提示词。适合复杂的判断逻辑。 4. Agent Hook 启动一个完整的子 Agent 来处理。适合需要多步推理的场景。 大多数情况下,Command Hook 就足够了。

配置 Hook 的方式

settings.json
1{
2 "hooks": {
3 "pre_tool_use": [
4 {
5 "type": "command",
6 "command": "echo '即将执行工具: $TOOL_NAME'",
7 "match_tools": ["Bash"]
8 }
9 ],
10 "post_tool_use": [
11 {
12 "type": "command",
13 "command": "echo '工具执行完成: $TOOL_NAME'"
14 }
15 ]
16 }
17}

Hook 在 settings.json 中配置:

📌 关键要点
Hook 让 Harness 可观测、可扩展
Hook 系统的核心价值是:在不修改引擎代码的情况下,在关键时刻插入自定义逻辑。这使得 OpenHarness 不仅是一个工具,更是一个可观测、可扩展的平台。
🧠 检验理解
PreToolUse Hook 最主要的特殊能力是什么?