Claude Code Hooks 测评:零成本自动化开发新体验

2026-06-17阅读 0热度 0
Claude

要说Claude Code里哪个功能最被低估,Hooks绝对算一个。它能在关键时刻自动跑脚本:文件保存后做格式化、危险命令执行前拦一把、任务搞定后发通知。更关键的是——它不占上下文窗口,这是真正的“零成本”自动化。

一、什么是Hooks

简单来说,Hooks就是一系列事件驱动的脚本,在Claude Code生命周期的特定节点自动触发。

Claude的执行流程大致是这样:

用户输入 → Claude推理 → PreToolUse → 工具执行 → PostToolUse → Claude响应 → Stop

           ↑↑

         拦截点  后处理点

核心优势在于,Hooks是作为外部脚本运行的,完全独立于Claude的上下文。你在Hooks里做的任何操作,都不消耗那宝贵的200K token——这才是真正“免费”的自动化手段。


二、触发时机

Hooks支持多种事件,覆盖了整个生命周期:

事件

触发时机

典型用途

PreToolUse

工具执行前

拦截危险命令、修改参数

PostToolUse

工具执行后

自动格式化、通知

Notification

Claude等待输入时

桌面通知

SessionStart

会话开始时

加载环境变量

SessionEnd

会话结束时

清理临时文件

Stop

Claude完成响应时

验证任务完成

PreCompact

上下文压缩前

保存关键信息

PostCompact

上下文压缩后

重新注入上下文

ConfigChange

配置文件变化时

审计日志


三、配置方式

Hooks的配置写在settings.json里,举个例子:

{

  "hooks": {

    "PostToolUse": [

      {

        "matcher": "Edit|Write",

        "hooks": [

          {

            "type": "command",

            "command": "prettier --write \"$CLAUDE_FILE_PATH\""

          }

        ]

      }

    ]

  }

}

配置文件可以放在三个位置,作用范围不同:

位置

作用域

可共享

~/.claude/settings.json

所有项目

.claude/settings.json

单个项目

是,可提交Git

.claude/settings.local.json

单个项目

否,gitignored


四、实战案例

案例一:桌面通知

让Claude完成任务后自动弹窗提醒你,不用一直盯着终端看进度。

{

  "hooks": {

    "Notification": [

      {

        "matcher": "",

        "hooks": [

          {

            "type": "command",

            "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"

          }

        ]

      }

    ]

  }

}

macOS用osascript,Linux用notify-send,Windows直接用PowerShell就行。

案例二:自动格式化

每次写完代码,自动跑Prettier格式化:

{

  "hooks": {

    "PostToolUse": [

      {

        "matcher": "Edit|Write",

        "hooks": [

          {

            "type": "command",

            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"

          }

        ]

      }

    ]

  }

}

案例三:保护敏感文件

阻止Claude修改.envpackage-lock.json这些关键文件:

#!/bin/bash

INPUT=$(cat)

FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path')

PROTECTED_PATTERNS=(".env" "package-lock.json" ".git/")

for pattern in "${PROTECTED_PATTERNS[@]}"; do

  if [[ "$FILE_PATH" == *"$pattern"* ]]; then

    echo "Blocked: $FILE_PATH is protected"

    exit 2 # exit 2 = 阻止操作

  fi

done

exit 0 # exit 0 = 放行

{

  "hooks": {

    "PreToolUse": [

      {

        "matcher": "Edit|Write",

        "hooks": [

          {

            "type": "command",

            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"

          }

        ]

      }

    ]

  }

}

案例四:压缩后重新注入上下文

上下文压缩之后,把项目规则重新注入进去:

{

  "hooks": {

    "SessionStart": [

      {

        "matcher": "compact",

        "hooks": [

          {

            "type": "command",

            "command": "echo 'Reminder: use Bun, not npm. Run bun test before committing.'"

          }

        ]

      }

    ]

  }

}

案例五:自动审批特定权限

跳过ExitPlanMode的审批对话框:

{

  "hooks": {

    "PermissionRequest": [

      {

        "matcher": "ExitPlanMode",

        "hooks": [

          {

            "type": "command",

            "command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"PermissionRequest\", \"decision\": {\"beha vior\": \"allow\"}}}'"

          }

        ]

      }

    ]

  }

}

案例六:环境变量自动加载

配合direnv,目录切换时自动加载环境变量:

{

  "hooks": {

    "SessionStart": [

      {

        "hooks": [

          {

            "type": "command",

            "command": "direnv export bash > \"$CLAUDE_ENV_FILE\""

          }

        ]

      }

    ],

    "CwdChanged": [

      {

        "hooks": [

          {

            "type": "command",

            "command": "direnv export bash > \"$CLAUDE_ENV_FILE\""

          }

        ]

      }

    ]

  }

}


五、输入输出机制

Hooks通过stdin接收事件数据,通过stdout/stderr和exit code返回结果。

输入示例

{

  "session_id": "abc123",

  "cwd": "/Users/sarah/myproject",

  "hook_event_name": "PreToolUse",

  "tool_name": "Bash",

  "tool_input": {

    "command": "npm test"

  }

}

输出控制

Exit Code

行为

0

放行,继续执行

2

阻止,stderr作为反馈给Claude

其他

放行,但显示警告

结构化输出

如果需要更精细的控制,可以返回JSON:

{

  "hookSpecificOutput": {

    "hookEventName": "PreToolUse",

    "permissionDecision": "deny",

    "permissionDecisionReason": "Use rg instead of grep for better performance"

  }

}


六、匹配器

matcher字段

按工具名来过滤:

{

  "matcher": "Edit|Write" // 匹配Edit或Write

}

{

  "matcher": "Bash" // 只匹配Bash

}

{

  "matcher": "mcp__github__.*" // 匹配所有GitHub MCP工具

}

if字段

更细腻一点,按工具参数过滤:

{

  "matcher": "Bash",

  "hooks": [

    {

      "type": "command",

      "if": "Bash(git *)",

      "command": "echo 'Git command detected'"

    }

  ]

}


七、高级用法

HTTP Hooks

把事件数据POST到外部服务:

{

  "hooks": {

    "PostToolUse": [

      {

        "hooks": [

          {

            "type": "http",

            "url": "http://localhost:8080/hooks/tool-use",

            "headers": {

              "Authorization": "Bearer $MY_TOKEN"

            },

            "allowedEnvVars": ["MY_TOKEN"]

          }

        ]

      }

    ]

  }

}

Prompt Hooks

让Claude模型来做决策:

{

  "hooks": {

    "Stop": [

      {

        "hooks": [

          {

            "type": "prompt",

            "prompt": "Check if all tasks are complete. If not, respond with {\"ok\": false, \"reason\": \"what remains\"}."

          }

        ]

      }

    ]

  }

}

Agent Hooks

启动子Agent做验证:

{

  "hooks": {

    "Stop": [

      {

        "hooks": [

          {

            "type": "agent",

            "prompt": "Verify that all unit tests pass. Run the test suite and check results.",

            "timeout": 120

          }

        ]

      }

    ]

  }

}


八、常见问题

Hook没触发

1. 运行/hooks确认配置存在

2. 检查matcher是否正确(注意大小写)

3. 确认事件类型对不对路

Hook报错

可以先手动测试脚本:

echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh

echo $? # 查看退出码

常见问题排查:

- 命令找不到 → 用绝对路径

- jq找不到 → 安装jq

- 脚本不执行 → chmod +x ./my-hook.sh

Stop Hook无限循环

需要检查stop_hook_active字段:

#!/bin/bash

INPUT=$(cat)

if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then

  exit 0 # 已经触发过,允许停止

fi


九、最佳实践

1. 优先用PostToolUse而非PreToolUse——PreToolUse可能被拒绝,PostToolUse更稳定

2. 脚本放项目目录——.claude/hooks/可以提交Git,团队共享

3. 用jq解析JSON——比awk/sed靠谱得多

4. stderr给Claude,stdout返回JSON——各司其职

5. 超时设置要合理——默认10分钟,复杂任务可以适当调长


十、Hooks vs Skills vs CLAUDE.md

维度

Hooks

Skills

CLAUDE.md

加载时机

事件触发

按需加载

每次会话

上下文成本

描述常驻

每次请求都带

能力

运行脚本

提供知识

提供规则

适用场景

自动化

工作流

项目约定

总结一下:Hooks是“自动化”,Skills是“知识库”,CLAUDE.md是“项目宪法”。三者配合得当,效率才能最大化。

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策