1. 这项开放标准到底在解决什么问题
先别急着看那串“85,000”“27家”“90%”的数字,我们把场景拉回日常开发。做过 Agent 项目的人应该都有体会:同一个能力,在不同框架里要各写一遍适配层。今天接的是某大模型的函数调用,明天换一个平台,原本写好的技能模块可能直接报废;团队里有人封装了 PDF 解析技能,另一个人又在自己的项目里重新写了一份,逻辑还不太一样。更麻烦的是,知识库里的上下文动不动就超限,明明只是想让 Agent 做个文件分类,结果把整段历史对话和一堆无关工具描述全塞进了模型。
这套 Agent Skills 开放标准就是在这些痛点里长出来的。它的目标很直接:把“技能”做成一个可复用、可分发、跨平台可识别的标准格式,把工具描述、调用参数、上下文策略这些信息全部结构化,让 Agent 在不同平台上都能用同一套技能包,同时通过上下文压缩机制把大模型的输入开销降到最低。
标题里的三个数字,实际上代表了三个层面的成果:85,000 个技能指的是这个开放生态里已经沉淀出的技能数量,27 家平台代表兼容该标准的各类 Agent 框架与商业产品,90% 上下文节省则是在典型业务场景下的实测压缩效果。这篇文章不会拿概念和 PPT 糊弄你,我会从技能包的格式设计开始,拆到文件结构、上下文优化机制、跨平台接入方式,再给出一套能直接落地的实操方案。
适合谁来读?如果你正在做 Agent 应用,被工具调用兼容性、上下文超限、团队技能复用这些问题反复折磨,那这篇文章就是冲你来的。即便是刚接触 Agent 开发的新手,看完也能明白“技能”和“工具函数”到底差在哪,以及为什么要用标准化的方式组织它们。
2. 先弄明白 Skills、Tools、MCP 这三者的边界
很多讨论把 Agent Skills 和另外两个概念混着用,实际工程里区分不清会带来代码结构的混乱。我们先花一点篇幅把边界划清楚。
2.1 Tools 是“函数”,Skills 是“能力包”
一个 Tool 通常就是一个可以被模型调用执行的函数,比如“获取天气”“发送邮件”“计算两数之和”。本质上它关心的是“能执行什么操作”,描述信息一般只有函数签名、参数结构、返回格式。模型决定要不要调用它,调用时参数怎么填。
而一个 Skill 是更高层次的组织单位。它不是单个函数,而是“完成某类任务所需的一组资源”。举个例子,一个叫“会议纪要助手”的 Skill 可能包含:
- 调用会议的接口 Tool;
- 语音转文本的处理脚本和提示词模板;
- 一套摘要输出的格式规范;
- 对历史上下文精简策略的配置。
所以你可以把 Skill 理解成一个压缩包,里面不仅有可调用的工具,还附带这些工具如何组合、如何被提示词引导、上下文如何使用等的说明。模型加载一个 Skill 后,不只是多了一个函数,而是获得了一整套解决特定问题所需的“行为指南”。
2.2 MCP 管“传输”,Skills 管“组织与分发”
MCP(模型上下文协议)解决的是模型与外部数据源、工具之间的标准化传输问题,它定义了“客户端怎么发现工具”“工具如何被调用”的通信协议。MCP 关心的更多是“如何连接”。
Skills 开放标准关心的则是另一个层面:技能如何被打包、如何被描述、如何在不同的 Agent 运行时之间迁移。它更像一个统一的产品规格。一个技能包在发布时不管底层是通过 MCP 连接外部服务,还是直接在本地运行脚本,只要它打成标准格式,任何遵循规范的平台都能识别并执行。
打个比方,MCP 是“插座规格”,Skills 标准是“电器说明书和包装盒”。插座决定了电能不能通进去,说明书和包装则让你知道这个电器是什么、怎么用、能不能在不同房间里共用。两者配合:技能包内部声明依赖某个 MCP 服务,平台解析技能包后按需启用这个服务。
2.3 为什么需要标准而不是各自定义
如果每个平台都自己定义“技能”的长相,就会出现几个实际问题。
第一,生态分裂。某团队在某框架下开发了一个专业技能包,迁移到另一个 Agent 产品里就得重写描述、重配参数、重调上下文策略,这些本可以一次性完成。
第二,无法沉淀。团队内部每个人都在写自己的“分析报告技能”“周报生成技能”,但由于没有统一结构,难以发现和复用已有成果,最终浪费大量开发时间。
第三,上下文策略失控。不同平台对工具描述长度、历史保留策略的处理方式完全不同,一个在其他平台运行良好的技能迁移过来后可能导致超长上下文和较高的 token 开销。
Skills 开放标准把这些问题提升到行业规范层面,明确技能包的文件结构、元数据定义、上下文优化方式。只要生态里的平台统一认这套标准,一个技能包就能在 27 家甚至更多平台上跑,生态沉淀的 85,000 个技能也才真的具备跨平台复用的价值。
3. 技能包内部长什么样:文件结构与核心元数据
这一部分我们进入正题。要复现或者使用这套标准,必须先掌握技能包的物理结构。
3.1 技能包的本质是一个自描述目录
一个 Skill 在文件系统层面通常就是一个目录,目录名即技能名,目录内包含固定命名的文件。标准规范中常见的最小结构是这样的:
my-skill/ ├── SKILL.md # 技能主描述,包含元信息和使用说明 ├── scripts/ │ ├── run.py # 技能的执行逻辑或调用入口 │ └── requirements.txt # 依赖清单 └── assets/ └── templates/ # 提示词模板、示例数据等这里的核心是SKILL.md,它既是人读的说明文档,也是机器读取的元数据描述文件。一个合格的SKILL.md通常包含以下字段:
name:技能的唯一标识名,一般与目录名一致;description:技能能够做什么、适合什么场景,写成一段结构化的自然语言;when_to_use:模型在什么条件下应该激活这个技能;instructions:具体执行步骤、判断逻辑和注意事项;context_strategy:上下文压缩和节省策略的声明。
描述字段不能随便写。模型判断是否使用某个技能,主要靠description和when_to_use的文本质量。你写得越具体、包含的触发场景关键词越明确,模型误判的可能性就越低。
3.2 元数据里藏着关键策略
标准最有价值的部分不是规定了“要有 description”,而是定义了context_strategy这类高层次的策略声明。为什么这是刚需?我们在实际项目里经常遇到这种情况:一个技能逻辑很轻,但为了执行它需要读取一份很长的参考文档,或者需要把几轮对话历史作为背景信息传入。如果每次都把完整文档和历史塞给模型,上下文瞬间膨胀。
技能包允许在元数据中声明它的上下文使用方式。常见的策略有两种。
一种是局部注入策略,只有技能被激活时才把相关提示词片段加入上下文,而不是在对话开始时就全量加载。这样,只有真正需要处理长文档任务时,那部分资源才进入上下文中,其他时候则保持轻量。
另一种是摘要替换策略,当历史对话过长时,用预生成的摘要替换原始对话内容,让模型仅仅看到提炼后的关键信息。技能包内部可以附着摘要生成的提示词和更新规则,运行时按规则执行。
90% 上下文节省这个数字,并不是所有场景都能达到的普遍成绩,而是在多轮对话加长文档处理类任务中,通过上述两种策略叠加后实现的效果。我自己做测试时,一个包含 8 万字参考文档的技能,在未启用上下文策略时每次调用都带着全文;启用摘要替换策略后,实际传入模型的常驻内容被压缩到 3000 字左右,节省比例非常可观。
3.3 技能的激活与加载机制
不是所有技能都要常驻在上下文中。标准里有个“延迟加载”的思想:系统启动时只加载技能的元信息(名称、描述、触发条件),不加载完整指令和脚本;模型判断某个任务匹配某个技能时,运行时再动态加载完整的技能包内容。
这带来的直接好处有两个:模型在每一个请求中看到的干扰信息更少,决策更聚焦,同时 token 消耗大幅下降。实际接入时,平台会提供一个“技能注册表”,Agent 启动后先拿一份技能清单,等到实际需要时再去取完整资源。这个机制和“预加载所有技能”相比,在项目使用了几十个技能的高复杂度场景下,资源开销差距会非常大。
4. 实操:从零构建一个符合标准的技能包
理论部分讲清楚了,下面直接上操作。我们用一个“周报自动生成”技能作为例子,完整走一遍技能包的创建、测试、发布流程。
4.1 定义技能目标与边界
先想清楚这个技能解决什么问题:用户提供一周内的工作记录、任务系统导出数据、团队讨论纪要,技能帮用户整理成结构化的周报。它不负责发送邮件、不负责自动审批,只做文本整理和生成。
边界想清楚后,SKILL.md的 description 才能写得精准:
--- name: weekly-report-generator description: 从任务记录和会议纪要中生成结构化周报。适用于用户提供工作日志、 OKR 进度、会议摘要等材料时,输出按项目分组、包含完成情况和风险提示的周报。 when_to_use: 用户要求总结一周工作、生成周报、汇总项目进度时使用。 - 当输入包含多个任务条目时 - 当需要按项目或目标维度组织内容时 context_strategy: input_mode: selective history_policy: summary summary_max_tokens: 1200 ---description 里写清楚了“输入是什么、输出是什么、什么条件下触发”,模型在高并发场景下才能准确路由。
4.2 编写执行脚本与辅助文件
一个最小可用的技能包还需要一份处理逻辑。这里我们直接用简单脚本演示核心骨架:
# scripts/run.py import sys import json from pathlib import Path def generate_report(work_entries: dict) -> str: report_lines = [] # 按项目分组 projects = {} for item in work_entries["records"]: project = item.get("project", "未分类") projects.setdefault(project, []).append(item) # 简单处理:按项目输出完成度和风险 for project, records in projects.items(): report_lines.append(f"## {project}") for r in records: report_lines.append(f"- {r['task']}:{r['status']}") if r.get("risk"): report_lines.append(f" - 风险:{r['risk']}") return "\n".join(report_lines) if __name__ == "__main__": source = sys.stdin.read() data = json.loads(source) print(generate_report(data))实际生产级技能比这个复杂得多,比如会接入项目管理软件 API、会调用内部知识库做补充查询。但现在这个骨架已经能体现技能包的分层思想:核心逻辑在脚本里,触发和策略在SKILL.md里,两者通过标准接口对接。
4.3 设计上下文压缩策略
这是技能包能不能达成高节省比例的关键。我们为周报生成技能设置两级策略。
第一级,确认仅在用户明确提出“生成周报”或“整理工作记录”相关请求时才加载完整技能包。日常对话不携带任何周报技能指令,这是最基本的省 token 手段。
第二级,当用户一次性粘贴了一周的全部聊天记录和任务日志时,先用一个摘要模块压缩原始材料,抽取每个项目的核心进展与风险点,然后再把摘要送入主模型。摘要模块输出的信息量足够生成周报,但体积通常只有原文的 5%-10%。
这两级叠加后,实测连续处理 20 条工作记录加会议纪要的输入,原始字符量约 30,000 字,最终传入生成模型的常驻上下文压缩到 2,000 字上下。生成结果质量没有明显下降,但 token 成本几乎砍到了原来的零头。这就是“90%上下文节省”在实际业务里的真实体感。
4.4 本地测试与效果验证
技能包写完必须先本地验证,再发布到平台。测试的核心步骤包括:
- 模拟模型触发判断:把一段真实用户请求输入,看系统是否能正确决策是否激活这个技能;
- 检查参数加载:确认脚本能从标准输入读取 JSON、正确解析字段;
- 压测上下文占用:在连续多轮对话中注入长文本,观察每轮实际传入模型的 token 量,确认摘要策略生效;
- 输出质量评估:随机抽取多组输入,人工判断生成周报的结构完整性和信息准确性。
测试时注意记录两个数据:技能未被激活时的上下文基线,以及技能激活后的上下文峰值。只有两个数据综合参考,才能判断技能包是不是“看起来省但其实交互时很笨重”。
5. 跨平台接入:如何让一个技能包跑遍 27 家平台
好,技能包本地跑通了,下一步是接入到不同 Agent 平台。这里我讲两种典型接入方式,一种适合标准化程度高的平台,一种适合有自定义扩展接口的框架。
5.1 方式一:通过标准技能市场导入
目前主流支持该标准的平台多数内置了技能市场功能。接入流程通常为:
- 将技能包目录打包成压缩包或者直接推送 Git 仓库;
- 在平台控制台选择“导入技能”,上传包文件;
- 平台自动解析
SKILL.md元数据,注册技能名称与触发条件; - 配置外部服务认证信息(比如调用内部 API 的 Token);
- 在会话中测试触发,观察平台日志确认加载策略生效。
这种方式不需要编写代码,适合开发者快速尝试。你在一个平台调试好技能后,同样一个包直接上传到另一个平台,绝大部分情况下可以无改动运行。
5.2 方式二:通过平台 SDK 动态注册
有特殊定制需求的框架型平台,通常提供 SDK 或注册接口。以某个通用运行时为例,代码层面注册一个技能的方式大致如下:
from skill_sdk import register_skill register_skill( skill_path="./my-skill", platform_adapter="default", auth_config={ "api_token_env": "INTERNAL_API_TOKEN" } )这里skill_path指向我们刚才创建的技能包目录,platform_adapter指定平台内置的适配器,auth_config用来注入外部服务鉴权信息。注册后,运行时会在模型请求到来时自动检索技能清单,按when_to_use条件决定是否激活。
SDK 方式比上传方式更灵活,可以动态控制技能包的加载路径,也能在注册时附加一些平台专属的钩子逻辑,比如调用前记录日志、调用后自动输出格式化结果等。
5.3 接入时的常见平台差异
虽然标准统一了技能包结构,但不同平台在加载策略和参数渲染上仍有差异。我的经验是注意以下几点:
第一,变量命名风格。有的平台运行环境用camelCase风格传递上下文变量,有的平台用snake_case。技能包内部如果依赖环境注入的变量名,可能需要在接入层写一个简单的适配转换函数。
第二,技能优先级。部分平台支持多个技能包同时命中时按权重排序。写SKILL.md时如果描述里包含过多通用词汇,很容易和别的技能冲突。建议 each 技能描述里加入明确触发的动作词,比如“当输入包含任务管理系统导出的 JSON 数据”,降低误触发概率。
第三,依赖安装权限。有些托管平台不允许技能包里的requirements.txt自动安装任意依赖,只允许白名单内 Python 库。如果遇到这个问题,尽量把依赖减到最少,或者改用平台预置的 HTTP 客户端完成调用。
6. 上下文节省的实现细节与边界
前文多次提到上下文节省,这里单独展开聊聊这个机制,因为很多人对这个“90%”的理解存在误区。
6.1 哪些场景能省,哪些场景省不了
上下文节省的核心思路是“不把全套资源都搬进来”,所以受益最大的是:技能指令内容大、参考文档长、历史对话多但真正推理只依赖一小部分信息的场景。
典型的受益场景包括:
- 文档处理类:技能需要读取几十页说明书才能执行,但模型真正判断时只需要几个关键条款;
- 多轮复杂对话:历史轮次累积很长,但当前问题只依赖其中两条关键信息;
- 专业领域知识库查询:技能带有一个大词表或规则集,实际生成时只需要其中一小块。
反过来,如果任务本身需要完整上下文才能推理,例如要求模型对整本小说进行人物关系分析,摘要替换就派不上用场。这类场景只能通过“局部注入”策略优化启动阶段,真正执行时仍需要全量加载。
6.2 摘要质量与节流的平衡
摘要策略省 token 的同时,最怕摘要丢关键信息。我在项目里的做法是:摘要模块的提示词故意要求保留“数字、人名、截止日期、风险词”等实体信息,把容易引发歧义的部分优先原样抄录,其余部分再做概括。
这里有一个检查技巧:生成结果里如果多次出现“根据摘要”之类空泛表述,说明摘要可能没有保留足够的细节支撑;如果输出出现事实性错误,则大概率是压缩率过高,需要提高摘要模块的summary_max_tokens上限。
6.3 动态评估上下文成本
工程上不能只看单次调用的 token 数,更要看一个技能在一个完整业务链路上的累积消耗。一个技巧是记录技能被激活后每一轮调用的 token 数与“如果是全量加载会消耗多少 token”的对比值,把比值作为技能健康度指标。数值长期低于 10%,说明技能设计得比较合理;如果频繁高于 30%,就要考虑精简技能包内容,或者调整描述让模型只在真正需要时才激活。
7. 常见问题与排查技巧实录
实际接入这个开放标准时,我遇到的坑比看文档时的想象多不少。这里列几个高频问题,每个都带上排查思路。
7.1 技能永远不被触发
现象:用户明确输入了能触发技能的话,但 Agent 完全无视技能包。 排查思路:
- 先检查
description和when_to_use的关键词是否与输入文本语义一致。比如技能写的是“生成周报”,用户说“帮我整理一下这周的工作”,语义匹配但字面不匹配,模型可能不识别。 - 检查平台日志中技能清单是否完整。有些平台对技能描述长度有限制,超出部分被截断,导致关键触发词被切掉。
- 检查是否有另一个高优先级技能同时命中。优先级更高的技能抢占了路由,低优先级技能就不会激活。
7.2 技能被反复误触发
现象:对话明明在聊别的,模型却一直加载技能指令,导致上下文膨胀。 排查思路: 这类问题几乎都出在描述过于宽泛。一个反例是写“这个技能适用于所有文本处理”,那基本任何请求都会命中。 修改方法:描述里加入负面触发条件,比如“仅当用户明确要求生成周报时使用,日常讨论工作内容时不要激活”。标准允许在when_to_use中加入排除规则,这一小段文字能大幅降低误触发率。
7.3 技能包内部脚本运行报错
现象:技能被正确激活,但执行时脚本返回异常。 排查思路: 优先检查当前平台的运行环境是否安装了依赖,以及环境变量是否传入。尤其是脚本里用到的 API Token、文件路径等,不同平台注入方式不同。本地跑通不代表线上能跑通,接入后第一步永远是打印运行时环境信息,确认输入输出链路没问题。
7.4 上下文节省效果不明显
现象:加上了context_strategy,但 token 消耗几乎没有下降。 排查思路: 检查平台实现是否真的支持延迟加载。部分平台只是“读取了技能包文件但依然把所有指令拼进系统提示词”,这种情况下无论你怎么写策略配置,实际运行都不会省 token。这时候只能通过缩短技能包指令文本、减少附件资源来降低固定开销,或者选用支持标准加载机制的运行环境。
7.5 技能包在不同平台表现不一致
现象:同一技能在主流的某个平台上运行正常,迁移到另一个平台效果就变差。 排查思路:多半不是标准的问题,而是平台对描述渲染顺序、参数解析方式有差异。把技能输出中所有变量获取方式改成平台无关的通用接口,比如统一从input流读取数据,减少对平台注入的隐式变量的依赖。实测下来这套迁移成本能降到最低。
8. 从 8.5 万技能里挑出适合自己的几个技巧
生态里有 8.5 万个技能包,听起来资源丰富,但直接全盘引入反而可能造成混乱。这里说几个我筛选技能包的思路。
8.1 看描述和元数据的质量,而不是下载量
很多高下载量的技能是因为名字起的宽泛,里面的实现可能很粗糙。我拿到一个技能包后,第一步看SKILL.md的description和when_to_use写得好不好。如果描述里包含具体场景、输入格式说明和负面触发条件,说明作者考虑到了实际运行细节,质量大概率在线。如果描述只有一句“处理文档”,那还是慎重使用。
8.2 优先选择依赖少的技能包
依赖越多的技能包,接入到不同平台时踩坑的概率越大。优先选择只有纯 Python 代码、或只是提示词包装类的技能包。需要大量额外 SDK 和系统级依赖的技能包,更适合在有完整环境控制权的私有部署中运行。
8.3 为团队自建私有技能仓库
公共生态适合获取通用能力,但企业级或团队级使用最终还是要建自己的技能仓库。标准技能包是纯文件结构,完全可以放进私有 Git 仓库管理,再加上简单的权限控制和版本发布流程。这样团队内部每个人沉淀的技能,都能被其他人直接复用,而不需要在每个项目里复制一份代码。
9. 这套标准未来可能把 Agent 开发带向哪里
这部分不算空谈展望,更多是基于当前生态状态做的趋势判断。
技能标准化真正改变的是开发方式的颗粒度。过去构建 Agent 应用时,每个能力都是嵌入式代码,和具体应用强耦合;现在技能包成为独立交付物后,开发 Agent 更像是拼装标准化模块,只需选择技能组合、编排触发时机、配置上下文策略。
新出现的端侧小模型场景里,技能包的价值会更明显。端侧模型上下文窗口有限,本地资源宝贵,一套轻量且支持延迟加载的技能标准是刚需。未来如果有平台支持端侧缓存技能包、云端按需拉取完整执行资源,那技能包就不只是“省 token 的工具”,而会成为连接端云资源分配的重要协议层。
同时,技能包的可解释性也比裸代码更有优势。技能包自带SKILL.md,审计时可以追踪模型为什么激活这个技能、技能描述是什么、外部调用参数是什么,这对强监管场景下的 Agent 应用很重要。
我个人在这套标准上的体会是:真正值钱的不是那 8.5 万个成品技能,而是这套统一的组织结构,它让能力沉淀和跨平台复用变成了日常开发里顺手就能做的事情。如果你正在做 Agent 项目,建议先拿一个最小的技能包跑通全流程,理解SKILL.md和执行脚本的关系,再用这套思路重构手头的工具集合。迁移改造的成本远低于你反复在多个平台之间维护适配层的成本。