Skip to content

Hooks 钩子

Hooks 允许你在 Claude Code 工作流的特定节点运行自定义 shell 命令——在工具调用前后、通知事件时、或 Claude 停止响应时触发自定义逻辑。

可用的 Hook 类型

类型触发时机典型用途
PreToolUse工具执行日志审计、权限检查、拦截危险操作
PostToolUse工具执行记录变更、触发后续流程、格式检查
Notification通知事件时发送 Slack/DingTalk 消息、写入日志
StopClaude 停止响应时通知任务完成、发送汇总报告

配置格式

.claude/settings.json.claude/settings.local.json 中配置:

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "audit-log.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'File edited' >> changelog.txt"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "notify-done.sh"
          }
        ]
      }
    ]
  }
}

matcher 匹配规则

matcher 可选,用于过滤特定工具。不设 matcher 则对所有工具触发。

matcher 值匹配范围
"Bash"只对 Bash 工具调用触发
"Edit"只对文件编辑触发
"Write"只对文件创建触发
"Read"只对文件读取触发
不设 matcher对所有工具调用触发

Hook 返回值对 Claude 行为的影响

Hook 命令的退出码(exit code)会影响 Claude Code 的后续行为:

退出码效果
0正常通过,Claude 继续执行
2阻止当前工具调用(PreToolUse 专用),Claude 会收到阻止信息并调整方案

这意味着你可以用 PreToolUse hook 实现动态权限控制——当命令返回退出码 2 时,Claude 的工具调用会被拦截。

动态拦截示例

拦截对生产环境的请求:

bash
#!/bin/bash
# pre-tool-use-guard.sh — 拦截对生产环境的 curl 命令

# 从 stdin 读取工具调用的 JSON 输入
INPUT=$(cat)

# 检查是否包含生产环境 URL
if echo "$INPUT" | grep -q "production.example.com"; then
  echo "阻止:不允许访问生产环境 URL"
  exit 2
fi

exit 0
json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "pre-tool-use-guard.sh"
          }
        ]
      }
    ]
  }
}

实战示例

示例 1:每次编辑后自动跑 lint

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx eslint --fix $(echo $CLAUDE_FILE_PATH)"
          }
        ]
      }
    ]
  }
}

示例 2:任务完成时发 Slack 通知

json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "curl -X POST -H 'Content-type: application/json' --data '{\"text\":\"Claude Code 任务已完成\"}' $SLACK_WEBHOOK_URL"
          }
        ]
      }
    ]
  }
}

示例 3:审计日志

json
{
  "hooks": {
    "PreToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo \"[$(date)] Tool: $CLAUDE_TOOL_NAME\" >> audit.log"
          }
        ]
      }
    ]
  }
}

最佳实践

  • Hook 命令应该快速完成——慢命令会阻塞 Claude 的工作流
  • 不要在 hook 中执行交互式命令(需要用户输入的命令)
  • PreToolUse hook 可以用退出码 2 实现动态权限拦截
  • 将复杂的 hook 逻辑写成独立脚本文件,而不是 inline 命令
  • Hook 中的环境变量(如 $CLAUDE_TOOL_NAME)提供工具调用的上下文信息

基于 MIT 协议发布