以下内容选自我精心打造的《.NET+AI | 智能体开发进阶》课程,如需系统学习,不妨阅读原文了解详情。
课程特价优惠券,限量 10 张。扫码领取,先到先得!


前面三篇,我们分别聊了 Inline Skill、File-based Skill 和 Class-based Skill。
如果只看单篇,你会觉得三种写法都成立;但真正进入项目时,最关键的问题从来不是“会不会写”,而是“到底该怎么选”。
这也是很多人学 Agent Skills 时最容易卡住的地方:三种写法看起来都能用,但它们解决的其实不是同一个问题。
一、先说结论:三者不是替代关系,而是分工关系
很多人会下意识地把它们理解成“越来越高级”的升级路线。
这种理解只对一半。
更准确的说法是:三种写法分别对应 Agent 能力组织的三个重点。
• Inline Skill:重点是快速接入 • File-based Skill:重点是能力沉淀 • Class-based Skill:重点是长期治理
所以它们不是简单替代关系,而是分工关系。
如果把这个判断想清楚,选型就会简单很多。
二、三种写法到底分别解决什么问题?
Inline Skill 解决的是:怎么用最低成本,把一个能力先接进 Agent。
它适合 Demo、教学、PoC、试验场景。核心不是“最强”,而是“最快”。
File-based Skill 解决的是:怎么把一个 Skill 做成可以维护、共享、分发的能力资产。
它适合跨项目复用、团队协作、内容外部化管理。核心不是“拆文件”,而是“资产化”。
Class-based Skill 解决的是:当一个 Skill 已经足够稳定时,怎么把它纳入系统内部长期治理。
它适合稳定核心能力、测试、重构、DI 接入、安全与审批。核心不是“优雅”,而是“治理”。
一句话概括就是:
• Inline:先跑通 • File-based:再沉淀 • Class-based:后治理
三、只会选还不够,真正的关键是怎么把它们聚合起来
在真实项目里,最常见的情况其实不是三选一,而是三者并存。
比如一个跨境物流 Agent,可能同时需要三类能力:
• 文件型 Skill:沉淀换算规则、SOP、脚本型动作 • Inline Skill:快速接入运费估算这类程序内业务逻辑 • Class-based Skill:承载包装建议、成本估算这类稳定核心能力
这时候,真正有价值的问题就变成了:
当三种 Skill 同时存在时,怎么把它们统一挂进 Agent?
答案不是手工一个个拼,而是交给 AgentSkillsProviderBuilder。
四、一个更像真实项目的聚合 Provider 示例
下面这个例子,直接把三种实现方式组合成一个 Provider:
#pragma warning disable MAAI001using System.ComponentModel;using System.Text.Json;using Microsoft.Agents.AI;using Microsoft.Extensions.AI;var shippingSkillPath = "./skills/shipping-metric-skill";var freightCostSkill = new AgentInlineSkill( name: "freight-cost-estimator", description: "根据计费重量与线路信息估算跨境物流运费。", instructions: "先读取费率,再调用 estimate-freight,最后返回计算过程和结论。") .AddResource("tariff-rate-table", "CN-US=38.0; fuel=0.10") .AddScript("estimate-freight", (double chargeableWeight, double basePricePerKg, double fuelRate) => { var baseCost = Math.Round(chargeableWeight * basePricePerKg, 2); var fuelCost = Math.Round(baseCost * fuelRate, 2); return JsonSerializer.Serialize(new { chargeableWeight, basePricePerKg, fuelRate, total = baseCost + fuelCost }); });internal sealed class PackagingAdvisorSkill : AgentClassSkill<PackagingAdvisorSkill>{ public override AgentSkillFrontmatter Frontmatter { get; } = new("packaging-advisor", "给出包装建议并估算包装成本。"); protected override string Instructions => "先读取 packaging-guidelines,再调用 estimate-packaging-cost。"; [AgentSkillResource("packaging-guidelines")] [Description("易碎品、电子品、纺织品包装建议")] public string PackagingGuidelines => "fragile=木箱加固; electronics=防静电袋; textile=防潮袋"; [AgentSkillScript("estimate-packaging-cost")]private static string EstimatePackagingCost(string category, int quantity) { var unitCost = category.ToLowerInvariant() switch { "fragile" => 12.5, "electronics" => 9.8, _ => 3.2 }; return JsonSerializer.Serialize(new { category, quantity, unitCost, totalCost = Math.Round(unitCost * quantity, 2) }); }}var provider = new AgentSkillsProviderBuilder() .UseFileSkill(shippingSkillPath) .UseSkill(freightCostSkill) .UseSkill(new PackagingAdvisorSkill()) .Build();这段代码最值得关注的,不是 API 多炫,而是它清楚表达了三种 Skill 的分工:
• UseFileSkill(...)接入文件型规则与脚本• UseSkill(freightCostSkill)接入程序内联业务逻辑• UseSkill(new PackagingAdvisorSkill())接入强类型核心能力• Build()产出一个最终可挂载的 Provider
这就意味着,Inline、File-based、Class-based 在运行时并不是三套平行世界,而是可以被统一装配到同一个 Agent 上下文里的。
五、什么时候该用聚合 Provider?
只要你的 Agent 开始进入真实业务,而不是单一 Demo,就几乎一定会遇到聚合问题。
比如:
• 一部分能力需要快速试验,用 Inline • 一部分能力需要共享给不同团队,用 File-based • 一部分能力已经稳定,需要长期治理,用 Class-based
如果没有 Builder,最后就很容易变成“能力越来越多,但装配越来越乱”。
而 AgentSkillsProviderBuilder 的真正价值,就是把“多来源 Skill 接入”变成统一入口。
再往前一步,它还能继续叠加:
• UseFilter做角色/租户隔离• UsePromptTemplate统一企业提示词框架• UseScriptApproval给脚本执行加审批门控
也就是说,Builder Pattern 的意义从来不只是“链式写起来好看”,而是它天然适合多技能聚合之后的治理。
六、最后给一个最短判断框架
如果你想要一个更直接的选型结论,可以记住下面这组判断:
• 想尽快跑通:Inline • 想沉淀成资产:File-based • 想纳入长期治理:Class-based
如果还要再补一句工程化建议,那就是:
• 单一 Skill 看选型 • 多种 Skill 共存,看 Builder 聚合
这基本已经够覆盖大多数 Agent Skills 场景了。
七、总结
Inline、File-based、Class-based 三种 Skill 写法,不是在重复解决同一个问题,而是在分别解决 Agent 能力组织中的三个不同阶段:先接入、再沉淀、后治理。
而当三种模式开始同时出现在一个真实系统中时,真正关键的能力就不再只是“会写 Skill”,而是“会不会把不同来源的 Skill 统一聚合成一个可治理的 Provider”。
这也是 MAF Agent Skills 最值得关注的地方:它不是只给了你几种 API,而是在给你一套从 Demo 到工程落地、再到统一装配治理的能力组织路径。
夜雨聆风