工具让 Agent 能做,知识让它知道,还差一样:会做——按专业的方法论做事。本篇讲知了的技能系统:把"写周报的规范""润色英文的流程"写成 markdown 文件,Agent 按需取用。代码对应
zhiliao/agent/skills.py和zhiliao/skills/目录。
一、先分清三个词:工具 / 知识 / 技能
这三个词经常被混着叫,但它们是三种完全不同的东西:
| 本质 | 存在形式 | 生效方式 | 例子 | |
|---|---|---|---|---|
| 工具 Tool | 能力(做动作) | Python 函数 | 注册表,模型调用 | 算数、读文件、搜索 |
| 知识 Knowledge | 事实(是什么) | 文档 | RAG 检索后注入 | 公司报销流程 |
| 技能 Skill | 方法论(怎么做才专业) | markdown 说明 | 按需加载进提示词 | 周报模板、润色流程 |
一个例子串起来:用户说"帮我写本周周报"——
- 技能 weekly_report 告诉它周报的结构和写作守则(怎么做)
- 工具 todo 帮它列出本周待办当素材(做什么)
- 知识 库里可能存着"团队的 OKR 进展"(背景事实)
三者协同,产出的周报才既规范又贴合实际。
二、技能 = 一个 markdown 文件
skills/weekly_report.md 的完整样子:
---
name: weekly_report
description: 按团队规范撰写工作周报
trigger: 用户要求写周报、本周总结、工作汇报时
---
# 周报技能
## 第一步:收集素材
- 用 todo 工具的 list 动作查看未完成事项,作为"下周计划"的素材。
## 第二步:按模板组织
(周报的结构模板……)
## 写作守则
- 用动词开头,量化结果("完成3个接口联调" 优于 "做了开发")
- 不写"努力、加油"之类的主观形容
头部 --- ... --- 叫 frontmatter(元数据):name 是模型点名用的,description 和 trigger 是给模型判断"该不该用我"的依据。正文就是写给模型看的操作手册。
为什么是 markdown 而不是代码? 因为"教模型做事"最好的语言就是自然语言+结构。改技能不用改一行 Python,把文件放进 skills/ 目录、重启程序即生效(想做"改完即生效"的自动重载?留作本篇作业之外的挑战)——这就是"可插拔"。
三、按需加载:技能系统最关键的设计
为什么不把所有技能全文一次性塞进系统提示?两个原因:
- 省 token:每个技能几千字,10 个技能常驻 = 每轮对话白烧几万 token
- 保专注:指令越多模型越容易跑偏。写周报时,"英文润色规则"是纯干扰
知了的方案是目录 + 点单两段式:
第一段:目录常驻。 系统提示里只有每个技能的一行简介(skills.catalog()):
【可用技能目录】
- weekly_report:按团队规范撰写工作周报(适用:用户要求写周报、本周总结时)
- english_polish:英文写作润色(适用:用户发来英文段落要求润色时)
第二段:模型判断任务匹配某个技能时,主动调用 use_skill 工具取全文,取回的内容和"工具结果"一样进入对话,模型按它执行。
这个"先看目录、再点单"的模式,就是你正在用来读这篇教程的环境(ZCode)里技能系统的同款机制——技能江湖几乎都收敛到了这个设计。
四、实现不足百行
agent/skills.py 的骨架:
class SkillBook:
def _load(self):
for f in sorted(self.skills_dir.glob("*.md")):
meta, body = self._parse_frontmatter(f.read_text(...))
self.skills[meta["name"]] = {
"description": meta.get("description", ""),
"trigger": meta.get("trigger", ""),
"content": body.strip(), ...}
def catalog(self): # 常驻目录:每技能一行
return "\n".join(f"- {s['name']}:{s['description']}(适用:{s['trigger']})" ...)
def get_skill(self, name): # 点单:返回全文;名字不对返回可用列表
...
frontmatter 解析用 15 行正则手写,不引第三方库。两个容错细节:README.md 不当技能扫描;get_skill 查无此技能时返回"可用技能列表",模型能自我纠正而不是卡死。
五、写一个好技能的三个特征
对照 zhiliao/skills/README.md 里的完整指南:
1. 触发条件明确。 trigger 是模型选择技能的唯一依据,要写场景不写抽象词。"用户发来英文段落并要求润色时" ✔,"提升文字质量" ✘。
2. 步骤可执行。 像给新同事的操作手册:第一步做什么、用什么工具、什么顺序。写"提高周报质量"是废话,写"先调 todo 的 list 动作收集素材"是步骤。
3. 有模板。 给出输出格式的骨架,模型照着填,产出稳定性立刻上一个台阶。
再送一条实战经验:技能里可以指挥模型用工具(如周报技能里"调 todo 的 list")。技能 × 工具的组合拳,才是 Agent 能力的乘法。
六、举一反三:值得写成技能的东西
翻翻你的收藏夹和团队 wiki,这些素材都值得技能化:
- 个人:邮件回复规范、简历定制流程、读书笔记模板、健身计划制定
- 团队:代码评审 checklist、发布流程、客服话术、需求文档模板
- 垂直:小红书文案公式、周报/日报规范、面试复盘模板
你的核心竞争力里,凡是"有一套固定方法"的部分,都可以变成技能文件。
本篇作业
- 给知了写一个属于你自己的技能(建议从"邮件回复"或"读书笔记"入手),重启后用匹配的任务实测它是否触发。
- 故意把
trigger写得很模糊,观察技能命中率的下降——理解描述质量的价值。 - 思考:如果把技能全文改成"默认全塞进系统提示",什么时候会先出问题?(提示:技能数量 vs 上下文预算)
下一篇预告:《08 · Web 界面与产品化》——命令行留不住朋友。用 FastAPI 给知了穿上网页外衣,顺便讨论产品化的第一课:让用户看见 Agent 在干什么。