基于.Net的NetCoreKevin框架中AgentFramework实现AI智能体Skill和工具动态管理和加载

基于.Net的NetCoreKevin框架中AgentFramework实现AI智能体Skill和工具动态管理和加载

系统实现效果图

## 开源地址

github.com/junkai-li/N...

gitee.com/netkevin-li...

1. 背景与目标

在大模型应用开发中,智能体需要灵活组合各种 工具(Tool)技能(Skill) 来完成任务。NetCoreKevin 框架基于自主研发的 AgentFramework 底层,提供了一套"数据驱动 + 文件热加载"的动态能力扩展方案,让开发者无需修改核心代码即可为不同智能体按需配置工具和技能。

本文深入剖析该方案的实现细节,涵盖从数据库定义、动态注入 AITool,到 .zip 技能包的自动解压与加载全过程,帮助读者快速理解底层架构并应用于实际项目。


2. 整体架构概览

NetCoreKevin 的能力管理分为两个维度:

  • 工具(Tool) :粒度小、无状态,通过 AIFunctionFactory 将普通 C# 方法包装为 AI 可调用的函数,直接注入 ChatOptions.Tools 列表。
  • 技能(Skill) :有状态的复合能力单元,以文件包(.zip)形式存储,通过 AgentSkillsProviderBuilder 构建为 AIContextProvider,由 AgentFramework 负责调度。

核心组件协作关系如下:

scss 复制代码
┌─────────────────────────────────────────────┐
│              ChatClientAgent                │
│  (ChatOptions.Tools + AIContextProviders)   │
└───────┬──────────────────────┬─────────────┘
        │Tools                 │Skills
        ▼                      ▼
┌──────────────┐     ┌───────────────────────┐
│AIAgentTool   │     │AgentSkillsProvider    │
│SkillService  │     │Builder (AgentFramework)│
└──┬───┬───────┘     └───────────┬───────────┘
   │   │                         │
   │   ▼                         ▼
   │ SysTools (静态工具)     文件系统 Skill 目录
   │ IKevinAITaskService 等  
   ▼
AISkillToolManagementService (数据库)

底层完全依赖 AgentFramework 提供的:

  • AgentSkillsProviderBuilderAgentFileSkillsSourceOptions
  • AIToolAIFunctionFactory
  • PySubprocessScriptRunner 等执行器

3. 数据驱动的 Skill 与 Tool 定义

框架将工具和技能统一存储在 TAISkillToolManagement 实体中,由 IAISkillToolManagementService 提供管理服务。关键字段包括:

字段 说明
Name 工具/技能唯一标识名
SkillToolType 枚举:Tool / Skill
ClassMethod 工具绑定的方法名(如 AddOrUpdateCronTask
Description 功能描述,供大模型决策用
ActiveStatus 是否启用
IsSystem 是否系统内置(禁止删除)

技能还附带一个 .zip 附件,包含脚本文件、资源等,通过文件服务管理。

csharp 复制代码
// 获取所有启用的工具
public async Task<List<AISkillToolManagementDto>> GetAllTools()
{
    return (await AISkillToolManagementRp.Query(...)
        .Where(t => t.SkillToolType == AISkillToolTypeEnums.Tool 
                  && t.ActiveStatus == InActiveStatusEnums.Active)
        .ToListAsync())
        .MapToList<TAISkillToolManagement, AISkillToolManagementDto>();
}

4. 工具的动态注入

工具注入由 AIAgentToolSkillService 实现,其核心流程为:

  1. 根据 agentId 查询绑定表 IAISkillToolBindIdService,获得该智能体允许使用的工具管理 ID。
  2. 通过 AISkillToolManagementService.GetAllTools() 过滤出这些 ID 对应的工具记录,提取 ClassMethod 名称。
  3. 调用 GetAITools 将方法名转化为 AITool 实例。

4.1 静态工具与动态工具的区分

SysTools.Tools 是一个预注册的全局字典,存放所有"静态工具"(无需依赖注入即可直接使用的工具)。如果工具名存在于字典,直接取出;否则进入 switch 分支,通过 AIFunctionFactory.Create 将具体服务方法包装为 AITool

csharp 复制代码
private async Task<List<AITool>> GetAITools(object data, List<string> toolNames)
{
    var aiTools = new List<AITool>();
    _kevinAITaskService.InitData(data);
    foreach (var item in toolNames)
    {
        if (SysTools.Tools.ContainsKey(item))
        {
            aiTools.Add(SysTools.Tools[item]); // 静态工具
        }
        else
        {
            switch (item)
            {
                case "AddOrUpdateCronTask":
                    aiTools.Add(AIFunctionFactory.Create(
                        _kevinAITaskService.AddOrUpdateCronTask,
                        new AIFunctionFactoryOptions { Name = "AddOrUpdateCronTask", 
                            Description = "创建或更新一个周期性自动任务" }));
                    break;
                case "RemoveCronTask":
                    // ... 类似
                    break;
                // ... 更多工具
            }
        }
    }
    return aiTools;
}

4.2 与智能体集成

在构造 ChatClientAgentOptions 时,如果配置启用了工具,则从服务中获取工具列表,合并到 ChatOptions.Tools

csharp 复制代码
if (aiapp.IsAITools)
{
    chatAgOs.ChatOptions.Tools ??= new List<AITool>();
    chatAgOs.ChatOptions.Tools.AddRange(
        _aIAgentToolSkillService.GetUserAIAgentToolsAsync(
            new { AIChatsId = add.AIChatsId }, 
            aiapp.Id.ToString(), 
            CurrentUser.UserId.ToString()
        ).Result
    );
}

这样每个智能体实例都能拥有不同的工具集,实现多租户级别的能力隔离。


5. 技能文件的动态加载

技能本质上是包含脚本(.py.sh.ps1)和资源文件的目录包。上传时打包为 .zip,由 AISkillToolManagementService.AddEdit 负责下载、解压并放置到应用根目录下的 Skills/{技能名称}/ 路径中。

csharp 复制代码
// 处理技能 zip 包
if (data.SkillToolType == AISkillToolTypeEnums.Skill)
{
    var flieData = _FileRp.Query().FirstOrDefault(t => 
        t.Table == "AISkillToolManagement" && t.Sign == "SkillZip" && t.TableId == data.Id.ToString());
    if (flieData != null)
    {
        var path = Path.Combine(AppContext.BaseDirectory, "Skills", data.Name, data.Name);
        if (Directory.Exists(path))
            Directory.Delete(path, true);
        Directory.CreateDirectory(path);
        _FileStorage.FileDownload(flieData.Url, path + flieData.Name);
        using var fileStream = File.OpenRead(path + flieData.Name);
        FileZipHelper.ExtractZipStreamToDirectory(fileStream, path);
        File.Delete(path + flieData.Name); // 删除原始 zip
    }
}

5.1 通过 AgentFramework 注册文件技能

在构建智能体时,从服务获取该智能体绑定的技能路径列表,然后利用 AgentSkillsProviderBuilder 将它们逐一注册为 FileSkill

csharp 复制代码
if (aiapp.IsSkill)
{
    var skillPaths = _aIAgentToolSkillService.GetUserAIAgentSkillsAsync(...).Result;
    var skillsProvider = new AgentSkillsProviderBuilder()
        .UseFileScriptRunner(PySubprocessScriptRunner.StaticRunAsync)
        .UseOptions(options => options.DisableCaching = true);

    foreach (var skillPath in skillPaths)
    {
        skillsProvider.UseFileSkill(
            Path.Combine(AppContext.BaseDirectory, "Skills", skillPath),
            new AgentFileSkillsSourceOptions
            {
                AllowedScriptExtensions = [".py", ".sh", ".ps1"],
                ScriptDirectories = ["scripts", "tools", "templates"],
            });
    }
    chatAgOs.AIContextProviders = [skillsProvider.Build()];
}

AgentSkillsProviderBuilder 属于 AgentFramework 核心,它负责扫描指定目录下的脚本文件,并与 PySubprocessScriptRunner 等执行器关联,生成可以响应大模型调用的技能上下文。


6. 管理与绑定服务

6.1 技能/工具管理服务

AISkillToolManagementService 提供标准 CRUD 操作:

  • 分页查询,支持按类型筛选;
  • 新增/编辑时自动处理附件解压;
  • 删除(逻辑删除)并对系统内置项进行保护。

6.2 智能体绑定

IAISkillToolBindIdService 维护智能体与技能/工具管理 ID 的映射关系,决定每个智能体可用的能力列表。AIAgentToolSkillService 正是依赖此服务实现按 agentIduserId 的动态过滤。

csharp 复制代码
public async Task<List<AITool>> GetAIAgentToolsAsync(object data, string agentId)
{
    var agentBindIds = (await _iAISkillToolBindIdService.GetListById(agentId))
        .Select(t => t.AISkillToolManagementId).ToList();
    var tools = (await _iAISkillToolManagementService.GetAllTools())
        .Where(t => agentBindIds.Contains(t.Id)).ToList();
    return await GetAITools(data, tools.Select(t => t.ClassMethod ?? "").ToList());
}

这种方式使得能力配置完全与代码分离,可通过后台管理界面灵活调整,而无需重启服务。


7. 总结

NetCoreKevin 框架基于 AgentFramework,通过 数据库驱动 + 文件系统热加载 实现了 AI 智能体工具与技能的动态管理。其核心优势在于:

  • 工具注入 :方法名映射与 AIFunctionFactory 结合,可零侵入地将业务方法暴露给大模型。
  • 技能加载.zip 文件包上传自动解压,再利用 AgentSkillsProviderBuilder 注册为上下文提供者,支持脚本类技能的热插拔。
  • 权限隔离:通过绑定表实现不同智能体、不同用户的能力差异化,满足多租户场景。

该方案已在生产环境中验证,显著提升了智能体应用的迭代效率和可维护性。未来框架还将引入远程插件仓库、版本回滚等高级特性,持续降低智能体扩展的门槛。

本文所有代码均基于 NetCoreKevin 框架及 AgentFramework 真实实现。

相关推荐
血小溅5 小时前
Git Submodule 实战指南:从基础概念到 AI-Native 项目落地
后端
日月云棠5 小时前
6 高级配置:Spring Boot整合、泛化调用与配置指南
java·后端
SE_NAK5 小时前
go-zero 两个限流器都踩了坑,最后自行实现了一个分布式令牌桶
后端
苏三说技术5 小时前
Durid和HikariCP,哪个连接池更好?
后端
思考着亮5 小时前
1.DDL(数据定义语言)
后端
她的男孩5 小时前
Spring Boot 3 后台框架的自动配置设计:少写配置,多做组合
后端
小黑蛋9125 小时前
Linux核心知识点全解01
后端
日月云棠5 小时前
5 高级配置:多注册中心与异步化编程
java·后端
她的男孩5 小时前
Maven 多模块项目如何避免越写越乱?Forge Admin 的模块边界实践
后端