ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Claude Skills 从原理到实战:SKILL.md 与 MCP 的完全指南

2026/10/2 20:14:16 拓冰建站 浏览量
Claude Skills 从原理到实战:SKILL.md 与 MCP 的完全指南 1. 为什么你的 Claude Code 总是“记不住”团队规范先说一个我踩过的坑。团队里定好了接口返回必须带trace_id、日志必须用loguru、目录必须按domain/service/repo分层结果每次让 Claude Code 写代码它都按自己的习惯来我得在 prompt 里把规范复述一遍。复述十几次之后我意识到这不是模型的问题是我把“程序性知识”当成了“一次性指令”。Claude Skills 解决的正是这件事。它是一套可复用的技能包机制把某个领域的操作流程、判断规则、辅助脚本打包成一个标准文件夹Claude 在启动时只读取每个技能的元数据大约 100 Token当你的任务描述命中技能描述时才把完整的SKILL.md指令加载进来脚本和参考文档再按需读取。这个机制叫渐进式披露Progressive Disclosure也是 Skills 和普通 Prompt 模板最本质的区别——它不占常驻上下文却能随时被唤醒。它适合谁三类人最该用一是团队里负责定规范的人把规范写成 Skill 后所有人共享二是经常做重复性文档处理、代码审查、数据清洗的开发者三是已经在用 MCP 接外部工具、但发现“工具会调了、流程还是乱的”的团队。Skills 管“怎么做”MCP 管“能调什么”两者是互补关系不是替代关系。这篇会从SKILL.md的声明结构讲起拆开加载流程说清 Skills 与 MCP 的协作边界然后给你一份可复制的模板和目录结构最后用一次真实任务验证技能到底有没有被正确触发。中间涉及模型调用的部分我会用 TaoToken 的 API 来做验证因为它的接口和 Anthropic 官方格式一致调试起来省事。2. SKILL.md 声明结构与渐进式加载流程拆解2.1 一个合规 Skill 的目录长什么样Claude Code 识别技能靠的是目录约定不是配置文件注册。默认扫描路径是~/.claude/skills/每个子文件夹就是一个技能文件夹名必须和SKILL.md里的name字段一致否则不加载。这是我实测下来最容易翻车的地方——名字对不上技能静默失效没有任何报错。~/.claude/skills/ └── team-code-review/ ├── SKILL.md # 必需入口文件 ├── scripts/ │ ├── check_naming.py # 命名规范检查 │ └── scan_layering.sh # 分层结构扫描 ├── references/ │ ├── naming_rules.md # 命名规则细则 │ └── error_codes.md # 团队错误码对照 └── assets/ └── review_template.mdSKILL.md分两段顶部是 YAML 前置元数据下面接 Markdown 指令正文。元数据里name和description是必填description直接决定技能会不会被触发写法上要包含具体场景词别写“处理文件”这种宽泛描述。2.2 渐进式披露的三层加载理解加载时机才能理解为什么可以装几十个技能还不卡。层级加载时机Token 量级内容元数据层会话启动约 100/技能name、description、version指令层任务命中描述时5k 词以内SKILL.md 正文流程资源层指令中显式引用时按需scripts、references、assets关键点在第二层到第三层的跳跃SKILL.md正文里不要把所有细节都写进去而是写“遇到命名问题查references/naming_rules.md”让模型自己决定要不要读。这样指令层能保持精简资源层几乎不占常驻开销。2.3 Skills 与 MCP 的协作边界很多人把这两个搞混。MCP 是 Model Context Protocol解决的是“模型怎么调用外部工具和数据源”比如查数据库、调内部 API、读实时监控。Skills 解决的是“模型按什么流程做事”比如代码审查先查命名再查分层最后查错误码。协作方式是这样的Skill 的指令里可以写“调用 MCP 提供的query_metrics工具获取近一小时错误率”于是 Skill 负责编排流程MCP 负责执行外部调用。反过来MCP 单独用的时候模型知道有这个工具但不知道什么时候该用、用完怎么处理结果这部分“判断逻辑”就交给 Skill。一句话边界MCP 提供能力Skill 提供判断。纯流程任务文档格式化、代码规范检查不需要 MCP需要实时数据或外部系统的任务才在 Skill 里挂 MCP 调用。2.4 元数据字段的写法要点description是触发开关写法上建议“动作 对象 场景词”。比如“检查 Python 代码的命名规范与目录分层当用户要求代码审查或提交前检查时启用”。这里“代码审查”“提交前检查”就是触发词用户说“帮我 review 一下这段代码”时能命中。allowed-tools是可选的权限声明写上Read, Bash, Python表示这个技能允许用这些工具。不写的话默认继承会话权限。企业环境里建议显式声明避免技能意外获得写文件或网络访问权限。3. 可复制的 SKILL.md 模板与目录配置3.1 完整 SKILL.md 模板下面这份是我在团队里实际用的代码审查技能你可以直接复制改。注意 YAML 的缩进和---分隔符格式错了整个技能不加载。--- name: team-code-review description: 检查 Python 代码的命名规范、目录分层与错误码使用当用户要求代码审查、提交前检查或 review 时启用 version: 1.0.0 license: MIT allowed-tools: Read, Bash, Python --- # 团队代码审查技能 ## 功能说明 对指定 Python 文件或目录执行三项检查命名规范、目录分层、错误码使用。 输出结构化审查报告标注问题等级error/warning/info。 ## 操作流程 1. 确认待审查路径若用户未指定则询问 2. 执行 scripts/check_naming.py 检查命名规范 3. 执行 scripts/scan_layering.sh 检查目录分层 4. 对照 references/error_codes.md 检查错误码使用 5. 汇总结果按 error warning info 排序输出 ## 判断规则 - 命名问题查 references/naming_rules.md不要凭记忆判断 - 分层问题domain 层不得 import service 层 - 错误码所有 raise 必须使用团队错误码禁止裸 Exception ## 异常处理 - 路径不存在提示用户确认路径 - 非 Python 文件跳过并说明 - 脚本执行失败输出错误码建议手动检查 ## 输出格式 ### 代码审查报告 #### error必须修复 - 文件:行号 - 问题描述 #### warning建议修复 - 文件:行号 - 问题描述3.2 辅助脚本的接口约定脚本放在scripts/下用相对路径调用。关键是输出要标准化方便模型解析。下面这个命名检查脚本输出 JSON模型读起来不会歧义。#!/usr/bin/env python3 # -*- coding: utf-8 -*- 命名规范检查输出 JSON 格式结果 import argparse import json import re import sys from pathlib import Path SNAKE_CASE re.compile(r^[a-z][a-z0-9_]*$) CAMEL_CASE re.compile(r^[A-Z][a-zA-Z0-9]*$) def check_file(path: Path) - list: issues [] for i, line in enumerate(path.read_text(encodingutf-8).splitlines(), 1): if line.strip().startswith(def ): name line.strip()[4:].split(()[0] if not SNAKE_CASE.match(name): issues.append({line: i, level: error, msg: f函数名 {name} 应为 snake_case}) if line.strip().startswith(class ): name line.strip()[6:].split(()[0].split(:)[0] if not CAMEL_CASE.match(name): issues.append({line: i, level: error, msg: f类名 {name} 应为 CamelCase}) return issues if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--path, requiredTrue) args parser.parse_args() target Path(args.path) if not target.exists(): print(json.dumps({error: 路径不存在}, ensure_asciiFalse)) sys.exit(1) result {file: str(target), issues: check_file(target)} print(json.dumps(result, ensure_asciiFalse, indent2))3.3 部署到 Claude Code把整个team-code-review文件夹复制到~/.claude/skills/下重启 Claude Code。验证是否加载成功可以在会话里问“你现在有哪些技能”或者直接触发一次审查任务看它是否自动调用脚本。如果你是通过 API 方式接入需要在请求头里带上 Skills 相关的 beta 标记。用 TaoToken 的 API 时Base URL 填https://taotoken.net/apiKey 在控制台生成模型 ID 选 Claude 系列即可。请求体里skills字段指向技能目录的挂载路径。{ model: claude-sonnet-4-20250514, max_tokens: 4096, messages: [ {role: user, content: 审查 /workspace/demo.py 的代码规范} ], skills: [ {type: custom, path: /root/.claude/skills/team-code-review} ] }注意path必须是容器内可访问的绝对路径本地开发时就是你机器上的实际路径。模型 ID 和路径这两项填错技能不会触发但请求本身可能返回 200所以一定要看返回内容里有没有走审查流程。4. 验证技能被正确触发的完整请求4.1 准备测试文件写一个故意违规的 Python 文件包含驼峰函数名、错误的分层 import、裸 Exception。# demo.py from service.user_service import get_user # 违规domain 不应 import service def getUserName(userId): # 违规函数名应为 snake_case try: return get_user(userId).name except Exception: # 违规应使用团队错误码 return None4.2 发起请求并观察加载行为用 curl 发一次请求重点看返回里有没有出现脚本执行结果和错误码对照。curl https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 4096, messages: [{role: user, content: 审查 /workspace/demo.py}], skills: [{type: custom, path: /root/.claude/skills/team-code-review}] }4.3 成功结果的判断标准技能被正确触发时返回内容应该包含三样东西一是命名问题getUserName应为get_user_name二是分层问题domain 层 import service 层三是错误码问题裸 Exception。如果只返回了泛泛的“代码看起来有问题”说明技能没触发模型在凭自己的知识回答。另一个判断信号是脚本调用痕迹。check_naming.py输出的 JSON 里issues数组会被模型引用返回里能看到具体的行号和问题描述。如果返回里完全没有行号级别的细节大概率是description没命中或者SKILL.md的 YAML 格式有问题导致整个技能没加载。实测下来从发起请求到拿到结构化报告大约 8 到 15 秒取决于文件大小和脚本执行时间。如果超过 30 秒还没返回检查脚本里有没有死循环或者网络请求。5. 常见报错与排查对照5.1 技能完全不触发最典型的表现是模型正常回答但没有任何脚本调用痕迹。排查顺序先确认文件夹名和name字段是否完全一致大小写敏感再检查SKILL.md顶部的---是否成对出现YAML 缩进是否用了 Tab必须用空格最后看description里有没有用户实际会说的触发词。如果用的是 API 方式检查skills数组里的path是否是容器内绝对路径。本地路径和容器路径不一致是高频错误比如你本地是/Users/you/.claude/skills/容器里可能是/root/.claude/skills/。5.2 报错 401 或 local proxy failed401通常是 Key 没带对或者过期。检查请求头里是x-api-key而不是Authorization: BearerAnthropic 格式用的是前者。如果返回local proxy failed说明请求根本没到服务端检查 Base URL 是否写成了https://taotoken.net/api末尾不要多加/v1SDK 会自己拼。5.3 报错 reading choices 或返回结构异常reading choices这类报错一般出现在用 OpenAI 格式的 SDK 去调 Anthropic 接口时。Anthropic 的返回结构是content数组不是choices。如果你用的是 OpenAI SDK需要把 Base URL 指向兼容层或者直接换用 Anthropic SDK。用 TaoToken 时模型对话页面可以直接测试接口连通性省去本地调试环境的时间。5.4 OAuth 相关报错Claude Code 本地登录用的是 OAuth 流程如果报 OAuth 错误通常是本地凭证过期。重新执行登录命令即可。如果是 API 方式接入不涉及 OAuth走的是 Key 认证两者不要混用。混用的典型症状是本地能跑、API 报 401或者反过来。5.5 脚本执行失败但技能触发了技能触发说明元数据和指令层加载正常问题出在资源层。检查scripts/下的脚本有没有执行权限chmod x依赖库是否安装PyPDF2、pdfplumber这类要显式装以及allowed-tools里有没有声明Bash或Python。没声明的话脚本调用会被权限拦截。6. 把技能目录纳入版本管理的实践技能目录本质就是文件直接扔进 Git 仓库跟团队共享是最省事的做法。我的做法是在项目根目录建skills/文件夹每个技能一个子目录然后在 CI 里加一步校验检查每个SKILL.md的 YAML 能否解析、name是否和文件夹名一致、description是否非空。这三项过了基本不会出现静默失效。共享方式有两种一是团队成员各自把skills/软链到~/.claude/skills/改一处全局生效二是通过 API 部署时把skills/目录挂载进容器。前者适合本地开发后者适合 CI 或服务端场景。如果你还在用 MCP 接外部工具建议把“什么时候调哪个工具”的判断逻辑抽出来写成 SkillMCP 只保留工具本身。这样工具升级不影响流程流程调整也不用动工具配置。两者解耦之后维护成本会低很多。需要生成 API Key 或者查看接入文档可以从控制台和文档页入手想先验证模型对技能描述的理解是否准确用模型对话页面发几条测试指令最快如果是要长期跑编码 Agent 任务Coding Plan 的额度模型更适合持续调用。