.NET+AI | Agent | 构建插件系统(7)
目录
一句话简介
学习如何通过插件系统设计企业级 AI Agent 架构,使用抽象基类和接口标准化实现模块化、可扩展的智能应用。
🎯 核心价值
-
✅ 模块化设计:按功能划分插件,独立开发和维护
-
✅ 依赖注入:使用 DI 容器管理插件依赖关系
-
✅ 选择性暴露:精确控制哪些方法暴露给 AI Agent
-
✅ 企业级标准:通过接口和抽象基类统一插件开发规范
📝 什么是插件系统?
插件系统是一种软件架构模式,允许在不修改核心代码的情况下,通过添加、移除或替换插件来扩展应用功能。

核心优势:
|
特性 |
价值 |
|---|---|
|
🔌 可扩展性 |
新功能通过插件添加,无需修改核心代码 |
|
🔧 可维护性 |
插件独立开发和测试,降低系统复杂度 |
|
🎛️ 灵活配置 |
按需启用/禁用插件,满足不同场景需求 |
|
👥 团队协作 |
不同团队开发不同插件,提高开发效率 |
💼 业务场景
某企业需要构建智能工作助手系统,为员工提供:
-
🌤️ 天气查询:为出差人员提供目的地天气信息
-
⏰ 时间查询:支持不同时区的时间查询(跨国团队协作)
-
📅 办公协作:会议室预订、通讯录查询等(未来扩展)
-
💰 财务管理:报销查询、预算管理等(未来扩展)
技术挑战: 功能模块持续增加、不同团队负责不同功能、需要独立测试和部署。
💻 实现方式
1. 基础插件类
最简单的插件实现:
public sealedclassWeatherPlugin
{
[Description("查询指定城市的天气信息")]
public string GetWeather(
[Description("城市名称,如:北京、上海")] string location)
{
return$"📍 {location}:晴转多云,温度 15°C,空气质量良好";
}
}
// 注册插件
var weatherPlugin = new WeatherPlugin();
var tools = new[] { AIFunctionFactory.Create(weatherPlugin.GetWeather) };
问题: 每个插件都需要手动处理工具注册,代码重复。
2. 依赖注入管理
通过依赖注入解耦插件和服务:
// 1. 定义服务类
publicsealedclassWeatherProvider
{
public string GetWeather(string location)
{
return$"📍 {location} 天气数据...";
}
}
// 2. 插件通过构造函数注入
publicsealedclassWeatherPlugin
{
privatereadonly WeatherProvider _provider;
public WeatherPlugin(WeatherProvider provider)
{
_provider = provider;
}
[Description("查询天气")]
public string GetWeather([Description("城市")] string location)
{
return _provider.GetWeather(location);
}
}
// 3. 使用 DI 容器管理
services.AddSingleton<WeatherProvider>();
services.AddSingleton<WeatherPlugin>();
优势: 代码更清晰,易于测试和替换实现。
3. 抽象基类统一实现
通过抽象基类减少重复代码:
// 1. 定义抽象基类
publicabstractclassAgentPluginBase
{
// 子类只需重写这个方法,声明要暴露的工具
protected abstract IEnumerable<Delegate> GetToolMethods();
// 基类统一实现 AsAITools()
public IEnumerable<AITool> AsAITools()
{
return GetToolMethods()
.Select(method => AIFunctionFactory.Create(method));
}
}
// 2. 插件继承基类
publicsealedclassWeatherPlugin : AgentPluginBase
{
privatereadonly WeatherProvider _provider;
public WeatherPlugin(WeatherProvider provider)
{
_provider = provider;
}
[Description("查询天气")]
public string GetWeather([Description("城市")] string location)
{
return _provider.GetWeather(location);
}
// 只需声明要暴露的方法
protected override IEnumerable<Delegate> GetToolMethods()
{
yieldreturnthis.GetWeather;
}
}
优势:
-
✅ 减少 33% 代码量
-
✅ 统一实现模式
-
✅ 保持选择性暴露能力
4. 企业级接口标准
通过接口实现完全标准化:
// 1. 定义插件接口
publicinterfaceIAgentPlugin
{
string PluginName { get; }
IEnumerable<AITool> AsAITools();
object GetPluginInfo();
}
// 2. 抽象基类实现接口
publicabstractclassStandardAgentPluginBase : IAgentPlugin
{
publicvirtualstring PluginName => GetType().Name;
protected abstract IEnumerable<Delegate> GetToolMethods();
public IEnumerable<AITool> AsAITools()
{
return GetToolMethods()
.Select(method => AIFunctionFactory.Create(method));
}
public virtual object GetPluginInfo()
{
returnnew { Name = PluginName };
}
}
// 3. 插件实现接口
publicsealedclassStandardWeatherPlugin : StandardAgentPluginBase
{
privatereadonly WeatherProvider _provider;
publicoverridestring PluginName => "天气查询插件";
public StandardWeatherPlugin(WeatherProvider provider)
{
_provider = provider;
}
[Description("查询天气")]
public string GetWeather([Description("城市")] string location)
{
return _provider.GetWeather(location);
}
protected override IEnumerable<Delegate> GetToolMethods()
{
yieldreturnthis.GetWeather;
}
}
🔗 多插件集成
统一管理所有插件:
// 1. 注册所有服务和插件
services.AddSingleton<WeatherProvider>();
services.AddSingleton<CurrentTimeProvider>();
services.AddSingleton<IAgentPlugin, StandardWeatherPlugin>();
services.AddSingleton<IAgentPlugin, StandardTimePlugin>();
var serviceProvider = services.BuildServiceProvider();
// 2. 通过接口统一获取所有插件
var plugins = serviceProvider.GetServices<IAgentPlugin>();
// 3. 自动收集所有工具
var tools = plugins.SelectMany(p => p.AsAITools()).ToArray();
// 4. 创建 Agent
var agent = chatClient.CreateAIAgent(
instructions: "你是企业智能工作助手",
name: "WorkAssistant",
tools: tools,
services: serviceProvider
);
架构图:

🎯 选择性暴露机制
通过 GetToolMethods() 精确控制哪些方法暴露给 AI:
public sealedclassWeatherPlugin : StandardAgentPluginBase
{
// ✅ 暴露给 AI
[Description("查询天气")]
public string GetWeather(string location) { }
// ❌ 不暴露:内部管理方法
public void UpdateWeatherCache() { }
// ❌ 不暴露:敏感操作
public void SetApiKey(string apiKey) { }
// 只返回要暴露的方法
protected override IEnumerable<Delegate> GetToolMethods()
{
yieldreturnthis.GetWeather;
}
}
流程图:

🏢 企业级最佳实践
1. 架构选型建议
|
项目规模 |
推荐架构 |
理由 |
|---|---|---|
|
小型项目/原型 |
直接函数 |
快速开发,无需过度设计 |
|
中型项目 |
基础插件类 |
基本模块化,易于理解 |
|
大型项目 |
抽象基类 |
减少重复,统一标准 |
|
企业级应用 |
接口+基类 |
完全标准化,长期可维护 |
2. 依赖注入最佳实践
// ✅ 推荐:通过接口注册
services.AddSingleton<IAgentPlugin, WeatherPlugin>();
services.AddSingleton<IAgentPlugin, TimePlugin>();
// ✅ 推荐:统一解析所有插件
var plugins = serviceProvider.GetServices<IAgentPlugin>();
3. 插件开发规范
必须遵循:
-
✅ 继承
StandardAgentPluginBase基类 -
✅ 实现
IAgentPlugin接口 -
✅ 重写
GetToolMethods()方法声明工具 -
✅ 使用
[Description]特性描述方法和参数 -
✅ 通过构造函数注入依赖
禁止事项:
-
❌ 在
GetToolMethods()中暴露敏感操作 -
❌ 直接在插件中创建服务实例
-
❌ 跳过接口直接使用具体类
📊 架构演进对比
|
阶段 |
代码量 |
复用性 |
标准化 |
适用场景 |
|---|---|---|---|---|
|
直接函数 |
30行/插件 |
⭐ |
⭐ |
快速原型 |
|
基础插件类 |
30行/插件 |
⭐⭐ |
⭐⭐ |
中型项目 |
|
抽象基类 |
20行/插件 |
⭐⭐⭐ |
⭐⭐⭐ |
大型项目 |
|
接口+基类 |
20行/插件 |
⭐⭐⭐⭐ |
⭐⭐⭐⭐ |
企业级 |
演进路径:

🎯 总结
-
✅ 插件系统价值:模块化设计,独立开发,按需扩展
-
✅ 依赖注入:使用 DI 容器管理插件依赖,提高可测试性
-
✅ 抽象基类:统一实现
AsAITools(),减少 33% 代码量 -
✅ 选择性暴露:通过
GetToolMethods()精确控制 AI 能力边界 -
✅ 企业级标准:接口+基类架构,实现完全标准化
-
✅ 多插件集成:通过
IAgentPlugin接口统一管理所有插件
更多推荐



所有评论(0)