第15章:技能封装 —— 设计你的专属 Agent Skill
本章摘要
在第14章,我们见证了多 MCP 能力协同产生的智能涌现。然而,随着系统复杂度的提升,依赖零散的 System Prompt 和分散的 MCP 配置来管理智能体能力,将变得难以维护、难以迁移。一个根本性的矛盾浮出水面:模型“知道”如何做事,但在具体的业务场景中却无法“稳定地做成”一件事。
本章将引入 Agent Skill 工程化的终局形态——技能封装。你将学习如何将前序课程中积累的“S.C.O.R.E. 提示词”、“PEAR 工作流”、“MCP 工具链”以及“安全围栏”打包为一个标准化的、可复用的 Agent Skill。我们将以课程实验环境 Cherry Studio 为技能工厂,通过四个递进实验——生成章节摘要、原子化切片写入、Dataview 查询与 GraphRAG 分析——完成一个完整的“课程知识管理”技能包的开发与调试。
最终,你产出的不仅是一个工作流,而是一个能随身携带、跨平台运行的数字技能资产。这标志着从“构建智能体”到“封装可复用技能”的思维跃迁。
基础理论:Agent Skill 从 Prompt 工程到能力工程
在深入实战之前,我们需要理解一个根本性问题:为什么 Agent Skills 会在 2025 年末成为 AI 工程领域的焦点?
答案在于,随着大语言模型能力的提升,一个核心矛盾日益尖锐——模型“知道”如何做事,但在具体的业务场景中却无法“稳定地做成”一件事。让 AI 帮忙填写公司报销单,它不知道审批流程;让它按照品牌规范设计海报,它只会自由发挥。传统的解决方案各有缺陷:微调成本高昂、系统提示词会臃肿爆炸、自定义指令无法承载复杂流程、RAG 擅长处理事实却不擅长传授“如何做”的程序性知识。
Agent Skills 的出现,正是为了填补这道“流程知识缺口”。它的核心理念是:将专业领域的“Know-How”封装为一个可复用、可移植、可版本控制的标本章实现了智能体工程的一次关键升级——将分散的能力碎片封装为可复用的标准化模块。准化模块。这标志着 AI 应用开发从“Prompt 驱动”正式迈向“技能驱动”的工程化新阶段。
2.1 起源与演进:从 Claude Skills 到开放标准
Agent Skills 的演进历程,诠释了“先产品打磨,再生态开放”的技术推广路径。
表15-1:Agent Skills 发展历程关键节点
#bvhSMIBfgvRa text { white-space: pre; }#bvhSMIBfgvRa .fb0 { stroke: var(--N900-FG, 0.15); }#bvhSMIBfgvRa .fb0 {stroke: rgba(31,35,41, 0.15)}#bvhSMIBfgvRa .fx0 { stroke-miterlimit: 10; }#bvhSMIBfgvRa .fx0 {stroke-miterlimit: 10}#bvhSMIBfgvRa .fa1 { fill: rgb(187, 191, 196); }#bvhSMIBfgvRa .fa1 {fill: rgb(187, 191, 196)}#bvhSMIBfgvRa .fx1 { font: 400 12px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#bvhSMIBfgvRa .fx1 {font-style: normal}#bvhSMIBfgvRa .fx2 { text-anchor: middle; }#bvhSMIBfgvRa .fx2 {text-anchor: middle}#bvhSMIBfgvRa .fx3 { dominant-baseline: central; }#bvhSMIBfgvRa .fx3 {dominant-baseline: central}#bvhSMIBfgvRa .fx4 { stroke: none; }#bvhSMIBfgvRa .fx4 {stroke: none}#bvhSMIBfgvRa .fc0 { fill: var(--text-caption); }#bvhSMIBfgvRa .fc0 {fill: #646a73}#bvhSMIBfgvRa .fa2 { fill: var(--text-link-disabled); }#bvhSMIBfgvRa .fa2 {fill: rgb(187, 191, 196)}#bvhSMIBfgvRa .fa3 { fill: rgb(31, 35, 41); }#bvhSMIBfgvRa .fa3 {fill: rgb(31, 35, 41)}#bvhSMIBfgvRa .fx5 { font: 700 14px LarkHackSafariFont, LarkEmojiFont, "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, "Noto Sans", Tahoma, "Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Zen Hei", STHeiti, SimHei, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", system-ui; }#bvhSMIBfgvRa .fx5 {font-style: normal}#bvhSMIBfgvRa .fx6 { text-anchor: start; }#bvhSMIBfgvRa .fx6 {text-anchor: start}#bvhSMIBfgvRa .fx7 { dominant-baseline: alphabetic; }#bvhSMIBfgvRa .fx7 {dominant-baseline: alphabetic}#bvhSMIBfgvRa .fc1 { fill: rgb(255, 255, 255); }#bvhSMIBfgvRa .fc1 {fill: rgb(255, 255, 255)}#bvhSMIBfgvRa .fc2 { fill: rgb(5, 16, 26); }#bvhSMIBfgvRa .fc2 {fill: rgb(5, 16, 26)}#bvhSMIBfgvRa .fx8 { font: 400 14px LarkHackSafariFont, LarkEmojiFont, "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, "Noto Sans", Tahoma, "Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Zen Hei", STHeiti, SimHei, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", system-ui; }#bvhSMIBfgvRa .fx8 {font-style: normal}#bvhSMIBfgvRa .fx9 { font: 400 14px 微软雅黑; }#bvhSMIBfgvRa .fx9 {font-style: normal}#bvhSMIBfgvRa .fx10 { font: 700 14px 微软雅黑; }#bvhSMIBfgvRa .fx10 {font-style: normal}#bvhSMIBfgvRa .fb1 { fill: var(--N900-FG, 0.15); }#bvhSMIBfgvRa .fb1 {fill: rgba(31,35,41, 0.15)}#bvhSMIBfgvRa .fb2 { fill: rgb(221, 221, 221); }#bvhSMIBfgvRa .fb2 {fill: rgb(221, 221, 221)}#bvhSMIBfgvRa .fa4 { fill: var(--bg-body); }#bvhSMIBfgvRa .fa4 {fill: #fff}ABC12345时间节点关键事件工程意义2025 年 10 月 16 日2025 年 12 月 18 日2026 年 1 月-2 月2026 年 2 月Anthropic 正式推出 Claude Skills 功能,在 Claude 3.7 Sonnet / Opus 中上线 [3]Anthropic 联合多家生态伙伴在 agentskills.io 正式开源 Agent Skills Specification V1.0,发布官方 SDK(支持 Python、TypeScript、Java)[4]微软 Azure AI Studio 原生支持;GitHub Copilot 实验性支持;Cursor 成为首个全面采用 Agent Skills 的 AI IDE [5]Anthropic 发布 30 余页《Skill 创建指南》,首次系统定义大模型“能力模块化”范式 [7]首次将“技能”作为产品化能力单元,伴随 docx、pdf、pptx、xlsx 等官方文档处理技能一同发布从官方层面确立了 Skill 的设计原则:职责单一、结构化 I/O 与可组合性Skills 从 Claude 专有功能转变为,奠定了生态爆发的协议基础行业级快速跟进,Agent Skills 被 TechCrunch 称为 [6]——让 AI 能力变得可移植、可组合、可版本控制跨平台开放标准“AI 领域的 Dockerfile”
Anthropic 正在复制 MCP 的路径:先在自家产品中打磨,再逐步开放形成生态。Skills 与 MCP 形成互补关系——MCP 解决“能调什么工具”,Skills 解决“如何完成任务流程”。
需要说明的是,当前所谓“Agent Skills Specification”等规范,仍处于生态探索阶段。不同平台在接口形式、加载机制与执行方式上存在差异。
从工程视角看,这一演进背后有一个关键变化:Prompt(表达) → Skill(能力单元)。也就是说,AI 系统正在从“语言交互接口”转向“能力模块接口”。
2.2 技术架构
2.2.1 渐进式披露与自描述能力
从技术层面看,Agent Skills 的核心设计理念是渐进式披露。技能的信息分为三个层次,AI 按需逐步加载。
表15-2:Agent Skills 的三层加载机制
#AuHSxuDSqDno text { white-space: pre; }#AuHSxuDSqDno .fb0 { stroke: var(--N900-FG, 0.15); }#AuHSxuDSqDno .fb0 {stroke: rgba(31,35,41, 0.15)}#AuHSxuDSqDno .fx0 { stroke-miterlimit: 10; }#AuHSxuDSqDno .fx0 {stroke-miterlimit: 10}#AuHSxuDSqDno .fa1 { fill: rgb(187, 191, 196); }#AuHSxuDSqDno .fa1 {fill: rgb(187, 191, 196)}#AuHSxuDSqDno .fx1 { font: 400 12px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#AuHSxuDSqDno .fx1 {font-style: normal}#AuHSxuDSqDno .fx2 { text-anchor: middle; }#AuHSxuDSqDno .fx2 {text-anchor: middle}#AuHSxuDSqDno .fx3 { dominant-baseline: central; }#AuHSxuDSqDno .fx3 {dominant-baseline: central}#AuHSxuDSqDno .fx4 { stroke: none; }#AuHSxuDSqDno .fx4 {stroke: none}#AuHSxuDSqDno .fc0 { fill: var(--text-caption); }#AuHSxuDSqDno .fc0 {fill: #646a73}#AuHSxuDSqDno .fa2 { fill: var(--text-link-disabled); }#AuHSxuDSqDno .fa2 {fill: rgb(187, 191, 196)}#AuHSxuDSqDno .fa3 { fill: rgb(31, 35, 41); }#AuHSxuDSqDno .fa3 {fill: rgb(31, 35, 41)}#AuHSxuDSqDno .fx5 { font: 700 14px LarkHackSafariFont, LarkEmojiFont, "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, "Noto Sans", Tahoma, "Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Zen Hei", STHeiti, SimHei, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", system-ui; }#AuHSxuDSqDno .fx5 {font-style: normal}#AuHSxuDSqDno .fx6 { text-anchor: start; }#AuHSxuDSqDno .fx6 {text-anchor: start}#AuHSxuDSqDno .fx7 { dominant-baseline: alphabetic; }#AuHSxuDSqDno .fx7 {dominant-baseline: alphabetic}#AuHSxuDSqDno .fc1 { fill: rgb(255, 255, 255); }#AuHSxuDSqDno .fc1 {fill: rgb(255, 255, 255)}#AuHSxuDSqDno .fc2 { fill: rgb(5, 16, 26); }#AuHSxuDSqDno .fc2 {fill: rgb(5, 16, 26)}#AuHSxuDSqDno .fx8 { font: 400 14px LarkHackSafariFont, LarkEmojiFont, "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, "Noto Sans", Tahoma, "Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Zen Hei", STHeiti, SimHei, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", system-ui; }#AuHSxuDSqDno .fx8 {font-style: normal}#AuHSxuDSqDno .fx9 { font: 400 11px LarkHackSafariFont, LarkEmojiFont, Consolas, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, "Noto Sans", Tahoma, "Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Zen Hei", STHeiti, SimHei, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", system-ui; }#AuHSxuDSqDno .fx9 {font-style: normal}#AuHSxuDSqDno .fx10 { font: 400 14px 微软雅黑; }#AuHSxuDSqDno .fx10 {font-style: normal}#AuHSxuDSqDno .fb1 { fill: var(--N900-FG, 0.15); }#AuHSxuDSqDno .fb1 {fill: rgba(31,35,41, 0.15)}#AuHSxuDSqDno .fb2 { fill: rgb(221, 221, 221); }#AuHSxuDSqDno .fb2 {fill: rgb(221, 221, 221)}#AuHSxuDSqDno .fa4 { fill: var(--bg-body); }#AuHSxuDSqDno .fa4 {fill: #fff}ABCD1234层次加载时机内容上下文成本第一层:元数据第二层:技能主体第三层:附加资源Agent 启动时预加载AI 判断技能与当前任务相关时仅当技能指令明确引用时约 100 tokens/技能< 5,000 tokens按需加载,无预占成本SKILL.mdnamedescriptionSKILL.mdscripts/references/../assets/ 的 YAML Frontmatter,包含 和 等字段 的 Markdown 正文,包含详细指令、工作流和示例 中的可执行脚本、 中的参考文档、 中的静态资源
图15-1:Agent Skill渐进式披露与自描述机制

这种三层加载机制并非随意设计,而是由大模型的运行约束决定的:
•
上下文窗口有限
•
推理成本随 token 增长
•
无关信息会干扰模型决策
因此,Skill 必须采用按需加载机制,在保证能力完整性的同时控制上下文复杂度。渐进式披露的本质,是在“能力规模”与“上下文成本”之间建立平衡。这种机制类似操作系统中的按需加载(lazy loading),只在需要时引入相关模块,从而保持系统整体效率。
2.2.2 多技能调度:Agent 如何选择正确的 Skill
当同一个 Agent 安装了多个 Skill(例如同时安装了 course-summarizer 和 note-atomizer)时,一个关键的工程问题随之浮现:面对用户的自然语言指令,Agent 如何知道该调用哪一个 Skill?
答案在于一套基于语义匹配的智能路由机制。这套机制并非依赖关键词匹配或预设规则,而是充分利用大语言模型对语义的理解能力,在运行时动态决策。其工作流程分为三个阶段:
表15-3:多技能调度机制的三阶段流程
图15-2:多 Skill 调度机制流程图
这套机制的核心设计思想是 “描述即路由协议” 。SKILL.md 头部的 description 字段不仅是给人看的说明文字,更是模型判断“何时调用该技能”的唯一依据。因此,编写高质量的 description 需要遵循两个原则:
2.3 标准目录结构与最小可行 Skill
在工程实践中,一个规范的 Agent Skill 需要遵循统一的目录结构。这不仅是代码整洁的要求,更是确保技能可被不同客户端正确解析的前提。
2.3.1 标准目录结构
一个完整的 Agent Skill 项目应遵循以下目录组织:
代码块
Python
🍰
•
SKILL.md:技能的“接口说明书”。定义技能的名称、描述、输入输出规范及使用约束。这是客户端识别技能的入口。
•
prompt.md:技能的“推理核心”。包含完整的角色设定、任务目标、执行规则和输出格式要求。
2.3.2 最小可行 Skill
一个最小可行 Skill(Minimum Viable Skill,MVS)必须包含以下三个核心文件:
•
SKILL.md:定义技能元数据与接口 -> 行为逻辑(如何做)
•
prompt.md:定义推理逻辑-> 数据结构(做成什么样)
•
schema.yaml:定义输入输出契约 -> 接口定义(如何调用)
三者构成一个最小闭环,使 Skill 可以被可靠加载与复用,其他目录和文件均为可选增强。
2.4 核心文件设计规范
2.4.1 SKILL.md——技能定义文件
SKILL.md 是技能的“接口说明书”。客户端通过解析该文件来决定何时触发技能、如何调用技能。
标准结构如下:本章实现了智能体工程的一次关键升级——将分散的能力碎片封装为可复用的标准化模块。
代码块
Markdown
# Skill:
## 1. Description
描述这个技能做什么。必须用一句话清晰说明,这是 AI 判断是否触发技能的关键依据。
## 2. Input Schema
引用 `schema.yaml` 中定义的输入结构。
## 3. Output Schema
定义输出结构,可引用 `schema.yaml` 或直接描述。
2.4.2 prompt.md——推理核心
prompt.md 是技能的“大脑”。它定义了 AI 在执行技能时应遵循的完整推理框架。
标准结构如下:
代码块
Markdown
# ROLE
你是一个<角色>
这个结构与课程第 2 章的 S.C.O.R.E. 模型高度契合:ROLE 对应 Setting,TASK 对应 Objective,RULES 对应 Requirements,OUTPUT FORMAT 对应结构化输出的约束。
2.4.3 schema.yaml——数据契约
schema.yaml 是技能的“数据契约”。它用结构化语言定义了技能的输入参数和输出格式。
代码块
Plain Text
这种契约化定义确保了下游系统(如工作流引擎、API 调用方)能够可靠地解析技能的输出结果。这与课程第 6 章“数据契约”的思想一脉相承。
2.5 Skill 封装的设计原则
高质量的 Agent Skill 遵循四项核心设计原则。这些原则直接决定了技能的可维护性、可复用性和可组合性。
表15-4:Skill 封装设计原则
这些原则并非新发明,而是经典软件工程思想在 AI 系统中的延续。区别在于:在传统系统中,我们模块化代码;在 Agent 系统中,我们模块化能力。单一职责保证边界清晰,稳定 I/O 确保系统可对接,无状态设计保证运行稳定,可组合性使复杂任务可以被拆解与重组。
2.6 生态现状:爆发中的技能经济
2.6.1 全球生态规模
截至 2026 年初,Agent Skills 的全球生态规模已相当可观:
•
技能数量:截至 2026 年初,主流 Agent Skills 市场(如 SkillsMP)已收录超过 66,000 个技能,部分聚合平台显示规模已超过 80,000 个,且仍在快速增长。
•
平台支持:支持该标准的主流平台达 20多家。微软、Atlassian、Figma、Canva 等企业已为其平台构建了官方 Skills。
•
社区规模:Anthropic 在 GitHub 上的 Skills 仓库星标数已超过11.5 万 。Vercel 于 2026 年 1 月 20 日发布的 skills.sh 平台,已成为技能生态的中央注册中心 。
•
标准化进程:Linux 基金会已启动讨论,拟将 Agent Skills 纳入其 AI & Data 基金会(AIDF)的候选标准之一 。
•
2.6.2 国内生态爆发
中国市场展现出极强的跟进速度与技术消化能力。
字节跳动旗下“扣子”平台于 2026 年 1 月 19 日上线“技能商店”,成为首个国内大厂跟进者 [1]。腾讯云于 2026 年 3 月发布 Agent 产品全景图,将腾讯会议、腾讯文档等办公应用全面 Skills 化 [2]。阿里云魔搭社区通过开源项目 MS-Agent 实现了 Agent Skills 协议 [3]。智谱 AI 发布的 GLM-5 系列模型具备开源 SOTA 级 Agent 能力 [4]。
表15-4:国内 Agent Skills 生态主要平台一览
截至 2026 年初,国内主流 AI 平台已普遍开始支持 Agent 能力扩展机制(如插件、工具调用或技能模块),并逐步探索基于 Skill 的能力封装与复用模式。与此同时,中文社区中围绕 Prompt、工具链与 Agent 工作流的能力模块已形成较大规模积累。
Skill 的爆发,本质是“能力模块化 + 分发机制”的结合。
2.6.3 中美生态差异
中美智能体平台呈现“美国重底座、中国重场景”的总体格局——美国在定义 AI 能力的技术天花板方面仍具领先优势,而中国则在技术扩散速度、产业落地效率以及商业应用规模方面展现出明显优势。
2.7 OpenClaw:Agent Skills 的工业化实现
OpenClaw 是一个开源的、可本地部署的 AI 智能体框架。该项目在 2026 年初快速迭代,并在短时间内获得了开源社区的广泛关注,在 GitHub 上实现了显著的 Star 增长,成为近期 AI Agent 领域中增长较快的开源项目之一。
与传统的 coding agent 不同,OpenClaw 更接近一种持续运行的事件驱动型 Agent——它可以长期运行,持续接收事件并触发执行。
表15-6:Claude Skills 与 OpenClaw Skills 的核心区别
Claude Skills 是 Anthropic 平台生态的一部分,而 OpenClaw 是一个独立的智能体应用,能够消费来自多种来源的 AI 能力。两者虽然都使用 SKILL.md 格式,但工程实现路径截然不同——OpenClaw 将 Skills 作为一种“被描述、被理解、被按需调用的能力”,启动时扫描技能目录,压成一份 <available_skills> 清单塞进 system prompt,由模型自己判断要不要选一个 Skill,再通过 Read 工具读取。
⚠️ 幻觉警示:Skill 生态的安全隐忧
Skill 生态的扩张速度正在显著快于其安全治理能力。已有多项安全研究表明,在大规模技能市场与插件生态中,存在不同程度的安全风险,包括数据泄露、权限滥用以及 prompt injection 等问题。部分案例显示,未经审查的 Skill 可能在用户不知情的情况下执行隐蔽的数据传输或恶意操作。
在缺乏统一审核机制的情况下,社区逐步形成了一些经验性安全策略,例如优先选择下载量较高、发布时间较长的 Skill,以降低潜在风险。
2.8 MCP 与 Agent Skills:黄金搭档
MCP 与 Agent Skills 并非替代关系,而是互补关系。
•
MCP 是“工具箱”:解决“模型能用什么”——标准化地连接外部数据和工具。
•
Agent Skills 是“操作手册”:解决“模型该怎么用”——封装专业工作流与知识。
需要说明的是,当前所谓“Agent Skills Specification”等规范本章实现了智能体工程的一次关键升级——将分散的能力碎片封装为可复用的标准化模块。,仍处于生态探索阶段。不同平台在接口形式、加载机制与执行方式上存在差异,因此更准确地理解应为:
一种“跨平台能力封装规范”的探索,而非完全统一的工业标准。
从工程视角看,这一演进背后有一个关键变化:Prompt(表达) → Skill(能力单元)。也就是说,AI 系统正在从“语言交互接口”转向“能力模块接口”。Skills 与 MCP 形成互补关系——MCP 解决“能调什么工具”,Skills 解决“如何完成任务流程”。
表15-7:MCP 与 Agent Skills 的多维度对比
图15-3:MCP 与 Agent Skills 互补关系对比图
两者的协同模式是:Skill 提供推理框架与执行流程,MCP 提供数据访问与工具执行。
2.9 技能与课程知识体系的映射
一个精心设计的 Agent Skill,能够完美承载本课程前三阶段的核心技术资产:
表15-8:Agent Skill 对课程核心技术的封装映射
实战演练:构建一个完整的“课程知识管理”技能
总体目标:为《零基础构建智能体工程》课程构建一个专属的智能体技能。它能自动读取课程讲义,生成章节摘要,将摘要切分为原子化知识点卡片并存入 Obsidian,最终支持通过 Dataview 和 GraphRAG 进行知识的查询与可视化,并具备安全审查能力。
3.1 实验准备:初始化技能项目与环境
3.1.1 模型配置流程
由于 Agent 功能依赖模型,我们需要先在全局配置好 ModelScope 的 Qwen 模型,再创建 Agent。
在 Cherry Studio 里使用 Agent Skills 时,选择兼容 Anthropic 端点类型 的模型,是确保 course-knowledge-manager 技能能够正常工作的关键前提。这是因为 Agent Skills 的核心机制(如渐进式披露、工具调用)深度依赖 Anthropic API 的特定格式,例如其 messages API 和工具调用(Tool Use)规范。
主流模型也提供了 Anthropic 兼容接口,但是 Cherry Studio 内置的模型配置选项,无法自定义模型的端点设置。为了确保实验成功,我们可以自动配置模型的选项支持 Antthropic 端点类型。
配置的具体步骤:
进入模型配置:打开 Cherry Studio,点击右下角的 设置,在左侧菜单选择 **“模型提供商” **(Model Provider)。
新增自定义提供商:点击提供商列表的 “Add” 按钮,在弹出的配置窗口中,进行如下关键设置。
•
Provider Name:输入一个易于识别的名称,例如 Qwen。
•
Provider Type:**必须从下拉菜单中选择 Anthropic**。
•
API Key:填入你从 ModelScope 获取的有效 API Key(MODELSCOPE_ACCESS_TOKEN)。
•
API Host:填入 https://api-inference.modelscope.cn(注意:不带 /v1 后缀,系统会根据 Provider Type 自动拼接 /v1/messages 路径)。
图15-4:填写模型 Provider Type
图15-5:填写模型配置信息
点击 OK 保存这个新提供商。
3.1.2 创建 Agent 并配置基础环境
首先,我们需要创建一个专门的 Agent,它将作为我们“课程知识管理”技能的运行环境。
进入 Agents 管理页:启动 Cherry Studio,点击页面中央或右上角的 + Add Agent 按钮(图15-01),开始创建我们的专属 Agent。
图15-06:点击 Add Agent 按钮
配置 Agent:在弹出的 “Add Agent” 界面中(图15-02),进行如下配置:
图15-07:Add Agent 配置界面
配置选项样例:
•
Name:输入 Course Notes Agent。
•
Model:选择一个支持 Function Calling(工具调用)的模型。此处以 Qwen/Qwen3.5-122B-A10B 为例。
•
Permission mode:选择 Normal Mode。此模式允许你在对话中手动批准或拒绝 AI 的工具调用请求。
•
Accessible directories:点击并选择你的课程讲义所在的根目录。Agent 将被授权访问该目录及其子目录下的所有文件。
•
Prompt(可选):你可以在此处预设一些通用的 System Prompt,或者留空。我们将在后续的 prompt.md 文件中定义更具体的指令。
保存 Agent:完成配置后,点击保存。此时你已成功创建 Course Notes Agent。
启用必要工具权限:
在 Agent 设置页面的 Tools 区域,确保以下工具处于启用状态(开关为开启),以便 Skill 能够正常读写文件:
◦
Read:读取文件内容。
◦
Edit:对文件进行针对性编辑。
◦
Write(或 MultiEdit):写入或批量修改文件。
图15-08:工具权限列表(确保 Edit/Write 等工具已启用)
3.1.3 关于 MCP 配置的说明
本章的实验将直接使用 Cherry Studio Agent 内置的文件处理能力(如读取讲义文件、写入笔记等),因此无需额外配置 MCP Server。但这并不意味着 Skill 不需要 MCP。
本次实验之所以能跳过 MCP 配置,是因为 Agent 的内置工具已经覆盖了我们的基础需求(文件读写、目录扫描)。在实际工程中,当你需要的能力超出 Agent 内置范围时——例如连接特定数据库、调用第三方 API、操作专属硬件——MCP 就是扩展 Skill 能力边界的关键协议。一个完整的 Agent Skill 架构,正是 Skill(编排层) + MCP(执行层) 的有机组合。
3.1.5 查看已安装 Skill
完成 Agent 创建后,你可以进入 Agent 的设置页面,在 Plugins 区域查看已安装的插件。
图15-9:打开Agent Skill技能文件倒入界面
在接下来的实验中,我们将通过“从本地文件夹导入”的方式,将刚才创建的技能加载为插件。届时它将出现在 Installed Plugins 列表中,并可供 Course Notes Agent 调用。
图15-10:导入 Agent Skill技能文件压缩包
你可以点击 Available Plugins 标签页,浏览社区提供的各类插件。当未来你的技能需要连接数据库、搜索网页或调用特定 API 时,可以在此处安装对应的 MCP 插件来扩展 Agent 的能力边界。
至此,我们的实验环境已准备就绪。你拥有了一个名为 Course Notes Agent 的专用 Agent,一个本地的技能项目文件夹 course-knowledge-manager,并且 Agent 的内置工具已经能够满足本章四个实验的所有文件操作需求。在实验一中,我们将正式编写技能的核心文件,并导入使用。
3.2 实验场景
3.2.1 实验一:生成课程每章知识点的归纳与总结
Skill 名称:course-summarizer
实验目标:编写技能的核心文件,使其能够读取课程讲义并生成结构化章节摘要。
预期输出:一个包含所有章节的结构化 Markdown 表格。
图15-11:实验一输出样例效果
步骤 1:初始化技能文件夹
在本地创建技能文件夹 course-summarizer,结构如下:
代码块
Plain Text
course-summarizer/
├── SKILL.md
├── prompt.md
└── schema.yaml
步骤 2:编写 SKILL.md
代码块
YAML
---
name: course-summarizer
description: 为《零基础构建智能体工程》课程提供知识管理能力,能够读取课程讲义并生成章节摘要的结构化 Markdown 表格。
version: 0.1.0
author: Gitconomy Reserch-郭晧
license: MIT
步骤 3:编写 prompt.md
代码块
Markdown
步骤 4:编写 schema.yaml
代码块
YAML
步骤 5:打包技能为 ZIP 压缩包
将 course-summarizer/ 文件夹中的三个核心文件(SKILL.md、prompt.md、schema.yaml),压缩为一个 ZIP 格式的压缩包,命名为 course-summarizer.zip。
操作要点:
•
压缩整个文件夹:不要直接压缩三个文件,而是压缩包含这些文件的 course-summarizer/ 文件夹。ZIP 解压后应得到一个名为 course-summarizer 的文件夹,其内部直接包含 SKILL.md 等文件。
•
确保 YAML 文件在根目录:SKILL.md、prompt.md、schema.yaml 必须位于 ZIP 包解压后的根目录下,不要嵌套多层文件夹。
•
Mac/Linux 用户:可使用终端命令 zip -r course-summarizer.zip course-summarizer/。
•
Windows 用户:右键点击 course-summarizer/ 文件夹,选择“发送到 → 压缩(zipped)文件夹”,然后将生成的 .zip 文件重命名为 course-summarizer.zip。
步骤 6:测试验证
导入技能:按照 3.1.4 节的方法,将 course-summarizer 文件夹导入为 Agent 插件。
发起对话:在 Cherry Studio 中选中 Course Notes Agent,输入以下指令:
请扫描我的课程讲义目录`/home/wguo/Documents/MyDev/Obsidian/Git4GenThinking/docs/module-notes`,读取所有章节文件,并生成一份章节摘要汇总表。
3.2.2 实验二:将知识点总结进行原子化切片存储
Skill 名称:note-atomizer
实验目标:创建一个独立、无状态的技能。它接收一个已生成的章节摘要表格文件(Markdown 格式)作为输入(实验1生成的结果),将其中的核心概念拆分为原子笔记,并写入 Obsidian 知识库的指定目录。技能不依赖任何对话上下文,所有必要信息均通过用户指令一次性传入。
预期输出:“全部写入完成后,Agent 会在对话中输出一份简要的写入结果摘要,
图15-12:实验二输出样例效果
步骤1:准备摘要表格文件
在调用 note-atomizer 技能之前,你需要先准备好一个有效的章节摘要表格文件(Markdown 格式)。该文件是技能的必需输入。你可以通过以下任一方式获取:
完成实验一后,对话界面会显示一个完整的 Markdown 表格。
选中表格的全部内容(包括表头行和分隔行),复制。
在 Agent 的 Accessible directories 路径下,创建一个新文件,命名为 chapter-summary.md。
将复制的内容粘贴进去,保存文件。
⚠️ 无状态设计说明
note-atomizer 技能遵循无状态(Stateless)原则,不依赖任何对话历史或上下文记忆。因此,你不能直接对它说“基于刚才的表格”,而必须显式提供摘要表格文件的完整路径。这一设计确保了技能在任何时间、任何对话中都能独立、可复现地运行。
步骤 2:初始化技能文件夹
在本地创建技能文件夹 note-atomizer/,结构如下:
代码块
Plain Text
note-atomizer/
├── SKILL.md
├── prompt.md
├── schema.yaml
└──../assets/
└── atomic-note-template.md
步骤 3:编写Skill文件
SKILL.md文件
代码块
YAML
---
name: note-atomizer
description: 将章节摘要表格文件拆分为独立原子笔记并写入指定目录,支持 Obsidian 知识库管理。
version: 0.1.0
author: Gitconomy Research-郭晧
license: MIT
---
# Skill: note-atomizer
## 1. Description
读取已生成的章节摘要表格文件(Markdown 格式),将其中的每一个核心概念拆分为独立的原子笔记,并写入指定的目标目录。当用户需要将课程知识点切片为可独立检索的原子卡片时使用。
## 2. Input Schema
本技能需要用户在对话指令中**一次性提供**以下参数(定义于 `schema.yaml`):
- `summary_file_path` (string):已生成的章节摘要表格文件的完整路径。
- `target_directory` (string):原子笔记写入的目标目录完整路径。
技能本身是无状态的,不依赖任何对话历史或上下文记忆。每次调用时,用户必须显式提供上述两个路径。
编写prompt.md文件
代码块
TypeScript
# ROLE
你是一位精通知识切片与原子化笔记构建的知识工程师。
# TASK
读取用户指定的章节摘要表格文件(Markdown 格式),解析其中的核心概念,将每一个核心概念拆分为独立的原子笔记,并调用内置的 `Write` 工具写入用户指定的目标目录。
# INPUT
用户将在对话指令中**一次性提供**以下两个路径:
- 章节摘要表格文件的完整路径。
- 原子笔记写入的目标目录完整路径。
# RULES
- 格式模板**:在生成每个原子笔记之前,必须先读取 `../assets/atomic-note-template.md` 文件,并严格遵循其中定义的 YAML Frontmatter 结构。
- type 字段取值规 执行安全扫描
在终端中,对待审查的技能文件夹执行扫描命令:则:根据概念的性质,从以下枚举中选出一项或多项最匹配的分类,以 YAML 数组格式输出(例如 `[protocol, framework]`):
- `concept`:通用概念,无法归入下述具体分类时使用
- `architecture`:系统架构或拓扑结构(如存算分离架构、客户端-服务端架构)
编写schema.yaml文件
代码块
YAML
编写atomic-note-template.md文件
代码块
YAML
步骤4:打包技能为 ZIP 压缩包
将 note-atomizer/ 文件夹压缩为 note-atomizer.zip。
操作要点:
•
压缩整个文件夹(而非单独文件),确保解压后根目录直接包含 SKILL.md 等文件。
•
Mac/Linux:zip -r note-atomizer.zip note-atomizer/
•
Windows:右键文件夹 → “发送到 → 压缩(zipped)文件夹”,重命名为 note-atomizer.zip。
步骤5:导入技能并测试验证
导入技能:
◦
进入 Cherry Studio 的 Agent 设置页面。
◦
将 note-atomizer.zip 拖拽到 Installed Plugins 区域的上传框。
◦
导入成功后,note-atomizer 将出现在插件列表中。
•
发起对话:在对话界面选中 Course Notes Agent,输入以下指令(将两个路径替换为你的实际路径):
代码块
Plain Text
请读取 `/home/wguo/Documents/Obsidian/Git4GenThinking/tutorials/chapter-summary.md` 文件中的章节摘要,将每个核心概念拆分为原子笔记,并写入 `/home/wguo/Documents/Obsidian/Git4GenThinking/tutorials/atomic-notes/` 目录。
3.2.3 实验三:实现知识点的 Dataview 查询与 GraphRAG 可视化
Skill 名称:dataview-query-generator
实验目标:创建一个独立、无状态的技能。它接收一个原子笔记目录路径和分析类型作为输入,能够生成两种输出:Dataview 查询代码(用于在 Obsidian 中检索特定知识点),或 GraphRAG 知识网络分析报告(用于理解知识库的整体结构)。技能不依赖任何对话上下文,所有必要信息均通过用户指令一次性传入。
预期输出:
图15-13:实验三Dataview输出样例效果
图15-14:实验三GraphRAG输出样例效果
步骤1:准备原子笔记目录
在调用 knowledge-graph-analyzer 技能之前,你需要先准备好一个包含原子笔记的目录。该目录是技能的必需输入。你可以通过以下方式获取:
•
使用实验二的输出:实验二成功执行后,会在你指定的目标目录(如 `/path/to/Obsidia 执行安全扫描
•
手动创建测试目录:如果尚未完成实验二,可手动创建一个测试目录,并在其中放入几个符合格式的原子笔记文件(可参考实验二的输出示例)。
⚠️ 无状态设计说明
knowledge-graph-analyzer 技能遵循无状态(Stateless)原则,不依赖任何对话历史或上下文记忆。因此,你不能直接对它说“分析刚才那些笔记”,而必须显式提供原子笔记目录的完整路径和分析类型。这一设计确保了技能在任何时间、任何对话中都能独立、可复现地运行。
步骤2:初始化技能文件夹
在本地创建技能文件夹 dataview-query-generator/,结构如下:
代码块
Plain Text
步骤 3:编写Skill文件
SKILL.md文件
代码块
Markdown
---
name: dataview-query-generator
prompt.md文件
代码块
Markdown
# ROLE
你是一个严格遵循指令的 Dataview 查询代码生成器。你的唯一任务是根据用户提供的参数生成一段 Dataview 代码,不做任何额外的事。
# TASK
根据以下参数生成 Dataview 查询代码,并调用 `Write` 工具写入输出文件。
# INPUT
- `target_directory`:原子笔记目录的相对路径(例如 `tutorials/atomic-notes`)
- `filter_field`:筛选字段名(例如 `type`)
- `filter_value`:筛选值(例如 `mechanism`)
- `display_fields`:要显示的字段列表(例如 `created, status, tags`)
- `output_file_path`:输出文件的绝对路径
# 强制输出格式(必须逐字遵守)
你写入文件的内容**必须**严格如下,不得有任何增减:
schema.yaml文件
代码块
YAML
input:
target_directory:
type: string
description: 原子笔记所在的 Obsidian 库内目录路径(相对于库根目录)
required: true
query_requirements:
type: string
description: 用自然语言描述的查询条件
required: true
output_file_path:
type: string
description: 生成的 Dataview 查询代码的输出文件完整路径
required: true
output:
summary:
type: object
description: 写入结果摘要
步骤4:打包技能为 ZIP 压缩包
将 knowledge-graph-analyzer/ 文件夹压缩为 knowledge-graph-analyzer.zip。
操作要点:
•
压缩整个文件夹(而非单独文件),确保解压后根目录直接包含 SKILL.md 等文件。
•
Mac/Linux:zip -r knowledge-graph-analyzer.zip knowledge-graph-analyzer/
•
Windows:右键文件夹 → “发送到 → 压缩(zipped)文件夹”,重命名为 knowl⚠️ edge-graph-analyzer.zip。
步骤5:导入技能并测试验证
导入技能:
◦
进入 Cherry Studio 的 Agent 设置页面。
◦
将 knowledge-graph-analyzer.zip 拖拽到 Installed Plugins 区域的上传框。
◦
导入成功后,knowledge-graph-analyzer 将出现在插件列表中。
测试 Dataview 查询生成:
输入以下指令(将路径替换为你的实际原子笔记目录):
代码块
Plain Text
请列出`/home/wguo/Documents/Obsidian/Git4GenThinking/tutorials/atomic-notes/ 目录下所有类型为mechanism的原子笔记,请生成 Dataview 查询,参数如下:
- target_directory: tutorials/atomic-notes
- filter_field: type
- filter_value: mechanism
- display_fields: created, status, tags, source_chapter
- output_file_path: /home/wguo/Documents/Obsidian/Git4GenThinking/tutorials/queries/mechanism-query.md
观察 Agent 是否输出一段语法正确的 Dataview 代码。
测试 GraphRAG 报告生成:
输入以下指令:
代码块
Plain Text
请分析 `/path/to/atomic-notes/` 目录下的原子笔记,生成一份 GraphRAG 知识网络分析报告。
观察 Agent 是否依次读取目录下的所有 .md 文件,并输出一份包含枢纽节点、孤立节点、社区聚类和健康度评分的结构化报告。
好的,我们来设计实验三-B:生成知识网络分析报告(对应你提到的“实验4”)。该技能名称为 knowledge-network-analyzer,目标是分析指定目录下的原子笔记,生成一份结构化的知识网络分析报告。
3.2.4 实验四:生成知识网络分析报告
Skill 名称:knowledge-network-analyzer
实验目标:创建一个独立、无状态的技能。它接收原子笔记目录路径和输出文件路径,分析目录下所有 .md 文件的 YAML 元数据和双向链接,生成一份包含核心枢纽节点、知识孤岛、主题聚类和健康度简评的知识网络分析报告。
预期输出:
图15-15:实验四知识网络输出样例效果
⚠️ ##### 步骤1:准备原子笔记目录
•
已完成实验二,atomic-notes 目录下存在多个原子笔记文件。
•
原子笔记的 YAML Frontmatter 包含 type、tags 等字段,正文中存在 [[笔记名]] 双向链接。
步骤 2:初始化技能文件夹
在本地创建 knowledge-network-analyzer/ 文件夹:
代码块
Plain Text
knowledge-network-analyzer/
├── SKILL.md
├── prompt.md
├── schema.yaml
└── examples/
步骤3:编写核心文件
SKILL.md
代码块
YAML
prompt.md文件
代码块
Markdown
# ROLE
你是一位精通知识网络分析的数据工程师。
# TASK
读取指定目录下的所有原子笔记(`.md` 文件),仅解析其 YAML 元数据和双向链接,生成一份知识网络分析报告,写入输出文件。
schema.yaml文件
代码块
YAML
input:
target_directory:
type: string
description: 原子笔记目录的相对路径(例如 tutorials/atomic-notes)
required: true
output_file_path:
type: string
description: 输出报告的绝对路径
required: true
output:
status: string
output_file: string
步骤4:打包技能
将 knowledge-network-analyzer/ 文件夹压缩为 knowledge-network-analyzer.zip。
步骤5:导入并测试
将 ZIP 包导入 Cherry Studio 的 Agent 插件列表。
在对话中输入测试指令:
请分析 `tutorials/atomic-notes` 目录下的原子笔记,生成一份知识网络分析报告,并保存到 `/home/wguo/Documents/Obsidian/Git4GenThinking/tutorials/reports/network-report.md`。
观察 Agent 是否依次调用 list_files 和 Read 工具,并最终生成报告文件。
预期输出示例
对话摘要:
代码块
Plain Text
报告文件内容示例:
代码块
Markdown
# 原子笔记知识网络分析报告
## 一、核心枢纽节点
| 笔记名 | 被引用次数 | type |
| :--- | :--- | :--- |
| MCP协议 | 5 | [protocol, framework] |
3.2.5 实验五:技能安全审查与风险管控
实验目标: 让学员意识到 Agent Skills 生态中的安全隐患,掌握一套可操作的安全审查流程。学员将学习如何在使用技能前进行安全评估,使用社区工具扫描潜在风险,并建立个人的技能可信度决策框架。
前置条件:
•
已完成实验一至四,拥有可运行的 Skill 技能。
•
已了解第 12 章“安全围栏”中的人机协同(HITL)与风险分级思想。
步骤 1:理解技能安全的威胁模型
在安装任何来自社区的 Skill 之前,必须了解潜在的威胁类型。根据安全社区的研究,恶意 Skill 可能执行以下操作:
•
数据外泄:读取本地文件(如 .env、~/.ssh/id_rsa)并发送至远程服务器。
•
环境变量窃取:获取 API_KEY、DATABASE_URL 等敏感信息。
•
命令执行:通过 scripts/ 中的脚本执行任意系统命令。
•
提示词注入:在 SKILL.md 中植入隐藏指令,劫持 AI 行为。
步骤 2:学习安全审查清单
在安装一个 Skill 之前,对照以下清单逐项检查:
步骤 3:使用安全扫描工具
skillsio 的技能系统中,**name 和 description** 是 Skill 的两个核心元信息字段,必须写在 SKILL.md 文件的开头,用于标识和识别技能。
代码块
YAML
---
name: course-summarizer
description: 为《零基础构建智能体工程》课程提供知识管理能力,能够读取课程讲义并生成章节摘要的结构化 Markdown 表格。
version: 0.1.0
author: Gitconomy Reserch-郭晧
license: MIT
示例输出:
代码块
SQL
cd /home/wguo/Documents/Obsidian/Git4GenThinking/tutorials/.claude/skill
skillsio add ./course-summarizer
npx skillsio add ./course-summarizer
███████╗██╗ ██╗██╗██╗ ██╗ ███████╗██╗ ██████╗
██╔════╝██║ ██╔╝██║██║ ██║ ██╔════╝██║██╔═══██╗
⚠️ 说明:课程使用 skillsio 对 Skill 进行扫描,是引起大家对 Skill 安全的重视。 skillsio 目前还没有和 Cherry Studio 完成适配,我们只是观察其扫描的结果,不用使用其安装到./agent 目录后的文件。如果是 Clause Code、Curso,扫描后自动加载该技能。
步骤 4:在技能中嵌入安全声明
作为技能的开发者,有责任让使用者信任你的技能。为 prompt- 在 README.md 中增加“安全与隐私”章节:
代码块
Plain Text
工程要点:本实验将安全意识从“被动接受”转变为“主动审查”,培养学员在享受 AI 能力爆发的同时,建立起必要的工程防御思维。这与第 12 章的安全围栏形成呼应——软围栏(Prompt 约束)和硬围栏(代码拦截)之外,还需要人的围栏(安全审查)。
本章总结
本章实现了智能体工程的一次关键升级——将分散的能力碎片封装为可复用的标准化模块。在 Agent Skills 出现之前,我们依赖 S.C.O.R.E. 提示词、PEAR 工作流和 MCP 工具链来构建智能体——这些资产虽强大,却是零散的、一次性的。Agent Skills 的核心理念,是将这些分散的“能力碎片”封装为一个可复用、可组合、可验证的标准化模块。用工程语言表达,就是 Skill = Prompt(推理逻辑) + Workflow(执行流程) + Tool(MCP 工具) + Constraint(安全与契约)。这一封装机制,标志着 AI 开发的基本单位正在从 Prompt 迁移到 Skill。
通过四个递进实验——结构化提取、原子化切片、图谱查询与安全审查——你将一个课程知识管理 MVA 迭代为遵循开放规范的数字技能资产。你亲身体验了“Skills 负责编排,MCP 负责执行”的黄金组合,也建立了从技能使用到安全审查的完整工作流。最终,你获得的不仅是一个可运行的技能包,更是一套将专业知识转化为可分发 AI 能力的工程方法论。在未来,衡量 AI 工程师的核心指标,将从“会写 Prompt”转变为“会封装 Skill”。
💡AI 开发的基本单位,正在从 Prompt 迁移到 Skill。
课后思考
技能的粒度设计:一个 Skill 应该只做一件事。如果功能过于复杂,应如何拆分?
查询生成的鲁棒性:如何确保生成的 Dataview 查询在不同用户知识库中都能正确运行?
GraphRAG 的本地化实现:如何在 scripts/ 中实现真正的 GraphRAG 社区摘要算法?
国内生态的机遇与挑战:为国内用户设计 Skill 时,需要额外考虑哪些因素?
附录 1:核心概念术语表