跳转到主要内容

Claude Code Hooks、Skills 与斜杠命令:区别、选型和最小配置

需要复用审查步骤,先写 skill;需要每次工具调用前检查一个具体条件,配置 hook。斜杠命令是调用入口,自定义 commands 已并入 skills,技能既能由人调用,也能由 Claude 按需加载。

LaoZhang AI Team发布于更新于 20 分钟阅读
文章目录
Claude Code 斜杠入口、Skills 与 Hooks 的选择和组合

选择 Claude Code 的 hooks、skills 和斜杠命令,可以先看你要完成什么:复用一套审查、写作或迁移方法,用 skill;在指定事件发生时执行检查,用 hook;控制启动时机或会话设置,用对应的 / 入口。 它们可以配合,但不是三个互斥的功能。

截至 2026 年 10 月 4 日,官方文档已明确:自定义 commands 合并到了 skills。.claude/commands/review-notes.md 和 .claude/skills/review-notes/SKILL.md 都能提供 /review-notes,旧命令文件仍可使用。Skill 默认允许用户直接调用,也允许 Claude 在相关任务中加载,因此“命令手动、技能自动”不能作为通用定义。官方 Skills 文档

本文先帮你选机制,再给出一套变更审查 skill 和一个保护 .env 文件的最小 hook。代码示例的 JSON、YAML 和 Python 分支做过离线检查;没有在 Claude Code 中安装、调用或验证模型输出。

先区分斜杠入口背后执行的是什么

输入 / 是一个操作入口,入口背后可能是固定控制逻辑,也可能是一套交给模型执行的指令。看到斜杠,不能直接判断是否调用模型、是否消耗 token,或是否修改文件。

类型做什么典型例子怎样确认
内置控制命令大多数直接执行固定逻辑,管理会话或设置/help、/permissions、/skills看当前会话菜单及官方命令参考
捆绑技能Claude Code 随产品提供的提示词流程,由 Claude 使用工具执行/code-review、/debug、/claude-api官方命令表在用途列标为 Skill;可用性受版本和功能影响
自定义技能或旧命令文件你维护的说明、步骤和资料,通过 /name 或模型加载使用/review-notes看技能文件、调用控制字段和 /skills
事件钩子(hook)运行时到达指定事件后,执行匹配的处理器PreToolUse 的文件检查用 /hooks 检查事件、匹配条件和处理器

这是当前 命令参考 与 捆绑技能说明 的区分。不同版本、平台和已启用功能可能提供不同入口,先检查自己的会话菜单,再照例子操作。

例如,想让 Claude 协助 Claude API 项目,可以输入 /claude-api;已有 API 代码需要迁移时,可用 /claude-api migrate。它是捆绑技能,会加载对应语言的参考资料;代码导入 anthropic 或 @anthropic-ai/sdk 时也可能自动激活。它不是“任何 API 设置都由一个内置命令完成”,更不代表无需凭证或可以直接发布项目。Claude API 技能说明

按具体任务选机制,先保留最小流程

现在的需求先选什么选择理由与下一步
每次审查都想使用同一套证据和报告格式自定义 skill把方法写进 SKILL.md,先用 /review-notes 文件路径 显式试用
发布检查需要你决定何时开始手动调用的 skill设置 disable-model-invocation: true;把发布授权与检查步骤分别写清
每次 Edit 或 Write 前都要检查目标是否为 .envPreToolUse command hook用事件和工具名定位,再在脚本里检查路径;下面提供可离线验证的例子
编辑完成后需要格式化PostToolUse hook动作已经发生,适合后处理;格式化失败不能撤销刚才的编辑
希望停止前由模型判断任务是否完成支持该事件的 prompt 或 agent hook可以做判断,但要接受模型误判、成本与延迟,并设计无法完成时的退出方式
Claude 缺少远程 PR、当前文档或浏览器访问现有工具或 MCP 集成Skill 教方法,不能凭空提供外部访问权限

最后一种需求可以继续看 按工作流选择 Claude Code MCP,先判断缺的是仓库、文档、浏览器还是观测数据。本篇只处理技能与钩子的分工。

按调用入口、可复用方法和事件处理区分命令、Skill 与 Hook

文件位置可以帮助维护,但不决定全部行为。一个 skill 也可以由人通过斜杠调用;hook 也可以调用模型做判断。真正影响选择的是:由谁启动、执行什么、失败时能改变哪一步。

写一个可手动调用的变更审查 skill

如果你反复粘贴同一份审查要求,先把它变成一个 skill,比同时增加命令包装、hook 和多个脚本更容易检查。下面的例子适合“阅读某个现有文件,输出风险和验证建议”,不负责执行修改或发布。

前提是已经安装并启动 Claude Code,项目中有待审查文件。入口文件名必须是 SKILL.md,区分大小写。以项目级技能为例,文件放在 .claude/skills/review-notes/SKILL.md,内容如下:

markdown
---
name: review-notes
description: 阅读指定代码文件,给出有位置和证据的变更审查意见
argument-hint: "[项目内文件路径]"
disable-model-invocation: true
---

审查用户指定的文件:$ARGUMENTS。

1. 如果没有参数,询问待审查文件路径,然后停止本次审查。
2. 读取指定文件及理解其行为所需的直接依赖;文件不存在时说明问题,不猜测内容。
3. 按 [检查清单](checklist.md) 检查行为。
4. 只报告能够指出文件位置和具体触发条件的问题;把不确定项标成待验证。
5. 输出“发现、依据、建议验证”三栏;未发现明确问题时说明检查范围。
6. 本流程只阅读和提出建议,不编辑文件、不提交、不发布。

同目录的 checklist.md 内容为:

markdown
# 变更审查清单

- 输入为空或格式错误时,代码走向哪里?
- 外部调用失败后,是否向调用者保留可识别的错误?
- 状态更新是否可能发生在验证之前?
- 哪个具体输入或已有测试可以验证发现?

文件中的 YAML frontmatter 必须从第一行的 --- 开始,字段名需准确。YAML 解析失败或字段拼写错误时,技能可能仍加载,但预期的调用控制不会生效;不要只靠菜单出现来判断配置正确。

$ARGUMENTS 会替换为技能名后的参数。例如项目中确实存在 src/auth.ts 时,在 Claude Code 提示框输入:

/review-notes src/auth.ts

成功的信号是:/skills 中能够找到 review-notes,调用后 Claude 阅读目标文件,输出带位置或检查范围的意见。菜单出现只说明技能被发现,不能证明审查质量;再核对回答是否遵循清单、是否把猜测当成事实。没有参数、路径不存在或依赖无法读取时,应得到明确说明,而不是一份假审查报告。

新建技能目录后若没有被发现,可以使用 /reload-skills 重新扫描。当前文档说明技能目录的文件变化通常会在会话中被发现;如果会话开始时顶层 skills 目录尚不存在,则需要重新扫描。创建与配置技能、支持文件

辅助文件按需读取,让入口保持简洁;没有额外资料的小 skill 也可以成立。它的价值在于可复用,不取决于必须配几个脚本。旧 .claude/commands/review-notes.md 若已经能完成同样任务,不需要为了目录变化立即迁移;需要同目录清单、脚本或其他支持文件时,再采用技能目录更方便。

调用开关与工具权限要分开理解

上面的 disable-model-invocation: true 是调用控制:让你决定何时开始。正文中的“不编辑文件”是流程要求,两者都不能替代工具权限策略。

字段设置用户能否输入 /nameClaude 能否按相关性调用适合什么
两个字段都用默认值能能可直接调用,也可按需加载的通用方法
disable-model-invocation: true能不能由人控制启动时机的流程
user-invocable: false不能能供模型加载的背景知识

user-invocable: false 不只是从菜单隐藏,直接输入 /name 也不会运行。disable-model-invocation: true 则同时避免把描述加入模型用于自动选择的技能列表。配置前先决定要限制哪一方,别把两个开关都设上却仍期待正常调用。调用控制说明

另一个容易误用的字段是 allowed-tools。例如 allowed-tools: Read Grep 预先批准列出的工具,不会把其他工具从可用列表移除。未列出的工具仍受正常权限设置约束;不能因此宣称整个技能已被强制限制为只读。若要移除工具,应理解 disallowed-tools;需要长期禁止某类工具,则使用权限设置中的 deny 规则。技能工具预授权

这些临时控制还有明确期限:技能正文在调用后会留在对话中,跨后续轮次保留;allowed-tools 的授权及 disallowed-tools 的工具移除会在下一条用户消息时清除。内容仍在,不代表授权也仍在。组织启用 allowManagedPermissionRulesOnly 时,受影响来源的 allowed-tools 还会被忽略,适用行为要求 v2.1.282 或更高版本,不应通过改配置绕开组织规则。内容生命周期、托管权限规则

Hook 的触发由事件决定,判断方式有五种

Hook 由事件、可选匹配条件和处理器组成。例如 PreToolUse 表示工具调用之前,Write|Edit 匹配工具名,command 指定执行脚本。配置生效且事件匹配时,运行时启动处理器,无需模型先决定“我要不要加载这个 skill”。

当前官方文档列出了五种处理器,支持的事件组合仍需查对应事件说明:

type如何执行适合的工作需要考虑什么
command执行 shell 命令,事件 JSON 通过标准输入传入路径检查、固定规则、格式化脚本依赖、退出码、超时与副作用
http将事件 JSON POST 到 URL由已有服务处理校验或记录数据去向、服务可用性、响应协议
mcp_tool调用已配置 MCP 服务器的工具使用现有集成执行事件动作服务器与工具权限、事件支持范围
prompt单轮模型评估根据事件输入作有限判断模型误判、token 成本与等待时间
agent多轮验证,可使用工具需要读文件或执行检查的验证实验性功能、成本、时限及执行范围

因此,事件触发确定,不等于判断结果确定。一个纯脚本可以按明确条件稳定返回结果;prompt 和 agent hook 仍包含模型判断。官方支持它们,不能笼统说“hooks 不允许主观判断”,也不能把自动触发解释成质量保证。Hook 工作方式、Prompt hooks

例如 Stop hook 判断任务未完成时,可以阻止停止、让 Claude 继续工作。但如果成功条件永远无法满足,就可能反复检查和继续执行。使用判断型 hook 前,应定义可检查的条件、超时和无法完成时的处理方式;需要你决定什么时候开始的复杂审查,仍可保留为手动 skill。

配置一个仅保护 .env 写入的 hook

下面的例子只检查 Claude Code 的 Write 和 Edit 工具,阻止写入文件名为 .env 或以 .env. 开头的文件,包含 .env.example。它不会读取文件内容,也不会发送网络请求。需要 macOS 或 Linux、可用的 Python 3,以及一个专门用于试验的项目。

将下面脚本保存为项目根目录下的 scripts/guard-env.py。它通过 Python 标准库读取输入,不需要安装第三方包,也不需要可执行权限,因为配置会显式调用 python3。

python
import json
import sys
from pathlib import PurePosixPath


def block(reason):
    print(reason, file=sys.stderr)
    return 2


def main():
    try:
        event = json.load(sys.stdin)
    except (json.JSONDecodeError, UnicodeDecodeError):
        return block("无法解析 hook 输入;请检查事件 JSON。")

    if not isinstance(event, dict):
        return block("hook 输入必须是 JSON 对象。")
    if event.get("hook_event_name") != "PreToolUse":
        return 0
    if event.get("tool_name") not in ("Write", "Edit"):
        return 0

    tool_input = event.get("tool_input")
    if not isinstance(tool_input, dict):
        return block("Write/Edit 输入缺少 tool_input 对象。")
    file_path = tool_input.get("file_path")
    if not isinstance(file_path, str) or not file_path:
        return block("Write/Edit 输入缺少有效的 file_path。")

    name = PurePosixPath(file_path.replace("\\", "/")).name
    if name == ".env" or name.startswith(".env."):
        return block("已阻止 Write/Edit 修改环境文件,请由维护者处理。")
    return 0


if __name__ == "__main__":
    sys.exit(main())

再把下面 hooks 配置合并进该测试项目的 .claude/settings.json。如果已有其他设置或 hook,要合并对应字段和数组,不要用这份对象覆盖整个文件。CLAUDE_PROJECT_DIR 由 Claude Code 提供;路径加引号可处理项目名中的空格。

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "python3 \"$CLAUDE_PROJECT_DIR/scripts/guard-env.py\"",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

个人配置 ~/.claude/settings.json 会影响多个项目,项目配置 .claude/settings.json 用于共享,本地项目配置 .claude/settings.local.json 用于个人设置。先选择范围再配置;/hooks 可查看已注册的事件与处理器,直接编辑配置后文件监听器通常会自动加载,未检测到变化时再重启会话。配置位置

先离线检查,再确认实际触发

在脚本所在项目根目录执行下面的输入模拟,不会创建或修改 .env:

bash
printf '%s\n' '{"hook_event_name":"PreToolUse","tool_name":"Write","tool_input":{"file_path":"/tmp/hook-demo/.env","content":"demo"}}' | python3 scripts/guard-env.py
printf '退出码:%s\n' "$?"

预期标准错误显示阻止原因,退出码为 2。再把路径换成 /tmp/hook-demo/notes.txt 重试,预期没有输出,退出码为 0。本次离线检查还覆盖了 Windows 风格的 .env.local 路径、非目标工具、错误事件、缺失路径和无效 JSON;结果符合脚本定义。它只证明解析和分支行为,不证明 Claude Code 已发现配置或真正触发了事件。

实际接入时,在测试项目的 /hooks 中确认 PreToolUse、Write|Edit 和脚本命令都已注册,再用无敏感内容的测试路径让 Claude 尝试 Write 或 Edit。成功判据是环境文件写入在发生前被阻止,并显示原因;普通文件进入正常权限流程。用 Bash 写文件不会触发这里的 Write|Edit 匹配,不能用那个结果判断此示例失效。

这个例子是窄规则,不是完整文件安全边界。它不覆盖 Bash、PowerShell、其他工具或文件名别名,也不能保证其他处理器没有副作用。需要更广的访问约束时,结合工具权限和操作系统隔离处理,别把一个文件名检查扩称为防泄露系统。PreToolUse 输入和决策

退出码的含义随事件变化

脚本使用一套简单协议:不输出 JSON,靠退出码和标准错误反馈。对这个 PreToolUse 例子,0 表示没有异议,不等于批准工具调用;2 会阻止这次工具调用,标准错误给出原因。

不能把这个规则直接套在所有事件上:

事件返回 2 会怎样
PreToolUse工具尚未执行,阻止工具调用
PostToolUse将标准错误反馈给 Claude;工具已经执行,无法撤销
Stop阻止停止,让对话继续
SessionStart向用户显示标准错误,会话仍继续

其他非零退出码通常是非阻断错误,但还要看结构化 JSON 是否有效,以及事件自身的例外。例如 WorktreeCreate 对任何非零退出码都按失败处理。需要 allow、ask 等结构化决策时,应改用对应事件的 JSON 输出协议,不要混用两套协议后凭退出码猜结果。退出码参考及事件表

组合时分清职责,也分清什么时候失效

变更审查和文件保护可以一起使用:你输入 /review-notes src/auth.ts 启动审查,skill 提供方法;项目级 hook 在任何匹配的写入前检查 .env 文件名。审查建议需要解释证据,路径规则只需返回通过或阻止,职责清楚就容易定位问题。

审查 Skill、写入前路径 Hook 与 Stop 模型判断的工作流示意

同一事件匹配的 hooks 会并行执行,所有处理器完成后再合并结果。一个 hook 拒绝动作,不会阻止另一个 hook 先完成日志记录或其他副作用;PreToolUse 权限决策按最严格结果合并。异步处理器完成时也不能追溯阻止已经执行的动作。多个 hooks 的结果合并

还有三个容易混淆的期限:

  • 技能正文:调用后进入对话,跨轮次保留;上下文压缩时仍受保留预算影响。
  • 技能工具授权或移除:allowed-tools 和 disallowed-tools 在下一条用户消息时清除。
  • 技能 frontmatter 中的 hooks:调用技能时注册,通常保留到会话结束,不会在该技能当前轮次结束时自动卸载。once: true 可在首次成功执行后移除;阻断、失败或超时不算成功。子代理自己的 hooks 则只在该子代理运行期间有效。

这些是不同机制,不能用“skill 已结束”推断其 hook 已经停止。上面的 .env 例子放在项目设置中,不属于技能临时授权。技能与子代理中的 hooks

维护时留下可读的说明:谁启动、检查什么、失败时怎么处理、允许什么副作用、什么时候删除。若一个斜杠入口只重复调用同一个 skill,通常没必要再维护一份提示词;若一个 hook 越来越像长篇审查方法,考虑把方法保留在 skill,hook 只负责需要自动发生的事件动作。

常见问题

自定义 slash commands 还要迁移吗?

不必全部迁移。官方明确旧 .claude/commands/*.md 继续工作,并已与 skills 合并。需要同目录支持文件或更完整的技能组织时,再用 .claude/skills/review-notes/SKILL.md;入口文件名必须准确。官方兼容说明

Skills 只能由 Claude 自动触发吗?

不是。默认既可由用户输入 /name,也可由 Claude 按需加载。disable-model-invocation: true 只保留用户调用;user-invocable: false 只保留模型调用,直接输入也不会运行。调用控制

allowed-tools: Read 能保证 skill 只读吗?

不能。它预先批准 Read,不移除其他工具。要区分技能正文中的行为要求、临时工具移除和长期权限 deny 规则,不能把预授权当作工具白名单。工具权限说明

Hooks 能保证每次判断都正确吗?

不能。事件匹配控制的是何时执行,模型型处理器仍可能误判,脚本也可能规则不完整。能明确检查的条件优先用简单脚本;需要模型判断时,为失败、超时和无法满足的条件设计处理方式。处理器类型

Hook 出错后,刚才的文件修改会撤销吗?

不会因为 PostToolUse 出错就自动撤销。要在工具执行前阻止,应使用支持该决策的 PreToolUse;工具已经运行时,后置 hook 只能按该事件的协议反馈或控制后续流程。事件与退出码

先把一个具体任务做通:可复用步骤成为 skill,启动时机由合适的调用入口控制,事件规则由 hook 执行。配置发现、脚本分支和实际触发分别检查,才知道问题出在入口、方法、权限还是事件上。

参考来源4

本文引用的外部页面,按正文出现顺序排列。最后更新于 2026年10月5日。

  1. 1.官方 Skills 文档code.claude.com/docs/en/skills
  2. 2.命令参考code.claude.com/docs/en/commands
  3. 3.Hook 工作方式code.claude.com/docs/en/hooks-guide
  4. 4.配置位置code.claude.com/docs/en/hooks
更多 Claude Code