处理器类型
Hook Handler Types
Claude Code Hooks 支持三种处理器类型,每种适用于不同的场景。理解它们的区别和特点,有助于选择最合适的方案。
三种处理器对比
| 特性 | command | prompt | agent |
|---|---|---|---|
| 执行方式 | 运行 Shell 命令 | 注入提示词 | 启动子 Claude |
| 执行环境 | 系统 Shell | Claude 上下文 | 独立 Claude 实例 |
| 可阻止工具调用 | ✅ | ❌ | ❌ |
| 可修改行为 | 通过返回值 | 通过提示词 | 通过子代理结果 |
| 性能开销 | 低 | 极低 | 高 |
| 适用场景 | 自动化脚本 | 行为调整 | 复杂后处理 |
command 处理器
最常用的处理器类型,执行系统 Shell 命令。
基本格式
json
{
"type": "command",
"command": "node scripts/my-hook.js"
}工作机制
- Hook 事件触发时,通过 Shell 执行指定命令
- 事件上下文数据通过 stdin 以 JSON 格式传入
- 处理器通过 stdout 返回 JSON 结果
- 通过 exit code 指示成功(0)或失败(非0)
输入输出约定
输入(stdin):
json
{
"hook_event": "PreToolUse",
"tool_name": "Bash",
"tool_params": {
"command": "npm install lodash"
}
}输出(stdout):
json
{
"allow": true,
"message": "命令安全检查通过"
}阻止工具调用
在 PreToolUse 事件中,返回 allow: false 可阻止工具执行:
json
{
"allow": false,
"reason": "不允许安装未经审核的依赖包"
}也可以通过非零退出码阻止:
bash
#!/bin/bash
# 检测危险命令
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_params.command')
if echo "$COMMAND" | grep -qE 'rm\s+-rf|drop\s+table|--force'; then
echo '{"allow": false, "reason": "检测到危险命令"}'
exit 1
fi
echo '{"allow": true}'
exit 0环境变量
命令执行时可访问以下环境变量:
| 变量 | 说明 |
|---|---|
CLAUDE_SESSION_ID | 当前会话 ID |
CLAUDE_WORKING_DIR | 工作目录 |
CLAUDE_HOOK_EVENT | 事件类型名称 |
超时设置
默认超时 30 秒,可通过 timeout 字段调整:
json
{
"type": "command",
"command": "node scripts/slow-check.js",
"timeout": 60000
}示例:Node.js 处理器
javascript
// scripts/check-bash-safety.js
const input = [];
process.stdin.on('data', (chunk) => input.push(chunk));
process.stdin.on('end', () => {
const data = JSON.parse(input.join(''));
if (data.tool_name !== 'Bash') {
console.log(JSON.stringify({ allow: true }));
return;
}
const cmd = data.tool_params.command || '';
const dangerous = [
/rm\s+-rf\s+\//,
/dd\s+if=/,
/mkfs\./,
/:\(\)\{.*\}/,
];
const isDangerous = dangerous.some(pattern => pattern.test(cmd));
console.log(JSON.stringify({
allow: !isDangerous,
reason: isDangerous ? `危险命令被阻止: ${cmd.substring(0, 50)}` : undefined
}));
process.exit(isDangerous ? 1 : 0);
});prompt 处理器
向 Claude 的当前上下文注入额外的提示词,影响其后续行为。
基本格式
json
{
"type": "prompt",
"prompt": "在修改代码时,请确保所有函数都有 JSDoc 注释"
}工作机制
- 事件触发时,将
prompt内容注入到 Claude 的上下文中 - Claude 在后续响应中会参考这段提示词
- 不会阻止任何操作,只是影响 Claude 的行为
适用场景
- PostToolUse — 文件修改后提醒 Claude 检查特定事项
- SessionStart — 会话开始时注入项目规范
- PreCompact — 压缩前强调需要保留的关键信息
示例
json
{
"hooks": {
"PostToolUse": [
{
"tool": "Write",
"handler": {
"type": "prompt",
"prompt": "你刚刚创建了一个新文件。请检查:\n1. 文件头部是否有版权声明\n2. 是否需要对应的测试文件\n3. 是否需要更新相关的 index 导出"
}
}
],
"SessionStart": [
{
"handler": {
"type": "prompt",
"prompt": "本项目使用 Vue 3 Composition API,请不要使用 Options API。所有组件使用 <script setup> 语法。"
}
}
]
}
}动态提示词
prompt 处理器也支持使用命令生成动态提示词:
json
{
"type": "prompt",
"command": "cat .claude/dynamic-rules.md"
}此时命令的 stdout 输出将作为提示词注入。
agent 处理器
启动一个独立的 Claude 子实例来处理事件。适合需要复杂推理或多步操作的后处理任务。
基本格式
json
{
"type": "agent",
"prompt": "检查刚刚创建的文件是否符合项目编码规范,如有问题请自动修复"
}工作机制
- 事件触发时,启动一个新的 Claude 实例
- 该实例可以使用所有可用工具
- 执行完成后,结果反馈给主会话
- 子实例有独立的上下文窗口
适用场景
- PostToolUse — 自动审查和修复新创建的代码
- Stop — 生成任务总结报告
- TaskCompleted — 对任务结果进行深度分析
示例
json
{
"hooks": {
"PostToolUse": [
{
"tool": "Write",
"handler": {
"type": "agent",
"prompt": "检查刚才写入的文件,确保:1) TypeScript 类型完整 2) 有适当的错误处理 3) 符合项目 ESLint 规则。如有问题,直接修复。"
}
}
],
"Stop": [
{
"handler": {
"type": "agent",
"prompt": "回顾本次会话的所有代码变更,生成一份简要的变更摘要,保存到 .claude/session-summary.md"
}
}
]
}
}注意事项
- agent 处理器性能开销较大,会消耗额外的 Token
- 子代理有独立的权限控制,遵循相同的权限规则
- 避免在频繁触发的事件(如每次 Read)上使用 agent 处理器
- 子代理的超时时间默认较长(5 分钟)
多处理器组合
同一个事件可以配置多个处理器,按顺序执行:
json
{
"hooks": {
"PostToolUse": [
{
"tool": "Write",
"handler": {
"type": "command",
"command": "npx prettier --write"
}
},
{
"tool": "Write",
"handler": {
"type": "prompt",
"prompt": "文件已自动格式化。请检查格式化后的内容是否仍然正确。"
}
}
]
}
}处理器按数组顺序依次执行。如果 command 处理器返回 allow: false(仅 PreToolUse),则后续处理器不再执行。
选择建议
| 需求 | 推荐处理器 |
|---|---|
| 运行 linter/formatter | command |
| 安全检查和拦截 | command |
| 调整 Claude 行为 | prompt |
| 注入项目规范 | prompt |
| 复杂的代码审查和修复 | agent |
| 生成报告或文档 | agent |
| 简单日志记录 | command |