一句话摘要
标题主题:构建真正好用的 Claude Code 技能
如何构建一个真正好用的 Claude Code Skill(完整指南)2026年7月18日 · 9分钟阅读 · 查看来源 ↗ Claude 自动化 AI
你用了一周 Claude,发现自己总是在重复输入同样的东西。每次提交代码,你都会粘贴同样三条关于提交格式的规则。每次写文档,你都要重新解释一遍你的风格。Claude 做得很好,但聊天一结束就全忘了,第二天你又得重新敲一遍。
一个 skill 能解决这个问题。它是一个你写一次的小文件夹,可以永久地教会 Claude 一个工作流,这样它每个会话都会自动应用,而不需要你开口。
简单说一下它的原理:一个 skill 就是一个文件夹,里面只有一个文件。Claude 始终把它的单行摘要放在视野里,只有当你的请求匹配时,才会加载完整指令。这就是全部机制。
在这份指南里,我们会从零构建一个真实的 skill:commit-messages,它用你指定的格式来写 git 提交信息。只要你装了 Claude,没有别的依赖,也能跟着每一步做下来。
你最终会得到什么
一个 skill 的核心就是一个文件夹,里面有一个必需的文件 SKILL.md。随着 skill 成长,后面还会出现三个可选文件夹:
your-skill-name/
├── SKILL.md # 必需 - skill 主文件
├── scripts/ # 可选 - 可执行代码
├── references/ # 可选 - 文档
└── assets/ # 可选 - 模板等
SKILL.md 本身分两部分:一段简短的头部,告诉 Claude 何时使用这个 skill;以及头部下方的指令,告诉 Claude 具体做什么。这样拆分是有原因的。Claude 会不断读取头部,所以它始终知道这个 skill 存在,但只有当你的请求匹配时,它才会加载指令。牢记这个区分,因为这份指南里几乎所有其他内容都由此而来。
创建它
skill 存放在主目录下一个叫 .claude/skills 的文件夹里,Claude Code 和桌面应用都会从这里读取。它是隐藏目录,可能还不存在,所以最快的办法是用一条命令同时创建它和你的 skill 文件夹。
在 Mac 上,打开终端运行:
mkdir -p ~/.claude/skills/your-skill-name
在 Windows 上,打开 PowerShell 运行:
New-Item -ItemType Directory -Force -Path "$HOME\.claude\skills\your-skill-name"
文件夹名不是装饰。Claude 把它用作 skill 的标识符,而有一条格式规则最容易让人踩坑:
使用 kebab-case:notion-project-setup ✔
不要有空格:Notion Project Setup ✖
不要有下划线:notion_project_setup ✖
不要有大写:NotionProjectSetup ✖
在这个文件夹里,创建一个恰好命名为 SKILL.md 的文件,用任意文本编辑器打开。接下来的一切都是放进这个文件的内容。
动笔之前先设计
真正好用的 skill,从两个决定开始,都发生在你写下文件第一行之前。两者看起来都可以跳过,但哪一个都不能跳过。
第一,明确这个 skill 应该在什么时候触发。用用户真正会打的字,写下两三个真实场景:
"commit these changes"(提交这些改动)
"write a commit message for this diff"(为这个 diff 写一条提交信息)
"stage and commit"(暂存并提交)
这不是无用功。这些短语会成为你后续写 description 和做测试的原材料,而没有按这种方式设计出来的 skill,往往恰恰模糊到永远无法触发。
第二,明确你如何判断它是否有效。最重要的一条标准是:这个 skill 能不能自行加载,而不需要你点名它。如果每次都要手动调用,那 skill 在技术上虽然运行了,但已经在自己真正的任务上失败了。还要一并观察的是:它能否在你不中途纠正的情况下完成任务,以及在不同会话之间是否给你同样形态的结果。
description 决定成败
在这个文件的全部内容里,头部的 description 干活最多,因为它是 Claude 决定是否加载这个 skill 时唯一读到的部分。你的指令可以写得天衣无缝也无济于事,因为如果 description 不匹配,Claude 根本读不到它们。这就是大多数"不好用"的 skill 真正失败的地方。
一个强 description 用一句话回答两个问题:这个 skill 做什么,以及 Claude 应该在什么时候去用它。后半句正是人们漏掉的部分。
差别如下:
# 弱 - 只说了它是什么,没给 Claude 任何可以匹配请求的东西
description: Helps with git commits.
# 强 - 点明了它应该触发的时刻
description: Writes git commit messages in Conventional Commits format. Use when the user asks to commit changes, write a commit message, or stage and commit files.
弱版本告诉 Claude 这个 skill 存在,却从不把它和你说的任何话连接起来。强版本点明了真实短语,所以当你打出 "commit these changes" 时,Claude 才有东西可以匹配。写出用户真正会用到的词,整体控制在 1024 个字符以内,别在里面放 < 或 >。
当一个 skill 不触发时,修复点几乎总在这里。加上你实际会用的措辞。如果你说 "save my work",而 description 只提到 "commit",Claude 就没法把两者联系起来。反过来,如果 skill 在不该触发时触发了,就收窄 description,或者加一个否定触发器:
description: Writes git commit messages in Conventional Commits format. Use when committing changes. Do not use for writing code comments or documentation.
在依赖它之前,有个快速自查的办法。直接问 Claude:
> "When would you use the commit-messages skill?"
Claude 会用自己的话把你的 description 读回来。如果这和你真正希望 skill 触发的时机对不上,你就找到了问题所在——而且问题出在 description,而不是下面的指令。
写出 Claude 真正会遵循的指令
头部下方是正文,用普通 Markdown 编写。这里承载你真正的工作流,有两个习惯能把"Claude 会遵循的指令"和"它悄悄偏离的指令"区分开。
第一是具体。Claude 对具体指令会照做,对模糊指令会一带而过,所以你写得越精确,它表现得越可靠:
# 差
Validate the commit before finalizing.
# 好
Run `python scripts/validate.py "<message>"`.
If it fails, fix these:
- Invalid type: use feat, fix, docs, refactor, test, chore
- Summary over 60 chars: shorten it
第二是顺序。Claude 对先读到的东西权重更高,所以埋在长文件底部的一条规则,就是一条会被漏掉的规则。把任何不能被打破的规则放在最上面,用一个能表明这点的标题:
## Important
- Summary line under 60 characters, always
- Present tense only: "add", not "added"
语言能保证的东西也有限度。指令是被解释执行的,也就是说 Claude 会做得很好,但不会每次都一模一样。当某个检查真的必须每次运行都通过时,别用散文描述它,把它移进一个脚本里,让指令去运行这个脚本。代码每次做同样的事,句子做不到。(这正是 scripts/ 文件夹的用途,接下来讲。)
一个能在大多数 skill 上站得住的结构长这样:
# Skill Name
## Important
绝不能漏掉的关键规则。
## Instructions
一步步来,具体且可操作。
## Examples
具体的输入和输出。Claude 模仿示例比遵循规则更可靠。
保持文件精简。一旦它开始超出核心指令而膨胀,就到了把额外细节移出去的时候,这正是什么要引入那些可选文件夹的原因。
Scripts、references、assets
到目前为止,一切都只是给 Claude 指令的 skill。三个可选文件夹把它变成给 Claude 工具的 skill,而正是在这里,skill 做到了普通提示词做不到的事。
scripts/ 存放 Claude 运行的代码,用于任何必须精确的东西。与其信任 Claude 去用眼睛判断一个提交格式对不对,不如交给它一个会检查的脚本:
# scripts/validate.py
import sys
msg = sys.argv[1]
types = ("feat", "fix", "docs", "refactor", "test", "chore")
if msg.split(":")[0] not in types:
print(f"Invalid type. Use: {', '.join(types)}")
elif len(msg.split("\n")[0]) > 60:
print("Summary too long (over 60 chars)")
else:
print("OK")
然后在 SKILL.md 里告诉 Claude 去用它:
Before finalizing, run `python scripts/validate.py "<message>"`
and fix anything it flags.
现在格式规则由每次都跑得一模一样的代码来强制执行,而不是依赖 Claude 记得去检查。
references/ 存放只在需要时才加载的文档。假设你的提交规范有两页的 scope、footer 和边界情况。把所有这些塞进 SKILL.md,它就会在每一次提交时都加载,哪怕只是一行提交。改成把它移进一个引用文件:
your-skill-name/
├── SKILL.md
└── references/
└── conventions.md
然后从主文件里指向它:
For the full convention list, see references/conventions.md
Claude 只在任务需要时才打开那个文件。这正是 skill 运行成本低的全部原因:繁重的细节静静躺在磁盘上,直到真正相关时才加载,而不是每次都跟着上下文走。
assets/ 存放 skill 在输出中用到的文件,而不是拿来读作指导的文件,比如模板、配置文件或 logo。一个 commit skill 不需要这些,但一个生成报告的 skill 可以在这里放一份 template.md,每次填进去,这样每份报告都保持同样的结构。
综合起来,这三个文件夹的区别就在于:一个 skill 是"告诉 Claude 你如何工作",还是"把让你以你的方式干活的精确工具交给 Claude"。
需要记住的一件事
一个 skill 并不是在教 Claude 一种新能力。它本来就知道怎么写 commit。skill 做的是让它每次都按你的方式来干,而不需要你再拼写一遍。
而当 skill 不好用时,原因几乎从来不是你煞费苦心写的那些指令,而是 description。Claude 在读到下面任何工作之前,就靠那一行来决定要不要加载这个 skill。把 description 写对,下面的一切终于才会被用上。
如果这对你有用,去我的主页关注我。我写技术、AI 和真正能跑起来的系统。
Ciao,
@undefinedKi
标签:# X # Claude # Automation # AI # Guide
相关文章 10 SEO backlink Claude automations for 61k AI mentions in 3 months Link building is trial and error. SEO AI Claude Automation
原文参考:https://maxed.wiki/posts/how-to-build-a-claude-code-skill-that-actually-works-full-guide/ (Maxed.wiki,本页为站内中文整理)