Claude Code 的 Hooks、Slash Command 与自动化

Claude Code 的 Hooks、Slash Command 与自动化


前十一篇文章,主要靠人工操作------输入指令、看输出、确认、提交。这对于个人项目够了,但团队协作和日常高频使用下,手动流程会让你慢慢开始不耐烦。

Claude Code 有一套事件系统(Hooks)和自定义命令(Slash Command),可以把你每次重复的操作自动化。这篇文章从三个实际场景出发,把配置逻辑讲清楚。


Hooks 是什么

Claude Code 在执行过程中会触发一些生命周期事件。你可以在这些事件上挂载脚本------事件触发时,Claude Code 自动跑你的脚本。

八个事件:

事件 触发时机 能拦截吗
PreToolUse 工具调用之前 能,exit code 2 阻止执行
PostToolUse 工具调用之后 能,exit code 2 阻止后续
UserPromptSubmit 用户提交 prompt
SessionStart 会话启动 不能
Stop 会话结束前
SubagentStop 子 Agent 结束 不能
Notification 通知事件 不能
PreCompact 上下文压缩前 不能

配置写在 .claude/settings.jsonhooks 字段里。


场景一:每次 AI 写代码后自动格式化

AI 写完代码之后,缩进和空行有时候不够干净。每次手动跑 prettier 很烦。

配一个 PostToolUse 钩子------当 WriteEdit 工具执行完后,自动对修改的文件跑格式化。创建一个脚本 .claude/hooks/format.sh

bash 复制代码
#!/bin/bash
# 从 stdin 读取 Claude Code 传入的 JSON
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_input',{}).get('file_path',''))")

if [ -n "$FILE_PATH" ]; then
    npx prettier --write "$FILE_PATH" 2>/dev/null || true
fi

然后在 settings.json 里挂上:

json 复制代码
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/format.sh"
          }
        ]
      }
    ]
  }
}

解释一下:

  • matcher: "Write|Edit" --- 只在文件写入或编辑时触发,Bash、Grep 等操作不触发
  • Hook 脚本从 stdin 读 JSON,其中 tool_input.file_path 是当前操作的文件路径
  • 2>/dev/null || true --- prettier 不支持的文件类型会报错,吞掉错误不中断流程

效果:AI 写完代码 → 自动格式化 → 你看到的 diff 已经是格式化后的版本。


场景二:危险命令拦一道

AI 在 Bash 里跑命令,理论上不会故意破坏,但你也不知道它会不会在你的项目里 rm -rf。PreToolUse 可以在命令执行前拦截:

json 复制代码
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 .claude/hooks/block-dangerous.py"
          }
        ]
      }
    ]
  }
}

配套的 Python 脚本 .claude/hooks/block-dangerous.py

python 复制代码
import json, sys, os

TOOL_INPUT = json.loads(sys.stdin.read())
command = TOOL_INPUT.get("tool_input", {}).get("command", "")

DANGEROUS_PATTERNS = [
    "rm -rf /",
    "git push --force",
    "git reset --hard",
    "sudo ",
    "chmod 777",
    "DROP TABLE",
    "DROP DATABASE",
]

for pattern in DANGEROUS_PATTERNS:
    if pattern.lower() in command.lower():
        print(f"\n BLOCKED: Dangerous command detected: '{pattern}'")
        print(f"   Full command: {command}")
        print("   To proceed, rephrase the command or manually approve.")
        sys.exit(2)  # exit code 2 = block

sys.exit(0)  # exit code 0 = allow

脚本从 stdin 读取 JSON 格式的工具调用信息,检查 command 是否匹配危险模式。匹配到就 exit code 2,Claude Code 阻止执行并在终端显示 BLOCKED 消息。

你加到 DANGEROUS_PATTERNS 里的规则会跟着项目走(.claude/hooks/ 提交到 git),整个团队共享。


场景三:Slash Command------封装常用流程

Hooks 负责"自动触发",Slash Command 负责"手动唤起"。你在 Claude Code 里输入 /project:commit,它会执行对应的指令。

定义方式:在 .claude/commands/ 下创建 Markdown 文件。

.claude/commands/commit.md --- 生成 commit message 并提交:

markdown 复制代码
---
description: 分析变更并生成 Conventional Commits 格式的 commit message
---

请执行以下步骤:

1. 运行 `git diff --staged` 和 `git log --oneline -5` 查看待提交的变更和最近的提交历史
2. 根据变更内容生成 commit message:
   - 遵循 Conventional Commits 格式
   - 标题不超过 72 字符
   - 用英文写 message
3. 把生成的 message 展示给我审查,等我确认后再执行 `git commit -m "..."`

使用方式------在 Claude Code 里输入:

复制代码
/project:commit

Claude Code 读取 commit.md,把 YAML 头之后的正文作为指令执行。生成 message、展示、等你确认、提交。

.claude/commands/pr.md --- 创建 PR:

markdown 复制代码
---
description: 分析当前分支变更并创建 Pull Request
---

请执行以下步骤:

1. 检查当前分支名和远程状态
2. 运行 `git diff main...HEAD --stat` 查看变更文件
3. 生成 PR 标题和描述:
   - 标题:简洁描述变更(中文)
   - 描述:列出改动点、测试情况、截图位置
4. 展示给我审查,确认后用 `gh pr create` 创建

写完一个功能后,/project:pr 一键搞定 PR。


场景四:启动会话时自动加载项目环境

SessionStart 钩子在 Claude Code 每次启动时运行。适合加载环境变量、检查依赖、激活虚拟环境。

json 复制代码
{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "source .claude/hooks/setup-env.sh"
          }
        ]
      }
    ]
  }
}

.claude/hooks/setup-env.sh

bash 复制代码
#!/bin/bash
# 激活 Python 虚拟环境
if [ -f .venv/bin/activate ]; then
    source .venv/bin/activate
fi

# 检查必要依赖
if ! command -v pytest &> /dev/null; then
    echo "⚠️  pytest not found --- tests won't run. Install: pip install pytest"
fi

# 设置环境变量
export PYTHONPATH="${PWD}/src:${PYTHONPATH}"

Claude Code 启动时自动激活 venv、检查依赖、设置 PYTHONPATH。不用每次手动 source .venv/bin/activate 了。


配置文件的最终结构

把这几个场景的配置整合到一起,项目里的完整配置:

复制代码
项目根目录/
├── .claude/
│   ├── settings.json          # hooks + permissions + 其他设置
│   ├── settings.local.json    # 个人覆盖配置(不提交 git)
│   ├── commands/
│   │   ├── commit.md          # /commit
│   │   └── pr.md              # /pr
│   └── hooks/
│       ├── block-dangerous.py # PreToolUse 拦截
│       ├── setup-env.sh       # SessionStart 环境
│       └── format.sh          # PostToolUse 格式化
├── .claudeignore              # 上下文排除
├── CLAUDE.md                  # 项目说明书
└── CLAUDE.local.md            # 个人覆盖指令

分层职责:

  • CLAUDE.md --- 告诉 AI 怎么写代码(代码风格、项目规则)
  • .claudeignore --- 告诉 AI 不要看什么(排除目录)
  • settings.json --- 告诉 Claude Code 怎么执行(权限、Hooks)
  • commands/ --- 封装你常做的重复操作
  • hooks/ --- 在特定时机自动触发的脚本

踩到的坑

1. Hook 脚本的性能很重要

PostToolUse 在每次工具调用后触发。如果你的格式化脚本很慢(比如 eslint 扫描整个项目),会严重影响使用体验。只格式化当前文件,不做全项目检查。

2. matcher 匹配模式要精确

matcher: "Edit" 只匹配 Edit 工具,matcher: "Write|Edit" 匹配两者。matcher 是 glob/管道匹配,不是完整正则------用 | 分隔、* 通配。如果你写 matcher: "W*" 会匹配 Write、WebSearch、WebFetch。建议用完整工具名。

3. settings.local.json 和 settings.json 的区别

settings.json 提交到 git,团队共享。settings.local.json 不提交,放个人偏好。如果你不愿意团队所有人继承你的权限配置,写到 local 里。

4. Hook 脚本的 exit code 含义

  • exit 0 = 允许,继续执行
  • exit 1 = 非阻塞错误,显示 warning 但继续
  • exit 2 = 阻止,Claude Code 中止操作

PreToolUse 用 exit 2 拦截,PostToolUse 用 exit 0 放行(格式化失败不应该阻止代码落地)。


下一篇

Hooks 和命令让 Claude Code 从交互式工具变成了可编程平台。下一篇更深入------Agent 模式和 Chat 模式到底有什么区别,什么时候该用哪一种。

相关推荐
一次旅行7 小时前
AI 前沿日报 | 2026年7月3日 星期五
人工智能·github·ai编程
Hyyy8 小时前
如何设计Agent的Harness
llm·agent·ai编程
架构技术专栏8 小时前
难以想象啊,我用 Codex 全 AI 一天做了个拼豆小程序
openai·ai编程
kyriewen9 小时前
我筛了 1400 个 Claude Code Skills,留下 5 个天天在用的
前端·ai编程·claude
nbtang20269 小时前
AI Agent 入门(三):Tool Use 入门 —— Function Calling 原理与实战
人工智能·ai·agent
不爱记笔记9 小时前
ClaudeCode接入DeepSeek教程!防封号!
人工智能·ai·deepseek·claudecode
hey2020052810 小时前
AI生图软件哪个好用?
人工智能·ai·ai作画·aigc
Muscleheng12 小时前
Spring Ai SpringBoot集成DeepSeek
ai·spring ai·deepseek
云边云科技_云网融合12 小时前
零信任安全:数字化时代的企业防护新范式
人工智能·安全·ai
Z-D-K12 小时前
考验AI的“自我“-AI对《红楼梦》后40回的改写(32)
人工智能·ai·aigc·交互·agi