.NET+AI | Agent Skills | MAF 悄悄更新到 RC5,Agent Skills的 脚本运行能力 Ready 了

张开发
2026/4/11 22:22:40 15 分钟阅读

分享文章

.NET+AI | Agent Skills | MAF 悄悄更新到 RC5,Agent Skills的 脚本运行能力 Ready 了
以下内容选自我精心打造的《.NETAI | 智能体开发进阶》课程如需系统学习不妨阅读原文了解详情。.NETAI | Agent Skills | MAF 支持Agent Skill了手把手教你如何集成 Agent Skills让Agent 拥有领域专长上一篇我们已经系统聊过一次 MAF 的 Agent Skills。当时对应的是较早阶段的版本核心能力还集中在静态知识注入• 用SKILL.md定义领域知识• 用load_skill按需加载正文• 用read_skill_resource读取补充资料• 让 Agent 通过渐进式披露Progressive Disclosure降低上下文成本。那篇文章解决的是一个问题如何让 Agent“知道什么”。但今天翻 Microsoft Agent Framework 最新源码时发现RC5已悄悄发布MAF 已经悄悄推进到 RC5而且 Agent Skills 这条线已经不再只是“读知识”而是开始往“可执行能力”演进了。最直接的信号就是.NET侧关于scripts的运行链路已经基本接上。这件事为什么重要因为它意味着 Skill 的定位正在变化• 以前更像知识包• 现在开始像能力包• 再往后很可能会演进成真正的 Agent Runtime Plugin。如果说上一篇是在回答“Skill 是什么、怎么接”那这篇续笔更想回答的是• RC5 到底变了什么• scripts 支持意味着什么• Skill 为什么不该再被理解成“提示词附件”• 如果你准备在企业项目里继续往前走架构上应该怎么想 本篇你将收获什么看完这篇文章你会更清楚这几件事✅ 理解 RC5 阶段 Agent Skills 的能力边界为什么已经和上一篇不同✅ 理解 Skill 从“静态知识模块”向“可执行能力模块”演进的核心信号✅ 看懂 .NET 源码里 Skills 的 4 层架构对象层、Source 层、Decorator 层、Provider 层✅ 看懂run_skill_script背后真正重要的不是“能不能跑脚本”而是谁来控制执行边界✅ 知道企业里落地 Skills 时为什么要把知识型、动态上下文型、动作执行型分开设计 先回顾一下上一篇讲清楚了什么上一篇我们重点讲的是MAF 如何集成 Agent Skills让 Agent 拥有领域专长。当时那套能力的核心价值主要体现在两个层面。1. 它解决了“领域知识如何模块化”的问题过去我们要让 Agent 懂报销规则、审批流程、FAQ、模板通常有几种方式• 全塞进 System Prompt• 写死在代码里• 上 RAG• 或者交给 Agent Skills。相比之下Skills 的优势很明显• 结构清晰• 维护成本低• 非开发者也能参与维护• 还能通过渐进式披露减少 Token 消耗。2. 它解决了“知识什么时候进上下文”的问题这也是 Skills 最有价值的设计点之一 Advertise先告诉模型“我有哪些技能”每次请求并不会把所有 Skill 全文塞进去只会注入技能名和描述让模型先知道有哪些可用能力。 Load命中后再加载正文模型判断某个任务适合某个 Skill 时再通过load_skill读取完整的技能说明。 Read需要资料时再读资源如果正文里还引用了 FAQ、模板、政策文档等补充材料再通过read_skill_resource去读取。所以上一篇的重点本质上是在回答如何让 Agent 在不浪费上下文的前提下按需获取领域知识。而 RC5 这次最值得关注的就是它开始继续往前走了。 RC5 最值得关注的不是“又多了几个类”而是 scripts 这条链开始闭环了如果你还把 Skill 理解成“一个SKILL.md文件夹”那这次很容易低估 RC5 的意义。因为这次真正关键的不是目录结构也不是 frontmatter 多了什么字段。而是Skill 正在从“让模型知道更多”升级为“让模型在受控边界内做更多”。这是质变不是量变。为什么说这是质变因为“知道什么”和“能做什么”在系统设计上根本不是一个难度级别。当 Skill 只负责知识时你主要处理的是• 怎么组织内容• 怎么控制上下文成本• 怎么做资源引用• 怎么保证内容规范。但当 Skill 开始触发脚本执行时系统面对的问题立刻升级成• 谁来发现脚本• 谁来告诉模型这个脚本怎么用• 参数结构如何描述• 脚本失败后结果怎么返回• 哪些脚本允许执行• 是否需要审批• 是否要审计• 是否要沙箱化和限权你会发现一旦进入 scriptsSkill 就不再只是知识治理问题而开始变成运行时能力治理问题。这也是为什么我觉得 RC5 值得单独写一篇。 这一版 Skill 的本质已经不只是“知识包”而是“能力包”官方对 Agent Skills 的定义一直很清楚Skill 是由指令、脚本、资源组成的可移植能力包。以前很多人只盯着其中的“指令”和“资源”。但 RC5 往前推进之后scripts这部分的信号变得越来越强。所以如果现在再用一句话概括 Skill我更愿意这样说Skill 不是提示词的附件而是 Agent 的模块化能力单元。它至少包含 4 个层次• 发现层信息让模型知道“有什么可用能力”• 技能正文让模型知道“应该怎么做”• 资源层让模型知道“需要时去哪里查资料”• 脚本层让模型知道“在满足条件时可以触发什么动作”。这样一看Skill 的角色就清楚多了。它不只是“多一段上下文”。它是一个可以被发现、被加载、被引用、被调用的能力单元。 从源码结构看MAF 把 Skills 拆成了 4 层如果你只看文档会觉得 Skills 很像一个目录规范。但从当前 .NET 源码看MAF 对 Skills 的实现其实非常工程化基本可以拆成 4 层1. 对象层定义 Skill 是什么2. Source 层定义 Skill 从哪里来3. Decorator 层定义 Skill 怎么过滤、去重、组合4. Provider 层定义 Skill 怎么进入 Agent 运行时这 4 层拆分是我认为整套设计最值得学习的地方。1️⃣ 第一层对象层——先把 Skill 建模清楚这一层的核心是AgentSkill。它没有把自己绑定到文件系统也没有把实现和加载方式揉在一起而是把 Skill 先抽象成 4 个核心组成•Frontmatter•Content•Resources•Scripts这说明框架关注的不是“Skill 必须长什么样的目录”而是一个 Skill 进入运行时之前至少要能被抽象成元数据、正文、资源和脚本。AgentSkillFrontmatter的意义把规范前移到构造阶段在当前实现里name、description、compatibility这些字段都不是随便写写。比如•name有长度限制•description有长度限制•name必须是 kebab-case• 不能首尾为-• 不能出现连续--。这背后反映的是一个很成熟的工程取向不要把 Skill 规范寄希望于“大家自觉遵守”而是直接变成代码约束。这样做的价值很明显• Skill 的发现层信息更稳定• 同名冲突和命名污染更少• 后续 Provider 生成提示词和 Tool 时更可控• 问题更容易在构造阶段暴露而不是拖到运行期。Resource 和 Script 用统一抽象承接这一层还有两个关键抽象•AgentSkillResource通过ReadAsync()提供读取能力•AgentSkillScript通过RunAsync()提供执行能力。这意味着不管 Skill 来自文件还是来自代码动态构造到了运行时都会被收敛为统一接口。这一步非常关键。因为只有接口统一了后面 Provider 才能稳定地把它们暴露成 Tool宿主系统也才能统一做缓存、审批、审计和权限控制。2️⃣ 第二层Source 层——Skill 的真正扩展点在“来源”AgentSkillsSource的设计非常简洁核心就是一个GetSkillsAsync()。但越是这种简洁抽象越说明框架对边界想得比较清楚。它其实是在表达Skill 的可扩展性重点不在 Skill 本体而在 Skill 从哪里来。理论上你完全可以接这些来源• 本地文件系统• 数据库• 配置中心• 多租户动态生成• 远程聚合服务。AgentInMemorySkillsSource代码定义 Skill 是一等公民这个实现很简单就是把一组内存中的AgentSkill返回出去。但它释放的信号很明确MAF 并不认为 Skill 只能是磁盘上的 Markdown。也正因为有这个抽象后面的AgentInlineSkill才能成立。AggregatingAgentSkillsSource多个来源可以天然组合这个类做的事情也很直接把多个 Source 按注册顺序聚合起来。这在真实业务里非常有用。比如你完全可以分层管理• 平台级 Skills• 部门级 Skills• 项目级 Skills• 用户动态 Skills最后统一进入运行时。到这一步Skill 就已经不只是“一个文件夹里的知识片段”而是一个可分层装配的能力体系了。3️⃣ 第三层Decorator 层——过滤、去重、组合都应该是管线能力真实项目里Skill 从来不是“扫描出来就全部可见”。所以 MAF 在 Source 外面又做了一层 Decorator这个设计非常加分。几个关键类包括•DelegatingAgentSkillsSource•FilteringAgentSkillsSource•DeduplicatingAgentSkillsSource过滤决定当前 Agent 能看到哪些 SkillFilteringAgentSkillsSource接收一个过滤条件决定哪些 Skill 能保留哪些 Skill 要被排除。这在企业项目里非常实用。常见过滤维度包括• 租户• 区域• 环境• 产品线• 灰度标识• 合规要求。所以它解决的不是“技术问题”而是“治理问题”。去重注册顺序其实就是优先级策略DeduplicatingAgentSkillsSource按Frontmatter.Name去重忽略大小写保留第一个出现的 Skill。这意味着什么意味着注册顺序本身就是覆盖策略。如果平台级和项目级都定义了同名 Skill那么谁先注册谁就赢。这一点在多团队协作下非常重要。它决定的不是代码风格而是能力治理的优先级规则。4️⃣ 第四层Provider 层——真正把 Skill 变成 Agent 运行时能力整套 Skills Runtime 里最关键的类是AgentSkillsProvider。它真正做的事情有两件1. 构建模型可理解的 Skills Instructions2. 构建模型可调用的运行时 Tools这两步接上之后Skill 才会从“静态资产”变成“运行时能力”。第一步告诉模型“现在你有哪些技能可用”Provider 会把所有 Skill 的名称和描述整理成一段系统提示。这一步不是把所有正文塞进去而是只暴露发现层信息。也就是上一篇我们讲的 Advertise 阶段。这背后的意义是• 控制初始 Token 成本• 让模型先知道“可用能力目录”• 只有命中时才进一步展开。第二步把 Skill 的运行时入口暴露成 Tool当前实现里Provider 会根据 Skill 集合动态构建 Tool•load_skill•read_skill_resource•run_skill_script注意这里最值得关注的一点run_skill_script的出现意味着 Skill 的职责已经明显从“知识读取”向“动作触发”延展。这不是一个小变化。因为只要 Skill 可以被模型显式调用脚本它在系统里的角色就发生了变化。它不再只是被动提供说明文档而是开始承担运行时行为入口。错误处理也很有 Agent Runtime 味道在load_skill、read_skill_resource、run_skill_script这些流程里很多错误场景最后返回的是错误文本而不是直接抛异常把宿主打崩。这很符合 Agent Runtime 的设计取向• 宿主不中断• 错误反馈给模型• 模型再根据错误信息决定下一步行为。这是典型的 Agent-Friendly 设计而不是传统 Web API 风格。 文件型 Skill 在 RC5 里依然重要但已经不只是“放文档”了如果你在项目里最先接触 Skills大概率还是从文件型实现开始。对应的核心类是AgentFileSkillsSource。从当前源码看它有几个特别值得关注的点。1. 扫描深度是受控的不是无限递归当前实现里最大扫描深度是2。也就是说• 你既可以直接传一个 Skill 目录• 也可以传一个包含多个 Skill 的父目录• 但框架不会无边界地往下乱扫。这很利于约束目录组织。2. Frontmatter 解析是轻量方案不适合复杂 YAML DSL源码里 frontmatter 解析并不是完整 YAML 解释器而是轻量解析方案。它支持核心字段比如•name•description•license•compatibility•allowed-tools• 一层metadata但如果你把 frontmatter 写成很复杂的嵌套结构就不太符合当前实现的设计预期。所以比较稳妥的实践是Frontmatter 保持扁平、稳定、容易审查。3. 目录名和 Skill 名要求一致当前 .NET 实现有个非常严格但很合理的规则SKILL.md里的name必须和父目录名一致否则这个 Skill 会被跳过。这个约束看似严实际上有利于治理。因为目录结构本身就承担了身份标识作用发现、排错、协作都会更清楚。4. 资源和脚本的识别本质上是按扩展名发现虽然文档示例里常见references/、scripts/、assets/这样的目录名但从当前 .NET 实现看真正识别资源和脚本的核心逻辑是按扩展名递归扫描整个 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 开发者最顺手的一部分除了文件型 Skill当前 .NET 还有一条很漂亮的路线AgentInlineSkill。这意味着你可以直接在 C# 里定义一个 Skill而不是必须落盘成目录。你可以在代码里定义• Skill 名称• Skill 描述• Skill 指令• 静态资源• 动态资源• 委托形式的脚本。它特别适合哪些场景特别适合那些只存在于运行时的信息比如• 当前租户配置• 当前区域• 实时配额• 当前系统状态• 动态生成的业务规则。这些信息如果硬要落盘成文件反而不自然。动态 Resource 的价值AgentInlineSkill支持把资源写成静态值也支持写成委托。这意味着模型每次读取资源时拿到的都可以是实时计算后的结果。这对于“上下文是活的”场景非常有用。Script 参数 Schema 自动化是很实用的细节内联脚本还会把委托参数转换成 JSON Schema并嵌入到 Skill Content 里。这个细节非常实用。因为很多时候模型调不好 Tool不是因为它不够聪明而是因为参数约束描述得不够清楚。在这点上MAF 的做法是对的。一个容易踩的坑Content 是惰性生成并缓存的这一点最好记住。AgentInlineSkill.Content在第一次访问时会生成并缓存。所以如果你已经访问过Content又继续AddResource()或AddScript()后加的内容可能不会再进入正文。最稳妥的写法是先把 Skill 完整构造好再注册给 Provider。 如果你准备在企业里落地 Skills我建议至少拆成 3 类如果只是做 Demo直接挂一个skills/目录就够了。但如果你是准备做真实业务我会更建议从一开始就把 Skills 分层设计。第一类稳定知识型 Skill适合文件型。比如• FAQ• 制度规则• 操作 SOP• 模板文档• 审批流程说明这类 Skill 的重点在于版本化、评审、复用。第二类动态上下文型 Skill适合AgentInlineSkill。比如• 当前租户配置• 当前地域信息• 当前配额• 实时状态• 运行时规则。这类 Skill 的重点在于按需注入、实时计算。第三类动作执行型 Skill这类就是 RC5 scripts 最容易让人兴奋也最容易让人忽略风险的一类。如果 Skill 会触发脚本执行我建议你至少补齐• 沙箱化• 审批机制• 审计日志• 超时和重试策略• 最小权限模型• 多租户隔离策略。一句话总结就是别把“可以执行”误以为“可以直接上线”。✅ 结语RC5 给我的最大感受是 Skill 正在从“知识模块”升级为“运行时插件单元”如果说上一篇我们是在讨论如何把领域知识模块化地交给 Agent。那么这篇续笔讨论的其实已经是另一个层级的问题如何把知识、资源、脚本和运行时治理统一收敛成一个可组合、可发现、可调用、可管控的 Skill 系统。这也是我为什么会给出一个更明确的判断MAF 当前 .NET 里的 Skills实现的已经不只是一个 Skill Loader而是一套正在成型的 Agent Runtime Plugin System。它已经具备了插件系统的很多关键要素• 稳定对象模型• 来源抽象• 过滤与去重管线• 统一运行时 Provider• Tool 化的调用入口• 面向 Agent 的错误处理• 脚本审批与执行扩展位。所以真正值得兴奋的不只是“scripts 能跑了”。更重要的是MAF 对 Skill 的理解已经明显不再停留在提示工程层而是开始往软件工程层迈进。接下来真正决定上限的也不再只是“谁会写提示词”。而是谁能把这些能力• 组织成体系• 治理成平台• 沉淀成长期可维护的基础设施。这可能才是 RC5 这次更新最值得关注的地方。对于 Agent Skills 的实战演练敬请期待下篇文章介绍。参考链接Skills 源码目录• https://github.com/microsoft/agent-framework/tree/main/dotnet/src/Microsoft.Agents.AI/Skills

更多文章