尧图精选

AI Agent Skills 实战指南:从MCP到SKILL.md的完整开发与调用

🕒 发布时间:2026/9/8 14:33:17 📁 来源:尧图网络
前阵子整理本地开发目录我发现自己已经在 Claude Code 里攒了快二十个 skills 文件。回想几个月前我还在每个新项目里重新教 AI 一遍你要怎么分析代码、怎么写测试、怎么整理日报现在这些流程全都变成了可复用的技能包一个命令就能加载。这种变化背后其实是 Agent 开发范式的一次明显转向从对话期临时编写指令到结构化沉淀技能。今天这篇就围绕 Skills 展开聊清楚它到底是什么、内部结构长什么样、怎么自己开发一个、怎么调用 MCP 工具以及我在 Claude Code、OpenCode、Codex、Cursor 这些工具里实测下来的真实差异。内容面向两类人一类是想把 AI 编程工具用得更深入的前端/全栈开发另一类是自己做 Agent 应用、想把能力做成标准模块的开发者。不管你是刚听说 agent skills还是已经看过一些 skills 推荐但没真正动手这篇应该都能给你一些可落地的参考。1. Skills 是什么从每次重新教 AI到一次打包、处处复用1.1 一句话讲清楚 SkillsSkills 本质上是给 Agent 准备的一套标准化技能包。里面装着任务说明、操作步骤、辅助脚本、参考模板当 Agent 遇到匹配的场景时会按这个技能包里的逻辑去执行。它像一个岗位说明书加上操作手册说明书告诉 AI 什么时候该出手手册告诉它具体怎么做。我比较喜欢用菜谱做类比。同样是教人做番茄炒蛋口头说一句炒熟就行跟给一份精确到克数、火候、下锅顺序的菜谱做出来的成品稳定性完全不同。Skills 就是那张精确菜谱。它把怎么做一件事的经验从人的脑子里、从一次性的对话上下文里搬到了文件系统里变成了可版本管理、可分享、可传承的东西。所以你会看到无论是 ChatGPT、Claude Code 还是 Codex这些主流工具都在推动同一种能力让开发者把高频、复杂、多步骤的任务固化成 Skills而不是每次重复描述需求。吴恩达在讲 Agent 落地的时候也反复强调这个概念核心观点是Skills 是让 Agent 从什么都懂但什么都要现想进化为遇到类似任务直接调用成熟流程的关键杠杆。1.2 为什么 Function Calling 不够用很多人第一次接触 Skills 时会问我们不是已经有 Function Calling 了吗为什么还要搞一个 Skills我理解的区别在于粒度。Function Calling 是单次、原子化的工具调用。模型根据当前上下文决定现在该调用哪个工具参数是什么一次对话里可以多次调用但每次调用本质上都是独立的请求。它解决的是AI 需要连接外部能力的问题比如查个天气、调个数据库接口一次一调。但真实工作任务往往是多步骤的编排。举个例子分析某个竞品这个任务需要先搜索相关信息、打开几个页面、提取关键内容、整理对比、最后生成报告。这已经不是单次函数调用能覆盖的范畴它需要 Agent 自己规划步骤、判断中间结果、决定下一步动作。问题在于这种编排逻辑如果每次都在对话里临时生成效果完全取决于模型心情和上下文长度很不稳定。Skills 的价值正是把这种编排逻辑固化下来。你可以想象一个竞品分析的 skill它内部定义了搜索关键词怎么写、页面抓取用什么工具、报告按什么结构输出。下次再遇到类似需求Agent 直接加载这套流程产出的质量就稳定得多。1.3 Skills、MCP、Agent 三者的位置关系我在折腾 Skills 的过程中踩过最大的认知误区是把 Skills 和 MCP 当成同一类东西。实际上它们的层级完全不同。维度Function CallingMCPSkills粒度单次函数调用标准化工具服务多步骤任务流程内容一个可调用的函数声明一组工具 协议指令 脚本 资源复用性模型现场决定服务级复用任务级复用形态写函数签名起 HTTP/stdio 服务写 SKILL.md 可选脚本典型场景查天气、调一个 API接入数据库、浏览器、文件系统完成一个完整工作流如果说 Agent 是大脑MCP 是手那 Skills 更像是小脑里预存的动作记忆。它不是一次性的应激反应而是一组训练好的动作序列。Skills 本身不负责连通外部服务连通是 MCP 做的事Skills 做的事情是指挥调度——告诉 Agent这一步调用哪个 MCP 工具拿到结果后下一步做什么最后按什么格式输出。搞清楚这个关系之后你就不会再纠结Skills 和 MCP 哪个好这种问题了。实际开发中它们的配合是这样的你配好一个浏览器 MCP server然后在某个 skill 的 SKILL.md 里写当需要抓取网页内容时调用 browser MCP 中的 fetch_page 工具Agent 在运行时会自己完成这个调度。2. 拆开一个 SkillSKILL.md、脚本、资源文件各自扮演什么角色2.1 标准目录结构长什么样一个 Skill 没有铁板一块的目录规范但主流工具基本都认可一个目录 一个入口文件的结构。我常用的布局是这样my-skill/ ├── SKILL.md # 技能入口Agent 首先读取这个文件 ├── scripts/ # 可执行脚本处理 Agent 不擅长的精确计算 │ ├── analyze.py │ └── requirements.txt ├── assets/ # 模板、示例、图片等静态资源 ├── references/ # 参考资料Agent 按需检索 └── output/ # 约定输出目录SKILL.md 是整个包的门面。Agent 不会一开始就去读所有文件它先读 SKILL.md根据里面的描述判断这个技能跟当前用户请求匹不匹配匹配了才会深入使用目录里的其他资源。很多人在折腾 skills 下载时下载完直接扔进 skills 目录就用结果发现 Agent 完全不理会这个技能大概率就是 SKILL.md 里的描述没写好导致检索阶段就被跳过了。2.2 SKILL.md 是灵魂前几行元信息决定了一切SKILL.md 的头部通常是 YAML 格式的元信息最核心的就是 name 和 description。description 的写法直接影响 Agent 会不会在合适的时机激活这个技能这也解释了为什么社区里关于skills如何调用的讨论总是绕不开 SKILL.md 的写法。举个反例。假设你想做一个生成测试用例的 skilldescription 如果写成:--- name: test_case_generator description: 用于测试相关任务 ---这个描述就太宽泛了。Agent 在遇到请帮我看下这段代码有没有 bug的时候可能也会觉得这是测试相关任务然后错误地加载这个技能结果答非所问。我把这称为乱触发。更好的写法是明确触发边界--- name: test_case_generator description: 当用户要求为某个函数或模块编写、补充或重构单元测试用例时使用。不适用于代码审查和 bug 定位。 ---多写一句不适用于什么场景误触发率会明显下降。这一点是我在大量实测 skills 使用技巧时总结出来的非常值得留意。2.3 正文指令怎么组织SKILL.md 的正文是给 Agent 看的操作手册写得越结构化越好。我一般会分成几个固定区块# 输入格式 - 目标模块路径 - 测试框架pytest / jest / 默认自动推断 # 执行步骤 1. 读取目标模块源码梳理公开函数 2. 为每个函数设计正常分支、异常分支、边界条件 3. 将测试代码写入 tests/ 目录文件名与模块对应 4. 运行测试修复失败项 # 输出规范 - 每个测试必须有 assert - 覆盖率达到 80% 以上 - 运行结果附在最后 # 失败处理 - 测试环境缺依赖时先用 pip/npm 安装 - 编译报错时定位语法问题并修复后重试Agent 本质上是一个靠指令驱动的系统你给的指令越像一份优秀的需求文档它执行出来的结果就越接近预期。很多 skills 开发新手把精力都放在写脚本上忽略了这段正文这其实是本末倒置的。2.4 脚本不是必需的但能用脚本解决的就别让模型硬算并不是所有 skill 都必须附带脚本。如果任务纯粹是生成一段文案整理一份提纲SKILL.md 里的指令就足够了。但只要涉及精确计算、批量文件处理、复杂数据解析就应该把脚本放进去。模型擅长的是理解和生成但像素计算、JSON 遍历、文件批量重命名这类工作让模型现写代码再执行不如直接在 skill 里放一个经过测试的脚本稳定。我见过很多人写了个 skill让 Agent用 Python 处理图像然后保存结果结果每次 Agent 都现场发挥时好时坏。正确做法是把图像处理那段代码固定成 scripts/analyze.pySKILL.md 里只写调用 scripts/analyze.py 并传入图片路径。当然脚本也要控制复杂度。能用纯 Python 标准库解决的就不要拉一堆重型依赖否则换一台机器跑的时候光装环境就能耗掉半天。3. 实战开发一个图片还原设计稿Skill 的完整过程3.1 为什么选这个场景我挑这个场景来讲实战是因为它非常典型设计稿转代码是前端高频刚需流程固定、步骤多、光靠对话描述很难稳定复现。社区里一直有人在找图片还原设计稿给前端开发好用的 skills说明这个需求确实存在也说明很多人还没找到一个顺手方案。这个 Skill 的目标是给 Agent 一张设计稿图片加上目标技术栈React/Vue/纯 HTML它能自动分析图片布局、提取主色、生成对应的页面代码。听起来已经很常见了但差距就藏在细节里布局怎么识别、色值怎么提取、字体怎么处理、输出结构怎么定。这些细节全部压实到一个 Skill 里不同人做出来的效果天差地别。3.2 开发前先拆解问题我习惯先画一条任务链路搞清楚每个环节哪些该交给模型哪些该交给脚本图片输入与基础识别 → 脚本处理布局结构分析几行几列、区块嵌套 → 脚本生成中间描述 模型修正主色提取、字体大小识别 → 脚本处理从中间描述生成前端代码 → 模型处理代码格式整理、组件拆分 → 模型处理核心思路是凡是能用确定性脚本完成的绝不让模型感觉凡是需要审美判断、结构理解的交给模型。这种分工既能提高稳定性又能减少 API 调用成本。3.3 目录与 SKILL.md 编写项目结构不需要搞太复杂两个主要目录就够image-to-code-skill/ ├── SKILL.md ├── scripts/ │ ├── analyze_image.py │ └── requirements.txt └── assets/ └── html_template.htmlSKILL.md 的内容我是这样设计的--- name: image_to_code description: 当用户提供 UI 设计稿图片并希望转换为前端页面代码时使用。支持 HTML/CSS、React、Vue 等目标技术栈。 ---正文部分# 输入 - 图片路径通常是用户上传的截图或设计稿文件 - 目标技术栈html / react / vue默认为 html # 执行步骤 1. 运行 scripts/analyze_image.py传入图片路径得到 JSON 格式的布局描述 2. 仔细阅读 JSON 描述确认页面区块划分和主色值 3. 使用 assets/html_template.html 作为基础模板按布局描述填充 4. 将最终代码保存到 output/ 目录文件名与设计稿一致 # 输出规范 - 区块结构必须与 JSON 描述一致不得擅自增删 - 主色值从 JSON 的 colors 字段中取 - 字体大小近似换算为 rem 单位保留两位小数 - 图片资源以相对路径引用 # 失败处理 - 如果 analyze_image.py 报错检查 Python 环境是否缺少 Pillow 依赖 - 如果图片分辨率过低提示用户重新上传高清原图这里我把步骤 1明确写成运行脚本等于把图像分析这种确定性工作固定下来不让 Agent 自由发挥。这是 Skills 开发里一个很关键的思路转换不要假设模型懂得怎么做所有事而是把能确定的都确定下来。3.4 辅助脚本实现要点analyze_image.py 不需要做太复杂的事它的任务是输出一份机器可读的布局描述。核心功能有三块读取图片尺寸、提取主色调、识别明显区块边界。我用的是 Python Pillow逻辑非常直接。#!/usr/bin/env python3 分析 UI 设计稿图片输出布局与颜色描述。 用法: python analyze_image.py image_path [--max-colors 8] import argparse import json from collections import Counter from PIL import Image def analyze(image_path, max_colors): img Image.open(image_path).convert(RGB) width, height img.size # 提取主色按出现频次排序 small img.resize((width // 8, height // 8)) colors Counter(small.getdata()).most_common(max_colors) palette [ {rgb: f#{r:02x}{g:02x}{b:02x}, weight: round(cnt / len(list(small.getdata())) * 100, 2)} for (r, g, b), cnt in colors ] # 简单横向扫描识别高度超过阈值的水平条带 # 这里只是兜底方案详细布局交给模型结合视觉理解 bands [] gray img.convert(L) for y in range(0, height, max(1, height // 40)): row [gray.getpixel((x, y)) for x in range(0, width, max(1, width // 40))] avg sum(row) / len(row) if len(bands) 0 or abs(bands[-1][avg] - avg) 15: bands.append({y: y, avg: round(avg, 1)}) return { size: {width: width, height: height}, palette: palette, horizontal_bands: bands, } if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(image_path) parser.add_argument(--max-colors, typeint, default8) args parser.parse_args() result analyze(args.image_path, args.max_colors) print(json.dumps(result, ensure_asciiFalse, indent2))这个脚本输出的 JSON 会被 Agent 当作后续代码生成的依据。你会发现我特意把横向条带识别做得很粗糙因为真正的布局理解能力应该由多模态模型完成脚本只需要提供准确的颜色数据和图片尺寸避免模型在基础数据上犯低级错误。如果基础脚本能把每个区块的颜色、坐标、文字区域大致框出来那这个 Skill 的稳定程度会大幅提升。3.5 测试循环不是写完就完事Skills 开发跟写业务代码一样必须走测试-反馈-修改的循环。我第一次写完这个 skill 时拿一张卡片类设计稿去测模型的布局识别完全跑偏把左对齐的文案识别成了居中。问题不在脚本而是 SKILL.md 里缺少了对齐方式的识别指令。于是我在执行步骤里加了一句注意文字对齐方式参照 JSON 中的 horizontal_bands 判断整体排版方向并在代码中保留与设计稿一致的对齐关系。重跑一遍结果明显改善。这个过程的要点是哪个环节出错就去补哪个环节的确定性。布局不准就补布局指令颜色不对就检查脚本取色的逻辑。反复几轮一个可用的 skill 就打磨出来了。4. Skill 调用 MCP 工具把会想和能干接起来4.1 理解调用逻辑现在聊回一个重要话题Skills 如何调用 MCP 工具。这也是很多人问得最多的。我在前面说了Skill 不直接内置 MCP 连接它只是一套指令。真正建立 MCP 连接的是 Agent 运行时。你在 Claude Code 或 Codex 里配置好 MCP server 之后Agent 才拥有了调用外部工具的能力Skill 能做的是在自己的 SKILL.md 里告诉 Agent什么时候该用哪个 MCP 工具。我这样理解它们的分工MCP 是工具层解决能不能Skill 是策略层解决什么时候用、用完做什么。这种分工让 Skills 和 MCP 可以独立演化。你可以换一套 MCP server而 Skill 不用改太多也可以给同一个 MCP 工具写不同用途的多个 Skill。4.2 在 SKILL.md 里具体怎么表达假设你现在有一个长文资料汇总的 Skill希望 Agent 在整理资料时能自动搜索网页并抓取正文。那么 SKILL.md 里可以这样写# 执行步骤 1. 使用 MCP server「browser」下的 search 工具搜索用户提供主题的关键词 2. 从搜索结果中选择权威性较高的前 3 个链接 3. 使用 browser 的 fetch_page 工具抓取每个链接的正文内容 4. 将抓取内容按「背景-现状-结论」结构整理保存到 output 目录 # 注意事项 - 每个 URL 正文抓取失败时标注原因并跳过不影响整体流程 - 引用来源时在每条结论后附上原文 URL关键在于写清楚两层信息一是用哪个 MCP server 的哪个工具二是拿到结果之后下一步做什么。如果把第二层省略Agent 可能抓完页面就不知道干嘛了生成的汇总文档会非常散。4.3 实例让 Skill 自动查资料并生成报告我再展开一个真实场景。最近我在做竞品分析写了一个竞品调研的 Skill。它内部依赖两个 MCP server一个是浏览器工具用来搜页面另一个是文件读写工具用来保存产出。整个流程是Agent 先读取用户输入的竞品名称调用浏览器 MCP 搜索该竞品的产品功能、定价策略、用户评价抓取 3 到 5 个页面正文抽取关键信息调用文件 MCP 把整理好的报告写到指定目录在对话中展示结构化总结最让我惊讶的不是它能搜索而是它能自己判断哪个信息源更有价值。这和 SKILL.md 里写了优先选择官网与专业评测网站避免内容农场这样的规则有关。当 Skill 把这类默认偏好写进去之后Agent 产出的报告质量明显上了一个台阶。4.4 调用 MCP 工具时的三个注意点第一MCP server 命名冲突。我遇到过 SKILL.md 里写调用 filesystem 工具但实际配置的 MCP server 名字是 local-fsAgent 找不到工具导致执行中断。现在我会在 SKILL.md 里明确写出完整的 server 名 工具名比如local-fs MCP 的 write_file 工具。第二返回内容过大。有些浏览器 MCP 工具会把整个网页正文都返回出来几万字的内容一下塞进上下文既烧 token 又容易让 Agent 迷失重点。对策是在 SKILL.md 里加一句如果页面内容过长只提取开头 3000 字和所有标题或者让脚本侧做截断。第三权限与确认。不是每个 MCP 工具都允许无感调用有些文件写入工具会要求交互确认。在自动化执行的场景里这种确认会卡住整个流程。我在测试中发现给 SKILL.md 加上调用写操作前先检查目标路径是否存在同名文件存在则追加时间戳后缀这样的避撞规则比每次停下来问用户更顺滑。5. Claude Code、OpenCode、Codex、Cursor 的 Skills 生态横评5.1 不同工具的 Skills 入口与目录Skills 这个概念虽然火但每个工具的落地方式还是有一些差异。我把最近实测的几个主流工具做了个横向汇总工具入口文件推荐存放目录我实测的体验Claude CodeSKILL.md.claude/skills/生态最丰富社区大量现成 skills 可下载Codex CLISKILL.md~/.codex/skills/与 Python/数据分析场景贴合亲和力强OpenCodeSKILL.md.opencode/skills/开源方案配置自由度高Cursor内置 Skills 管理全局或项目级前端日常使用顺手可视化界面友好Claude Code 在 skills 方面起步早官方文档给出了一套相对完整的格式规范所以社区里流传的大量 skills 推荐基本都是围绕它来写的。Codex CLI 推出 Skills 功能之后我第一感受是它对分析类任务非常友好可能和 OpenAI 在代码理解方面的底子有关。OpenCode 是一个开源项目它的自由度最大但相应的你要自己踩的坑也多。Cursor 则把 Skills 做成了内置功能前端开发者最关心的图片还原设计稿这类能力在 Cursor 里调用门槛很低。5.2 该选哪个没有最好只有最合适我给不了下载一个万能 skills 包这种建议因为选择哪个工具完全取决于你的具体场景。如果你日常用的是 Claude Code那么直接拥抱它的生态就好。社区里已经有人做了数学建模 skills、测试用例 skills、结构图 skills 等等大多都遵循同一套格式下载之后放到 .claude/skills 目录即可。如果你团队统一在用 OpenCode 这类开源工具那 Skills 的格式兼容性就要优先考虑。我的经验是尽量把 SKILL.md 写得通用一些不要绑定某个工具特有的配置项这样未来换工具时迁移成本最低。如果你主要写前端Cursor 内置能力的体验确实顺畅。不过我在实际对比中发现Cursor 对多模态输入的 UI 设计稿分析不如直接把图片路径交给脚本去跑来得准确这可能是因为内置能力更侧重自然语言描述而自定义脚本在图像处理上更可控。5.3 跨工具迁移的一点经验因为工作原因我经常要在不同工具之间切换所以对 Skills 的可迁移性特别敏感。我的建议是保持最小公共格式。核心文件只依赖 SKILL.md 加 scripts 目录不要使用某个工具特有的 frontmatter 字段不要在工作目录之外的地方硬编码绝对路径。这样做出来的 Skill基本在任何一个支持该格式的工具里都能跑。我见过一些人下载了某个工具的专属 skills 包换一个工具用就各种报错大多是写了硬编码路径或者依赖了特定工具的环境变量。遇到这种情况打开 SKILL.md 检查一下把路径相关的内容改成相对路径把特殊字段删掉往往就能救回来。6. 我踩过的一些坑路径、编码、乱触发和安全边界6.1 相对路径陷阱脚本里一切路径都要考虑工作目录这是我踩得最频繁的坑。Skills 里的脚本如果用了相对路径比如open(output/result.txt, w)Agent 在不同工作目录下运行时这个路径的解析结果完全不一样。有时候它会写进项目根目录有时候会写进 skill 目录你根本不知道结果去哪了。我的处理方式很简单在 SKILL.md 的输出规范里强制规定输出文件的根目录以当前工作目录为基准同时在脚本里通过os.getcwd()显式拼接路径而不是用默认相对路径。这样一来不管 Agent 在哪里运行行为都是可预期的。6.2 编码问题中文环境下的 UTF-8 之痛做中文相关内容时编码问题几乎一定会碰到。脚本输出的 JSON 如果没指定ensure_asciiFalse中文就会变成一堆\uXXXX转义符Agent 读取时会产生误解反过来SKILL.md 本身如果用 GBK 编辑器保存Agent 读到的乱码会让整个技能失效。我现在固定两套规范所有文本文件统一 UTF-8 编码所有 Python 脚本在打开文件时显式传encodingutf-8。这能省掉一大批后期排查的麻烦。6.3 描述写得太宽Agent 就乱触发前面已经提过乱触发问题这里再展开一下危害。我早期给一个代码审查的 skill 写描述时只写了分析代码质量结果用户在问这段代码怎么优化时Agent 加载了这个 skill却用审查模板回答给出的建议非常怪异。解决方法是把 description 写成仅当用户明确要求代码审查例如提到 review、code review、审查意见时使用代码写法和语法咨询不属于本技能范围。这种把正例和反例都写清楚的做法比单纯加形容词有效得多。6.4 依赖没有随包走换台机器就挂如果你在 scripts 里用了第三方库一定要在 requirements.txt 里写清楚。很多公开下载的 skills 包并没有包含依赖说明下载之后一跑就报ModuleNotFoundError体验非常差。我习惯在 SKILL.md 的失败处理里也加一条如果出现 ModuleNotFoundError先查看 scripts/requirements.txt 并安装缺失依赖。这样 Agent 遇到依赖问题时不会傻眼而是自己尝试解决。6.5 安全边界来路不明的 skills 不要乱跑Skills 里的脚本是直接以当前用户权限执行的也就是说它拥有你机器上的文件读写和网络访问能力。如果从网上随意下载一个来路不明的 skills 包里面的恶意脚本完全可以读取你的 SSH 密钥、向外部服务器发送数据。这不是危言耸听。我强烈建议任何第三方下载的 Skills都要先打开目录里的所有脚本通读一遍确认没有可疑操作再使用。判断可疑操作有几个简单标准有没有主动删除文件的逻辑、有没有把本地文件内容通过网络发出的代码、有没有尝试读取敏感路径如.ssh、.aws。6.6 幂等性同一个 skill 别跑一次一个样最后一个坑是幂等性。早期的 skill 执行逻辑写得很随意Agent 第一次跑一种结果第二次跑另一种结果完全不可控。后来我在写 SKILL.md 时会刻意强调重复执行时保持结果一致。具体做法是输入参数尽量明确输出路径固定步骤顺序固定。如果某个步骤可能产生随机性比如搜索排序变化我会要求 Agent 将中间结果缓存到本地第二次执行时优先使用缓存。这样即使技能被反复调用产出的结果也具备可对比性。我在大量使用和开发这些技能包之后最深的体感是Skills 不是玄学也不是什么复杂框架它就是把教 AI 做一件事的过程标准化了。比起每次在对话里长篇大论地描述期望你更需要做的只是把一套流程写成文档、配上脚本然后把它交给 Agent 反复使用。与其花时间找各种 skills 推荐不如从一个你真正高频重复的任务开始亲手做一个自己的 skill——那个过程会让你对整个机制的理解彻底上一个台阶。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →