Featured image of post 第九话|Skill 系统:把做法变成资产

第九话|Skill 系统:把做法变成资产

从 Markdown 检查 Skill 出发,把做事方法沉淀为能力资产。

系列 GYA(Get Your Agent) 第 9 / 12 篇
主题 AgentLLM教程Skill工程化

第八话里,工具接入终于有了统一的边界。

Agent 想查天气,可以调用 MCP Server;想读数据库,也可以通过同一套协议发现和调用工具。工具来自另一个进程、另一种语言,甚至另一个团队时,调用方不必再为每一项能力重写适配代码。

可一个任务通常不只缺一个工具。

让 Agent 检查一篇文章,它也许找得到文件检查工具,却不知道应先看 frontmatter 还是标题;它也许发现了错误,却不知道能否直接改原文;它也许完成了几步操作,却没有明确的完成判定。工具越来越多,“应该怎样把事情做完整”反而更值得被固定下来。

先说结论:

MCP 解决“Agent 能调用什么”,Skill 解决“Agent 应该按什么方法完成任务”。

Skill 不是把 Prompt 写得更长。它把一套经过思考的方法拆成能被发现、按需加载、执行和验证的资源。

一、工具暴露动作,Skill 组织方法

假设我们有一个 Markdown 检查工具。它能接收文件路径、返回检查结果,也许还支持修复参数。这些信息足以描述一个动作,却不能自动给出一条可靠的任务路径。

任务问题单个工具通常能否回答
检查哪个文件可以
先检查 frontmatter 还是标题不一定
失败后是否继续不一定
能否直接修改原文不能替代权限约束
什么结果算任务完成需要额外规则

这和 Java 服务里已经注册了一组接口很像:checkFrontmatter()checkHeading()checkLinks() 都可调用,并不等于“文章质量检查”这个业务流程已经存在。顺序、分支、验收标准和修改权限仍需要被组织起来。

关键洞察:工具把能力暴露出来,Skill 把能力组织成方法。

二、一个 Skill 到底保存了什么

人说“我会检查博客文章”时,脑中通常不只是一句提醒,还包括适用场景、检查步骤、参考标准、可以交给脚本的部分,以及失败时应如何收尾。

Agent Skills Specification 规定,一个 Skill 至少是包含 SKILL.md 的目录;scripts/references/assets/ 都是按任务需要才加入的可选资源。真正重要的不是目录长相,而是把原本藏在人脑中的做法,拆成可审阅、可替换的职责。

Skill 把发现、说明、资料、脚本和验证边界组织成能力包

图中有一个容易被忽略的顺序:先用 name + description 判断这个 Skill 是否相关;匹配后才加载 SKILL.md;执行时再按需要读取参考资料、调用脚本或复用资产。目录的作用不是堆文件,而是让不同类型的知识在恰当的时机进入任务。

一个过于抽象的写法往往没有可执行性:

# Markdown 质量检查

请认真、全面地检查文章。

下面这种写法才把“做事方法”落到了可操作的层面:

---
name: markdown-quality
description: Check Markdown articles for required frontmatter, one H1 title, and a closing summary.
---

1. 读取 `references/checklist.md`2. 运行 `scripts/validate.py <markdown-file>`3. 报告每条失败规则和可操作的修复建议。
4. 未经明确请求,不修改文章。

差别不在于后者更长,而在于它明确了输入、步骤、确定性工具、输出和权限边界。

三、Skill 如何被发现,又为何不必一次读完

一个 Agent 不需要在每次任务开始时,把所有 Skill 的全部说明、资料和脚本都塞进上下文。官方 Quickstart 把过程拆成发现、激活和执行:启动时先看到技能的 namedescription;任务匹配后再读取完整 SKILL.md;真正执行时才访问需要的资源。Agent Skills Quickstart

Skill 的渐进加载:只在任务匹配后加载指令,并按需读取资料和调用脚本

这张图描述的是分层加载,而不是某个模型保证会做出的路由决定。description 写得太泛,匹配阶段就缺少足够线索;把无关资料全塞进入口文件,又会让每次执行背负不必要的上下文。一个好的描述更像服务注册中心里的服务名片:它不执行业务,却决定调用方能否先找到正确入口。

关键洞察:Skill 的入口要足够具体以便被发现,细节则应在真正需要时才加载。

四、动手:运行一个最小 Skill Host

这一节不模拟 LLM 推理,也不声称模型一定会选择正确 Skill。它只把一个 Skill Host 的协议边界固定下来:扫描 frontmatter、按 description 做最小匹配、加载指令、调用确定性验证脚本。

代码位于 GYA 的 c09-skill-system

c09-skill-system/
├── main.py
├── skills/
│   └── markdown-quality/
│       ├── SKILL.md
│       ├── references/checklist.md
│       └── scripts/validate.py
└── samples/
    ├── good.md
    └── bad.md

运行环境只有 Python 3.9+,不依赖第三方包,也不需要 API Key:

git clone https://github.com/renxin2024/GYA.git
cd GYA/c09-skill-system
python3 main.py

2026-08-22 在 Python 3.9.6 上的实际输出如下:

[discover] markdown-quality
[match] markdown-quality
[load] SKILL.md + references/checklist.md
[validate] good.md -> PASS: frontmatter=ok h1=1 summary=ok
[validate] bad.md -> FAIL: frontmatter must be delimited by ---; missing closing section: ## 总结
[validate] passed=1 failed=1 (expected)
[result] status=PASS

这里最后的 status=PASS 不表示两份样例都合格。它表示 Host 的验收条件被满足:合格样例通过,故意损坏的样例被拦截。把“验证器工作正常”和“被验证对象合格”分开,是写 Skill 时很重要的工程习惯。

如果运行结果不同,先按下面顺序排查:

  1. 确认当前目录是 GYA/c09-skill-system,否则 main.py 找不到相对路径下的 Skill 和样例。
  2. 确认使用 Python 3.9+;本 demo 使用了 Python 3.9 开始支持的内置泛型类型标注。
  3. 检查 skills/markdown-quality/SKILL.md 是否保留了 references/checklist.md 这一引用;demo 会把缺少该引用视为无效 Skill。

五、哪些工作交给模型,哪些交给脚本

Skill 不等于“把所有步骤都交给脚本”。模型仍然适合开放判断,例如观点是否清楚、语气是否自然、解释是否遗漏读者前提。脚本更适合结果只有明确对错的事情。

工作更适合的职责方原因
判断文章观点是否清楚模型需要语义理解与上下文判断
判断语气是否自然模型需要综合语言和读者语境
统计 H1 数量脚本可得到稳定的确定性结果
检查 JSON 能否解析脚本成功或失败有明确判定
检查文件是否存在脚本不需要模型猜测
删除文件、发送消息、部署权限系统与人工审批正确性不等于被授权

模型处理语义,脚本锁住不应漂移的事实,权限系统控制不可逆影响。Skill 的价值正是在任务层把这三类职责串成一条可检查的方法,而不是把其中任何一类神化成万能方案。

六、Prompt、Memory、MCP、Skill 各自解决什么

这几个词经常同时出现在 Agent 架构里,但它们回答的问题不同。

能力保存或提供什么主要回答的问题不能替代什么
Prompt当前任务的即时指令与上下文“这次希望我怎样回答?”可复用工作流与长期事实
Memory过去的事实、偏好或经验“上次我们决定了什么?”工具接入和任务方法
MCP可发现、可调用的工具与资源“现在能做什么?”步骤、验收和权限策略
Skill完成一类任务的方法与边界“这件事应该怎样完成?”模型推理、外部工具本身和授权

在一个真实任务里,Memory 可以补充用户偏好,MCP 可以提供读写外部系统的工具,Skill 可以规定检查流程,Agent Loop 负责推进步骤,脚本负责验证局部结果。它们相互协作,但不应互相冒充。

七、从 demo 到生产,Skill 还要补什么

SKILL.md 写出来只是起点。一个错误的 Skill 可能让 Agent 更稳定地执行错误流程,所以生产环境至少还要补上几件事:

  • 用真实样例检验它是否会在该触发时被发现;
  • 用故意失败的样例确认验证器真的能拦住错误;
  • 为规则变化保留版本和原因;
  • 将写文件、发消息、发布、部署等高影响动作放在明确的权限边界后;
  • 记录执行轨迹,把重复失败沉淀为下一版规则。

这些是从本文 demo 推导出的工程实践,不代表这个几十行的示例已经具备完整生产能力。它的职责只有一个:让“发现—加载—执行—验证”的边界变得可见、可运行、可讨论。

结尾:方法也应成为可复用的能力

第八话解决了工具如何标准化接入;第九话继续回答工具接入之后的事:怎样把经过验证的做法保存下来,让下一次任务不必从零猜测。

当 Agent 既能调用工具,又能复用方法时,新的追问自然出现:这些推理和行动方式又是怎样一步步演化出来的?下一篇,我们沿着 CoT、ReAct、Toolformer、Reflexion、Voyager 到 SWE-Agent 的线索继续往前看。

理解检验

  1. 如果一个 Skill 只有 SKILL.md,没有脚本和参考资料,它仍然可以成立吗?为什么?
  2. 为什么“验证器通过”和“被验证对象通过”不能混为一谈?
  3. 当一个任务需要读取用户偏好、调用文件工具、并检查输出格式时,Memory、MCP、Skill 和脚本各自承担什么职责?

参考资料

留言

欢迎分享你的想法。评论提交后会在审核通过后显示。