本文摘要:技能路径正确却从不触发,命中不稳定让排查反复落空。
description写成功能清单不匹配意图,三步测试可定位失准环节。边界是单技能调优,需 100% 确定触发时应改用显式调用。
一、问题与结论
你在~/.claude/skills/db-optimizer/SKILL.md写了一份自认详尽的技能,frontmatter 三件套齐全,放进去后会话里却始终等不到它。换成另一句问法偶尔闪现一次,下次又哑了——这是触发不稳定,不是没写。
结论先行:命中由三个触发条件共同决定,name的区分度、description的语义方向、keywords的场景覆盖面。多数不触发属于第二项:描述写成了"我能做什么",而模型在匹配"你遇到了什么问题"。
当前目录结构(项目级为例):
your-repo/ ├── .claude/ │ └── skills/ │ ├── db-optimizer/ │ │ └── SKILL.md │ └── pg-index-debugger/ │ └── SKILL.md └── CLAUDE.md用户级技能在~/.claude/skills/<name>/SKILL.md。SKILL.md的 frontmatter 会随 Claude Code 版本变化,是否支持显式keywords列表以当前安装版本文档为准;本文字段按社区通用实践整理,示例输出均标注验证状态。
二、排查与选择依据
结论:三步测试能把"不触发"归因到具体一环,不要一上来改文件。
Step 1:确认技能已加载。
ls.claude/skills/*/SKILL.md预期输出:
.claude/skills/db-optimizer/SKILL.md .claude/skills/pg-index-debugger/SKILL.md文件不在列表 → 查路径与目录名一致性;在列表 → 进 Step 2。会话内再用/help或当前版本的技能列表命令确认技能名出现(命令与输出以实际版本为准,本文未验证)。
Step 2:复制description原句直接发给会话。
原句能触发而自己的话不触发 → 文本有效但覆盖面不足,进 Step 3;原句也不触发 →name或description本身有问题,回到第三节修复。
Step 3:用你平时会自然敲出的说法测试。
| 测试输入类型 | 触发结果 | 归因与修复 |
|---|---|---|
description原句 | 触发 | 覆盖面不足,补口语化场景句 |
| 自然口语 | 不触发 | description缺场景描述 |
| 自然口语 | 触发了别的技能 | name区分度不够,提高特异性 |
替代方案与取舍
| 方案 | 选择条件 | 代价 | 边界 |
|---|---|---|---|
显式调用/pg-index-debugger | 需要 100% 确定触发 | 打断自然语言流,每次手动敲 | 不适合探索式排查 |
| CLAUDE.md 常驻指令 | 规则无条件生效 | 占用上下文,所有对话都加载 | 不适合条件触发型技能 |
| Hook(settings.json) | 格式化、lint 等确定性动作 | 无法处理语义条件 | 不适合需要推理的诊断 |
当技能正文极短、按上述方法调完仍不命中、或团队要求行为完全可复现时,不该继续在description上耗时间,直接改用显式调用。
三、关键原理
Claude Code 是通过自然语言命令与代码库交互的终端工具,技能没有传统"函数调用"入口,命中是语义匹配的概率结果。三个字段对命中率的影响分工如下:
| 字段 | 对命中的作用 | 常见失误 |
|---|---|---|
name | 技能标识,候选池内区分度 | db-optimizer、code-linter这类泛化名 |
description | 权重最高,快速筛选的主文本 | 写成 analyze / recommend 功能清单 |
keywords | 覆盖同义词与口语表述 | 只有领域词,没有问题场景句 |
功能清单描述与用户意图的语义方向相反:前者陈述能力,后者陈述故障。把"我能做什么"改写成"你会遇到什么问题",是提高命中率成本最低的一步;name与keywords更多起辅助确认作用。
四、可运行示例
环境:Claude Code(当前安装版本),项目根目录已有.claude/skills/。目标是"索引问题"稳定命中。
文件.claude/skills/pg-index-debugger/SKILL.md:
--- name: pg-index-debugger description: > 当开发者遇到 PostgreSQL 索引不生效、全表扫描、EXPLAIN ANALYZE 显示 Seq Scan 而非 Index Scan、建了索引查询反而更慢、 pg_stat_user_indexes 中 idx_scan 为 0 等问题时使用。 诊断统计信息误判、列顺序不匹配、隐式类型转换、索引膨胀。 keywords: - 索引失效 - Index Scan vs Seq Scan - EXPLAIN ANALYZE 索引 - query slow after index --- # PostgreSQL 索引诊断 1. `EXPLAIN ANALYZE` 确认是否出现 Seq Scan 2. `pg_stat_user_indexes` 查 idx_scan 是否为 0 3. 核对 WHERE 列顺序与索引定义 4. 检查统计信息是否过时、是否存在隐式类型转换 输出:诊断结论一句话 + EXPLAIN 片段 + 修复命令。操作步骤:保存文件 → 开新会话 → 输入 Step 3 的自然口语:
12 万行的表加了复合索引还是走 Seq Scan,EXPLAIN ANALYZE 里 cost=0.00..18500预期输出:技能被加载,回答先给出 Seq Scan 归因,再附EXPLAIN ANALYZE片段与ANALYZE/ 重建索引命令。
实际输出:未验证——本文未在本机执行 Claude Code 会话,以上为按字段设计推理的预期行为。验证方法:开新会话连续三次输入同一句话,观察技能是否每次都在响应链路中出现。
常见失败及修复:沿用name: db-optimizer的旧文件时,Step 2 原句能触发、Step 3 口语不触发。原因是description写成 “PostgreSQL and MySQL query performance optimization tool” 这类能力陈述,keywords只有database optimization领域词。修复:name收窄为pg-index-debugger,描述首句改为问题场景句。
五、验证结果与边界
代价有三。其一,技能按需加载只在命中后才读正文,但技能列表元数据常驻上下文,description越长、技能堆到几十个,列表本身就越推高 token。其二,场景句堆叠过多会与同领域技能互相抢命中,覆盖面和精确度是直接冲突的。其三,模型升级后语义理解变化,同一份文件的命中行为可能变好也可能变差,需重跑三步测试。
不适用的边界:路径与加载顺序问题不在本方法范围内,项目级与用户级技能在部分版本中合并优先级不同,先确认加载;需要外部工具集成走 MCP Server;确定性动作走 Hook。以上示例输出与命中行为均未在本机验证,字段以当前版本官方文档为准。
参考资料
- anthropics/claude-code
- affaan-m/ECC
- farion1231/cc-switch