码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 基于.Net的NetCoreKevin框架中AgentFramework实现AI智能体Skill和工具动态管理和加载


    合集 - AI(18)
    1.NetCoreKevin-DDD-微服务-WebApi-AI智能体、AISemanticKernel集成、MCP协议服务、SignalR、Quartz2025-08-192.NetCoreKevin-DDD-微服务-现代化Saas企业级-WebAPI-前后端分离架构2025-11-193.Net AI智能体开源框架NetCoreKevin为企业AI智能体系统Saas信息化建设赋能-开启智能应用的无限可能2025-12-034..Net使用AgentFramework进行多Agent工作流编排-智能体AI开发2025-12-065..Net——AI智能体开发基于 Microsoft Agent Framework 实现第三方聊天历史存储2025-12-176.Net优雅实现AI知识库基于Ollama模型,Qdrant作为向量数据库实现RAG流程AI检索增强01-157.NetCoreKevin是一个基于.NET9 AI时代的 SaaS 企业级AI 架构,专注于 AI 智能体开发与集成,AgentFramework和知识库,为企业提供高效的 AI 应用开发框架。01-168.基于 .NET 的 AI 流式输出实现AgentFramework+SignalR01-209..Net C# AI 如何实现联网搜索01-2110.OpenClaw 安装指南(面向开发人员)03-0911.OpenClaw 安装指南(面向非开发人员)03-0912..Net基于AgentFramework中智能体Agent Skill集成Shell命令实现小龙虾mini版03-1813..Net如何在AgentFramework中给AI智能体给AI添加执行python脚本和运行代码的能力后——后续可用于对接openClaw技能03-2014.基于.NET AgentFramework开发OpenClaw智能体框架03-2315..NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块04-1316..Net基于NetCoreKevin框架 AI 与 Hangfire 集成:实现AI智能自动任务调度05-15
    17.基于.Net的NetCoreKevin框架中AgentFramework实现AI智能体Skill和工具动态管理和加载05-22
    18.深入 .NET AI Agent 开发:利用 Microsoft.Agents.AI 提取思考、调用工具与执行脚本05-27
    收起

    基于.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 提供的:

    • AgentSkillsProviderBuilder、AgentFileSkillsSourceOptions
    • AITool、AIFunctionFactory
    • 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 正是依赖此服务实现按 agentId 和 userId 的动态过滤。

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

  • 相关阅读:
    第一次使用项目管理软件进行项目资源监控,再也不用进行“抢人大战”了!
    集团施工企业安全生产风险管控和隐患排查治理双重预防机制数字化建设方案
    springboot配置swagger
    MybatisPlus的CRUD接口
    使用fabric8操作k8s
    线性回归学习
    C++游戏设计教程(4)—— 用颜色原理打印平面地图
    JavaScript_DOM
    基于微信小程序的土地租赁的设计与实现
    (免费领取源码)计算机毕业设计项目:57788基于SSM框架的绿化设施管理系统(开题答辩+程序定制+全套文案 )上万套实战教程手把手教学JAVA、PHP,node.js,C++、python、大屏数据
  • 原文地址:https://www.cnblogs.com/net-kevin-li/p/20121110
  • 最新文章
  • 【FHE】我们如何实现同态加密推理(八):SiLU 的密文化——两条路径,和一个 8 字节的开关
    SQLcl 中 c/old/new 替换变量为何失效?先定位再替换
    不让模型写作文,直接从它脑子里读答案:Jev 决策在 .NET 的两条路线
    Halo插件:支持GitHub的图床附件策略
    电视投屏界的“一股清流”!SimpleTVCast 6.0.0-beta 抢先体验:无需TV端App,界面大换血!✨
    华三VXLAN集中式网关实战指南:Spine多活网关 + 双活接入(M-LAG)
    软件更好写之后口碑会更重要
    大 O、大 Omega、大 Theta 的区别,O(n) 复杂度是什么意思
    Java标签跳转:一个鲜为人知但却很实用的小技巧
    多智能体系统论文速读
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号