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


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

    系统实现效果图

    779aa82b-248c-4bf5-b31b-af45b6036bff

    932393ac-9076-4f09-a663-7b034f4620e5
    39426481-fc9d-4ad0-b66a-1b51874f6da2

    开源地址

    https://github.com/junkai-li/NetCoreKevin

    https://gitee.com/netkevin-li/NetCoreKevin

    1. 背景与目标

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

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


    2. 整体架构概览

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

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

    核心组件协作关系如下:

    ┌─────────────────────────────────────────────┐
    │              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 附件,包含脚本文件、资源等,通过文件服务管理。

    // 获取所有启用的工具
    public async Task> GetAllTools()
    {
        return (await AISkillToolManagementRp.Query(...)
            .Where(t => t.SkillToolType == AISkillToolTypeEnums.Tool 
                      && t.ActiveStatus == InActiveStatusEnums.Active)
            .ToListAsync())
            .MapToList();
    }
    

    4. 工具的动态注入

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

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

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

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

    private async Task> GetAITools(object data, List<string> toolNames)
    {
        var aiTools = new List();
        _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

    if (aiapp.IsAITools)
    {
        chatAgOs.ChatOptions.Tools ??= new List();
        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/{技能名称}/ 路径中。

    // 处理技能 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

    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 的动态过滤。

    public async Task> 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 真实实现。

  • 相关阅读:
    WPF利用Path自定义画头部导航条(TOP)样式
    Qt实现2D绘图
    CSP-J2 2022 游记
    PROTAC——靶点选择与设计 | MedChemExpress
    JSP config对象
    MySQL底层知识总结
    【信号去噪】基于麻雀算法优化最小二乘法lms自适应滤波器实现语音去噪附matlab代码
    基于Java毕业设计在线课堂辅助系统源码+系统+mysql+lw文档+部署软件
    如何使用 Java 将 PDF 转换为文本 (TXT)
    前端周刊第三十期
  • 原文地址:https://www.cnblogs.com/net-kevin-li/p/20121110