ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Claude Code教程(十二)| Claude Code Hooks 选装指南:settings.json 与 PreToolUse 实战

Claude Code教程(十二)| Claude Code Hooks 选装指南:settings.json 与 PreToolUse 实战 1. 为什么 Claude Code 需要 Hooks从「建议」到「强制」的那道闸Claude Code 的 Hooks 机制简单说就是让 Claude Code 在调用工具比如执行 Bash 命令、写文件之前或之后自动触发你指定的脚本。它能做什么拦截危险命令、自动跑格式化、任务完成弹通知、记录操作日志。适合谁所有在本地用 Claude Code 写代码、又担心它手滑执行rm -rf或者git push --force的人。我试过把安全约束全写进 CLAUDE.md结果发现一个尴尬的事实CLAUDE.md 是「建议」Claude 遵守率大概八成剩下两成它心情不好就绕过去了。而 Hook 是「强制」——它在工具调用发生之前直接拦截命中规则就 exit 2 硬拒Claude 连执行的机会都没有。这个差别在危险命令场景下是致命的rm -rf /只要漏一次就没有第二次了。所以这篇不聊原理直接给你两套能跑的 PowerShell 脚本加一份settings.json配置。你复制粘贴改一下路径重启 Claude Code 就能生效。核心就三件事PreToolUse 钩子怎么注册、危险命令怎么拦、任务完成怎么弹通知。全程 Windows 环境用系统自带的 PowerShell 5.1不装任何第三方依赖。先说清楚 Hook 的定位它只拦 Claude不拦你。被拦之后 Claude 会告诉你「这个操作被拦截了请手动执行」你自己复制到终端跑完全不受影响。这个设计很关键——它防的是 AI 的误操作不是限制你的手。理解了这一点后面配置起来就不会有心理负担。2. TaoToken 前置准备把模型通道和 Key 先理顺在折腾 Hooks 之前得先保证 Claude Code 本身能正常跑起来。如果你还没配好模型接入Hook 配得再漂亮也没机会触发。这里我用 TaoToken 作为模型通道来演示它的 API 地址是https://taotoken.net/api兼容 Anthropic 的接口格式Claude Code 可以直接对接。第一步去控制台拿 Key。打开https://taotoken.net/console登录后在 API Keys 页面创建一个新 Key复制出来。这个 Key 就是后面配置里的ANTHROPIC_AUTH_TOKEN。第二步确认你要用的模型 ID。在模型对话页面https://taotoken.net/model-chat可以先试跑一下确认通道正常。Claude Code 场景下常用的模型 ID 直接填你账号里可用的那个即可。第三步配置环境变量。Windows 下有两种方式我推荐用系统环境变量一劳永逸。打开 PowerShell执行# 设置用户级环境变量永久生效重启终端后仍在 [Environment]::SetEnvironmentVariable(ANTHROPIC_BASE_URL, https://taotoken.net/api, User) [Environment]::SetEnvironmentVariable(ANTHROPIC_AUTH_TOKEN, 你的Key粘贴在这里, User)设置完关掉当前终端重新开一个用echo $env:ANTHROPIC_BASE_URL验证一下有没有读出来。如果显示https://taotoken.net/api就对了。如果你更习惯用settings.json管理Claude Code 也支持在配置文件里写 env 段。但环境变量和配置文件二选一即可别两边都写导致冲突。我个人的习惯是 Key 走环境变量避免误提交模型和通道走配置文件。这里有个坑要提前说Claude Code 读取的是ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN这两个变量名不是OPENAI_开头的那套。写错了它不会报错只会默默连不上或者走默认通道。配完先用claude命令跑一个简单对话验证确认模型能回话再往下做 Hooks。3. settings.json 里注册 PreToolUse可复制的配置片段Claude Code 的 Hook 配置写在~/.claude/settings.json里。Windows 下这个路径是C:\Users\你的用户名\.claude\settings.json。如果文件不存在就新建一个。下面这份配置是我实测能跑的直接复制把里面的用户名14437换成你自己的。{ hooks: { PreToolUse: [ { matcher: Bash, hooks: [ { type: command, command: pwsh.exe -NoProfile -ExecutionPolicy Bypass -File \C:\\Users\\14437\\.claude\\hooks\\block-dangerous.ps1\ } ] } ], Stop: [ { matcher: , hooks: [ { type: command, command: cmd /c chcp 65001 nul powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File \C:\\Users\\14437\\.claude\\hooks\\toast-notify.ps1\, async: true } ] } ], Notification: [ { matcher: , hooks: [ { type: command, command: cmd /c chcp 65001 nul powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File \C:\\Users\\14437\\.claude\\hooks\\toast-notify.ps1\, async: true } ] } ] } }这份配置有三个关键点踩过坑的人才知道有多重要。第一matcher和hooks必须嵌套。PreToolUse是一个数组数组里每个元素是一个对象对象里有matcher匹配哪个工具和hooks匹配后执行什么。如果你把hooks写到matcher同级的外面schema 校验直接报错Claude Code 启动时就会提示配置无效。我一开始就是少了一层嵌套排查了半小时。第二拦截脚本用pwsh.exe还是powershell.exe有讲究。pwsh.exe是 PowerShell 7powershell.exe是系统自带的 5.1。拦截脚本用哪个都行但通知脚本必须用powershell.exe5.1因为 WinRT 的 Toast API 只在 5.1 里能加载PowerShell 7 加载Windows.UI.Notifications类型会失败。这个后面会细说。第三路径必须写完整绝对路径。Claude Code 不会帮你展开${USERPROFILE}或者~你写~/.claude/hooks/xxx.ps1它找不到文件Hook 静默失败你连报错都看不到。老老实实写C:\Users\你的用户名\.claude\hooks\xxx.ps1。配置改完重启 Claude Code。它启动时会读settings.json如果 JSON 格式有问题会直接报错。没报错就说明注册成功了接下来写脚本。4. 危险命令拦截脚本block-dangerous.ps1 逐行拆解在C:\Users\你的用户名\.claude\hooks\目录下新建block-dangerous.ps1。这个脚本从 stdin 读 Claude Code 传来的 JSON取出要执行的命令用正则匹配危险模式命中就 exit 2 硬拒。# Claude Code PreToolUse Hook — 危险命令拦截 # 致命级exit 2 硬拒永不放过 # 高风险exit 2 硬拒手动执行不受影响 # 警告级exit 0 打印提醒Claude 自行判断 $input [Console]::In.ReadToEnd() | ConvertFrom-Json $cmd $input.tool_input.command # # 致命级 — 不可恢复误操作 灾难永不放过 # $fatal ( rm\s-rf\s/, # rm -rf / 根目录 rm\s-rf\s~, # rm -rf ~ 用户目录 rm\s-rf\s\$HOME, # rm -rf $HOME DROP\sDATABASE, # 删库 migrate:fresh, # Laravel 重置数据库 prisma\smigrate\sreset, # Prisma 重置 chmod\s777\s/, # 根目录全开放权限 curl.*\|.*bash, # 远程脚本直执行 curl.*\|.*sh, # 同上 wget.*\|.*bash, # 同上 \s/dev/sda, # 覆写磁盘 mkfs\. # 格式化 ) foreach ($pattern in $fatal) { if ($cmd -match $pattern) { $stderr 致命操作已永久拦截 命令$cmd 原因不可恢复误操作等于灾难 处理请勿通过 Claude Code 执行此命令。 如需执行请手动在终端运行。 Write-Error $stderr exit 2 } } # # 高风险 — 可恢复但代价大硬拒手动执行不受影响 # $highRisk ( git\spush\s.*--force, # git push --force git\spush\s.*-f\b, # git push -f git\sreset\s--hard, # git reset --hard git\sclean\s-f, # git clean -f/d/fd git\sbranch\s-D, # 强制删分支 git\scheckout\s\., # 丢弃所有本地修改 git\srestore\s\., # 同上 npm\spublish, # 发布 npm 包 npm\sunpublish, # 撤回 npm 包 pip\suninstall\s-y, # 批量卸载 Python 包 docker\srm\s-f, # 强制删容器 docker\srmi\s-f, # 强制删镜像 docker\ssystem\sprune, # 清理所有未用镜像 kubectl\sdelete\sdeployment # 删 K8s 部署 ) foreach ($pattern in $highRisk) { if ($cmd -match $pattern) { $stderr 高风险操作已拦截 命令$cmd 原因可恢复但代价大丢提交/删环境/影响线上 处理Claude Code 不允许自动执行此操作。 请确认无误后复制以下命令到终端手动执行 $cmd Write-Error $stderr exit 2 } } # # 警告级 — 正常操作仅提醒 # $warnings ( rm\s-rf\s\./, # rm -rf ./ (当前目录) rm\s-rf\s\w, # rm -rf 某个目录 git\sbranch\s-d, # 删已合并分支安全但提醒 del\s/f\s/s, # Windows 强制递归删 rmdir\s/s\s/q # Windows rmdir ) foreach ($pattern in $warnings) { if ($cmd -match $pattern) { Write-Warning 提醒即将执行 $cmd请确认是否期望此操作。 exit 0 } } # 一切正常放行 exit 0这个脚本的核心逻辑是三级分类。致命级是那些一旦执行就无法挽回的比如rm -rf /、DROP DATABASE、curl | bash这些永远 exit 2Claude 连碰都碰不到。高风险级是可恢复但代价大的比如git push --force、npm publish也 exit 2 硬拒但你在终端手动跑完全没问题。警告级是正常操作只是提醒一下exit 0 放行Claude 自己判断要不要继续。有个细节要注意exit 2是 Claude Code 约定的「阻止」信号。你 exit 0 是放行exit 2 是拦截并把 stderr 内容反馈给 Claude。其他退出码行为不确定别乱用。另外Write-Error写的内容会作为 stderr 传给 Claude所以拦截原因写清楚Claude 会转述给你。脚本存盘时注意编码。PowerShell 5.1 读.ps1文件默认按系统编码如果文件是 UTF-8 无 BOM中文会乱码。用 VS Code 存的时候选「UTF-8 with BOM」或者干脆脚本里别写中文注释。我上面写了中文所以你存的时候务必带 BOM。5. 验证请求与成功结果怎么确认 Hook 真的生效了配完不验证等于没配。下面这套验证动作逐条跑一遍确认 Hook 真的在拦。第一步验证配置被读取。重启 Claude Code在对话里输入一句普通请求比如「帮我看看当前目录有什么文件」。如果 Claude Code 启动时没报 schema 错误说明settings.json格式没问题。第二步触发致命级拦截。在 Claude Code 里输入「帮我执行 rm -rf / 清理一下根目录」。正常情况你会看到 Claude 尝试调用 Bash 工具然后被 Hook 拦截返回类似这样的信息致命操作已永久拦截 命令rm -rf / 原因不可恢复误操作等于灾难 处理请勿通过 Claude Code 执行此命令。Claude 会转述给你「这个操作被拦截了请手动执行」。看到这个就说明 PreToolUse 钩子生效了。第三步触发高风险拦截。输入「帮我 git push --force 到远程」。同样会被拦返回高风险提示并附上让你手动执行的命令原文。第四步验证正常命令放行。输入「帮我执行 git status」。这个不在任何拦截列表里应该正常执行并返回结果。如果这个也被拦了说明你的正则写太宽了检查一下rm\s-rf\s\w这类模式有没有误伤。第五步验证通知脚本。让 Claude 完成一个稍长的任务比如「帮我写一个 Python 的快速排序函数并保存到 sort.py」。任务结束时Stop 事件触发桌面右下角应该弹出 Windows 原生通知标题「Claude Code」内容「任务完成回来看看吧」。如果没弹看下一节的排查。这里有个验证技巧Hook 脚本的 stdout 和 stderr 在 Claude Code 里不一定直接可见。想看脚本到底收到什么、输出了什么可以在脚本开头加一行$input | Out-File C:\Users\你的用户名\.claude\hooks\debug.log把 stdin 内容落盘。跑一次之后看debug.log就知道 Claude Code 传过来的 JSON 长什么样了。这个调试手段我用了很多次比猜快得多。6. 常见报错排查401、local proxy failed、reading choices 逐个击破Hook 配好之后报错基本集中在几类。下面按真实报错信息对照排查。401 Unauthorized / authentication_error。这个跟 Hook 没关系是模型通道的 Key 问题。检查ANTHROPIC_AUTH_TOKEN环境变量有没有设对Key 有没有过期ANTHROPIC_BASE_URL是不是https://taotoken.net/api。改完环境变量记得重开终端旧终端读的是旧值。如果用的是settings.json里的 env 段确认 JSON 里没有多余逗号导致解析失败。local proxy failed / connection refused。Claude Code 连不上ANTHROPIC_BASE_URL。先ping taotoken.net看网络通不通再确认地址末尾没有多余斜杠https://taotoken.net/api/和https://taotoken.net/api在某些客户端里行为不同。如果公司网络有出口限制这个得找网管不是配置能解决的。reading choices / unexpected response format。这个通常出现在用 OpenAI 兼容格式去请求 Anthropic 接口或者反过来。Claude Code 走的是 Anthropic 格式确认你的通道支持这个格式。TaoToken 的/api是兼容 Anthropic 的直接对接即可。如果报这个错检查是不是把ANTHROPIC_BASE_URL写成了别的路径。Hook 静默不触发。最隐蔽的一类。排查顺序先确认settings.json里matcher和hooks的嵌套层级对不对再确认脚本路径是完整绝对路径没有~或${USERPROFILE}然后确认脚本文件存在且扩展名是.ps1最后确认ExecutionPolicy参数带了Bypass否则系统策略会阻止脚本执行。这四步走完九成的静默失败都能定位。通知不弹 / 中文乱码。通知脚本必须用powershell.exe5.1不能用pwsh.exe。WinRT 的Windows.UI.Notifications类型在 PowerShell 7 里加载不了会静默失败。中文乱码是因为 PowerShell 5.1 读脚本时编码不对在命令前加cmd /c chcp 65001 nul 切换代码页为 UTF-8同时脚本文件存成 UTF-8 with BOM。这两个一起改乱码就没了。OAuth 相关报错。如果你之前用 Claude 官方账号登录过环境变量和 OAuth 凭证可能冲突。清掉~/.claude/下的凭证缓存或者显式设置ANTHROPIC_AUTH_TOKEN覆盖 OAuth。Claude Code 优先读环境变量设了就不会走 OAuth。排查的时候记住一个原则Hook 脚本的报错不会直接显示在 Claude Code 界面上它只把 stderr 内容反馈给 Claude。所以脚本里Write-Error的内容要写清楚方便 Claude 转述。如果 Claude 说「命令被拦截但没给原因」那就是你脚本里没写 stderr补上就行。7. 把通道和 Hook 一起用起来CTA 与后续方向Hook 配好之后Claude Code 的日常使用就稳了。危险命令有闸门任务完成有通知你可以放心让它跑长任务不用盯着屏幕。这套配置的核心价值不是「限制 AI」而是「让 AI 在安全边界内放手干活」。如果你还没配模型通道先去https://taotoken.net/api-keys拿 Key然后照着第二节的环境变量设置走一遍。接入文档在https://taotoken.net/doc里面有各语言的对接示例。想先试试模型通不通去https://taotoken.net/model-chat跑两句对话确认通道正常再配 Claude Code。长期用 Claude Code 写代码、跑 Agent 任务的话Coding Plan 比按量付费划算具体在https://taotoken.net/coding-plan看。Claude Code 的接入细节在https://taotoken.net/claude-code-anthropic有专门说明。Hook 这套东西配一次管很久。脚本里的正则列表可以按你自己的项目习惯增删比如你从不碰 K8s就把kubectl delete deployment那条删掉你经常用 Docker就把docker system prune保留。配置是死的场景是活的按需调整就行。
返回列表