Hooks 事件脚本专题教程

advanced
## 什么是 Hooks Hooks 是 OpenClaw 的事件驱动脚本机制。当特定事件发生时(比如新会话开始、会话重置、Gateway 启动),OpenClaw 会自动执行你预先定义的脚本。 你可以把 Hooks 想象成"触发器": ``` 事件发生 → OpenClaw 检测到事件 → 执行对应的 Hook 脚本 → 完成自动化操作 ``` 与定时任务(Cron)不同,Hooks 是**被动触发**的——不是按时间执行,而是按事件执行。这让你可以在关键时刻自动完成一些操作,而不需要手动干预。 ### Hooks vs 其他自动化机制 | 机制 | 触发方式 | 适用场景 | |------|----------|----------| | Hooks | 事件驱动 | 会话开始时发欢迎语、工具调用时记日志 | | Cron | 定时触发 | 每天早上发天气预报、每周生成报告 | | Heartbeat | 周期触发 | 每 30 分钟检查邮箱、定期巡检 | | Standing Orders | 持久指令 | 始终保持某种行为模式 | ## 支持的事件类型 OpenClaw 支持以下事件类型,覆盖了智能体生命周期的关键节点: ### 会话事件 | 事件 | 触发时机 | 典型用途 | |------|----------|----------| | `/new` | 用户发送 `/new` 开始新会话 | 发送欢迎消息、初始化工作区 | | `/reset` | 用户发送 `/reset` 重置会话 | 清理临时文件、重置状态 | | `/stop` | 用户发送 `/stop` 停止智能体 | 保存工作进度、发送告别消息 | | `compaction` | 会话压缩触发时 | 记录压缩日志、通知用户 | ### 系统事件 | 事件 | 触发时机 | 典型用途 | |------|----------|----------| | `gateway:start` | Gateway 启动时 | 发送启动通知、检查配置 | | `gateway:stop` | Gateway 停止时 | 发送停机通知 | ### 消息事件 | 事件 | 触发时机 | 典型用途 | |------|----------|----------| | `message:incoming` | 收到用户消息时 | 消息日志、内容过滤 | | `message:outgoing` | 智能体发送回复时 | 回复日志、质量监控 | ### 工具事件 | 事件 | 触发时机 | 典型用途 | |------|----------|----------| | `tool:before` | 工具调用前 | 审计日志、权限检查 | | `tool:after` | 工具调用后 | 结果记录、错误监控 | ## Hook 文件格式和目录结构 ### 目录位置 Hook 脚本存放在以下目录: ``` ~/.openclaw/hooks/ ├── on-new-session.sh ├── on-reset.sh ├── on-gateway-start.sh ├── log-tool-calls.sh └── ... ``` 你也可以在智能体的工作区目录中放置 Hook: ``` ~/.openclaw/agents//hooks/ ├── welcome.sh └── cleanup.sh ``` 优先级:智能体级别的 Hook > 全局 Hook。 ### 文件格式 Hook 脚本是普通的 shell 脚本,但需要在文件头部声明监听的事件类型: ```bash #!/bin/bash # hook: /new # description: 新会话开始时发送欢迎消息 echo "欢迎回来!有什么我可以帮你的吗?" ``` 关键要素: - `#!/bin/bash`:指定脚本解释器(也可以用 `#!/usr/bin/env node` 等) - `# hook: <事件类型>`:声明监听的事件 - `# description:`:可选的描述信息 - 脚本内容:事件触发时执行的逻辑 ### 支持的脚本语言 Hook 脚本不限于 Bash,你可以使用任何可执行的脚本: **Bash 脚本** ```bash #!/bin/bash # hook: /new echo "新会话已开始" ``` **Node.js 脚本** ```javascript #!/usr/bin/env node // hook: /new // description: 新会话欢迎消息 console.log('欢迎!今天想做什么?'); ``` **Python 脚本** ```python #!/usr/bin/env python3 # hook: /new # description: 新会话欢迎消息 print("你好!新的对话开始了。") ``` ### 文件权限 Hook 脚本需要有执行权限: ```bash chmod +x ~/.openclaw/hooks/on-new-session.sh ``` ## 创建第一个 Hook 让我们从一个简单的例子开始——在每次新会话开始时发送欢迎消息。 ### 步骤 1:创建 Hook 文件 ```bash # 创建 hooks 目录(如果不存在) mkdir -p ~/.openclaw/hooks # 创建 Hook 脚本 cat > ~/.openclaw/hooks/welcome.sh << 'EOF' #!/bin/bash # hook: /new # description: 新会话开始时发送欢迎消息 echo "👋 你好!新会话已开始。" echo "输入 /help 查看可用命令。" EOF # 添加执行权限 chmod +x ~/.openclaw/hooks/welcome.sh ``` ### 步骤 2:验证 Hook 已注册 ```bash # 查看已注册的 Hooks openclaw hooks list ``` 输出示例: ``` Hooks: welcome.sh Event: /new Description: 新会话开始时发送欢迎消息 Path: ~/.openclaw/hooks/welcome.sh ``` ### 步骤 3:测试 Hook 在任意渠道中发送 `/new` 命令,你应该会看到欢迎消息: ``` 用户: /new Agent: 👋 你好!新会话已开始。 输入 /help 查看可用命令。 ``` ## 按事件类型过滤 一个 Hook 脚本可以监听多个事件,也可以在脚本内部根据事件类型执行不同逻辑。 ### 监听单个事件 ```bash #!/bin/bash # hook: /new echo "新会话开始" ``` ### 监听多个事件 ```bash #!/bin/bash # hook: /new, /reset echo "会话已初始化" ``` ### 在脚本内区分事件 OpenClaw 会通过环境变量传递事件信息: ```bash #!/bin/bash # hook: /new, /reset, /stop case "$OPENCLAW_HOOK_EVENT" in "/new") echo "👋 新会话开始!" ;; "/reset") echo "🔄 会话已重置。" ;; "/stop") echo "👋 再见!" ;; esac ``` ### 可用的环境变量 Hook 脚本执行时,OpenClaw 会注入以下环境变量: | 变量 | 说明 | 示例 | |------|------|------| | `OPENCLAW_HOOK_EVENT` | 触发的事件类型 | `/new` | | `OPENCLAW_AGENT_ID` | 当前智能体 ID | `default` | | `OPENCLAW_SESSION_ID` | 当前会话 ID | `telegram:bot123:alice` | | `OPENCLAW_CHANNEL` | 当前渠道 | `telegram` | | `OPENCLAW_CONTACT` | 当前联系人 | `alice` | ## CLI 管理命令 OpenClaw 提供了一组 CLI 命令来管理 Hooks。 ### 查看所有 Hooks ```bash # 列出所有已注册的 Hooks openclaw hooks list ``` 输出示例: ``` Global Hooks: welcome.sh /new 新会话开始时发送欢迎消息 cleanup.sh /reset 重置时清理临时文件 log-tools.sh tool:before 记录工具调用日志 Agent Hooks (default): daily-greeting.sh /new 每日问候 ``` ### 添加 Hook ```bash # 交互式添加 Hook openclaw hooks add # 指定参数添加 openclaw hooks add --event "/new" --script ~/.openclaw/hooks/welcome.sh ``` ### 移除 Hook ```bash # 移除指定 Hook openclaw hooks remove welcome.sh # 交互式选择移除 openclaw hooks remove ``` ### 测试 Hook ```bash # 手动触发 Hook 测试(不会影响实际会话) openclaw hooks test welcome.sh ``` ## 实用场景示例 ### 场景 1:会话重置时清理临时文件 当用户重置会话时,自动清理智能体创建的临时文件: ```bash #!/bin/bash # hook: /reset # description: 重置会话时清理临时文件 TEMP_DIR="$HOME/.openclaw/agents/$OPENCLAW_AGENT_ID/tmp" if [ -d "$TEMP_DIR" ]; then rm -rf "$TEMP_DIR"/* echo "🧹 临时文件已清理。" fi ``` ### 场景 2:工具调用时记录日志 记录所有工具调用,方便后续审计: ```bash #!/bin/bash # hook: tool:before # description: 记录工具调用日志 LOG_FILE="$HOME/.openclaw/logs/tool-audit.log" TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') echo "[$TIMESTAMP] Agent: $OPENCLAW_AGENT_ID | Session: $OPENCLAW_SESSION_ID | Tool: $OPENCLAW_TOOL_NAME" >> "$LOG_FILE" ``` ### 场景 3:Gateway 启动时发送通知 Gateway 启动后发送通知到你的手机(通过 Webhook): ```bash #!/bin/bash # hook: gateway:start # description: Gateway 启动时发送通知 WEBHOOK_URL="https://your-webhook-service.com/notify" HOSTNAME=$(hostname) TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') curl -s -X POST "$WEBHOOK_URL" \ -H "Content-Type: application/json" \ -d "{\"text\": \"🚀 OpenClaw Gateway 已启动\\n主机: $HOSTNAME\\n时间: $TIMESTAMP\"}" ``` ### 场景 4:新会话时加载项目上下文 当新会话开始时,自动读取当前项目的关键信息: ```bash #!/bin/bash # hook: /new # description: 新会话时加载项目上下文 PROJECT_DIR="$HOME/current-project" if [ -f "$PROJECT_DIR/package.json" ]; then PROJECT_NAME=$(node -e "console.log(require('$PROJECT_DIR/package.json').name)") echo "📂 当前项目: $PROJECT_NAME" echo "📋 最近 Git 提交:" cd "$PROJECT_DIR" && git log --oneline -3 fi ``` ### 场景 5:会话压缩时记录统计 当会话压缩触发时,记录压缩前后的 Token 数量: ```bash #!/bin/bash # hook: compaction # description: 记录会话压缩统计 LOG_FILE="$HOME/.openclaw/logs/compaction.log" TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') echo "[$TIMESTAMP] Session: $OPENCLAW_SESSION_ID | Agent: $OPENCLAW_AGENT_ID | Compaction triggered" >> "$LOG_FILE" echo "📦 会话已压缩,早期对话已总结为摘要。" ``` ### 场景 6:消息内容过滤 在收到用户消息时进行简单的内容过滤: ```bash #!/bin/bash # hook: message:incoming # description: 消息内容过滤 # 检查是否包含敏感关键词 if echo "$OPENCLAW_MESSAGE_CONTENT" | grep -qi "password\|密码\|secret"; then echo "⚠️ 提醒:请不要在对话中发送密码或敏感信息。" fi ``` ## Hook 执行顺序 当同一个事件有多个 Hook 时,执行顺序为: 1. **全局 Hooks**(`~/.openclaw/hooks/`)按文件名字母序执行 2. **智能体 Hooks**(`~/.openclaw/agents//hooks/`)按文件名字母序执行 如果你需要控制执行顺序,可以在文件名前加数字前缀: ``` ~/.openclaw/hooks/ ├── 01-log-event.sh # 先记录日志 ├── 02-check-security.sh # 再检查安全 └── 03-send-welcome.sh # 最后发送欢迎消息 ``` ## Hook 错误处理 ### 脚本执行失败 如果 Hook 脚本执行失败(非零退出码),OpenClaw 会: 1. 记录错误到日志 2. 继续执行后续的 Hook(不会因为一个 Hook 失败而中断) 3. 不影响正常的消息处理流程 ### 超时处理 Hook 脚本有默认的执行超时时间(通常 30 秒)。如果脚本执行时间过长,会被强制终止。 对于需要较长时间的操作,建议在 Hook 中启动后台进程: ```bash #!/bin/bash # hook: gateway:start # description: 启动时执行耗时初始化 # 在后台执行,不阻塞 Hook nohup bash -c ' sleep 5 # 执行耗时操作... curl -s https://api.example.com/init ' > /dev/null 2>&1 & echo "初始化任务已在后台启动。" ``` ### 调试 Hook ```bash # 查看 Hook 执行日志 openclaw logs --filter hooks # 手动执行 Hook 脚本测试 bash ~/.openclaw/hooks/welcome.sh # 检查脚本语法 bash -n ~/.openclaw/hooks/welcome.sh ``` ## 最佳实践 ### 1. 保持 Hook 脚本简短 Hook 应该快速执行完毕,不要在 Hook 中做复杂的计算或网络请求。如果需要执行耗时操作,启动后台进程。 ### 2. 做好错误处理 ```bash #!/bin/bash # hook: /new set -e # 遇到错误立即退出 # 使用 || true 防止非关键命令失败导致脚本中断 some_command || true ``` ### 3. 使用日志记录 ```bash #!/bin/bash # hook: tool:before log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> ~/.openclaw/logs/hooks.log } log "Hook triggered: $OPENCLAW_HOOK_EVENT" ``` ### 4. 避免无限循环 如果 Hook 脚本中发送了消息,可能会触发 `message:outgoing` 事件,进而触发另一个 Hook。确保你的 Hook 不会形成循环触发。 ### 5. 测试后再部署 ```bash # 先在本地测试 bash ~/.openclaw/hooks/my-hook.sh # 确认无误后再添加到 Hooks openclaw hooks add --event "/new" --script ~/.openclaw/hooks/my-hook.sh ``` ## 小结 Hooks 是 OpenClaw 事件驱动自动化的核心机制: - 在特定事件发生时自动执行脚本 - 支持会话事件(/new、/reset、/stop)、系统事件(Gateway 启动/停止)、消息事件和工具事件 - Hook 脚本存放在 `~/.openclaw/hooks/` 目录,支持 Bash、Node.js、Python 等语言 - 通过环境变量获取事件上下文信息 - 使用 `openclaw hooks list/add/remove` 管理 Hooks - 适合实现欢迎消息、日志记录、通知推送、临时文件清理等自动化场景 Hooks 让你的智能体不仅能"被动回答",还能在关键时刻"主动行动"。 #Hooks事件脚本 #自动化 #生命周期事件 #事件驱动 #龙虾技能库