Agent Skills介绍
Agent Skills是一种为AI智能体引入可共享专业技能的开发方式,技能 (Skill) 是由指令、脚本和资源组成的模块化功能包,能够扩展智能体的能力。
这些技能存放在特定目录下(每个技能一个文件夹),当 模型 判断某个技能与当前用户请求相关时,便会自动加载相应技能来完成任务,这种触发是模型自主决策的,而非需用户手动指定调用。这种方法有别于传统的MCP服务器,更侧重于通过详细的自然语言指令来引导模型完成任务。
Skills三层渐进式披露
为了高效管理上下文,Agent Skills采用了“渐进式披露”设计理念,信息按需加载,既确保必要时不遗漏细节,又避免一次性将过多内容塞入上下文。
| 层级 | 内容 | 触发条件 | 目的与示例 |
|---|---|---|---|
| 第一层:元数据 | SKILL.md文件开头的YAML信息(名称、描述)。 | 智能体启动时预加载所有技能的元数据。 | 提供使用该技能的线索,让模型对技能用途有初步了解。 |
| 第二层:技能主体 | SKILL.md文件内的详细指令、规则和示例。 | 模型判断任务与技能相关时加载。 | 指导模型如何具体完成任务,包含步骤、约束等。 |
| 第三层:附加文件 | 技能文件夹中的脚本、额外文档等资源。 | 仅当详细指令中引用或任务需要时才加载。 | 提供具体工具,如Python脚本、参考文档。 |
Agent Skills根据 三层结构 可实现动态的上下文管理。无关任务时,仅加载技能元数据,几乎不占用上下文窗口;一旦识别出相关技能,再逐步加载详细内容和工具 ,按需加载机制使技能能够包含海量信息却不怕超出上下文窗口限制,大幅减少了重复prompt 。
Skills vs. MCP对比
| 对比维度 | Agent Skills | MCP |
|---|---|---|
| 本质 | “操作手册” :基于Prompt的指令系统,引导模型完成任务。 | “外部API接口” :标准协议,让AI能直接调用外部工具或服务。 |
| 配置复杂度 | 极简。核心只需一个SKILL.md文件。 | 复杂。需配置服务器、定义工具接口等。 |
| Token效率 | 极高。按需加载,几乎不占用初始上下文。实测安装10个Skills仅占用约2K Token(仅加载用到的) | 较低。工具定义需在启动时载入Prompt。加载MCP服务器就占用多个Token。 |
| 开发效率 | 高。写指令文档即可,适合快速封装领域知识。 | 低。需要编写和调试代码,适合复杂集成。 |
| 最佳适用场景 | 简单或流程化任务:文档分析、代码审查、使用CLI工具等。 | 复杂集成与实时交互:连接数据库、调用第三方API、需要严格认证与数据流的场景。 |
核心结论:两者是互补关系,而非替代,建议优先用Skills解决,只有当任务需要复杂的实时数据集成或操作时,再考虑使用MCP。
Skills详解
技能是一个目录,其中包含一个 SKILL.md 文件,该文件包含组织有序的文件夹,其中包含指令、脚本和资源,这些指令、脚本和资源为代理提供额外的功能。
SKILL.md 文件必须以 YAML Frontmatter 开头,其中包含文件名和描述,该文件在启动时加载到系统提示符中。
你可以通过添加文件将更多上下文信息添加到你的技能中,然后模型可以根据系统提示触发该技能。
技能和上下文窗口
技能会在上下文窗口中通过系统提示符触发。
所示操作顺序:
- 首先,上下文窗口会显示核心系统提示符和每个已安装技能的元数据,以及用户的初始消息;
- 模型 通过调用 Bash 工具来读取 PDF 文件的内容,从而触发 PDF 技能
pdf/SKILL.md; - 模型选择阅读
forms.md与该技能捆绑在一起的文件; - 最后,模型 从 PDF 技能中加载了相关说明后,便开始执行用户的任务。
技能和代码执行
技能还可以包括供 模型 自行执行的代码作为工具。大型语言模型在某些操作更适合传统的代码执行,许多应用程序还需要只有代码才能提供的确定性可靠性。
在示例中,PDF 技能包含一个预先编写的 Python 脚本,该脚本读取 PDF 文件并提取所有表单字段,模型 无需将脚本加载到上下文中即可运行此脚本。代码是确定性的,该工作流程具有一致性和可重复性。
技能还可以包括供 模型 根据任务性质自行决定执行的工具代码。
编写Skills
创建技能很简单,只需创建一个SKILL.md文件夹,其中包含一个 YAML 前置元数据和说明文件即可。您可以参考模板技能作为起点:
---
name: my-skill-name
description: 该技能的清晰描述,说明其功能及使用场景
---
# 我的 skill 名称
[在此处添加模型在激活此技能时应遵循的指令]
## 示例
- 示例用法1
- 示例用法2
## 指南
- 指南1
- 指南2
前置元数据只需要两个字段:
name- 您的技能的唯一标识符(小写,空格用连字符表示)description- 对该技能的作用以及何时使用进行完整描述
Body内容
Markdown 正文包含技能说明。格式没有限制,只需编写有助于Agent有效完成任务的内容即可。
- 分步说明
- 输入和输出示例
- 常见边界情况
Agent会在决定激活技能时加载整个文件,建议将较长的SKILL.md内容拆分成多个引用文件。
目录数据
脚本/
包含Agent可以运行的可执行代码。脚本应:
- 要么是自包含的,要么清楚地记录依赖关系
- 包含有用的错误信息
- 优雅地处理极端情况
支持的常见的语言包括 Python、Bash 和 JavaScript。
参考/
包含Agent需要时可查阅的其他文档:
REFERENCE.md- 详细技术参考FORMS.md- 表单模板或结构化数据格式- 域特定文件(
finance.md,legal.md等)
保持参考文件的简洁性。Agent按需加载这些文件,因此文件越小,对上下文信息的依赖就越少。
资产/
包含静态资源:
- 模板(文档模板、配置模板)、图片(图表、示例)、数据文件(查找表、模式)
渐进式披露
技能应结构化,以便有效利用上下文:
- 元数据(约 100 个标记):所有技能的
name`anddescription`字段在启动时加载。 - 说明(建议使用少于 5000 行):
SKILL.md技能激活时,全身都会加载完毕。 - 资源(按需加载):文件(例如位于
scripts/、references/、assets/)仅在需要时加载。
正文请控制SKILL.md在 500 行以内。详细的参考资料请移至单独的文件中。
文件引用
在技能中引用其他文件时,使用相对于技能根目录的相对路径:
See [the reference guide](references/REFERENCE.md) for details.
Run the extraction script:
scripts/extract.py
文件引用应保持在当前目录下至少一层SKILL.md,避免使用深度嵌套的引用链。
验证
使用skills-ref参考库来验证您的技能:
skills-ref validate ./my-skill
这会检查您的SKILL.mdfrontmatter 是否有效并符合所有命名规则。
Skills实践
注意: 我在本地使用ollama部署qwen3:8b作为模型服务进行skills实践测试。
演示AgentScope框架使用Skills的核心功能:
创建一个智能排序助手Agent,通过ReActAgent集成排序技能,使用OllamaChatModel驱动,包含三个测试场景:1)让代理自我介绍技能,2)数字列表排序测试(如[5,1,3,2]升序排列),3)字符串排序测试(如['banana','apple','cherry']字母倒序)。
Agent会自动读取sort-data技能目录下的SKILL.md文件,按照技能描述执行排序流程,通过execute_python_code调用后端sort.py脚本完成实际的排序操作,实现从用户需求识别到结果呈现的完整智能交互流程。
# -*- coding: utf-8 -*-
"""使用AgentScope调用sort-data技能的示例主入口点。"""
import asyncio
from agentscope.agent import ReActAgent
from agentscope.formatter import OllamaChatFormatter,OpenAIChatFormatter
from agentscope.memory import InMemoryMemory
from agentscope.message import Msg
from agentscope.model import OllamaChatModel, OpenAIChatModel
from agentscope.tool import Toolkit, execute_shell_command, view_text_file, execute_python_code
# 注册修改后的工具
async def main() -> None:
"""ReAct 代理示例的主入口点。"""
toolkit = Toolkit()
# 注册必需的基础工具
toolkit.register_tool_function(execute_shell_command)
toolkit.register_tool_function(execute_python_code)
toolkit.register_tool_function(view_text_file) # 核心:用于让Agent读取SKILL.md文件
# --- 关键步骤:注册你的排序技能 ---
# 将路径指向你的 `sort-data` 技能文件夹
toolkit.register_agent_skill("./skill/sort-data")
# 创建Agent
agent = ReActAgent(
name="排序助手",
sys_prompt="""你是一个专注于数据处理的助手,擅长对列表进行排序。
# 重要说明
- 当用户需要排序时,你必须使用你装备的 `sort-data` 技能。
- 关于排序的所有操作指令,都必须从技能文件中获取,不要自行假设规则。
- 请严格按照技能描述中的步骤执行:先确认数据和要求,然后调用脚本,最后清晰呈现结果。
""",
# ollama本地部署模型调用
# model=OllamaChatModel(
# host="http://localhost:11434",
# model_name="qwen3:8b",
# stream=True,
# enable_thinking=False
# ),
# formatter=OllamaChatFormatter(),
# OpenAI部署模型调用
model=OpenAIChatModel(
api_key="pk-cfc606e3-4edf-4f4d-809e-9935ebcfc2b9",
model_name="deepseek-v3",
stream=True,
client_kwargs={
"timeout": 30.0, # 请求超时
"max_retries": 2, # 最大重试次数
"base_url": "http://ai-api.jdcloud.com/v1", # 默认值,通常不需要显式设置
},
),
formatter=OpenAIChatFormatter(),
toolkit=toolkit,
memory=InMemoryMemory(),
)
print("\033[1;32m代理已启动,技能已装备。\033[0m\n")
# 测试1:让Agent介绍自己的技能(触发元数据加载)
print("\033[1;33m用户: 你有什么技能?\033[0m")
await agent(Msg("user", "你有什么技能?", "user"))
print("\n" + "=" * 50 + "\n")
# 测试2:提出一个排序请求(触发技能主体加载和执行)
print("\033[1;33m用户: 请帮我把 [5, 1, 3, 2] 按从小到大的顺序排列。\033[0m")
response_msg = await agent(Msg("user", "请帮我把 [5, 1, 3, 2] 按从小到大的顺序排列。", "user"))
# 打印模型的原始思考过程(如果模型输出中包含的话)
if hasattr(response_msg, 'content'):
print(f"\033[1;32m助手回复:\033[0m {response_msg.content}")
print("\n" + "=" * 50 + "\n")
# 测试3:一个更复杂的请求(测试技能对流程的理解)
print("\033[1;33m用户: 将 ['banana', 'apple', 'cherry'] 按字母倒序排一下。\033[0m")
response_msg = await agent(Msg("user", "将 ['banana', 'apple', 'cherry'] 按字母倒序排一下。", "user"))
if hasattr(response_msg, 'content'):
print(f"\033[1;32m助手回复:\033[0m {response_msg.content}")
# 运行主程序
if __name__ == "__main__":
asyncio.run(main())
---
name: sort-data
description: 对用户提供的数字列表或字符串列表进行排序,支持升序和降序。
---
# 排序技能
当用户需要排序一个列表时,请激活此技能。
## 工作流程
1. 从用户消息中识别需要排序的列表(例如 `[5, 1, 3]` 或 `["banana", "apple"]`)。
2. 询问用户排序顺序(升序或降序),如果未明确说明。
3. 调用 `scripts/sort.py` 脚本执行排序。
4. 将排序后的结果返回给用户。
## 如何调用脚本
使用以下命令进行排序:
```bash
python scripts/sort.py --data '[5, 1, 3]' --order ascending
### 2. 排序脚本 `skills/sort-data/scripts/sort.py`
#!/usr/bin/env python3
import json
import argparse
import sys
def main():
parser = argparse.ArgumentParser(description='最小排序工具')
parser.add_argument('--data', required=True, help='要排序的列表,JSON格式,例如:'[3, 1, 2]'')
parser.add_argument('--order', choices=['ascending', 'descending'], default='ascending', help='排序顺序')
args = parser.parse_args()
try:
# 1. 解析数据
data = json.loads(args.data)
if not isinstance(data, list):
print("错误:输入必须是列表", file=sys.stderr)
sys.exit(1)
# 2. 执行排序
reverse = (args.order == 'descending')
sorted_data = sorted(data, reverse=reverse)
# 3. 输出结果
print(json.dumps(sorted_data, ensure_ascii=False))
except json.JSONDecodeError:
print(f"错误:无法解析JSON数据 - {args.data}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"排序时发生未知错误:{e}", file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
main()
运行结果
技术集成与实践框架
Skills不仅可以单独使用,也能与智能体框架集成,可以使用阿里达摩院开源的AgentScope框架来承载Skills机制。框架负责模型接入、消息流转和工具调度,而Skills则提供领域专用的知识和操作规范,二者结合能构建出更强大的智能体应用。
技术集成架构模式
Agent Skills 可以以不同的技术架构模式融入现有系统。
| 集成模式 | 架构描述 | 适用场景 | 优点 | 挑战 |
|---|---|---|---|---|
| 框架内嵌式 | Skills 作为智能体框架(如AgentScope,LangChain)的原生功能或插件。 | 从零开始构建 AI 应用,或希望框架统一管理技能生命周期。 | 开发体验好,框架提供开箱即用的技能加载、触发和工具调用。 | 与特定框架绑定,技能生态可能受限于框架的发展。 |
| 网关代理式 | 在智能体前增加一个Skills 网关或编排层。智能体发送请求给网关,由网关负责技能的匹配、加载和上下文组装。 | 已有成熟的智能体系统,希望以非侵入式方式引入技能能力;需要统一管理多模型、多来源技能。 | 解耦性好,对现有智能体改动小;便于实现复杂的技能路由和混合编排策略。 | 增加系统复杂度和延迟;需要额外开发和维护网关服务。 |
| 运行时挂载式 | 将 Skills 的目录通过网络文件系统或卷挂载的方式,直接暴露给运行在容器或虚拟机中的智能体。 | 基于Claude Desktop,Cursor等桌面 AI 工具,或已将技能仓库作为基础设施管理。 | 部署简单,技能更新实时生效,与 AI 工具的原生体验一致。 | 安全性需要仔细控制(如技能脚本的执行权限);难以做细粒度的技能访问控制。 |