1. 为什么你的 SKILL.md 写了却从不触发
很多人第一次接触 Agent Skill,都会经历同一个场景:照着文档建好文件夹,把 SKILL.md 塞进去,重启 Claude Code,然后对着对话框敲下需求,结果 Agent 像没看见一样,该干嘛干嘛。你以为是路径放错了,换个目录再试;以为是模型太笨,换 Opus 再试;甚至怀疑是不是要重启系统。折腾一小时之后才发现,问题根本不在正文,而在 SKILL.md 最上面那两行 YAML。
Agent Skill 是什么?一句话说清:它是一个用 Markdown 描述、由 Agent 按需加载的能力包,让模型在遇到匹配任务时自动读取你的工作流、规范和脚本。它能做什么?把重复的团队约定、代码风格、发布流程、MCP 调用步骤固化下来,一次编写、处处复用。适合谁?适合已经在用 Claude Code、Codex、OpenClaw 这类编码 Agent,并且被"每次都要重新解释一遍"折磨过的工程师。
我试过把同一个 Skill 分别放在个人目录和项目目录,触发率差了将近一倍,后来才明白是描述字段的写法问题。Skill 的加载机制是"渐进式披露":启动时只读每个 Skill 的 name 和 description(约 100 token),只有当 Agent 判断描述与当前请求相关,才会用 bash 把整个 SKILL.md 读进上下文。也就是说,description 不是写给人看的说明,而是写给 Agent 看的触发条件。你正文写得再漂亮,description 没写清"什么时候用",它永远不会被激活。
这篇文章按资深工程师的视角,把 Agent Skill 从 SKILL.md 规范、目录结构、MCP 对接,到 Claude Code 里的加载验证,完整走一遍。每一步都给可复制的配置和命令,你跟着做就能跑通。
2. SKILL.md 规范与目录结构:description 才是触发器
先把最容易踩的坑讲透。SKILL.md 的 YAML 前缀有两个必填字段:name 和 description。规范约束是这样的:name 只能用小写字母、数字和连字符,最长 64 字符,不能以连字符开头或结尾,不能出现连续连字符;description 最长 1024 字符,必须同时说清"这个 Skill 做什么"和"什么时候用它"。文件必须精确命名为 SKILL.md,大小写敏感。另外避免在 YAML 里用尖括号,它可能在系统提示里被当成标签注入。
description 的推荐结构是:[做什么] + [何时使用,包含触发语句]。举个反例,很多人写成"帮助写 README",Agent 根本不知道什么时候该调用。正例应该是"当用户要求为项目生成或更新 README、需要统一 README 结构时使用,触发语句包括'写个 README''更新文档''生成项目说明'"。把用户可能说的原话塞进去,命中率会明显提升。
目录结构上,唯一必需的是 SKILL.md,其余都是可选的,但 Skill 越复杂越需要它们:
your-skill-name/ ├── SKILL.md # 必须:YAML 元数据 + 指令正文 ├── scripts/ # 可选:Agent 可执行的代码 ├── references/ # 可选:按需加载的详细文档 └── assets/ # 可选:模板、图片、字体等资源三级加载系统决定了你该怎么拆分内容。第一级是元数据,始终加载,每个 Skill 约 100 token,所以你可以装几十个 Skill 而不撑爆上下文。第二级是 SKILL.md 正文,触发时才加载,建议控制在 5000 token 以内,实践上把 SKILL.md 主体压在 40 行以下,细节全部丢进 references/。第三级是引用文件和脚本,真正需要时才读,脚本甚至可以在不进上下文的情况下直接执行。这就是 Skill 可扩展的原因:空闲时 token 成本为零。
放置位置决定了作用域。Claude Code 的个人级在~/.claude/skills/{name},项目级在.claude/skills/{name},后者可以随 git 共享给团队。Codex 在~/.codex/skills/和仓库级.codex/skills/。OpenClaw 在~/.openclaw/skills/。同名 Skill 时,优先级更高的位置胜出,项目级覆盖个人级,团队定默认、个人做覆盖。
下面是一个可直接复制的 SKILL.md 模板,用于"规范化提交信息"这个场景:
--- name: commit-message-writer description: 当用户要求生成 git 提交信息、整理 commit message、或提到"提交""commit""写提交说明"时使用。根据暂存区改动生成符合 Conventional Commits 的中文提交信息。 metadata: version: 1.0.0 --- # 提交信息生成器 ## 执行步骤 1. 运行 `git diff --cached --stat` 查看暂存文件列表。 2. 运行 `git diff --cached` 读取具体改动。 3. 按 Conventional Commits 生成信息:`type(scope): 描述`。 4. type 取值:feat / fix / docs / refactor / test / chore。 5. 描述用中文,不超过 50 字,动词开头。 ## 异常处理 - 暂存区为空时,提示用户先 `git add`。 - 改动超过 500 行时,只概括模块级别变化。 - 详细规则见 references/conventions.md。注意正文里引用了 references/conventions.md,这就是第三级加载:只有 Agent 觉得需要细节时才会去读,平时不占上下文。
3. 可复制配置:把 MCP 服务注册进 Skill
Skill 和 MCP 的关系,用一句话概括:MCP 给 Agent 提供访问某个 API 的能力,Skill 告诉 Agent 怎么可靠、一致地用这个能力。没有 Skill,用户连上 MCP 还得自己一步步指挥;有了 Skill,一句话就能跑完整个工作流。
先看 MCP 服务本身的注册配置。以 Claude Code 为例,MCP 配置写在项目根目录的.mcp.json,或者用命令行添加。下面是一个可复制的.mcp.json片段,注册一个名为taotoken的 MCP 服务:
{ "mcpServers": { "taotoken": { "command": "npx", "args": ["-y", "@taotoken/mcp-server"], "env": { "TAOTOKEN_BASE_URL": "https://taotoken.net/api", "TAOTOKEN_API_KEY": "${TAOTOKEN_API_KEY}" } } } }这里三个要素必须齐全,缺一个都连不上:Base URL 指向https://taotoken.net/api,API Key 通过环境变量注入(不要硬编码进文件),Model ID 在 Skill 正文里指定。环境变量在 shell 里这样设置:
export TAOTOKEN_API_KEY="sk-你的密钥"如果你用的是 Codex,配置写在~/.codex/auth.json,结构类似,把 base_url 和 api_key 填进去即可。Cline 的 MCP 配置则在扩展的 settings 面板里,字段名是baseUrl、apiKey、model,本质一样。
接下来是引用 MCP 的 SKILL.md 模板,注意 metadata 里声明了 mcp-server:
--- name: repo-analyzer description: 当用户要求分析代码仓库结构、统计代码量、生成仓库概览报告时使用,触发语句包括"分析仓库""代码统计""生成概览"。 metadata: mcp-server: taotoken version: 1.0.0 --- # 仓库分析器 ## 前置条件 - 已注册 taotoken MCP 服务。 - Model ID 使用 claude-sonnet-4-5。 ## 执行步骤 1. 调用 MCP 工具 `list_files` 获取仓库文件树。 2. 调用 `count_lines` 按语言统计代码行数。 3. 汇总为 Markdown 表格,包含语言、文件数、行数、占比。 4. 输出到 `docs/repo-overview.md`。 ## 异常处理 - MCP 连接失败时,提示检查 TAOTOKEN_API_KEY 是否设置。 - 详见 references/error-handling.md。关于allowed-tools字段,规范里标记为实验性,各平台支持不一,Claude Code 支持较好,其他平台可能忽略。生产环境建议先不用,等稳定后再引入。
4. 验证请求:在 Claude Code 里确认 Skill 真的被加载
配置写完不代表生效,必须验证。Claude Code 里 Skill 默认出现在斜杠命令菜单,你可以显式调用,也可以隐式触发。
显式调用直接敲斜杠命令:
/commit-message-writer隐式调用则用自然语言,让 Agent 自己判断:
帮我给暂存区的改动写个提交信息如果 description 写得好,第二句会自动激活 Skill。验证是否真的加载,看两个信号:一是 Agent 回复里会提到它正在使用某个 Skill;二是执行过程中会调用 Skill 正文里定义的步骤,比如先跑git diff --cached。
更严谨的验证方式是直接测 MCP 连通性。在 Claude Code 里输入:
/mcp它会列出已注册的 MCP 服务及连接状态。如果 taotoken 显示 connected,说明 MCP 层通了。再发一条会触发 Skill 的请求,观察是否调用了 MCP 工具。
实测下来,最常见的失败是 Skill 被加载了但 MCP 没连上,表现为 Agent 说"我要调用 list_files"然后卡住或报错。这时候先查/mcp状态,再查环境变量。
一个完整的成功链路长这样:你输入"分析这个仓库",Agent 读取 repo-analyzer 的 description,判断匹配,加载 SKILL.md 正文,发现需要 MCP 工具,调用 taotoken 服务的 list_files,拿到文件树,继续执行后续步骤,最后输出报告。每一步都能在对话里看到痕迹。
5. 常见报错排查:401、local proxy failed 与 OAuth
排障是工程化落地绕不开的一环。下面按真实报错逐条对照。
401 Unauthorized:最常见,几乎都是 API Key 问题。检查TAOTOKEN_API_KEY是否真的导出到了当前 shell,echo $TAOTOKEN_API_KEY看有没有值。如果用了.mcp.json的${TAOTOKEN_API_KEY}语法,确认 Claude Code 启动时能读到这个变量。Key 本身过期或复制时带了空格也会 401。
local proxy failed / connection refused:MCP 服务进程没起来。先手动跑一遍npx -y @taotoken/mcp-server,看是否报错。常见原因是 npx 缓存损坏,清一下npm cache clean --force再试。如果公司网络有出口限制,确认能访问https://taotoken.net/api。
Error reading choices / 响应解析失败:通常是 Model ID 写错,或者返回格式和 Skill 预期不符。确认 SKILL.md 里指定的 Model ID 是平台支持的,比如claude-sonnet-4-5。如果 MCP 服务返回的是流式数据而 Skill 按非流式解析,也会报这个,检查服务端配置。
OAuth 相关报错:某些 MCP 服务需要 OAuth 授权,首次连接会弹浏览器。如果无头环境跑,会卡在授权。解决办法是先在本地有浏览器的机器完成一次授权,把 token 缓存复制过去,或者改用 API Key 认证方式。
Skill 完全不触发:回到第 2 节,99% 是 description 问题。把用户可能说的原话加进去,把"做什么"和"何时用"都写清。另外确认文件确实叫SKILL.md,不是skill.md或SKILL.MD。
同名 Skill 冲突:项目级和个人级同名时项目级胜出,但如果你期望的是个人级,就会觉得"我的 Skill 没生效"。检查两个位置是否都有同名文件夹。
排查顺序建议固定下来:先/mcp看连接,再echo看环境变量,再手动跑 MCP 进程,最后查 Skill 的 description。按这个顺序,大部分问题五分钟内能定位。
6. 建立可维护的 Skill 目录与接入入口
Skill 写多了之后,目录管理就成了新问题。我的做法是按作用域分三层:个人通用 Skill 放~/.claude/skills/,团队共享的放项目.claude/skills/并提交 git,实验性的单独放一个~/.claude/skills-lab/定期清理。每个 Skill 的 references/ 里放详细文档,SKILL.md 主体保持精简,这样第二级加载始终轻量。
命名上统一用动词-名词格式,比如commit-message-writer、repo-analyzer,一眼能看出用途。description 里把触发语句写全,宁可啰嗦也别漏。版本号写在 metadata 里,方便追踪变更。
安全方面必须强调:Skill 能捆绑可执行代码,恶意 Skill 同样能控制 Agent 行为。只安装可信来源的 Skill,安装前把 scripts/ 里的每个文件读一遍,对任何要求出站网络调用或让你在对话里粘贴密钥的 Skill 保持警惕。社区 Skill 在安装前用 VirusTotal 之类的工具扫一遍,有广泛权限的手动审核。
要把这套流程跑起来,你需要一个稳定的 API 入口。TaoToken 提供兼容主流 Agent 的接入方式,Base URL 是https://taotoken.net/api。先去 API Keys 页面 拿密钥,再对照 接入文档 把 MCP 服务注册好。想先验证模型响应是否正常,可以直接在 模型对话 里发一条测试请求。如果你打算长期跑编码 Agent 或做多步工作流,Coding Plan 更适合持续调用。配置过程中卡在 MCP 连接或 Skill 不触发,回到第 5 节按顺序排查,基本都能解决。