第 15 章 Hooks——事件驱动的自动化

Mr.Tong...
  • AI
  • Claude Code
大约 5 分钟

❓ 引导问题:如何在 Claude 执行操作前后自动运行自定义脚本?10 种钩子事件分别做什么?如何用退出代码和 JSON 输出精细控制行为?

📖 15.1 Hooks 是什么

Hooks(钩子)是用户自定义的 Shell 命令,在 Claude Code 生命周期的特定节点自动执行。它们是应用级的硬规则——只要触发对应事件就强制执行,稳定性和可靠性高于提示词约束。

典型场景:桌面通知提醒、代码自动格式化、操作日志审计、阻止修改敏感文件、代码规范校验。

⚠️ 钩子运行时直接使用当前系统凭证,使用前必须逐行审查命令逻辑和权限,避免在钩子中执行来源不明的脚本。

📖 15.2 十种钩子事件

工具类事件(支持匹配器筛选特定工具)

事件触发时机核心作用
PreToolUse工具调用拦截工具执行、修改入参、自动批准/拒绝权限
PermissionRequest弹出权限请求对话框时自动处理权限申请
PostToolUse工具调用成功后执行后置操作(格式化代码、记录日志)
NotificationClaude 发送通知时自定义通知方式(桌面弹窗、邮件)
PreCompact执行上下文压缩前自定义压缩规则、备份重要上下文

会话/任务类事件(无匹配器)

事件触发时机核心作用
UserPromptSubmit用户提交提示后、Claude 处理前验证提示合法性、补充上下文
Stop主 Agent 完成响应时智能判断是否需继续执行任务
SubagentStop子 Agent 任务完成时评估子任务结果,决定是否终止
SessionStart启动/恢复会话时初始化环境、加载项目配置
SessionEnd会话结束时清理临时文件、记录会话日志

📖 15.3 两种钩子类型

特性command 类型(命令钩子)prompt 类型(提示词钩子)
执行方式运行 Shell 命令/脚本调用 LLM(默认 Haiku)做智能决策
决策逻辑基于代码逻辑的确定性判断基于上下文的灵活语义判断
响应速度快(本地执行)较慢(需 API 调用)
适用场景代码格式化、日志记录、权限拦截任务完成度评估、复杂意图判断

📖 15.4 快速入门:命令日志记录

步骤 1:输入 /hooks,选择 PreToolUse 事件

步骤 2:添加匹配器,输入 Bash(仅 Bash 工具触发)

步骤 3:添加钩子命令:

jq -r '"\(.tool_input.command) - \(.tool_input.description // "无描述")"' >> ~/.claude/bash-command-log.txt

步骤 4:选择存储位置——User settings(全局)或 Project settings(当前项目)

验证:让 Claude 执行 ls,然后 cat ~/.claude/bash-command-log.txt 查看日志。

📖 15.5 退出代码与 JSON 输出

退出代码控制

退出代码含义行为
0执行成功stdout 可返回 JSON 做高级控制
2阻止操作stderr 反馈给 Claude,阻止当前事件继续
其他非零值非阻塞错误stderr 仅在详细模式显示,不影响事件执行

JSON 高级控制(退出代码为 0 时)

通用字段作用
continue: true/false是否允许事件继续(false 优先于其他规则)
stopReasoncontinue=false 时展示给用户的原因
systemMessage向用户显示的警告信息

PreToolUse 特有permissionDecision(allow/deny/ask)、updatedInput(修改工具入参)

PostToolUse 特有additionalContext(向 Claude 注入附加上下文)

📖 15.6 实用配置示例

自动格式化 TypeScript 文件

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "jq -r '.tool_input.file_path' | { read fp; if echo \"$fp\" | grep -q '\\.ts$'; then npx prettier --write \"$fp\"; fi; }"
      }]
    }]
  }
}

禁止修改敏感文件

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "python3 -c \"import json, sys; d=json.load(sys.stdin); p=d.get('tool_input',{}).get('file_path',''); sys.exit(2 if any(x in p for x in ['.env','package-lock.json','.git/']) else 0)\""
      }]
    }]
  }
}

退出代码 2 阻止工具调用,从而禁止修改这些文件。

Claude 等待输入时发送桌面通知

{
  "hooks": {
    "Notification": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "notify-send 'Claude Code' '请确认权限或输入指令'"
      }]
    }]
  }
}

📖 15.7 扩展配置(Skill/Agent 内嵌 Hooks)

在 Skill 或 Agent 的 YAML frontmatter 中内嵌 Hooks,仅在该组件生命周期内生效:

---
name: secure-operations
description: 执行 Shell 命令前做安全校验
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: "command"
          command: "./scripts/security-check.sh"
          once: true        # 会话内仅运行一次
          timeout: 15
---

📖 15.8 匹配器规则

匹配规则示例说明
精确匹配Write仅匹配 Write 工具
多工具匹配Edit|Write匹配 Edit 或 Write
前缀匹配Notebook.*匹配所有 Notebook 开头的工具
全匹配* 或空字符串匹配所有工具
MCP 工具mcp__memory__.*匹配 memory 服务器的所有工具

📖 15.9 配置文件路径

配置级别文件路径生效范围
用户级~/.claude/settings.json所有项目
项目级.claude/settings.json当前项目
本地项目级.claude/settings.local.json当前项目,不提交 Git
托管策略级管理员指定路径企业统一管控

📖 15.10 安全与调试

安全最佳实践:严格校验 tool_input 中的文件路径和命令参数,防止路径遍历(../);Shell 中使用 "$VAR" 而非 $VAR 避免参数注入;钩子脚本仅赋予必要权限,避免 sudo

调试:钩子不生效 → 执行 /hooks 检查注册状态,验证 JSON 语法,检查匹配器与工具名是否一致。查看详细日志 → 启动时加 --debug 参数。


📖 15.XX 要点总结

  1. 钩子是硬规则——事件触发必定执行,比提示词约束更可靠
  2. 10 种事件分两类:工具类(支持匹配器,精确控制哪些工具触发)+ 会话/任务类(无匹配器,全局生效)
  3. 退出代码 2 = 阻止操作;退出代码 0 + JSON = 精细控制(修改入参、注入上下文、动态权限决策)
  4. command vs prompt 类型:固定规则用 command(快),灵活判断用 prompt(智能)
  5. 扩展配置允许在 Skill/Agent frontmatter 中内嵌 Hooks,作用域仅限组件生命周期

你认为这篇文章怎么样?

  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.14.1