
1. 从一次“重复解释”说起Claude Code Skills 到底解决什么问题如果你用 Claude Code 写过一段时间代码大概率遇到过这种场景每次让它按团队规范生成接口文档都要重新贴一遍格式要求每次让它做代码审查都要重复强调“先看有没有空指针、再看日志埋点是否齐全”。这些知识你脑子里很清楚但 Claude 每次开新会话都像失忆一样得从头教。Claude Code Skills 就是冲着这个痛点来的。简单说它是一套让 Agent 按需加载“专业技能包”的机制——你把某类任务的流程、规范、脚本打包成一个文件夹Claude 在遇到相关任务时自动识别并加载不需要你每次手动喂上下文。适合谁适合已经在用 Claude Code 做日常开发、想让 Agent 稳定复现某套工作流的开发者尤其是团队里需要统一代码规范、文档模板、审查清单的场景。核心概念有三个SKILL.md 是技能的描述文件用 YAML frontmatter 声明名称和用途Progressive Disclosure渐进式披露是加载策略分三层按需读取避免一次性塞满上下文窗口MCP 则是另一条线负责连接外部系统和 Skills 是互补关系而非替代关系。这篇会从目录结构讲到可复制的 SKILL.md 模板再演示一次技能触发和验证最后说清楚 Skills 和 MCP 的边界在哪。我试过把一个“API 文档生成”技能包放进项目里之后每次让 Claude 生成接口说明它都会自动按我们团队的字段顺序和示例格式输出省掉了反复贴模板的步骤。下面把整套流程拆开讲。2. 前置准备TaoToken 统一 Key 与 Claude Code 接入配置在写 SKILL.md 之前得先让 Claude Code 能正常跑起来。如果你已经在用官方通道可以跳过这节如果希望通过统一 Key/API 通道管理调用TaoToken 是一个可选方案。它的作用是把模型调用收敛到一个 Base URL 和一把 Key 上方便在 Claude Code、Cline、Codex 等工具之间切换时不用反复改配置。先拿 Key。打开 https://taotoken.net/api-keys 登录后创建一个 API Key复制保存。注意这个 Key 只在创建时完整显示一次丢了就得重新生成。接下来配置 Claude Code 的接入信息。Claude Code 读取的是环境变量或 settings 文件推荐用 settings 方式路径在项目根目录的.claude/settings.json或者用户级的~/.claude/settings.json。内容如下{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoToken密钥 } }如果你用的是 Claude Code 的 CLI 启动方式也可以直接在 shell 里导出export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的TaoToken密钥这里有个容易踩的坑Base URL 末尾不要带/v1Claude Code 会自己拼接路径。如果你写成https://taotoken.net/api/v1请求会变成/api/v1/v1/messages直接 404。配置完成后验证一下通道是否通claude -p 回复一句通道正常如果返回了正常文本说明 Key 和 Base URL 都生效了。如果报 401先检查 Key 有没有复制完整如果报连接超时检查 Base URL 是否写错。这一步过了再往下写 SKILL.md 才有意义否则技能触发了也调不通模型。关于模型 ID 的选择Claude Code 默认会用一个通用模型名你也可以在 settings 里显式指定{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoToken密钥, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }Model ID 写错会报model not found这个在排障章节会细说。配置好之后Claude Code 的每次请求都会走你设置的通道Skills 的加载和触发也在这个基础上进行。3. 可复制配置SKILL.md 模板与目录结构Claude Code Skills 的载体是一个文件夹文件夹里必须有一个SKILL.md。这个文件以 YAML frontmatter 开头至少包含name和description两个字段。Claude 在启动时会扫描所有技能的元数据只加载 name 和 description 到系统提示里用来判断当前任务该不该激活某个技能。这就是 Progressive Disclosure 的第一层。先看目录结构。假设你要做一个“API 文档生成”技能放在项目根目录的.claude/skills/下.claude/ skills/ api-doc-generator/ SKILL.md templates/ endpoint-template.md scripts/ extract_routes.pySKILL.md是入口templates/放模板文件scripts/放可执行脚本。Claude 在需要时才会去读 templates 或执行 scripts平时这些文件不占上下文。下面是SKILL.md的完整模板可以直接复制改--- name: api-doc-generator description: 根据代码中的路由定义生成符合团队规范的 API 文档。当用户要求生成接口文档、API 说明或 endpoint 列表时使用。 --- # API 文档生成技能 ## 使用场景 当用户要求为某个模块或文件生成 API 文档时按以下步骤执行。 ## 执行步骤 1. 读取用户指定的源文件识别路由定义如 Flask 的 app.route、FastAPI 的 router.get。 2. 对每个路由提取 HTTP 方法、路径、请求参数、返回结构。 3. 按 templates/endpoint-template.md 的格式生成文档。 4. 如果路由数量超过 10 个调用 scripts/extract_routes.py 批量提取避免手动逐个解析。 ## 字段顺序规范 - 接口名称 - 请求方法 路径 - 请求参数表格 - 返回示例JSON 代码块 - 错误码说明 ## 注意事项 - 如果源文件里没有类型注解在文档中标注“类型待确认”。 - 不要编造返回字段只写代码里实际出现的。这个文件里frontmatter 的description很关键。它决定了 Claude 什么时候激活这个技能。写得太泛比如“生成文档”会导致误触发写得太窄又可能漏触发。建议把触发场景写具体比如“当用户要求生成接口文档、API 说明或 endpoint 列表时使用”。Progressive Disclosure 的第二层就是加载整个SKILL.md的内容。第三层是SKILL.md里引用的templates/endpoint-template.md和scripts/extract_routes.pyClaude 只在执行到对应步骤时才去读或执行。templates/endpoint-template.md可以这样写## {{接口名称}} **{{请求方法}} {{路径}}** ### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | {{name}} | {{type}} | {{required}} | {{desc}} | ### 返回示例 json {{response_json}}错误码错误码说明{{code}}{{message}}scripts/extract_routes.py 是一个简单的路由提取脚本 python import re import sys import json def extract_routes(filepath): with open(filepath, r, encodingutf-8) as f: content f.read() pattern r\w\.(get|post|put|delete)\([\]([^\])[\]\) matches re.findall(pattern, content) return [{method: m[0].upper(), path: m[1]} for m in matches] if __name__ __main__: routes extract_routes(sys.argv[1]) print(json.dumps(routes, ensure_asciiFalse, indent2))这个脚本的作用是把路由提取这件事从“让模型读代码猜”变成“确定性执行”减少幻觉。Claude 通过代码执行工具调用它拿到 JSON 结果后再填模板。目录放好后Claude Code 启动时会自动扫描.claude/skills/下的所有文件夹。你不需要额外注册只要SKILL.md的 frontmatter 格式正确技能就会被识别。4. 验证请求与成功结果一次技能触发与验证动作配置和文件都就位后怎么确认技能真的被触发了这里演示一次完整的验证流程。先准备一个测试用的源文件比如demo_routes.pyfrom flask import Flask app Flask(__name__) app.route(/users, methods[GET]) def list_users(): return [] app.route(/users/int:user_id, methods[GET]) def get_user(user_id): return {} app.route(/orders, methods[POST]) def create_order(): return {}然后在 Claude Code 里输入帮我为 demo_routes.py 生成 API 文档如果技能配置正确Claude 会先扫描到api-doc-generator的 description判断当前任务匹配然后加载完整的SKILL.md按里面的步骤执行。你会看到它先读取demo_routes.py识别出三个路由然后按templates/endpoint-template.md的格式输出文档。成功的结果大概长这样## 用户列表 **GET /users** ### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | 无 | - | - | - | ### 返回示例 json []错误码错误码说明500服务器内部错误如果你在输出里看到字段顺序和模板一致、返回示例是 JSON 代码块、错误码表格存在说明技能生效了。如果 Claude 只是随便回了一段文字没有按模板走那可能是 description 没匹配上或者 SKILL.md 的 frontmatter 格式有问题。 再验证一下第三层加载。当路由数量超过 10 个时SKILL.md 里写了要调用 scripts/extract_routes.py。你可以造一个包含 12 个路由的文件再让 Claude 生成文档观察它是否执行了脚本。如果它直接开始手动解析而不是调脚本说明脚本调用那一步的指令不够明确可以在 SKILL.md 里把条件写得更硬“路由数量超过 10 个时必须调用 scripts/extract_routes.py不要手动解析。” 验证通过后你可以把这个技能包复制到其他项目里只要目录结构一致Claude Code 就能识别。这就是 Skills 的可移植性——一个文件夹带走一套工作流。 ## 5. 本篇常见错排查401、local proxy failed、reading choices、OAuth 技能跑不起来很多时候不是 SKILL.md 写错了而是接入层出了问题。下面按真实报错逐个排查。 **401 Unauthorized** 这是最常见的。报错原文一般是API error: 401 Unauthorized - invalid api key原因通常是 Key 没复制完整、Key 已失效、或者 Base URL 和 Key 不匹配。先检查 ANTHROPIC_API_KEY 是否以 sk- 开头且没有多余空格。如果用的是 settings.json注意 JSON 里不能有注释末尾不能有多余逗号。改完后重启 Claude Code 让配置生效。 **local proxy failed** 报错原文Error: local proxy failed to start: listen tcp 127.0.0.1:xxxx: bind: address already in use这是 Claude Code 的本地代理端口被占用了。常见原因是上一次会话没正常退出进程还在后台。解决方式是找到占用端口的进程并结束或者换个端口。在 settings 里可以指定 json { env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoToken密钥 }, proxyPort: 8899 }如果换端口后还是报错检查系统代理设置有没有冲突。reading choices 相关报错报错原文类似Error: reading choices: unexpected end of JSON input这个通常出现在流式响应解析失败时。原因可能是 Base URL 写成了带/v1的路径导致返回体格式不对。确认ANTHROPIC_BASE_URL是https://taotoken.net/api不带/v1。另外检查网络是否稳定流式响应中断也会导致 JSON 解析失败。OAuth 相关报错如果你之前用官方账号登录过 Claude Code配置里可能残留 OAuth token和 API Key 模式冲突。报错原文Error: OAuth token invalid or expired解决方式是清除本地 OAuth 缓存强制走 API Key 模式。缓存文件通常在~/.claude/下找到credentials.json或类似文件备份后删除。然后在 settings 里确保只配置了ANTHROPIC_API_KEY没有 OAuth 相关字段。技能不触发如果接入层没问题但技能就是不激活先检查SKILL.md的 frontmatter 是否合法。YAML 对缩进敏感name和description必须顶格写冒号后面要有空格。另外确认技能文件夹放在.claude/skills/下而不是项目根目录或其他位置。Claude Code 只扫描特定路径。脚本执行失败如果SKILL.md里引用了scripts/extract_routes.py但执行时报ModuleNotFoundError检查脚本依赖是否安装。Claude Code 执行脚本时用的是当前环境的 Python不会自动装依赖。可以在技能包里加一个requirements.txt并在SKILL.md里写明“执行前先安装依赖”。6. 语义一致 CTASkills 与 MCP 的边界及后续接入把 Skills 和 MCP 放在一起看两者的分工其实很清楚。MCP 解决的是“连通性”——让 Claude 能访问外部数据库、API、文件系统相当于给 Agent 装了一双能伸出去的手。Skills 解决的是“程序性知识”——告诉 Agent 某类任务该按什么步骤、什么规范来做相当于给 Agent 一本操作手册。什么时候用 Skills当你需要固化一套工作流比如代码审查清单、文档模板、部署检查步骤这些知识不依赖外部系统只是“怎么做”的指令。什么时候用 MCP当任务需要实时读取外部数据比如查数据库、调内部 CRM、拉取监控指标这些是 Skills 做不到的因为 Skills 本身不直接连接外部服务。两者可以协作。比如一个“发布检查”技能SKILL.md里写清楚检查步骤其中一步是“调用 MCP 工具查询当前服务健康状态”。这样 Skills 负责流程编排MCP 负责数据获取各司其职。如果你还没配好接入通道可以先从 API Keys 页面拿 Key再对照接入文档把 Base URL 和 Model ID 填进 settings。想先验证模型对话是否正常可以用模型对话页面发一条测试消息。如果打算长期用 Claude Code 做编码和 Agent 任务Coding Plan 页面有更完整的配置说明。技能包写好后建议先在单个项目里跑通确认触发和脚本执行都正常再复制到其他项目。每次改SKILL.md的 description 后重新启动 Claude Code 让元数据刷新。脚本里的路径尽量用相对路径避免换项目后失效。