深度分析为何系统提示在长会话中容易被忽视,演示 hooks 机制如何通过确定性执行保证行为约束;包含 hooks 生命周期和应用场景。
如果你花过时间定制 Claude Code,你可能在 CLAUDE.md 中写过类似这样的指令:"编辑文件后总是运行格式化器"或"永远不要修改 .env 或任何 .pem/.key 文件"。这些规则确实有效——直到某个长会话、一个大幅改动,或者充满其他指令的上下文窗口让这条规则被降低优先级。这不是模型在不在意;系统提示词本质上是建议性的。提示词中的每条指令都在与上下文中的其他所有内容竞争注意力,而早期写入的指令往往会随着对话的展开而逐渐淡去。
这是一个结构性的问题,不是提示词的错误。这也说明了一个关键事实:任何你真正需要每一次都执行的操作——不是"通常",不是"当模型想起来的时候"——都不应该放在提示词里。
Claude Code hook 是连接到工具生命周期特定时点的 shell 命令:文件编辑后、工具运行前、Claude 完成响应时、需要你的权限时、会话开始时等。它们以代码形式执行,具有确定性,与对话内容或模型那一轮的"决定"无关。模型没有发言权——hook 直接运行。
这个区别看起来小,实际上很重要。CLAUDE.md 中的规则是一个你希望被遵守的请求。Hook 才是保证,因为强制执行的不是模型。
并非所有东西都适合用 hook 实现。有用的分界线是这样的:
必须每次都执行,无需判断 → hook。每次编辑后重新格式化文件。在凭证文件被写入前就阻止它。Claude 停止的那一刻运行测试套件并输出通过/失败一行。在 Claude 等待你时 ping 桌面。每次都记录会话启动,包含时间戳。
从针对具体情况的推理中受益 → prompt / subagent。判断某个 diff 是否有安全问题、文档字符串应该怎么写、如何重构函数——这些需要判断,而判断就是模型存在的目的。试图把它硬编码到 shell 脚本里,只是把问题的脆弱性转移到更糟的地方。
走反方向是常见的失败模式:人们写越来越复杂的 CLAUDE.md 指令,试图从一个概率系统中硬生生挤出确定性行为,而一个五行的 shell hook 早就解决问题了。
statusline 不强制任何东西——它只是提示下方的一行文字,显示你当前用的模型、目录和 git 分支。它的价值在于另一个原因:一旦你同时运行多个 Claude Code 会话(这在用 subagent 和 worktree 时很常见),"这到底是哪个会话"就成了真正的错误来源。添加一个 statusline 很简单,但如果你在四个终端之间切换上下文,很容易忘记需要它。
在给你的 CLAUDE.md 再加一段指令之前,先问问自己:你真正想要的是一条模型应该权衡的规则,还是一个不应该依赖模型权衡任何东西的保证?如果是后者,改写一个 hook。
这些工具的完整方案——编辑时自动格式化、在写入前阻止 .env/.pem/.key 的秘密文件守卫、停止时运行测试、桌面通知和会话日志——加上 12 个斜线命令、6 个 subagent 和一个 git 感知的 statusline,被打包为 Claude Code Power Pack(复制粘贴到 .claude/,€29):https://vincentdu2a.gumroad.com/l/bqndfi。这是一个独立的非官方项目——与 Anthropic 无关联、未经认可或赞助。"Claude"和"Claude Code"是 Anthropic 的商标。
进一步操作,你可以考虑屏蔽此人和/或举报滥用。