《Claude Code 工程化实战》第 11 讲 任务型 Skills 实战 本讲摘要第 10 讲讲了 Skills 的自动发现机制description 匹配 → LLM 加载。本讲讲反向操作——怎么让 Skill “禁止模型自动调用”、只允许用户主动调类似 Command 的令行禁止。核心是disable-model-invocation: true这个 frontmatter 字段加了它、Skill 就退化成团队命令,LLM 看不到、不会自动加载、只有用户输入/skill-name才触发。本讲的三条主线第一、disable-model-invocation: true是什么?——Skills 的反向开关、让 Skill 退化成用户主动调的命令,LLM 看不到、占 0 token、不自动加载。第二、为什么需要禁止自动调用?——3 类应用场景团队 SOP / 危险操作 / 调试工具、共性是必须严格按步骤走、不能 LLM 自由发挥。第三、vs Command 的边界——两者效果几乎一样都是用户主动调区别在配置管理粒度——Skill 走.claude/skills/可打包、可分发,Command 走.claude/commands/团队统一用 Skill 更便于管理。学完本讲、你应该能用disable-model-invocation: true写出 4 个标准团队命令/review / /commit / /deploy / /sync-env)、能给 3 个危险操作/rollback / /db-migrate / /purge-cache配双保险(disable 字段 Hook 二次拦截、能判断什么场景用 disable-model-invocation Skill、什么场景用真 Command。 详细内容disable-model-invocation: true 是什么?第 10 讲我们说 Skills 的核心是自动发现——Claude 在推理时看 description 匹配用户的话、自动加载 SKILL.md。这对大多数能力是好事、但对某些场景是坏事。典型反例你的项目有个 Skill “deploy-prod”,description 写Deploy to production. Use when user says ‘deploy’ / ‘部署’.“——这本来挺好。但有天用户在主对话里随口说今天 deploy 顺利吗?”在讨论昨天的部署,Claude 看到 “deploy” 关键词就匹配、自动加载 deploy-prod 的 SKILL.md、开始问是否要部署?——结果是用户被打断、deploy 行为被误触发。更糟的是危险操作场景rollback回滚到上一版本/ db-migrate数据库迁移/ purge-cache清空缓存——这些能力绝对不能 LLM 自动触发、必须用户显式调起。这就是disable-model-invocation: true的设计初衷。加了disable-model-invocation: true的 Skill 会有 3 个变化LLM 看不到——Claude 在推理时不会看到这个 Skill 的 description、关键词匹配也不触发。占 0 token——frontmatter 也不加载、完全从 Claude 的可见能力列表中隐藏。用户主动调才触发——用户输入/deploy或/rollback,Claude Code 才把 SKILL.md 全文加载、严格按步骤执行。这就是令行禁止——LLM 没有自主判断何时调用的权力、只有用户显式命令才能执行。这种 Skill 退化成团队命令、行为完全可预测。为什么需要禁止自动调用?3 类应用场景disable-model-invocation: true不是对所有 Skill 都要加的银弹、只在 3 类场景下有意义场景 1团队 SOP必须严格按步骤走团队的 code review 流程是 5 步跑测试 → 静态分析 → 安全审计 → 文档同步 → 报告生成。每一步都有明确顺序、明确产出、明确负责人。这种流程不能让 LLM 自由发挥——LLM 可能省略某步或调换顺序或漏掉关键检查。配disable-model-invocation: true后、用户输入/review才触发、Claude 严格按 5 步走、每步产出固定格式。这就把团队 SOP固化成 Skill 模板、任何团队成员触发/review都是同样 5 步同样产出、标准化。场景 2危险操作LLM 误触 灾难部署到生产 / 回滚到上一版本 / 数据库迁移 / 清空缓存——这些操作一旦执行就不可逆或者说回滚成本巨大。如果 LLM 看到 “deploy” / “rollback” 关键词就自动加载、可能在用户随便说今天 deploy 顺利吗时、误触发开始部署流程。这类 Skill 必须配disable-model-invocation: true——LLM 看不到、不会误触、只有用户显式/deploy//rollback才执行。这是双保险的第一层第二层是 Hook 二次拦截、在第 6 讲配的 deny 列表基础上、再加特定命令的拦截。场景 3调试工具日常不该启用、只排查时用有些 Skill 是排查问题时才用的工具debug-mode开启详细日志/ verbose打印所有中间结果/ trace-network追踪网络请求。这些能力日常不该启用会污染日志 / 拖慢速度、只在排查时才需要。配disable-model-invocation: true让 Claude 永远不知道我还有 debug-mode 这个工具、用户排查时才主动/debug-mode启用。这避免了LLM 在普通对话里顺手开启了 debug 模式。3 类场景的共性“必须严格按步骤 / 绝不能 LLM 自由发挥 / 行为必须可预测”。判断标准这件事如果 LLM 误触了会出大问题吗?会的话、加disable-model-invocation: true。应用场景危险等级触发频率适合 disable 程度团队 SOP(review/commit)低不可逆性弱高每天多次可选看团队偏好危险操作deploy/rollback)高不可逆性低每周几次必须 disable调试工具debug/verbose)中影响日志/性能极低排查时用必须 disable团队 SOP 实战4 个标准命令4 个最常见的团队命令SOP 是/review审查流程/ /commit(commit 流程/ /deploy部署流程/ /sync-env环境同步。每个都有严格步骤、配disable-model-invocation: true后、触发方式变成用户主动调、严格按步骤。/review:5 步审查流程步骤 1跑测试必须全过、失败则停止。步骤 2静态分析ruff mypy。步骤 3安全审计skills/security-audit。步骤 4文档同步检查 src/ 改了但 docs/ 没改的情况。步骤 5报告生成Markdown 报告 commit 检查清单。每步的硬约束任何一步失败就停、不继续。报告格式固定、任何人触发 /review 都得到一样的产出。/commit:commit 流程步骤 1:git status 看未提交改动。步骤 2:git diff 看具体改了什么。步骤 3跑测试必须全过。步骤 4跑 pr-drafter skill 生成 commit message 草稿写到 .claude/drafts/commit-msg.txt。步骤 5用户确认 commit message不直接 git commit。步骤 6用户自己 git commit。硬约束Claude 永远不自己 git commit、只产草稿让人确认。/deploy部署流程步骤 1确认当前分支是 main 且最新。步骤 2确认所有测试在 CI 上通过。步骤 3确认 CHANGELOG.md 已更新用 sync-changelog skill。步骤 4:tag 当前版本从 package.json 读。步骤 5推送 tag触发 CI 部署流水线。步骤 6通知团队Slack 通知。硬约束每步都询问用户确认、不自动继续。/sync-env环境同步步骤 1本地环境 vs 远端环境对比dev/staging/prod。步骤 2列出差异配置 / 依赖 / 数据库 schema。步骤 3对每项差异给出是否需要同步的建议。步骤 4用户确认后逐项同步用第 6 讲的 permission 白名单、只允许白名单命令。4 个 SOP 的共同设计原则步骤数控制在 3-7 步太少 SOP 价值不大、太多用户记不住。每步有明确产出报告 / 文件 / 状态变更。硬约束必须执行“失败就停” / “不自动 git commit” / “每步问用户”。SKILL.md 控制在 100-200 行用户主动调时一次性加载、不能太长。危险操作实战必须令行禁止的能力危险操作 Skill 的双保险设计第一层是disable-model-invocation: true(LLM 看不到、不会误触第二层是 Hook 二次拦截即使有其他方式触发、HW 也会拦下。两层叠加、几乎不可能误执行。/rollback回滚到上一版本触发用户输入/rollback [commit-hash 或 version-tag]。流程确认当前部署版本 → 拉取目标版本 → 跑数据库迁移回滚如有 → 重新部署 → 健康检查 → 通知团队。双保险disable-model-invocation: true阻止 LLM 误触PreToolUse Hook 拦截git reset --hard/kubectl rollout undo等危险命令、即使有其他路径触发也拦下。/db-migrate数据库迁移触发用户输入/db-migrate [env],env dev / staging / prod。流程确认当前 schema 版本 → 跑alembic upgrade head生产前先 dry-run)→ 数据完整性检查 → 通知团队。双保险disable-model-invocation: true阻止误触Hook 拦截alembic downgrade意外回滚/DROP TABLE/TRUNCATE等命令。/purge-cache清空缓存触发用户输入/purge-cache [scope],scope redis / cdn / both。流程确认当前缓存命中率 → 软清渐进过期→ 硬清强制删除→ 健康检查 → 监控告警阈值。双保险disable-model-invocation: true阻止误触Hook 拦截redis-cli FLUSHALL/curl -X DELETE ...cdn...等命令。3 个危险操作 Skill 的共同特征都有不可逆或回滚成本巨大的属性。都有显式参数([env] / [scope] / [version])、防止误用。都有健康检查 监控告警兜底、出问题能第一时间发现。都配双保险LLM 看不到 Hook 拦命令、即使 LLM 误触、Hook 也会拦截。vs Command 的边界什么时候用 disable-model-invocation Skill、什么时候用真 Command新人的常见困惑“disable-model-invocation: true的 Skill 效果和 Command 不是一样吗?都用户主动调、都 LLM 看不到、都不自动加载——那为什么不全用 Command?”答案是配置管理粒度的区别用 disable-model-invocation Skill 的场景需要渐进式披露——SKILL.md 里有快速参考 / 详细步骤 / 边界 case 多层内容、需要时整体加载、不要时零成本。Skill 走.claude/skills/name/SKILL.md目录结构、可以放 references/ 子目录做深层引用。需要打包分发——Skill 是工程资产、可以做成 NPM 包或 GitHub repo 跨项目复用。Command 在这一点上更扁平、没有目录结构、跨项目复用需要复制整个文件。需要和普通 Skill 一起管理——项目里同时有自动发现的 Skill 禁止自动调用的 Skill、两者放.claude/skills/统一管理、组织清晰。Command 走单独.claude/commands/、分散。用真 Command 的场景极简命令——就一个固定动作比如 /clear 清屏、/help 看帮助、/init 初始化项目。这种 1-2 行的命令用 Command 更轻。需要参数解析——Command 支持$ARGUMENTS变量、Skill 没有这个机制。如果命令需要解析复杂参数比如 /deploy --envprod --version1.2.3)、用 Command 更合适。团队对 Skills vs Commands 有强约定——如果团队历史上都是用 Command、新加的禁止自动调用能力也用 Command 保持一致。实操建议能 Skill 就 Skill、只在 Skill 表达不了参数解析时才用 Command。两者并存不冲突、可以.claude/skills/放 80% 的能力、.claude/commands/放 20% 的极简命令。维度普通 Skilldisable-model-invocation SkillCommandLLM 是否可见是description 全量可见否占 0 token)否走 commands 目录触发方式LLM 自动 用户 /仅用户 /仅用户 /加载时机description 匹配时用户输入命令时用户输入命令时目录结构.claude/skills//SKILL.md.claude/skills//SKILL.md.claude/commands/.md渐进式披露支持可放 references/)支持可放 references/)不支持单文件参数解析不支持不支持支持$ARGUMENTS)Skills 的渐进披露在命令场景的特殊处理disable-model-invocation: true的 Skill 加载成本进一步降低——LLM 完全看不到连 frontmatter 都不加载、占 0 token。但用户主动调/name时、SKILL.md 全文一次性加载、所以仍然要控制 SKILL.md 长度。控制策略SKILL.md 控制在 100-200 行用户主动调时一次性加载、不能太长。详细文档放 references/ 子目录、SKILL.md 用详见 references/xxx.md引用。命令的核心步骤放 SKILL.md 主体、边界 case 反例放 references。这一条和普通 Skill 一致、只是加载时机不同——普通 Skill 是 description 匹配时加载、disable-model-invocation Skill 是用户输入/name时加载。特殊优化disable-model-invocation Skill 可以写得重一些用户主动调时加载、内容详尽是好事、不像普通 Skill 必须轻以减少自动加载的 token 成本。但仍要控制总长度200-300 行内、用户主动调也不希望等太久。️ 实战代码 第 11 讲配套4 个标准团队命令 SKILL.md完整模板--- # .claude/skills/review/SKILL.md name: review description: NOT-USED-BY-MODEL (禁止 LLM 自动调用,只在 /review 时触发) disable-model-invocation: true allowed-tools: Bash, Read, Grep, Edit --- # /review:团队 5 步审查流程 ## 流程 1. 跑测试(必须全过,失败则停止报告) 2. 静态分析(ruff check mypy src) 3. 安全审计(调 security-auditor skill) 4. 文档同步(检查 src/ 改了但 docs/ 没改) 5. 报告生成(写到 .claude/reports/review-date.md) ## 硬约束 - 任一步失败 → 停止,不继续 - 不跳过任何步骤 - 报告格式严格按模板 ## 报告模板 markdown # Review: branch - Test: PASS/FAIL - Lint: PASS/FAIL - Security: PASS/FAIL (Critical: N, Warning: N) - Docs: SYNC/OUT-OF-SYNC - Verdict: APPROVE / REQUEST_CHANGES# .claude/skills/commit/SKILL.md name: commit description: NOT-USED-BY-MODEL disable-model-invocation: true allowed-tools: Bash, Read, Grep --- # /commit:commit 流程 ## 流程 1. git status(看未提交) 2. git diff(看具体改动) 3. 跑测试(必须全过,否则终止) 4. 调 pr-drafter skill 生成 commit message 草稿(写 .claude/drafts/commit-msg.txt) 5. 展示草稿给用户,**不直接 git commit** 6. 用户确认后,用户自己 git commit -F .claude/drafts/commit-msg.txt ## 硬约束 - Claude 永远不自己 git commit - 测试不过 → 终止,不允许 commit - commit message 必须符合 Conventional Commits# .claude/skills/deploy/SKILL.md name: deploy description: NOT-USED-BY-MODEL disable-model-invocation: true allowed-tools: Bash, Read, Grep --- # /deploy:部署流程(只能手动触发) ## 前置检查(必须全通过) - [ ] 当前分支是 main - [ ] CI 全部通过(查 GitHub Actions) - [ ] CHANGELOG.md 已更新 - [ ] 当前版本号 上一版本号 ## 流程 1. 读 package.json / pyproject.toml 拿当前版本号 2. git tag version(本地打 tag) 3. git push origin version(推送 tag,触发 CI 部署) 4. 监控部署状态(kubectl get pods -n prod 或类似命令) 5. 通知团队(Slack webhook / 邮件) ## 硬约束 - 每步询问用户确认,不自动继续 - 任何前置检查失败 → 终止 - 部署失败 → 立即通知 暂停后续操作# .claude/skills/sync-env/SKILL.md name: sync-env description: NOT-USED-BY-MODEL disable-model-invocation: true allowed-tools: Bash, Read, Grep --- # /sync-env:环境同步流程 ## 流程 1. 对比本地 vs 远端环境(dev / staging / prod) 2. 列出差异(配置 .env / 依赖 requirements.txt / DB schema) 3. 对每项差异给出是否需要同步的建议 4. 用户确认后,逐项同步(用第 6 讲的 permission 白名单) ## 硬约束 - 不自动同步,每项询问用户 - prod 环境的同步必须二次确认 通知团队 - 同步后必须跑一次健康检查 第 11 讲配套disable-model-invocation 字段 3 种取值的对比# 取值 1:disable-model-invocation: true --- name: deploy description: Deploy to production disable-model-invocation: true # ✅ LLM 完全看不到,只有用户 /deploy 触发 --- # 取值 2:disable-model-invocation: false --- name: sync-changelog description: Update CHANGELOG.md from git commits. Use when user says 更新 changelog. disable-model-invocation: false # ✅ 显式 false(等同于不写),LLM 自动发现 --- # 取值 3:缺省(不写) --- name: sync-changelog description: Update CHANGELOG.md from git commits. Use when user says 更新 changelog. # 不写 disable-model-invocation 字段 默认 false LLM 自动发现 --- # 行为对比: # true → LLM 看不到,占 0 token,用户 /name 才触发 # false → LLM 自动发现,description 匹配时加载 # 缺省 → 同 false 第 11 讲配套危险操作 Skill 的双保险配置配 disable Hook 二次拦截# .claude/skills/rollback/SKILL.md name: rollback description: NOT-USED-BY-MODEL disable-model-invocation: true # 第一层保险:LLM 看不到 allowed-tools: Bash, Read --- # /rollback:回滚到上一版本 ## 流程 1. 确认当前部署版本(kubectl get deployment -n prod) 2. 拉取目标版本(用户指定的 commit/tag) 3. 跑数据库迁移回滚(如有 alembic 迁移) 4. 重新部署(kubectl rollout undo 或 helm rollback) 5. 健康检查(curl /health 看监控) 6. 通知团队 ## 硬约束 - 每次只回滚一个版本,不批量 - 失败立即停止 通知# .claude/hooks/deny-extra-dangerous.sh # 第二层保险:HW 拦截危险命令(即使 SKILL disable 失效,HW 也兜底) #!/usr/bin/env bash COMMAND$1 # 拦截 git reset --hard(回滚工作区) if echo $COMMAND | grep -qE git\sreset\s--hard; then echo ❌ 拒绝:git reset --hard 被禁止(用 /rollback skill) exit 2 fi # 拦截 alembic downgrade(数据库回滚) if echo $COMMAND | grep -qE alembic\sdowngrade; then echo ❌ 拒绝:alembic downgrade 被禁止(用 /db-migrate rollback) exit 2 fi # 拦截 redis-cli FLUSHALL(清空缓存) if echo $COMMAND | grep -qE redis-cli\sFLUSHALL; then echo ❌ 拒绝:redis FLUSHALL 被禁止(用 /purge-cache skill) exit 2 fi # 拦截 kubectl rollout undo(默认走 /rollback) if echo $COMMAND | grep -qE kubectl\srollout\sundo; then echo ❌ 拒绝:kubectl rollout undo 被禁止(用 /rollback skill) exit 2 fi exit 0// .claude/settings.json // 把双保险 HW 配到 PreToolUse 钩子里 { hooks: { PreToolUse: [ { matcher: Bash, hooks: [ {type: command, command: bash .claude/hooks/deny-extra-dangerous.sh}, {type: command, command: bash .claude/hooks/deny-pipe-exec.sh} ] } ] } } 第 11 讲配套团队命令集的 .claude/skills/ 目录组织按团队 / 按阶段 / 按风险等级# 方式 1:按团队角色组织 .claude/skills/ ├── dev/ # 开发阶段命令 │ ├── review/SKILL.md # /review │ ├── commit/SKILL.md # /commit │ └── pr/SKILL.md # /pr(开 PR) ├── ci/ # CI 阶段命令 │ ├── test/SKILL.md # /test │ ├── lint/SKILL.md # /lint │ └── coverage/SKILL.md # /coverage └── release/ # 发布阶段命令 ├── deploy/SKILL.md # /deploy ├── rollback/SKILL.md # /rollback └── tag/SKILL.md # /tag # 方式 2:按风险等级组织 .claude/skills/ ├── safe/ # 低风险(可让 LLM 自动发现或主动调) │ ├── review/SKILL.md │ ├── commit/SKILL.md │ └── test/SKILL.md ├── medium/ # 中风险(可 LLM 自动发现,执行前 ask) │ ├── sync-env/SKILL.md │ └── sync-deps/SKILL.md └── dangerous/ # 高风险(必须 disable-model-invocation Hook) ├── deploy/SKILL.md # /deploy ├── rollback/SKILL.md # /rollback ├── db-migrate/SKILL.md # /db-migrate └── purge-cache/SKILL.md # /purge-cache # 方式 3:按功能模块组织(适合多技术栈) .claude/skills/ ├── backend/ │ ├── db-migrate/SKILL.md │ └── api-test/SKILL.md ├── frontend/ │ ├── build/SKILL.md │ └── e2e-test/SKILL.md └── infra/ ├── deploy/SKILL.md └── rollback/SKILL.md⚠️ 常见坑⚠️ 把日常高频的操作也加 disable-model-invocation用户每次都得手输命令、反而累常见的过度防御把所有 Skill 都加disable-model-invocation: true,“安全是安全了、但用户每次都得输 /test / /commit / /lint、反而累。disable 字段是为危险 低频场景设计的危险操作必须 disable(LLM 误触 灾难高频操作别 disable(LLM 自动调用 节省用户输入。判断标准这件事 LLM 自动触发会出大问题吗?会的话、disable不会的话、别 disable。⚠️ 危险操作 Skill 只加了 disable 字段、没配 Hook 二次拦截单层防御不够危险的假安全误判给 deploy / rollback / db-migrate 加了disable-model-invocation: true、以为就安全了。但 disable 字段是LLM 推理层的防御——如果有人绕开 LLM 推理、直接调起 Skill比如 CLI 直接传参数 / CI 流水线自动调 / 别的 Skill 嵌套调,disable 就失效了。必须加第二层 HW 防御——PreToolUse Hook 拦截危险命令即使 SKILL disable 失效、HW 兜底。双保险叠加、几乎不可能误执行。判断标准你的危险操作 Skill 配了 HW 兜底吗?没配、补上。⚠️ 团队命令没版本管理不同人用的步骤不一致团队 /review 流程应该是 5 步、但每个人的 SKILL.md 文件可能略有不同——A 同事加了一步通知 reviewer”,B 同事加了跑 linter,C 同事漏了安全审计。结果团队里 /review 行为不一致、review 质量参差。修正团队命令进 git 配 PR review 用 semver 打 tag——任何修改必须 PR 评审、谁也不能私自改。判断标准你的团队命令 SKILL.md 是个人还是团队资产?如果是个人、赶紧入 git 配 PR review。⚠️ SKILL.md 正文 1000 行用户主动调时一次性加载、token 爆炸渐进式披露失效的反面以为 disable-model-invocation Skill 是用户主动调、可以写得详细点、塞 1000 行进去。结果用户输入 /deploy 触发、1000 行一次性加载到上下文、token 爆炸。修正即使 disable Skill,SKILL.md 仍控制在 200 行内、详细文档放 references/。判断标准SKILL.md 300 行就该拆。 一句话备忘disable-model-invocation: true是 Skills 的反向开关——把自动发现退化成用户主动调、让 SOP / 危险操作 / 调试工具 3 类场景从LLM 自由发挥变成令行禁止、再加 Hook 兜底就形成了双保险。