1. 项目概述:MAF Agent Skills 的工程化演进
在 .NET 生态中构建 AI Agent 时,我们常常面临一个核心挑战:如何将业务知识和执行能力模块化地注入 Agent 运行时。Microsoft Agent Framework(MAF)1.0 版本带来的 Agent Skills 设计,正是对这一问题的系统性回答。不同于简单的提示词模板或技能说明书,MAF 实现了一套完整的技能分层架构,将 agentskills.io 标准从文件协议推进到了运行时能力层面。
1.1 核心需求解析
在典型的 AI Agent 开发场景中,开发者通常需要处理三类核心要素:
- 领域知识:如产品文档、业务流程等静态信息
- 业务规则:如审批策略、计算逻辑等条件判断
- 执行能力:如 API 调用、数据处理等动态操作
传统做法往往将这些要素硬编码到提示词中,导致:
- 上下文长度膨胀(Token 成本高)
- 不同租户/场景的规则难以隔离
- 动态能力扩展受限
- 安全边界模糊
MAF 的 Agent Skills 设计正是针对这些痛点,通过五层架构实现了:
- 知识的渐进式披露(按需加载)
- 能力的模块化封装(技能即组件)
- 多租户的隔离治理
- 执行的安全边界控制
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 架构全景:五层设计解析
2.1 协议与内容层:标准化基石
MAF 严格遵循 agentskills.io 的渐进式信息披露(progressive disclosure)模型,将技能目录结构映射为运行时协议:
markdown复制skills/
├── customer-service/ # 技能目录
│ ├── SKILL.md # 必须:Frontmatter元数据+技能描述
│ ├── references/ # 可选:参考文档
│ ├── assets/ # 可选:静态资源
│ └── scripts/ # 可选:可执行脚本
关键设计决策:
- Frontmatter 最小化:仅包含技能名称、描述等发现元数据
- 资源分类存储:references 存放说明文档,assets 存放二进制资源
- 脚本白名单:默认支持 .py/.js/.sh/.ps1/.cs/.csx 等扩展名
提示:MAF 通过 AgentFileSkillsSource 实现目录扫描时,默认限制递归深度为2层,并会校验路径安全性,防止目录遍历攻击。
2.2 统一模型层:能力抽象
MAF 定义了四个核心模型类,将不同来源的技能统一为运行时对象:
| 模型类 | 职责 | 对应协议要素 |
|---|---|---|
| AgentSkill | 技能完整抽象 | 整个技能目录 |
| AgentSkillFrontmatter | 发现元数据(名称/描述/兼容性) | SKILL.md 的 YAML 头 |
| AgentSkillResource | 参考资料/静态资源 | references/assets |
| AgentSkillScript | 可执行脚本能力 | scripts/ |
这种抽象的关键价值在于:
csharp复制// 无论技能来自文件、内存还是代码,最终都统一为 AgentSkill
AgentSkill skill = new AgentSkill(
frontmatter: new AgentSkillFrontmatter(...),
content: "技能完整说明...",
resources: new List<AgentSkillResource> {...},
scripts: new List<AgentSkillScript> {...}
);
2.3 技能来源层:供给扩展
MAF 通过 AgentSkillsSource 抽象支持多种技能供给方式:
2.3.1 文件来源(AgentFileSkillsSource)
- 递归扫描目录中的 SKILL.md
- 自动关联同目录下的 references/assets/scripts
- 生产级特性:
- 路径安全校验
- 扩展名白名单
- 文件锁并发控制
2.3.2 内存来源(AgentInMemorySkillsSource)
csharp复制// 动态构建技能集合
var skills = new List<AgentSkill> {
BuildRefundSkill(),
BuildQuerySkill()
};
var source = new AgentInMemorySkillsSource(skills);
适用场景:
- 配置中心下发技能
- A/B 测试不同技能版本
- 租户自定义规则注入
2.3.3 代码技能(AgentInlineSkill/AgentClassSkill)
csharp复制// 内联脚本技能
var skill = new AgentInlineSkill(
name: "calculate-tax",
description: "税费计算",
script: (args) => {
// 直接嵌入C#代码
var rate = GetTaxRate(args["region"]);
return amount * rate;
}
);
// 类形式技能
[AgentSkill("advanced-tax")]
public class TaxCalculatorSkill : IAgentSkill
{
[SkillScript("calculate")]
public object CalculateTax(dynamic args) {...}
}
优势:
- 强类型检查
- 更好的可维护性
- 直接访问业务层代码
2.4 组装治理层:生产就绪
AgentSkillsProviderBuilder 提供企业级治理能力:
csharp复制var provider = new AgentSkillsProviderBuilder()
.UseFileSkills("/skills/platform") // 平台默认技能
.UseFileSkills($"/skills/{tenantId}") // 租户技能
.UseSource(customSource) // 自定义来源
.UseFilter(skill => { // 技能过滤
return CheckTenantAccess(tenantId, skill);
})
.UseScriptApproval((script, context) => { // 脚本审批
return AuditSystem.Validate(script);
})
.UseOptions(options => { // 全局配置
options.MaxSkillDepth = 3;
options.ResourceSizeLimit = 1024 * 1024;
})
.Build();
关键治理点:
- 聚合(Aggregate):合并多个来源的技能
- 过滤(Filter):基于租户/角色/环境的可见性控制
- 去重(Deduplicate):解决命名冲突(先到先得)
- 审批(Approval):敏感脚本执行前的安全检查
2.5 运行时注入层:AIContext 集成
AgentSkillsProvider 继承自 AIContextProvider,将技能深度集成到 Agent 运行时:
mermaid复制sequenceDiagram
participant User
participant Agent
participant SkillsProvider
User->>Agent: 查询订单状态
Agent->>SkillsProvider: 获取可用技能(available_skills)
SkillsProvider-->>Agent: ["order-query", "refund-check"]
Agent->>SkillsProvider: load_skill("order-query")
SkillsProvider-->>Agent: 完整技能内容
Agent->>SkillsProvider: run_skill_script("query", orderId)
SkillsProvider-->>Agent: 执行结果
Agent-->>User: 订单详情
注入机制:
- Prompt 注入:技能名称和描述进入系统提示
- 工具注册:
load_skill:加载完整技能内容read_skill_resource:读取参考资料run_skill_script:执行脚本能力
3. 实战:多租户客服案例
3.1 场景需求
为电商平台构建支持多租户的客服 Agent,需要处理:
- 平台级通用规则(如服务规范)
- 租户定制流程(如退货政策)
- 临时活动规则(如双11特殊政策)
3.2 技能规划
bash复制skills/
├── platform/ # 平台技能
│ ├── service-baseline/
│ └── risk-control/
├── tenants/
│ ├── tenant-a/ # 租户A技能
│ │ ├── order-service/
│ │ └── refund-policy/
│ └── tenant-b/ # 租户B技能
└── campaigns/ # 活动技能
└── black-friday/
3.3 运行时装配
csharp复制// 初始化技能提供者
var provider = new AgentSkillsProviderBuilder()
// 平台默认技能(只读)
.UseFileSkills("/skills/platform",
new FileSkillOptions { ReadOnly = true })
// 租户技能(动态加载)
.UseFileSkills($"/skills/tenants/{tenantId}",
new FileSkillOptions {
ScriptRunner = CreateTenantRunner(tenantId)
})
// 活动技能(内存动态注入)
.UseSource(GetCampaignSkills())
// 租户隔离过滤
.UseFilter(skill => {
// 平台技能对所有租户可见
if (skill.IsPlatformSkill) return true;
// 其他技能需匹配租户前缀
return skill.Name.StartsWith($"{tenantId}-");
})
// 脚本执行审批
.UseScriptApproval((script, context) => {
if (script.IsDangerous) return false;
return CheckTenantPermission(tenantId, script);
})
.Build();
// 注入到Agent
var agent = new AgentBuilder()
.WithSkills(provider)
.Build();
3.4 典型交互流程
-
用户提问
"订单#12345为什么还没有发货?" -
技能发现
Agent 从available_skills中发现:tenant-a-order-serviceplatform-shipping-policy
-
按需加载
python复制# 加载完整订单服务技能 order_skill = load_skill("tenant-a-order-service") # 读取物流SLA文档 sla_doc = read_skill_resource( "tenant-a-order-service", "shipping-sla" ) # 执行订单查询 status = run_skill_script( "tenant-a-order-service", "query-order", {"order_id": "12345"} ) -
响应生成
结合技能内容和查询结果生成回复:
"您的订单预计将在24小时内发货,根据商户政策,超时将自动补偿5元优惠券。"
4. 工程化价值总结
MAF 的 Agent Skills 设计带来了三个层面的提升:
4.1 架构层面
- 关注点分离:技能描述、供给、装配、执行解耦
- 扩展性:支持文件、代码、内存、自定义来源
- 统一抽象:所有技能最终收敛为 AgentSkill 对象
4.2 生产就绪特性
- 安全控制:路径校验、脚本审批、资源限制
- 多租户支持:技能过滤、命名空间隔离
- 治理能力:聚合、去重、版本管理
4.3 运行时效率
- 渐进式加载:减少初始上下文长度
- 按需执行:避免不必要的能力暴露
- 本地缓存:高频技能的内存缓存机制
5. 演进建议
对于已经在使用 MAF 的团队,建议逐步实施:
-
技能标准化
按照 agentskills.io 规范整理现有知识库 -
分层迁移
- 先迁移静态知识到文件技能
- 再封装业务逻辑到代码技能
- 最后处理动态规则到内存技能
-
治理策略
- 制定技能命名规范
- 设计租户隔离方案
- 建立脚本审批流程
-
性能优化
- 技能预加载
- 资源缓存
- 懒加载策略
这套架构最精妙之处在于:它既尊重了开放标准,又提供了企业级扩展点,使 Agent 技能从"文档说明"真正进化成了"运行时能力"。对于需要构建复杂业务 Agent 的 .NET 团队,这无疑是当前最值得深入研究的架构范式之一。
