
最近翻阅 Microsoft Agent Framework (MAF) 的源码时,发现它已经悄悄地推进到了 RC5 版本。这次更新中最值得关注的变化,是 Agent Skills 的能力边界发生了显著演变。它不再局限于“读知识”,而是开始向“可执行能力”迈进。最直接的信号就是 .NET 侧关于 scripts 的运行链路已经基本接上。
这为什么重要?因为它意味着 Skill 的定位正在发生根本性变化:以前它更像一个知识包,而现在正演进为能力包,未来很可能成为真正的 Agent 运行时插件。如果说之前的文章解决了“如何让 Agent 知道什么”,那么这次更新则是在回答“如何让 Agent 在受控边界内做什么”。
这次,我们来深入探讨几个问题:
- RC5 到底变了什么?
scripts 支持意味着什么?
- Skill 为什么不该再被理解成“提示词附件”?
- 如果你准备在企业项目里往前走,架构上应该怎么想?
本篇收获
阅读后,你会更清楚以下几件事:
- 理解演进:明白 RC5 阶段 Agent Skills 的能力边界与之前版本的根本不同。
- 抓住信号:理解 Skill 从“静态知识模块”向“可执行能力模块”演进的核心信号。
- 看懂架构:看懂 .NET 源码中 Skills 的 4 层架构:对象层、Source 层、Decorator 层、Provider 层。
- 洞察本质:看懂
run_skill_script 背后真正重要的,不是“能不能跑脚本”,而是“谁来控制执行边界”。
- 指导实践:了解在企业里落地 Skills 时,为何要将知识型、动态上下文型、动作执行型分开设计。
回顾:之前解决了什么问题?
上一篇文章的核心是 MAF 如何集成 Agent Skills,让 Agent 拥有领域专长。其核心价值体现在两个层面:
-
解决了“领域知识如何模块化”的问题
过去让 Agent 懂报销、审批、FAQ 等知识,通常塞进 System Prompt、写死在代码或用 RAG。相比之下,Skills 的优势是结构清晰、维护成本低、非开发者也能参与,并能通过渐进式披露减少 Token 消耗。
-
解决了“知识何时进上下文”的问题
- Advertise:先告诉模型“我有哪些技能”(仅名称和描述)。
- Load:模型命中某个 Skill 后,再通过
load_skill 加载完整说明。
- Read:需要时再通过
read_skill_resource 读取 FAQ、模板等补充材料。
所以,之前的重点是解决 如何让 Agent 在不浪费上下文的前提下,按需获取领域知识。而 RC5 的关键在于,它开始继续往前走,让 Agent 能“做”更多。
RC5 的关键:Scripts 闭环,是质变而非量变
如果你还把 Skill 理解成“一个 SKILL.md 文件夹”,那很容易低估 RC5 的意义。这次真正关键的,不是目录结构或字段变化,而是:
Skill 正在从“让模型知道更多”升级为“让模型在受控边界内做更多”。
这是质变。因为“知道什么”和“能做什么”,在系统设计上难度完全不同。
当 Skill 只负责知识时,处理的是内容组织、上下文成本控制、资源引用和内容规范。但当 Skill 开始触发脚本执行时,问题立刻升级为:
- 谁来发现脚本?
- 如何向模型描述参数结构?
- 脚本失败后结果如何返回?
- 哪些脚本允许执行?是否需要审批?是否要审计?是否要沙箱化和限权?
一旦进入 scripts,Skill 就不再只是知识治理问题,而开始变成运行时能力治理问题。
Skill 的本质:从“知识包”到“能力包”
官方对 Agent Skills 的定义一直很清晰:它是由指令、脚本、资源组成的可移植能力包。以前人们只盯着“指令”和“资源”,但 RC5 让 scripts 的信号变得极强。
现在如果用一句话概括 Skill,应该是:
Skill 不是提示词的附件,而是 Agent 的模块化能力单元。
它包含至少 4 个层次:
- 发现层信息:让模型知道“有什么可用能力”。
- 技能正文:让模型知道“应该怎么做”。
- 资源层:让模型知道“需要时去哪里查资料”。
- 脚本层:让模型知道“在满足条件时可以触发什么动作”。
从源码看 MAF 的 4 层 Skills 架构
从当前 .NET 源码看,MAF 对 Skills 的实现非常工程化,清晰拆分为 4 层:
- 对象层:定义 Skill 是什么
- Source 层:定义 Skill 从哪里来
- Decorator 层:定义 Skill 怎么过滤、去重、组合
- Provider 层:定义 Skill 怎么进入 Agent 运行时

第一层:对象层——清晰建模 Skill
核心是 AgentSkill,它将 Skill 抽象为 4 个核心部分:Frontmatter、Content、Resources、Scripts。这表示框架关注的是 Skill 运行时所需的最小抽象,而非具体存储形式。
AgentSkillFrontmatter 的意义:前移规范
name、description、compatibility 等字段有严格约束(如长度、kebab-case 格式)。这体现了成熟的工程取向:不要寄望于自觉遵守,而是变成代码约束。这样做让 Skill 信息更稳定,问题更容易在构造阶段暴露。
Resource 和 Script 的统一抽象
AgentSkillResource:通过 ReadAsync() 提供读取能力。
AgentSkillScript:通过 RunAsync() 提供执行能力。
这意味着,无论 Skill 来自文件还是代码动态构造,在运行时都会被收敛为统一接口。只有这样,Provider 才能稳定地将它们暴露为 Tool,宿主系统也才能统一做缓存、审批和权限控制。
第二层:Source 层——Skill 的真正扩展点在“来源”
AgentSkillsSource 的核心就是一个 GetSkillsAsync()。这种简洁的抽象表明:Skill 的可扩展性,重点不在 Skill 本体,而在 Skill 从哪里来。理论上,你可以接入本地文件系统、数据库、配置中心、动态生成等多种来源。
AgentInMemorySkillsSource:表明代码定义的 Skill 是一等公民,Skill 不必非得是磁盘上的 Markdown。
AggregatingAgentSkillsSource:可将多个 Source 聚合,便于分层管理(如平台级、部门级、项目级 Skills),形成一个可分层装配的能力体系。
第三层:Decorator 层——治理作为管线能力
真实项目中,Skill 不是“扫描出来就全部可见”。Decorator 层提供了关键的治理能力:
FilteringAgentSkillsSource:根据租户、区域、环境、合规要求等条件过滤,决定当前 Agent 能看到哪些 Skill。
DeduplicatingAgentSkillsSource:按 Frontmatter.Name 去重,保留第一个出现的 Skill。这意味着注册顺序本身就是覆盖策略,决定了能力治理的优先级规则。
第四层:Provider 层——将 Skill 转化为运行时能力
AgentSkillsProvider 是整套 Skills Runtime 的关键,它做两件事:
- 构建 Skills Instructions:将所有 Skill 的名称和描述整理成系统提示(Advertise 阶段),控制初始 Token 成本。
- 构建运行时 Tools:根据 Skill 集合动态构建
load_skill、read_skill_resource、run_skill_script 等 Tool。
run_skill_script 的出现,意味着 Skill 的职责已明显从“知识读取”向“动作触发”延展。
此外,错误处理也很有 Agent Runtime 风格:很多错误场景返回的是错误文本给模型,而不是直接抛异常中断宿主,这符合 Agent 自主决定下一步行为的特点。
文件型 Skill 的变化与约束
对于大多数从文件入手的项目,AgentFileSkillsSource 有几个值得关注的细节:
- 受控扫描深度:最大深度为 2,利于约束目录组织。
- 轻量 Frontmatter 解析:支持核心字段(
name, description, license 等),但不适合复杂嵌套 YAML DSL。实践建议是保持 Frontmatter 扁平、稳定、易审查。
- 目录名与 Skill 名一致:
SKILL.md 里的 name 必须和父目录名一致,否则会被跳过。这有利于治理和排错。
- 按扩展名发现资源与脚本:核心逻辑是按扩展名递归扫描整个 Skill 目录。
- 默认资源扩展名:
.md, .json, .yaml, .yml, .csv, .xml, .txt。
- 默认脚本扩展名:
.py, .js, .sh, .ps1, .cs, .csx。
这表明 Skill 目录天然具备“知识+资源+脚本”混合封装的能力。
Scripts 的核心:执行边界的明确划分
这是 RC5 最值得关注的部分。AgentFileSkillScript 表示脚本,而真正决定“怎么跑”的是 AgentFileSkillScriptRunner。这是一种成熟的边界划分:
- 框架负责发现脚本。
- Provider 负责把脚本暴露成 Tool。
- 宿主系统自己决定如何执行(安全、沙箱、审批等)。
MAF 先把运行机制打通,但把安全决策权留给宿主。
这一点之所以特别重要,是因为一旦模型开始触发脚本,你就是在构建一个模型驱动的动作系统。此时,以下能力必须正视:
- 审批机制
- 审计日志
- 超时控制
- 最小权限
- 沙箱隔离
- 执行环境治理
因此,RC5 scripts 的真正意义在于:
MAF 开始把 Skill 从知识治理,推进到了能力治理。

程序内联 Skill:.NET 开发者的利器
除了文件型, .NET 还提供了 AgentInlineSkill,允许直接在 C# 代码中定义 Skill。
适用场景:特别适合那些只存在于运行时的信息,如当前租户配置、实时配额、动态生成的业务规则。硬落盘成文件反而不自然。
动态 Resource:支持将资源定义为委托,让模型每次读取都能拿到实时计算结果,非常适合“活的上下文”。
参数 Schema 自动化:内联脚本会将委托参数自动转换为 JSON Schema 并嵌入 Skill Content,这能极大提升模型调用 Tool 的准确性。
注意点:AgentInlineSkill.Content 在第一次访问时会惰性生成并缓存。因此,最稳妥的做法是先把 Skill 完整构造好,再注册给 Provider,避免后续添加的资源或脚本未生效。
企业级实践:建议将 Skills 拆分为三类
对于 Demo,一个 skills/ 目录足矣。但对于真实业务,建议从一开始就分层设计:
-
稳定知识型 Skill
- 适合:文件型。
- 例子:FAQ、制度规则、操作 SOP、模板文档。
- 重点:版本化、评审、复用。
-
动态上下文型 Skill
- 适合:
AgentInlineSkill。
- 例子:当前租户配置、实时状态、运行时规则。
- 重点:按需注入、实时计算。
-
动作执行型 Skill
- 这是 RC5 scripts 最容易让人兴奋也最容易忽略风险的一类。
- 如果 Skill 会触发脚本,建议至少补齐:沙箱化、审批机制、审计日志、超时策略、最小权限模型。
- 一句话总结:别把“可以执行”误以为“可以直接上线”。
结语:Skill 正演变为 Agent 运行时插件系统
如果说之前讨论的是 如何把领域知识模块化地交给 Agent,那么这篇讨论的是更高层级的问题:
如何把知识、资源、脚本和运行时治理,统一收敛成一个可组合、可发现、可调用、可管控的 Skill 系统。
MAF 当前 .NET 里的 Skills,实现的已经不只是一个 Skill Loader,而是一套正在成型的 Agent Runtime Plugin System。它具备了插件系统的关键要素:稳定对象模型、来源抽象、治理管线、统一运行时 Provider、Tool 化调用入口等。
真正值得兴奋的,不只是“scripts 能跑了”,更重要的是:
MAF 对 Skill 的理解,已经明显不再停留在提示工程层,而是开始往软件工程层迈进。
接下来决定上限的,不再只是“谁会写提示词”,而是谁能把这些能力组织成体系、治理成平台、沉淀成长期可维护的基础设施。这,才是 RC5 更新最值得关注的地方。
关于 Agent Skills 更深入的实战演练,我们将在后续的文章中继续探讨。
参考链接