第九章:Skills 技能系统深入

Skills是DeepAgents最强大的知识管理机制。本节课深入讲解技能包结构、加载机制、内置技能清单及自定义技能开发。

Skills 是 DeepAgents 中最强大的知识管理机制 — 让 Agent 按需获取专业能力。

9.1 什么是 Skills?

Skills 是可复用的领域知识包,每个技能包含:

  • 指令(SKILL.md)— 告诉 Agent 做什么、怎么做
  • 脚本(可选)— 辅助代码
  • 参考文档(可选)— 额外知识

类比 Web 开发

概念Web 开发类比
SkillNPM 包 — 封装了特定功能
SKILL.mdpackage.json — 元数据 + 说明
渐进式披露代码分割(Code Splitting)
技能目录node_modules — 所有可用技能

9.2 Skills vs Function Call vs MCP

三者的关系是递进和互补的:

flowchart TD
FC["Function Call<br/>工具调用<br/>━━━━━━━━━━━<br/>粒度:单个函数<br/>发现:手动注册"]

MCP["MCP 模型上下文协议<br/>━━━━━━━━━━━<br/>粒度:一组工具+资源+提示词<br/>发现:自动 list_tools"]

SK["Skills 技能系统<br/>━━━━━━━━━━━<br/>粒度:完整工作流<br/>发现:渐进式披露"]

FC -->|标准化+服务化| MCP
MCP -->|领域知识+流程编排| SK

style FC fill:#e1f5fe
style MCP fill:#fff9c4
style SK fill:#e8f5e9

一句话区分

  • Function Call:让 Agent 能”做一件事”(调用一个函数)
  • MCP:让 Agent 能”用一组标准化的工具”(连接一个工具服务)
  • Skills:让 Agent 能”完成一个专业工作流”(领域知识 + 工具组合 + 步骤指引)

9.3 Skills 的渐进式披露机制

这是 Skills 最精巧的设计:

flowchart TD
A["🚀 启动阶段"] --> B["读取每个 SKILL.md 的 frontmatter<br/>(名称 + 描述)"]
B --> C["几十个技能只消耗几百 tokens"]
C --> D["🔍 匹配阶段"]
D --> E["用户提问后,Agent 检查<br/>哪个技能的 description 匹配"]
E --> F["只选择 1-2 个相关技能"]
F --> G["📖 加载阶段"]
G --> H["Agent 读取匹配技能的<br/>完整 SKILL.md 内容"]
H --> I["按需加载,只消耗需要的 tokens"]
I --> J["⚡ 执行阶段"]
J --> K["Agent 按照技能指令<br/>调用工具、访问参考文档"]
K --> L["完整的工作流执行"]

style A fill:#e3f2fd
style D fill:#fff9c4
style G fill:#f3e5f5
style J fill:#e8f5e9

类比 Web 开发

1
2
3
4
就像前端的路由懒加载:
- 首屏只加载路由列表(frontmatter)
- 用户点击某个路由才加载对应 JS(完整 SKILL.md)
- 这样 100 个技能的首页加载时间 ≈ 5 个技能

9.4 创建一个完整的 Skill

目录结构

1
2
3
4
5
6
7
8
skills/
├── sql-expert/
│ ├── SKILL.md # 必须:元数据 + 指令
│ ├── sql_patterns.md # 可选:SQL 模式参考
│ └── query_helper.py # 可选:辅助脚本
└── data-analyst/
├── SKILL.md
└── chart_templates/ # 可选:资源目录

SKILL.md 规范

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
---
name: sql-expert
description: 当用户需要查询数据库、编写SQL、优化查询或分析数据结构时使用此技能。涵盖SQL语法检查、查询优化和数据库Schema理解。
license: MIT
compatibility: 需要数据库访问权限和SQL执行工具
metadata:
author: your-team
version: "2.0"
allowed-tools: list_tables, get_table_schema, run_sql_query, check_sql_query
---

# SQL 专家技能

## 概述
提供专业的 SQL 查询编写、检查和优化能力。

## 何时使用此技能
- 用户询问数据库相关问题
- 需要编写或修改 SQL 查询
- 需要优化查询性能
- 需要理解数据库结构

## 工作流程

### 步骤 1:了解数据
1. 使用 `list_tables` 工具列出所有可用表
2. 使用 `get_table_schema` 查看相关表的结构
3. 将 Schema 信息保存到虚拟文件系统(`/workspace/schema/`)

### 步骤 2:编写查询
1. 根据用户需求编写 SQL
2. 遵循以下规范:
- 只使用 SELECT 语句
- 添加适当的 WHERE 条件
- 使用 LIMIT 限制结果数量(默认 10)
- 避免 SELECT *,只查询需要的列

### 步骤 3:验证查询
1. 使用 `check_sql_query` 检查语法
2. 检查常见错误:
- NOT IN 与 NULL 值
- UNION vs UNION ALL
- 数据类型不匹配
- JOIN 条件遗漏

### 步骤 4:执行并解释
1. 使用 `run_sql_query` 执行查询
2. 如果出错,分析错误并修正后重试(最多 3 次)
3. 用自然语言解释查询结果

## 常见查询模式

### 分组统计
```sql
SELECT category, COUNT(*) as count, AVG(price) as avg_price
FROM products
GROUP BY category
ORDER BY count DESC
LIMIT 10;

多表关联

1
2
3
4
5
SELECT o.id, c.name, p.product_name
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN products p ON o.product_id = p.id
WHERE o.created_at >= '2026-01-01';

故障排除

  • 如果表不存在:先用 list_tables 确认表名
  • 如果列不存在:先用 get_table_schema 确认列名
  • 如果查询超时:添加 LIMIT 或优化 WHERE 条件
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

### Frontmatter 字段说明

| 字段 | 必填 | 说明 |
|------|------|------|
| `name` | 是 | 技能标识符 |
| `description` | 是 | 用于技能匹配,务必具体!超过 1024 字符会被截断 |
| `license` | 否 | 许可证信息 |
| `compatibility` | 否 | 依赖/约束条件 |
| `metadata` | 否 | 附加元数据(author、version 等) |
| `allowed-tools` | 否 | 此技能允许使用的工具列表 |

## 9.5 在 DeepAgents 中使用 Skills

### 基本用法

```python
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
model="openai:gpt-4o",
skills=["/skills/"], # 技能目录路径
checkpointer=InMemorySaver(),
)

使用 StateBackend 提供技能文件

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 deepagents import create_deep_agent
from deepagents.backends.utils import create_file_data
from langgraph.checkpoint.memory import InMemorySaver

# 准备技能文件
skill_content = open("skills/sql-expert/SKILL.md").read()

skills_files = {
"/skills/sql-expert/SKILL.md": create_file_data(skill_content),
}

agent = create_deep_agent(
model="openai:gpt-4o",
skills=["/skills/"],
checkpointer=InMemorySaver(),
)

result = agent.invoke(
{
"messages": [{"role": "user", "content": "帮我查一下销售额最高的客户"}],
"files": skills_files,
},
config={"configurable": {"thread_id": "skill-demo"}},
)

使用 StoreBackend 持久化技能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from deepagents import create_deep_agent
from deepagents.backends.utils import create_file_data
from langgraph.store.memory import InMemoryStore
from langgraph.checkpoint.memory import InMemorySaver

store = InMemoryStore()

# 预加载技能到 Store
skill_content = open("skills/sql-expert/SKILL.md").read()
store.put(
("skills", "sql-expert"),
key="SKILL.md",
value=create_file_data(skill_content),
)

agent = create_deep_agent(
model="openai:gpt-4o",
skills=["/skills/"],
store=store,
checkpointer=InMemorySaver(),
)

9.6 Skills 与子 Agent 的配合

子 Agent 类型技能继承说明
通用子 Agent自动继承主 Agent 的技能无需额外配置
自定义子 Agent不继承,需单独指定必须显式传入 skills 参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 自定义子 Agent 使用特定技能
research_subagent = {
"name": "data-researcher",
"description": "数据研究助手",
"system_prompt": "你是一个数据研究员。",
"tools": [list_tables, run_sql_query],
"skills": ["/skills/sql-expert/", "/skills/data-analysis/"], # 子 Agent 专属技能
}

agent = create_deep_agent(
model="openai:gpt-4o",
skills=["/skills/main/"], # 主 Agent + 通用子 Agent 的技能
subagents=[research_subagent],
)

9.7 技能源优先级

当多个技能源包含同名技能时,最后列出的源优先

1
2
3
4
5
# 如果两个源都有 "web-search" 技能,
# "/skills/project/" 中的版本会覆盖 "/skills/user/" 中的
agent = create_deep_agent(
skills=["/skills/user/", "/skills/project/"], # project 优先级更高
)

9.8 在沙箱中执行技能脚本

如果技能包含可执行脚本,需要配置沙箱后端:

1
2
3
4
5
6
7
8
9
10
11
12
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend

agent = create_deep_agent(
model="openai:gpt-4o",
skills=["/skills/"],
backend=CompositeBackend(
default=modal_sandbox, # 沙箱后端
routes={"/skills/": StoreBackend()}, # 技能文件存储
),
store=InMemoryStore(),
)

自定义中间件同步技能文件到沙箱

1
2
3
4
5
6
7
8
9
10
11
12
class SkillSandboxSyncMiddleware(AgentMiddleware):
"""在每次 Agent 运行前,将技能文件同步到沙箱"""

async def abefore_agent(self, state, runtime):
store = runtime.store
for item in await store.asearch(SKILLS_NAMESPACE):
key = str(item.key)
if ".." in key or any(c in key for c in ("*", "?")):
raise ValueError(f"Invalid key: {key}")
files.append((f"/skills/{key}", item.value["content"].encode()))
if files:
await self.backend.aupload_files(files)

9.9 Skills vs Memory 对比

Skills(技能)Memory(记忆 / AGENTS.md)
目的按需加载的专业能力始终加载的持久上下文
加载方式渐进式披露(按需)启动时全部加载
格式SKILL.md + 脚本 + 文档AGENTS.md 文件
优先级后列出的源覆盖先列出的用户级 + 项目级合并
适用内容任务特定的知识和流程始终相关的约定和偏好
Token 消耗只在匹配时消耗始终消耗
何时使用指令量大、任务特定内容精简、始终相关

9.10 实战:创建一个完整的 SQL 分析技能包

1
2
3
4
5
6
7
8
skills/
└── sql-analyst/
├── SKILL.md # 主技能文件
├── patterns.md # SQL 模式参考
├── optimization.md # 查询优化指南
└── examples/
├── ecommerce.md # 电商场景示例
└── analytics.md # 分析场景示例

SKILL.md

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
---
name: sql-analyst
description: 当用户需要进行数据分析、编写复杂SQL查询、数据统计、生成报表时使用此技能。支持多表关联、窗口函数、CTE等高级特性。
metadata:
author: data-team
version: "2.1"
tags: ["sql", "analytics", "database"]
allowed-tools: list_tables, get_table_schema, run_sql_query, check_sql_query
---

# SQL 数据分析师技能

## 概述
提供端到端的数据分析能力,从需求理解到 SQL 编写到结果解读。

## 工作流程

### 1. 需求分析
- 理解用户的数据需求
- 确定需要的表和字段
- 制定分析计划

### 2. 数据探索
1. 使用 `list_tables` 获取所有表
2. 使用 `get_table_schema` 查看相关表结构
3. 执行简单的探索性查询(如 COUNT、DISTINCT)

### 3. 查询编写
按照 `patterns.md` 中的模式编写 SQL,使用 `optimization.md` 中的原则优化。

### 4. 结果解读
- 用自然语言解释查询结果
- 指出数据中的关键趋势和异常
- 给出业务建议

## 参考文档
- 阅读 `patterns.md` 获取 SQL 模式参考
- 阅读 `optimization.md` 获取查询优化指南
- 阅读 `examples/` 目录获取场景示例

9.11 Skills 的未来:与 MCP 的融合

Skills 和 MCP 正在走向融合:

方向说明
MCP Prompts → SkillsMCP 的 Prompts 原语可以看作标准化的 Skill 模板
MCP Resources → Skills 参考MCP 的 Resources 可以作为 Skills 的参考文档来源
MCP Tools → Skills 工具MCP 暴露的工具可以作为 Skills 的 allowed-tools

未来趋势:Skills 可能成为 MCP 之上的组织层 — 用 MCP 发现和连接工具,用 Skills 编排和指导工作流。