第 7 章 · Skills 技能系统
Harness 锚点|判别清单第 9 项「扩展机制」——把领域方法论沉淀成可加载技能。
工具越加越多,Agent 反而变笨了
那个卖家的 Agent 越来越能干:会查销量、查竞品、读 GitHub、发通知、操作表格……工具一个个加上去,某天他发现——Agent 变笨了。
原因藏在一个容易忽略的地方。每个工具的说明、参数格式、使用示例,都得塞进模型的上下文里。工具一多,问题就来了:
- 上下文被几十个工具的说明撑得老长,每次调用都在为它们烧 token。
- 模型面对满屏工具,反而挑花了眼,该用 A 时用了 B,选择质量下降。
- 大部分工具在某次具体任务里根本用不上,却始终占着位置。
这就像新员工第一天上班,你把公司所有部门的操作手册全堆在他桌上。他需要的不是“全部手册常备手边”,而是“用到哪本时,能找到那本”。
模式:把能力打包成“按需加载”的技能
Skills(技能) 就是这个思路:把一个完整的能力——包括说明、工作流步骤、辅助脚本、参考资料——打包成一个自包含的单元,平时不占上下文,只有任务需要时才加载进来。
一个技能通常分两层:
- 简介(始终可见):这个技能是什么、什么时候该用它。这部分很短,一直摆在模型眼前,供它判断“要不要加载”。
- 正文(按需加载):详细的步骤、注意事项、最佳实践、附带的脚本和模板。只有技能被激活后,这些才进入上下文。
于是模型的决策变成了两层:先扫一眼简短的技能清单(“哦,我有一个‘导出合规报告’的技能”),判断当前任务用不用得上;用得上,才把完整内容拉进来。上下文从“全部常备”变成了“按需调取”——这就从根上解决了上面那个“工具越多越笨”的问题。
用 pi 实现:Agent Skills 标准
pi 实现了 Agent Skills 标准——这是一个跨工具通用的技能格式(Claude Code 等也遵循)。这意味着你写的技能可以在支持该标准的不同 Agent 之间复用。
一个技能就是一个目录,核心是一份 SKILL.md:
.pi/skills/export-compliance-report/
SKILL.md ← 技能定义(简介 + 正文)
scripts/
export.py ← 辅助脚本
templates/
report.html ← 参考模板
SKILL.md 长这样,注意开头那段 frontmatter:
---
name: export-compliance-report
description: 把销售数据导出为符合欧盟 VAT 要求的合规报告。当用户要求"导出/生成合规报告、VAT 报告"时使用。
---
# 导出合规报告
## 步骤
1. 用 query_sales 工具拉取指定季度的销售数据
2. 运行 scripts/export.py 生成报告
3. 用 templates/report.html 作为版式模板
4. 把生成的文件路径返回给用户
## 注意
- 金额一律保留两位小数,币种标注 EUR
- 缺失税号的订单要单独列出提醒
关键全在 frontmatter 的 description:它始终对模型可见,是模型判断“要不要加载这个技能”的唯一依据。所以它必须写清触发条件——“当用户要求导出合规报告时使用”。而正文里的详细步骤,只有技能被激活后才进上下文,平时一分钱 token 不花。
pi 里技能放两个位置都会被自动发现:~/.pi/agent/skills/(全局,所有项目可用)和 .pi/skills/(项目内,随仓库走)。
Skills 和 Tools 到底差在哪
这是最容易混的地方,一句话钉死:
Tool 是一个“动作”,Skill 是一套“工作流 + 知识”。
| Tool(工具) | Skill(技能) | |
|---|---|---|
| 粒度 | 单个原子操作 | 一整套流程 + 说明 + 资源 |
| 加载 | 注册后常驻上下文 | 按需加载,平时只留一行简介 |
| 内容 | 一个可执行函数 | Markdown 指南 + 脚本 + 模板 |
| 例子 | query_sales、send_slack | “如何做竞品调研”、“如何出合规报告” |
它们不是二选一,而是互补:技能的工作流里,往往会调用若干工具。技能负责“怎么组织这些动作、按什么步骤、注意什么”,工具负责“每个动作具体怎么执行”。上面那个合规报告技能,第一步就用到了第 4 章的 query_sales 工具。
动手看看
pi 自带一个 dev-browser 技能(第 31 章会用到),是很好的真实范本——它把“如何驱动浏览器做开发调试”的整套工作流打包成了一个技能。找到它的 SKILL.md,重点看两处:它的 description 怎么写触发条件;正文怎么把一系列浏览器操作组织成清晰的步骤。仿照它,你就能给自己的领域方法论写技能了。
实战中的几个坑
坑一:description 写不清触发条件。
- 现象:技能明明该用,模型却没加载。
- 原因:简介没说清“什么时候用它”。
- 对策:在 description 里明确“当用户要做 X 时使用”,把触发场景说透。
坑二:把技能写成工具。
- 现象:一个“技能”里只有一个动作。
- 原因:混淆了技能与工具的粒度。
- 对策:技能要包含流程和知识,单个动作用工具。
坑三:正文塞太多无关内容。
- 现象:技能一加载就占掉大量上下文。
- 原因:正文没聚焦,堆了太多参考资料。
- 对策:正文只留真正需要的步骤和注意点,参考资料拆成附件。
坑四:忘了技能可以调工具。
- 现象:在技能里重复描述工具已有的能力。
- 原因:没分清“编排”和“执行”的职责。
- 对策:技能负责编排,具体动作交给工具,别重复。
对比:其他框架
“按需加载能力包”这个一等概念,各家成熟度不一:
| 框架 | 有无“按需加载技能”机制 | 说明 |
|---|---|---|
| LangGraph | 无原生概念 | 用子图或工具分组近似,加载逻辑自己设计 |
| CrewAI | 无一等机制 | 靠给角色配“任务 + 工具集”近似 |
| PydanticAI | 无内建技能系统 | 需自己实现“按任务动态加载指令/工具” |
| Agno | 部分近似 | 用 Knowledge + Toolkit 组合,加载模型与标准不同 |
| pi | 遵循 Agent Skills 标准 | 含 SKILL.md 的自包含目录,可跨工具复用 |
Agent Skills 之所以正在成为标准,是因为它解决的是上下文经济学问题——如何在有限窗口里,只加载当下真正需要的能力。这是每个想让 Agent 更能干的团队都会撞上的墙。
小结
- 工具太多会撑爆上下文、拖垮模型的选择质量;Skill 用“按需加载”破解:简介常驻供判断,详细工作流只在需要时加载。
- pi 遵循跨工具通用的 Agent Skills 标准,技能是含
SKILL.md的自包含目录,靠description里的触发条件被模型选中。 - 记住区别:Tool 是动作,Skill 是工作流 + 知识,且技能常常在内部调用工具,二者互补。
- 它本质解决的是上下文经济学——有限窗口里只放当下该放的能力。
下一章讲 pi 最有特色的扩展机制——Hooks 与事件系统:如何在循环运行时插入你自己的规则和控制。