钩子和自动化
连接 SessionStart 钩子以自动加载上下文。使用 PreToolUse 阻止危险命令。通过审批门控在 cron 上运行 Claude。
钩子 是 Claude Code 在特定生命周期事件时运行的命令。在 ~/.claude/settings.json 中配置一次;它们会自动触发。钩子强制执行你否则会忘记的纪律:每个会话加载 STATE.md,在提交前检查暂存的 .env 文件。设置成本是 10 分钟。回报是永久性的。
SessionStart 在会话打开的那一刻触发;它打印的任何内容都会在你的第一条消息之前成为上下文:
{
"hooks": {
"SessionStart": [
{
"command": "cat ~/notes/STATE.md ~/notes/MEMORY.md 2>/dev/null || true"
}
]
}
}|| true 很重要:如果文件丢失,不要中断会话启动。保持钩子在 50ms 以下,并且在会话打开时不要进行网络调用。需要最新的 API 数据?运行一个 cron 来写入本地文件;在钩子中加载该文件。
另外四个钩子事件:
Stop: 会话结束时触发。用于提醒:“在关闭之前:更新 STATE.md。”
PreToolUse: Claude 调用工具之前触发。你的安全执行层:阻止危险命令,记录调用以进行审计跟踪。退出 0 允许调用;退出 2 阻止调用。
PostToolUse: 工具返回后触发。文件写入后运行 linter,SQL 迁移后检查 RLS 策略。
UserPromptSubmit: 你按下回车键时触发。注入上下文或对外部内容应用提示注入防御。
一个阻止任何包含 rm -rf 的 Bash 调用的 PreToolUse 钩子:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'rm -rf'; then echo 'BLOCKED: rm -rf not allowed' >&2; exit 2; fi"
}
]
}
}matcher 字段针对特定工具。没有它,钩子会在每次工具调用时触发。使用匹配器来保持钩子快速和有针对性。
当钩子没有触发时,按顺序检查:
语法: JSON 是否有效?运行 cat ~/.claude/settings.json | python3 -m json.tool。
文件路径: 在你的终端中手动测试钩子命令。
退出代码: || true 是否缺失?
速度: 超过 3 秒?将慢的部分移到 cron。
两个生产环境的陷阱。在每个钩子上设置一个明确的 timeout 字段,以便行为保持可预测。钩子在精简环境中运行,而不是你的完整 shell:如果钩子需要环境变量(如 Slack token),请在钩子命令中明确地 source 你的 .env。这是钩子在你的终端中工作但在 Claude Code 中静默失败的最常见原因。
Cron 驱动的 Claude Code。 相同的代理可以通过 claude --headless 按计划运行:早上 7 点发布到 Slack 的早报,每 4 小时进行社交媒体监控,每 30 分钟进行一次部署健康检查。
关键模式:审批门控。cron 起草,你审查,系统发送。一个未经审查就发送出站消息的自主代理最终会发送错误的东西:错误的模板、错误的受众、错误的时机。架构:代理发现并起草,人类审查并发布。 实现:代理将草稿写入 Slack 频道;在人类批准之前,任何东西都不会出站。这可以扩展到数十个代理,而不会有任何一个失控。
分阶段构建钩子系统:
第一阶段(第 1-2 周),加载钩子: SessionStart 加载 STATE.md 和 MEMORY.md;Stop 提醒你更新。
第二阶段(第 3-4 周),防护钩子: PreToolUse 硬性阻止不可逆命令(强制推送到主分支、DROP TABLE、rm -rf)。
第三阶段(第 2 个月以上),审计钩子: PostToolUse 检查实际写入的内容:SQL 迁移缺少 RLS 策略,新的 API 路由缺少速率限制,任何写入文件中的秘密。
PostToolUse 对于审计比 PreToolUse 更强大,因为它读取写入的文件内容,即事实真相,而不仅仅是 Claude 的意图。围绕你的实际故障模式构建钩子:两个解决实际问题的钩子胜过十个理论上的钩子。
SessionStart 加载上下文,Stop 提醒,PreToolUse 阻止危险命令(退出 2),PostToolUse 审计写入的内容,cron 加上审批门控将 Claude 变成一个有计划的系统,由人类控制发送按钮。从一个钩子开始:SessionStart 中的 cat ~/notes/STATE.md 2>/dev/null || true。每个月添加下一个阶段。