学习中心/Claude Code/Hooks 自动化工作流
中级

Hooks 自动化工作流

用 Hooks 在特定事件触发时自动执行脚本,构建自定义自动化工作流

Anthropic25 min

学习笔记

Hooks 自动化工作流

Hooks 是 Claude Code 的事件驱动自动化机制——在特定事件(如工具调用前后、会话开始/结束)触发时,自动执行你定义的脚本或操作。它是构建定制化开发工作流的基础设施。

你将学到

  • Hooks 的 9 种事件类型及其触发时机
  • 4 种 Hook 类型(command、prompt、http、agent)
  • 实用 Hook 配置示例
  • Hook 的输入输出格式
  • 权限控制与安全考量

适合谁

  • 想要自动化开发工作流的工程师
  • 需要在团队中执行统一规范的技术负责人
  • 有 CI/CD 经验、想深度定制 AI 工具行为的开发者

1. Hook 事件类型

Claude Code 支持 9 种事件,覆盖了工具调用和会话生命周期的各个阶段:

事件 触发时机 典型用途
PreToolUse 工具执行 权限控制、阻止危险操作、修改输入
PostToolUse 工具执行 日志记录、结果检查、自动格式化
UserPromptSubmit 用户提交提示词时 输入验证、注入额外上下文
Notification 通知事件 自定义权限提示和空闲通知处理
Stop Claude 准备停止时 评估任务是否真正完成
SessionStart 会话开始/恢复/压缩时 初始化、注入上下文
SessionEnd 会话结束时 清理临时文件
SubagentStart 子代理启动时 初始化子代理资源
SubagentStop 子代理停止时 清理子代理资源

2. Hook 配置基础

.claude/settings.json(项目级)或 ~/.claude/settings.json(用户级)中配置:

{
  "hooks": {
    "事件名": [
      {
        "matcher": "工具名或模式",
        "hooks": [
          {
            "type": "hook类型",
            "command": "要执行的命令"
          }
        ]
      }
    ]
  }
}

matcher 匹配规则

  • "Bash" — 匹配 Bash 工具
  • "Write" — 匹配文件写入
  • "mcp__server__tool" — 匹配特定 MCP 工具
  • 不设 matcher — 匹配所有

3. 四种 Hook 类型

command — 执行 Shell 命令

最常用的类型,执行任意 shell 命令或脚本:

{
  "type": "command",
  "command": "echo 'Tool used' >> /tmp/claude-log.txt"
}

prompt — LLM 评估

使用 LLM 判断(如任务是否完成):

{
  "type": "prompt",
  "prompt": "Check if all tasks are complete. If not, respond with what remains.",
  "timeout": 30
}

http — HTTP 请求

发送 HTTP 请求到外部服务:

{
  "type": "http",
  "url": "http://localhost:8080/hooks/pre-tool-use",
  "timeout": 30,
  "headers": {
    "Authorization": "Bearer $MY_TOKEN"
  },
  "allowedEnvVars": ["MY_TOKEN"]
}

agent — 子代理

生成子代理执行任务:

{
  "type": "agent",
  "prompt": "Review the changes for security issues"
}

4. Hook 输入格式

每个 Hook 收到 JSON 格式的输入(通过 stdin),包含公共字段和事件特定数据:

{
  "session_id": "abc123",
  "cwd": "/Users/dev/myproject",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": {
    "command": "npm test"
  }
}

5. 实用配置示例

阻止危险命令

阻止 rm -rf 等破坏性操作:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/block-dangerous.sh"
          }
        ]
      }
    ]
  }
}

.claude/hooks/block-dangerous.sh

#!/bin/bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')

if echo "$cmd" | grep -qE 'rm\s+-rf|drop\s+table|git\s+push\s+--force'; then
  echo '{"decision":"block","reason":"Dangerous command blocked by hook"}'
fi

记录所有 Bash 命令

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.command' >> ~/.claude/command-log.txt"
          }
        ]
      }
    ]
  }
}

压缩后重新注入上下文

当对话被压缩时,重要的上下文可能丢失。用 SessionStart hook 在压缩后重新注入:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "compact",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Reminder: use pnpm, not npm. Run tests before committing. Current sprint: auth refactor.'"
          }
        ]
      }
    ]
  }
}

会话结束时清理

{
  "hooks": {
    "SessionEnd": [
      {
        "matcher": "clear",
        "hooks": [
          {
            "type": "command",
            "command": "rm -f /tmp/claude-scratch-*.txt"
          }
        ]
      }
    ]
  }
}

检查任务是否完成

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "Review whether all requested tasks are complete. If anything is missing, respond with what remains to be done.",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

6. Hook 输出格式

PreToolUse 权限控制

允许操作:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "permissionDecisionReason": "Auto-approved: safe read operation"
  }
}

拒绝操作:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Database writes are not allowed"
  }
}

修改输入后放行:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "updatedInput": {
      "command": "npm test -- --coverage"
    }
  }
}

阻止操作

任何 Hook 都可以返回 block 决策:

{
  "decision": "block",
  "reason": "This operation is not allowed in production environment"
}

7. 安全建议

  • Hook 在权限系统之前运行——可以用来实现自定义权限策略
  • 项目级 Hooks 写在 .claude/settings.json,提交到 Git 让团队共享
  • 敏感信息(如 API Key)通过 allowedEnvVars 从环境变量注入
  • 测试 Hook 脚本时确保它正确处理各种输入
  • Hook 脚本应快速返回——避免长时间阻塞

小结

  • Hooks 是事件驱动的自动化机制,9 种事件覆盖工具调用和会话生命周期
  • 4 种 Hook 类型:command(shell 命令)、prompt(LLM 评估)、http(HTTP 请求)、agent(子代理)
  • PreToolUse 可实现自定义权限控制,PostToolUse 适合日志和格式化
  • SessionStart + compact matcher 可在压缩后重新注入关键上下文
  • 将 Hook 配置提交到 Git,团队共享自动化工作流

延伸阅读

内容来源:Anthropic 官方文档