在 AI Agent 的世界里,大语言模型是大脑,而 Skill 是双手。没有 Skill 的 Agent 只能”纸上谈兵”,而拥有丰富 Skill 的 Agent 才能真正改变世界。今天,我们来深入探讨 Agent Skill——智能体的核心执行能力。

什么是 Agent Skill?

Agent Skill(智能体技能)是指 AI Agent 能够执行的特定能力或功能。它是连接 LLM(大语言模型)与现实世界的桥梁,让智能体从”会说”变成”会做”。

简单来说:

Skill = 让 Agent 真正能够完成任务的能力单元

一个 Skill 通常包含三个核心要素:

  • 输入(Input):技能执行所需的参数
  • 逻辑(Logic):技能的具体实现
  • 输出(Output):技能执行后的返回结果

Skill 的核心结构:Reference 与 Script

一个完整的 Agent Skill 不仅仅是一个函数定义,它还包含两个关键组成部分:ReferenceScript。这两者共同构成了技能的第三层结构,使 Agent 能够处理更复杂的任务。

📚 Reference(参考)

Reference 允许技能引用同一目录下的其他文件,如脚本、配置文件或参考文档。智能体仅在需要时才加载这些资源,从而优化资源管理。

Reference 解决的核心问题是:让技能携带超出上下文限制的知识

1
2
3
4
5
6
7
8
9
skills/
├── data_analysis/
│ ├── skill.yaml # 技能定义
│ ├── references/
│ │ ├── pandas_guide.md # Pandas 使用指南
│ │ ├── sql_syntax.md # SQL 语法参考
│ │ └── chart_types.json # 图表类型配置
│ └── scripts/
│ └── analyze.py

在技能定义中引用这些资源:

1
2
3
4
5
6
7
8
9
10
name: data_analysis
description: 分析数据并生成可视化报告

references:
- path: references/pandas_guide.md
description: Pandas 数据处理指南,包含常用操作示例
- path: references/sql_syntax.md
description: SQL 查询语法参考
- path: references/chart_types.json
description: 支持的图表类型及其配置参数

Reference 的优势:

  • 按需加载:只有当 Agent 需要时才读取,节省 token
  • 知识外置:复杂的领域知识可以独立维护和更新
  • 上下文扩展:突破 LLM 上下文长度限制

📜 Script(脚本)

Script 是技能目录中的可执行代码文件,用于执行特定的任务或操作。这些脚本在需要时由智能体调用,以实现确定性的执行,避免大语言模型生成过程中的不确定性和幻觉问题。

Script 解决的核心问题是:用代码保证执行的准确性和可靠性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# scripts/analyze.py
import pandas as pd
import json

def analyze_csv(file_path: str, analysis_type: str) -> dict:
"""
对 CSV 文件进行数据分析

Args:
file_path: CSV 文件路径
analysis_type: 分析类型 (summary/correlation/distribution)

Returns:
分析结果字典
"""
df = pd.read_csv(file_path)

if analysis_type == "summary":
return {
"rows": len(df),
"columns": list(df.columns),
"stats": df.describe().to_dict()
}
elif analysis_type == "correlation":
return {
"correlation_matrix": df.corr().to_dict()
}
elif analysis_type == "distribution":
return {
col: df[col].value_counts().to_dict()
for col in df.select_dtypes(include=['object']).columns
}

return {"error": "Unknown analysis type"}

在技能定义中声明脚本:

1
2
3
4
5
6
7
name: data_analysis
description: 分析数据并生成可视化报告

scripts:
- path: scripts/analyze.py
function: analyze_csv
description: 执行 CSV 数据分析,支持摘要、相关性和分布分析

Script 的优势:

  • 确定性执行:复杂计算由代码完成,结果准确可靠
  • 避免幻觉:数据处理、格式解析等任务不依赖 LLM 生成
  • 性能优化:计算密集型任务用代码执行更高效
  • 可测试性:脚本可以独立进行单元测试

Reference + Script 的协作

Reference 和 Script 结合使用,能让 Agent 处理非常复杂的任务:

1
2
3
4
5
6
7
用户请求 → Agent 理解意图

加载相关 Reference(获取领域知识)

调用 Script(执行确定性操作)

LLM 整合结果 → 返回给用户

例如,一个”财务报表分析”技能:

  1. Reference 提供:会计准则、财务指标定义、行业基准数据
  2. Script 执行:解析 Excel、计算财务比率、生成图表
  3. LLM 负责:理解用户问题、解读分析结果、生成自然语言报告

这种分工让每个组件发挥所长,构建出真正可靠的智能体技能。

Skill vs Tool:有什么区别?

在 Agent 开发中,SkillTool 这两个概念经常被混用,但它们有着微妙的区别:

维度 Tool(工具) Skill(技能)
粒度 单一功能 可组合多个 Tool
抽象层次 底层执行 高层能力
复杂度 通常较简单 可包含复杂逻辑
示例 发送 HTTP 请求 完成一次网络搜索并总结

你可以这样理解:Tool 是原子操作,Skill 是能力组合

Skill 的分类

根据功能和应用场景,Agent Skill 可以分为以下几类:

🔍 信息获取类

负责从外部世界获取信息:

  • 网络搜索:Google、Bing、DuckDuckGo 搜索
  • 知识检索:RAG、向量数据库查询
  • API 调用:天气、股票、新闻等 API
  • 网页爬取:提取网页内容和结构化数据

📝 内容生成类

负责创建各种形式的内容:

  • 文本生成:文章、邮件、报告
  • 代码生成:各种编程语言的代码
  • 图像生成:调用 DALL-E、Midjourney 等
  • 文档生成:PDF、PPT、Excel

⚡ 操作执行类

负责执行具体的操作:

  • 文件操作:读取、写入、删除文件
  • 代码执行:运行 Python、JavaScript 代码
  • 数据库操作:CRUD 操作
  • 系统命令:执行 Shell 命令

🔗 集成交互类

负责与外部系统交互:

  • 邮件发送:SMTP、Gmail API
  • 消息推送:Slack、Discord、微信
  • 日历管理:Google Calendar、Outlook
  • 项目管理:Jira、Notion、Trello

🧠 认知推理类

负责复杂的思维和推理:

  • 数学计算:符号计算、数值计算
  • 逻辑推理:规则引擎、约束求解
  • 规划决策:任务分解、路径规划

设计优秀 Skill 的原则

设计一个好用的 Skill,需要遵循以下原则:

1. 单一职责原则

每个 Skill 应该只做一件事,并把它做好:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ❌ 不好的设计:一个 Skill 做太多事
def do_everything(query):
# 搜索 + 分析 + 总结 + 发送邮件
...

# ✅ 好的设计:拆分成多个 Skill
def search_web(query: str) -> list:
"""搜索网页"""
...

def analyze_content(content: str) -> dict:
"""分析内容"""
...

def summarize(text: str) -> str:
"""生成摘要"""
...

2. 清晰的接口定义

Skill 的输入输出要清晰明确,便于 LLM 理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from typing import TypedDict

class SearchResult(TypedDict):
title: str
url: str
snippet: str

def web_search(
query: str,
num_results: int = 10,
language: str = "zh-CN"
) -> list[SearchResult]:
"""
搜索网页内容

Args:
query: 搜索关键词
num_results: 返回结果数量,默认10条
language: 搜索语言,默认中文

Returns:
搜索结果列表,包含标题、链接和摘要
"""
...

3. 优雅的错误处理

Skill 应该能够优雅地处理各种异常情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class SkillResult:
success: bool
data: any
error: str | None

def safe_api_call(url: str) -> SkillResult:
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
return SkillResult(success=True, data=response.json(), error=None)
except requests.Timeout:
return SkillResult(success=False, data=None, error="请求超时,请稍后重试")
except requests.HTTPError as e:
return SkillResult(success=False, data=None, error=f"HTTP错误: {e}")
except Exception as e:
return SkillResult(success=False, data=None, error=f"未知错误: {e}")

4. 可观测性

Skill 的执行过程应该可追踪、可调试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import logging
from functools import wraps
import time

def with_logging(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
logging.info(f"Skill [{func.__name__}] 开始执行,参数: {args}, {kwargs}")

try:
result = func(*args, **kwargs)
elapsed = time.time() - start
logging.info(f"Skill [{func.__name__}] 执行成功,耗时: {elapsed:.2f}s")
return result
except Exception as e:
logging.error(f"Skill [{func.__name__}] 执行失败: {e}")
raise

return wrapper

@with_logging
def my_skill(param: str) -> str:
...

实现 Skill 的常见模式

模式一:Function Calling

这是最常见的 Skill 实现方式,通过函数调用让 LLM 使用工具:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from openai import OpenAI

client = OpenAI()

# 定义 Skill
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如:北京、上海"
}
},
"required": ["city"]
}
}
}
]

# 调用
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "北京今天天气怎么样?"}],
tools=tools,
tool_choice="auto"
)

模式二:MCP(Model Context Protocol)

MCP 是一种开放协议,让 Skill 可以跨模型、跨平台使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from mcp import Server, Tool

server = Server("my-skills")

@server.tool()
def calculate(expression: str) -> str:
"""计算数学表达式"""
try:
result = eval(expression)
return f"结果是:{result}"
except:
return "计算出错,请检查表达式"

@server.tool()
def translate(text: str, target_lang: str = "en") -> str:
"""翻译文本"""
# 调用翻译 API
...

# 启动 MCP 服务器
server.run()

模式三:插件系统

构建可扩展的插件架构,动态加载 Skill:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from abc import ABC, abstractmethod
import importlib
import os

class BaseSkill(ABC):
@property
@abstractmethod
def name(self) -> str:
"""技能名称"""
pass

@property
@abstractmethod
def description(self) -> str:
"""技能描述"""
pass

@abstractmethod
def execute(self, **kwargs) -> any:
"""执行技能"""
pass

class SkillRegistry:
def __init__(self):
self.skills: dict[str, BaseSkill] = {}

def register(self, skill: BaseSkill):
self.skills[skill.name] = skill

def load_from_directory(self, path: str):
"""从目录加载所有 Skill"""
for file in os.listdir(path):
if file.endswith("_skill.py"):
module = importlib.import_module(f"skills.{file[:-3]}")
if hasattr(module, "skill"):
self.register(module.skill)

def get(self, name: str) -> BaseSkill:
return self.skills.get(name)

def list_all(self) -> list[dict]:
return [
{"name": s.name, "description": s.description}
for s in self.skills.values()
]

Skill 组合与编排

单个 Skill 的能力是有限的,真正强大的 Agent 需要组合多个 Skill:

顺序执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async def research_and_write(topic: str) -> str:
# 1. 搜索资料
search_results = await web_search(topic)

# 2. 提取内容
contents = await extract_contents(search_results)

# 3. 分析总结
summary = await summarize(contents)

# 4. 生成文章
article = await generate_article(topic, summary)

return article

并行执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import asyncio

async def gather_info(topic: str) -> dict:
# 并行执行多个 Skill
results = await asyncio.gather(
web_search(topic),
search_academic_papers(topic),
search_news(topic),
get_social_trends(topic)
)

return {
"web": results[0],
"academic": results[1],
"news": results[2],
"social": results[3]
}

条件执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async def smart_answer(question: str) -> str:
# 判断问题类型
question_type = await classify_question(question)

if question_type == "factual":
# 事实性问题:搜索知识库
return await search_knowledge_base(question)
elif question_type == "calculation":
# 计算问题:使用计算器
return await calculate(question)
elif question_type == "creative":
# 创意问题:直接生成
return await generate_creative_response(question)
else:
# 默认:综合处理
return await general_answer(question)

构建 Skill 生态

一个成熟的 Agent 平台需要建立完善的 Skill 生态:

🏪 Skill 市场

  • 提供丰富的官方 Skill
  • 支持第三方开发者贡献
  • 完善的审核和评分机制

📦 Skill 包管理

1
2
3
4
5
6
7
8
9
# 安装 Skill
agent-cli skill install weather-skill
agent-cli skill install translator-skill

# 列出已安装的 Skill
agent-cli skill list

# 更新 Skill
agent-cli skill update --all

🔐 安全与权限

1
2
3
4
5
6
7
8
9
10
class SkillPermission:
NETWORK = "network" # 网络访问
FILE_READ = "file:read" # 文件读取
FILE_WRITE = "file:write" # 文件写入
EXECUTE = "execute" # 代码执行

@skill(permissions=[SkillPermission.NETWORK])
def fetch_url(url: str) -> str:
"""需要网络权限的 Skill"""
...

最佳实践

基于实践经验,这里总结几条 Skill 开发的最佳实践:

✅ DO

  • 保持 Skill 小而专注:一个 Skill 只解决一个问题
  • 提供详细的描述:帮助 LLM 正确选择和使用 Skill
  • 设置合理的超时:避免 Skill 执行时间过长
  • 实现幂等性:同样的输入应产生同样的输出
  • 添加使用示例:在文档中提供典型用例

❌ DON’T

  • 不要在 Skill 中硬编码密钥:使用环境变量或密钥管理服务
  • 不要忽略错误处理:所有异常都应该被正确捕获
  • 不要返回过大的数据:限制返回数据的大小
  • 不要阻塞主线程:耗时操作使用异步执行

未来展望

Agent Skill 的发展正在朝着以下方向演进:

🌐 标准化

  • MCP、A2A 等开放协议的普及
  • 跨平台、跨模型的 Skill 复用
  • 统一的 Skill 描述规范

🤖 自动化

  • Agent 自动发现和学习新 Skill
  • 根据任务自动组合 Skill
  • Skill 的自我优化和进化

🔒 安全化

  • 更细粒度的权限控制
  • Skill 执行的沙箱隔离
  • 完善的审计和监控

总结

Agent Skill 是让 AI 智能体从”能说”到”能做”的关键。设计好的 Skill 系统需要:

  1. 清晰的职责划分:每个 Skill 专注做一件事
  2. 标准的接口定义:让 LLM 能正确理解和使用
  3. 健壮的错误处理:优雅应对各种异常
  4. 灵活的组合能力:支持复杂任务的编排

随着 AI Agent 技术的发展,Skill 生态将变得越来越丰富。掌握 Skill 的设计与开发,是构建强大 AI Agent 的必备能力。

现在就开始构建你的第一个 Agent Skill 吧!🚀