学习资料:Datawhale《Deep Agents 实战》第七章:Skills
本章重点:
SKILL.md、Progressive Disclosure、SkillsMiddleware、Backend、权限控制、Skills 与 Tools/Memory 的区别。
一、为什么需要 Skills?
前面学习了 Deep Agents 的任务规划和 SubAgent 机制,分别解决了复杂任务如何拆解、如何委派执行的问题。
但还有一个问题:如何让 Agent 稳定复用已有的工作流程和领域经验?
例如,让 Agent 根据团队规范审查代码、查阅 LangGraph 文档,或者按照固定格式撰写技术报告。
这些任务不是调用一次工具就能完成的,而是涉及多个步骤、领域知识、操作规范和模板资源。
一种简单方案是将所有规则直接写进 System Prompt,但随着功能增加,Prompt 会越来越长,产生两个问题:
-
无关指令占用上下文窗口,增加 Token 成本。
-
不同任务的规则混在一起,容易相互干扰。
Skills 就是为了解决这一问题。
Skill 本质上是一个标准化的能力包,将某类任务的执行流程、领域知识和辅助资源封装起来,由 Agent 按需加载。
Skills 遵循开放的 Agent Skills 规范,不是 Deep Agents 私有的设计。Claude Code、Codex、Gemini CLI 等工具也支持这一生态。
二、Skill 的目录结构
一个 Skill 就是一个目录,核心文件是 SKILL.md,还可以包含脚本、参考文档和模板。
skills/
└── code-review/
├── SKILL.md
├── scripts/
│ └── check.py
├── references/
│ └── coding-style.md
└── assets/
└── report-template.md
各部分作用如下:
| 文件或目录 | 作用 |
|---|---|
SKILL.md |
必需,定义技能元数据和执行指令 |
scripts/ |
可选,存放 Python、Shell 等脚本 |
references/ |
可选,存放详细参考资料 |
assets/ |
可选,存放模板、Schema 等资源 |
2.1 SKILL.md 的组成
SKILL.md 由两部分组成:
-
YAML Frontmatter:定义 Skill 的名称、描述等元数据。
-
Markdown Body:编写具体的执行步骤与注意事项。
例如:
---
name: code-review
description: 当用户要求代码审查、质量检查或安全分析时使用。
---
# Code Review
## Workflow
1. 阅读目标代码和项目结构。
2. 检查代码逻辑与潜在异常。
3. 检查安全风险和性能问题。
4. 输出问题列表与修改建议。
其中 name 和 description 是必填字段。
这里最重要的是 description。
Agent 在选择 Skill 时,不会提前阅读全部正文,而是根据 description 判断是否匹配当前任务。
如果描述过于宽泛,例如"帮助用户编程",就容易发生错误匹配;如果描述包含明确的适用场景和触发条件,通常更容易被正确选择。
因此,编写 Skill 首先要回答的问题是:什么情况下应该调用它?
三、Progressive Disclosure:渐进式披露
这是本章最核心的机制。
传统 Prompt 往往在启动时一次性加载全部指令,而 Skills 采用 Progressive Disclosure(渐进式披露),根据任务需要逐步加载信息。
3.1 三级加载机制
| 层级 | 加载内容 | 加载时机 |
|---|---|---|
| Level 1:Metadata | 名称、描述、路径 | Agent 启动时 |
| Level 2:Instructions | SKILL.md 正文 |
Agent 判断需要该技能时 |
| Level 3:Resources | 脚本、参考文件、模板 | 执行过程中按需读取 |
整体流程:
Agent 启动
|
v
SkillsMiddleware
扫描 Skill 目录
|
v
注入 name + description + path
|
v
用户提出任务
|
v
模型判断匹配的 Skill
|
v
read_file(".../SKILL.md")
|
v
按照指令执行
|
v
按需读取 references / assets
例如,用户询问 LangGraph 的中断机制,Agent 发现 langgraph-docs Skill 的描述与任务相关,随后通过 read_file 读取完整指令,再根据指令访问官方文档。
需要注意:SkillsMiddleware 主要负责技能发现和元数据注入,具体选择哪个 Skill、是否读取参考文件,仍然由 LLM 决定。
3.2 为什么采用这种设计?
主要有三个原因。
第一,减少 Token 消耗。
假设一个 Agent 配置了 20 个 Skills,每个 Skill 正文有 2000 Tokens。
如果全部加载,需要约 40000 Tokens;采用渐进式加载,启动时只需要注入简短元数据,真正执行任务时才读取相关 Skill。
第二,降低无关指令干扰。
执行代码审查时,不需要加载数据可视化、论文写作等其他技能的完整指令。
第三,提高扩展性。
开发者可以持续增加 Skills,而不必将所有领域知识都放进 System Prompt。
不过,Skill 数量过多仍然会增加元数据开销与模型选择难度,并不意味着可以无限制添加。
四、Skills 的三种存储 Backend
Deep Agents 支持不同的文件存储后端,决定 Skill 文件放在哪里,以及如何读取。
4.1 FilesystemBackend
直接读取本地磁盘,适合本地开发、CLI 和个人项目。
from deepagents import create_deep_agent
from deepagents.backends.filesystem import FilesystemBackend
backend = FilesystemBackend(
root_dir="./my-project",
virtual_mode=True
)
agent = create_deep_agent(
model=model,
backend=backend,
skills=["/skills/"]
)
对应本地目录:
my-project/
└── skills/
└── code-review/
└── SKILL.md
注意:skills 指向的是包含 Skill 子目录的父目录 ,而不是某个 SKILL.md 文件。
4.2 StateBackend
将 Skill 文件保存在 LangGraph Agent State 中,适合无磁盘部署或动态注入文件。
其特点是:
-
文件通过
invoke()的files字段注入。 -
文件内容需要经过
create_file_data()格式化。 -
状态生命周期由 Agent State 和 Checkpointer 管理。
它适合会话级文件管理,但不等于自动实现跨线程共享。
4.3 StoreBackend
使用 LangGraph Store 保存文件,适合多个线程共享 Skills。
例如企业维护统一的代码审查规范,只需要将 Skill 写入 Store,各个 Agent 线程就可以读取。
三种 Backend 的主要区别:
| Backend | 数据位置 | 典型场景 |
|---|---|---|
| FilesystemBackend | 本地磁盘 | 本地开发 |
| StateBackend | Agent State | 动态注入、会话级文件 |
| StoreBackend | LangGraph Store | 跨线程共享 |
需要注意,InMemoryStore 只能提供进程内存储。真正的跨进程持久化还需要接入持久化 Store。
五、多源 Skills 与优先级
Deep Agents 可以从多个目录加载 Skills。
agent = create_deep_agent(
model=model,
skills=[
"/skills/shared/",
"/skills/project/"
]
)
如果两个目录中存在同名 Skill,采用 Last Wins 规则,即后面的覆盖前面的。
这个机制很适合分层管理:
组织级 Skills
|
v
团队级 Skills
|
v
项目级 Skills
例如,组织提供通用代码审查规范,项目可以在此基础上定义针对当前代码库的审查流程。
需要注意,覆盖的是同名 Skill 的选择结果,不是自动合并两份 SKILL.md 内容。
六、Skills 与 SubAgent
第五章学习了 SubAgent,这一章进一步说明 Skills 在主 Agent 和子 Agent 之间的继承关系。
规则如下:
-
General-purpose SubAgent:自动继承主 Agent 配置的 Skills。
-
自定义 SubAgent:默认不继承,需要显式指定。
-
各 Agent 具有独立的 Skill 状态空间,但底层共享存储仍需要正确管理访问权限。
例如:
researcher = {
"name": "researcher",
"description": "负责科研文献调研",
"system_prompt": "你是一名科研助手。",
"skills": ["/skills/research/"]
}
agent = create_deep_agent(
model=model,
skills=["/skills/main/"],
subagents=[researcher]
)
此时,主 Agent 使用 /skills/main/,自定义 researcher 使用 /skills/research/。
这种机制让不同 Agent 拥有各自的专业能力,避免不相关的技能影响任务执行。
七、Skills 的权限控制
实际部署时,Skills 不只是能否读取的问题,还需要考虑是否允许修改。
Deep Agents 可以通过 FilesystemPermission 控制访问权限。
例如,禁止 Agent 修改 Skills:
from deepagents import FilesystemPermission
permission = FilesystemPermission(
operations=["write"],
paths=["/skills/**"],
mode="deny"
)
配置到 create_deep_agent(permissions=[permission]) 后,Agent 对匹配路径的写入操作会被拒绝。
另一种方式是 mode="interrupt",即写入时暂停执行,等待人工审批。
这种方式需要配置 Checkpointer,确保中断状态能够恢复。
对于企业应用,可以采用"团队共享 Skills 只读、个人 Skills 可写"的方案,既保证统一规范,也允许用户积累个人工作流。
八、Skills 不只是 Prompt,还可以包含代码
Skills 除了提供文字指令,也可以封装代码。
本章介绍了两种执行模式。
1. Sandbox Scripts
在 scripts/ 中存放 Python 等脚本,通过支持沙箱执行的 Backend 运行。
适合数据处理、文件转换和外部程序调用。仅能读取脚本文件并不意味着具备执行环境。
2. Interpreter Skills
通过 metadata.entrypoint 指定 JS/TS 模块入口,配合 CodeInterpreterMiddleware,允许 Agent 导入预先定义的函数。
例如:
const { groupByStatus } =
await import("@/skills/order-helpers");
优势在于复用经过测试的确定性代码,而不需要模型每次重新生成实现。
这一点比较重要:Skills 既能复用知识和流程,也能复用可执行的程序逻辑。
九、Skills、Memory 和 Tools 的区别
这三个概念很容易混淆。
| 对比 | Skills | Memory | Tools |
|---|---|---|---|
| 核心作用 | 封装领域能力 | 保存长期上下文 | 执行具体操作 |
| 典型形式 | SKILL.md |
AGENTS.md |
Python 函数/API |
| 加载机制 | 按需读取正文 | 启动时加载 | 调用时执行 |
| 例子 | 论文审查流程 | 项目编码规范 | 搜索、读文件 |
可以用一个科研场景理解:
-
Memory:记录当前研究方向、项目规范和长期背景。
-
Skill:规定如何开展文献检索、筛选论文和总结结果。
-
Tool:实际调用搜索 API、读取 PDF 或运行代码。
三者并不是替代关系,而是各自负责不同层面的功能。
十、如何编写高质量 Skill?
结合本章内容,记录几个实践要点。
-
description写清楚使用场景和触发条件,避免模糊描述。 -
SKILL.md正文建议控制在 500 行或约 5000 Tokens 以内,复杂内容放在references/。 -
使用明确的执行步骤、条件分支和输入输出示例,而不是大段概念性描述。
-
定期整理技能目录,合并重复 Skills,删除失效内容。
-
涉及外部脚本和敏感文件操作时,配置沙箱与访问权限。
另外,Skill 是否真正有效,需要通过任务测试验证,而不只是检查文件格式是否正确。
例如,可以设计正向任务和反向任务,观察 Agent 是否正确选择 Skill、是否遵循执行步骤,以及最终任务质量是否提升。
十一、学习总结
本章最重要的收获是理解 Skills 如何实现 Agent 能力的模块化复用。
此前主要通过 System Prompt、Tools 和 SubAgent 来扩展 Agent 能力,但这些方式各有局限。Skills 提供了一种更灵活的方式:将领域知识和执行流程组织为独立目录,再通过 Progressive Disclosure 按需加载。
其中最值得关注的是两个设计:
第一,知识与模型上下文解耦。 大量领域资料保存在文件系统中,只有任务需要时才进入上下文。
第二,能力与具体模型解耦。 Skill 采用开放的文件规范,因此同一套流程可以在不同兼容 Agent 工具间复用,但具体执行效果仍取决于模型和运行环境。
从 Agent Harness 的角度看,Skills 相当于可插拔的能力模块。一个通用 Agent 可以通过加载不同 Skills,切换为代码审查、文献调研或数据分析助手,而不需要重新训练模型。
结合前面学习的内容,Deep Agents 的整体结构逐渐清晰:任务规划负责拆解目标,SubAgent 负责委派执行,文件系统负责管理中间信息,Skills 负责复用专业流程。
Skills 的价值不在于让 Agent 知道更多,而在于让 Agent 在合适的任务中,按照经过整理和验证的流程开展工作。
参考资料:
Datawhale《Deep Agents 实战》第七章:Skills------可复用的 Agent 能力包
标签: Deep Agents Agent Skills LangChain SkillsMiddleware Context Engineering Agent Harness