第 20 章 · Skills:可插拔的领域能力
本章目标:理解 Agno 的 Skills 技能包体系(基于 Anthropic Agent Skills 规范),学会编写符合规范的
SKILL.md、用LocalSkills把技能挂载到 Agent 与 Team,并了解 Claude 云端预置技能(pptx/xlsx/docx/pdf)的接入方式。
20.1 为什么需要 Skills:从 instructions 到技能包
本章之前的课程内容里,我们把领域知识塞进 Agent 只有两类手段:
| 手段 | 适用场景 | 短板 |
|---|---|---|
instructions / system prompt | 简短的行为约束 | 知识一多就撑爆上下文、每次请求都全量付费 |
Knowledge(RAG) | 海量静态资料的事实性问答 | 检索的是"资料片段",不擅长传递成套的方法论与脚本 |
真实业务里还有第三种需求:把"某类任务该怎么做"打包成一个可复用、可分享的知识单元——比如"如何做代码评审"、"怎么写行业周报"。这正是 Skill(技能) 的定位:
一个 Skill 是一个自包含的目录包,内含结构化指令、可选的可执行脚本与参考文档。Agent 按"发现 → 加载 → 引用 → 执行"四步渐进式地使用它。
Skills 与 Tools 是互补关系而非替代关系:Tools 给 Agent 能力(能做什么动作),Skills 给 Agent 方法论(这类事该怎么做好)。
与社区生态的关系
Agno 的 Skills 集成遵循 Anthropic 开源的 Agent Skills 规范,也就是说你为 Claude Code 写的技能目录、网上分享的第三方技能包,只要结构合规即可直接放进 Agno 项目复用。
20.2 渐进式加载:Skills 省 Token 的核心机制
直接把所有领域知识写进系统提示词的问题在于"全量付费、全程占位"。Skills 采用**渐进式发现(Progressive Discovery)**策略:
- Browse(浏览):注册后,Agent 的系统提示词里只出现每个技能的名称 + 一句话描述(几十个 token);
- Load(加载):当任务匹配某个技能时,模型自行调用
get_skill_instructions(skill_name)读入完整指令; - Reference(参考):需要更多细节时再按需读取
references/下的文档; - Execute(执行):需要精确计算/校验时,运行
scripts/下带 shebang 的脚本。
挂载 Skills 后,Agent 自动获得这三个专用工具:
| 工具 | 作用 |
|---|---|
get_skill_instructions(skill_name) | 加载某技能的完整指令 |
get_skill_reference(skill_name, reference_path) | 读取某技能的一篇参考文档 |
get_skill_script(skill_name, script_path, execute, args, timeout) | 读取或执行某技能中的脚本 |
Token 经济学
十份完整方法论直接进 system prompt 可能是数万 token 的固定开销;同样的内容做成十份技能,system prompt 里只剩十条摘要——只有真正命中的那份会被完整载入。
20.3 编写一个合规的 Skill:SKILL.md 与目录结构
技能就是一个普通目录,唯一必需的是根下的 SKILL.md:
my-skills/
├── report-writer/ # 目录名 = 技能名(强制一致)
│ ├── SKILL.md # 必需:YAML frontmatter + Markdown 指令
│ ├── scripts/ # 可选:可执行脚本(必须有 shebang)
│ │ └── wc_check.py
│ └── references/ # 可选:参考文档,按需加载
│ └── style-guide.md
└── code-review/
└── SKILL.mdSKILL.md 由 YAML frontmatter 元数据 + 正文指令构成。合法的顶级字段只有六个:name、description、license、compatibility、allowed-tools、metadata,其他任何顶级字段都会导致校验失败(自定义信息请放到 metadata 字典里):
---
name: report-writer
description: 撰写结构化行业周报,含字数校验脚本与文风指南
license: Apache-2.0
metadata:
version: "1.0.0"
author: gaoxueling
tags: ["writing", "report"]
---
# 行业周报撰写技能
当用户要求生成行业周报/月报时启用本技能。
## 流程
1. 先问清楚报告周期与目标读者;
2. 按"本周动态 → 数据亮点 → 下期展望"三段式组织;
3. 输出前运行 scripts/wc_check.py 校验正文字数是否在范围内。
## 细则
文风要求见 references/style-guide.md,仅在用户质疑措辞时加载。加载时会做严格校验,违反规则的技能会抛出 SkillValidationError:
name:仅允许小写字母、数字、连字符,≤64 字符,不能以-开头/结尾、不能连续--,且必须与目录名一致;- 长度上限:
description≤1024 字符、compatibility≤500 字符;license建议用 SPDX 标识符(如MIT、Apache-2.0); - 脚本必须以
#!shebang 开头(如#!/usr/bin/env python3),执行时以技能目录为工作目录,模型可以传参。
一个简单实用的配套脚本 scripts/wc_check.py:
#!/usr/bin/env python3
"""统计输入文本的中文字数与总行数,用于周报交付前的自检。"""
import sys
text = sys.stdin.read() if not sys.argv[1:] else open(sys.argv[1], encoding="utf-8").read()
cjk = sum(1 for ch in text if "\u4e00" <= ch <= "\u9fff")
print(f"中文字符 {cjk} 个,共 {len(text.splitlines())} 行")
sys.exit(0 if 800 <= cjk <= 2000 else 1)20.4 用 LocalSkills 把技能挂到 Agent
Skills 是技能编排器,LocalSkills 是目前内置的文件系统加载器,支持加载整个技能库或单个技能:
import os
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.skills import Skills, LocalSkills
agent = Agent(
name="周报助手",
# 全书约定:OpenAI 兼容三方模型
model=OpenAIChat(
id="deepseek-chat",
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com/v1",
),
skills=Skills(loaders=[
LocalSkills("./my-skills"), # 整个技能库
LocalSkills("./team-shared/skills"), # 多个 loader 会合并
]),
instructions=[
"你拥有若干专业技能。",
"遇到匹配的任务时,先用 get_skill_instructions 加载对应技能再作答。",
],
markdown=True,
)
agent.print_response("帮我写一份 AI Agent 行业的本周周报", stream=True)工程细节:
- 多个 loader 同名覆盖:靠后的 loader 中同名技能会覆盖先前的,可用来实现"团队共享库 + 项目定制库"的分层;
- 运行时热更新:磁盘上的技能文件变更后调用
skills.reload()即可重新载入,无需重启进程; - 宽松模式:
LocalSkills(path, validate=False)跳过规范校验按尽力而为加载(只有完全读不出 SKILL.md 的才跳过并警告),适合灰度引入外部技能包。
可以用 debug_mode=True 观察渐进加载的全过程:第一条请求应只看到摘要注入,命中任务后才会出现对 get_skill_instructions 的工具调用。
20.5 Team 中的 Skills:让 leader 直接拥有专家知识
把 Skills 传给 Team 的 skills 参数,队长会直接获得技能工具与系统提示摘要,无需转交成员处理:
import os
from pathlib import Path
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.skills import Skills, LocalSkills
from agno.team import Team
skills_dir = Path(__file__).parent / "my-skills"
implementer = Agent(
name="Implementer",
role="根据评审意见修改代码",
model=OpenAIChat(id="deepseek-chat", api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com/v1"),
)
review_team = Team(
name="Code Review Team",
model=OpenAIChat(id="deepseek-chat", api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com/v1"),
members=[implementer],
skills=Skills(loaders=[LocalSkills(str(skills_dir))]), # 队长持技能
instructions=["先用你的技能完成代码评审,再把修改工作分派给 Implementer。"],
markdown=True,
)
review_team.print_response("评审并改进这段代码:def calc(x,y): return x+y", stream=True)三种配置层级怎么选:
| 配置方式 | 适用场景 |
|---|---|
Team(skills=...) | 队长需要领域标准来协调调度(评审规范、路由规则) |
成员 Agent(skills=...) | 专家成员需要专业知识完成本职工作 |
| 两层都配置 | 队长需要上下文做分派,成员也需要知识做执行 |
其内部机制与前几章的 knowledge/memory/tools 完全同构:skills.get_tools() 把技能工具加进队长的工具列表,get_system_prompt_snippet() 把技能元数据注入队长的系统提示词。
20.6 进阶:Claude 云端 Agent Skills(选读)
如果你使用 Anthropic 官方 API,还可以让技能"跑在云端"——Claude 提供四个开箱即用的容器化技能,能在隔离沙箱中直接产出 Office 文件:
| Skill ID | 能力 |
|---|---|
pptx | 创建/编辑演示文稿并分析其内容 |
xlsx | 创建电子表格、生成带图表的报告 |
docx | 创建/编辑 Word 文档 |
pdf | 生成排版精美的 PDF 报告 |
用法是把技能配置传给 Claude 模型对象(单次请求最多挂 8 个技能;type="custom" 配合 skill_* ID 可使用上传到工作区的自定义技能):
from agno.agent import Agent
from agno.models.anthropic import Claude
agent = Agent(
model=Claude(
id="claude-sonnet-4-6",
skills=[{"type": "anthropic", "skill_id": "pptx", "version": "latest"}],
),
instructions="制作简洁、结构清晰的演示文稿。",
)
run = agent.run("生成一份三页的《可再生能源》演示文稿")
# 产物不在本地:从 run.model_provider_data 提取 file_ids,
# 再经 Anthropic Files API(client.beta.files.download)下载落盘。生产注意
云端技能运行在无网络的隔离容器中;产物必须经 Files API 下载且该 API 仍为 beta;pause_turn 长任务中断场景建议改用 Anthropic 原生 SDK 续传。Skills/Files API 在 Amazon Bedrock 与 Google Vertex AI 渠道上不可用。本节为选读扩展,全书其余示例不依赖 Anthropic 直连。
20.7 工程实践清单
- 什么值得做成 Skill:流程稳定、跨 Agent 复用的方法论(评审规范、写作模板、运维手册);"每次都要取最新值"的内容请继续交给 Tools/RAG;
- 确定性计算交给脚本:字数统计、格式转换、lint 校验写成脚本让模型调用,比让它"口算"可靠得多;
- 技能也要写测试:SKILL.md 是提示词工程的一部分,换模型后务必回归验证;
- 版本治理:用
metadata.version记录迭代,重要变更走 Git PR 评审。
20.8 本章小结
- Skill =
SKILL.md+ 可选scripts/+ 可选references/;六大合法 frontmatter 字段,name必须与目录名一致; - 渐进式加载:摘要常驻 → 指令按需 → 参考按需 → 脚本执行,显著节省 token;
Skills(loaders=[LocalSkills(...)])挂载到 Agent;传给Team.skills则队长直接持有;- Anthropic 用户可叠加云端预置技能(pptx/xlsx/docx/pdf)生成 Office 文件。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. 把 Skills 注册到 Agent 后,它会自动获得哪些工具?
2. 关于技能目录与 SKILL.md 的命名规则,正确的是?
3. 为什么说 Skills 比"把全部方法论文档塞进 system prompt"更省钱?
4. 在 Team 中传入 skills= 参数的效果是?
🛠️ 动手实践
- 为自己的日常任务编写一个技能包(如
daily-report或pr-review):包含合规的 SKILL.md、一个脚本与一篇参考文档;再故意把name改成非法值,观察SkillValidationError的报错信息; - 挂载到 Agent 后开启
debug_mode=True,观察一次命中任务的请求里"摘要注入 → get_skill_instructions → 执行脚本"的发生顺序; - 把同一个技能库分别挂到一个单独 Agent 和一个 Team 的 leader 上,对比两种形态下的回答质量差异;
- (选做)有 Anthropic API Key 的话,运行 20.6 的 pptx 示例并补全 Files API 下载逻辑,拿到真正的
.pptx文件。
Skills 补齐了"能力型"工具之外的"方法论型"积木。下一章把视角转向安全与合规:进入第 21 章 · 人机协同与 Guardrails;生产服务化安排在第 23 章:AgentOS。