• .Net基于NetCoreKevin框架 AI 与 Hangfire 集成:实现AI智能自动任务调度


    .Net基于NetCoreKevin框架 AI 与 Hangfire 集成:实现AI智能自动任务调度

    效果图

    1998
    1999

    参考源代码: NetCoreKevin框架下的kevin.AI.AgentFramework中的IKevinAITasksService模块

    基于.NET构建的企业级SaaSAI智能体应用架构,采用前后端分离设计,具备以下核心特性:

    1. 概述

    NetCoreKevin 是一个 AI Agent 框架,内置了丰富的工具(如 HTTP 请求、Python 执行、Shell 命令等)。通过集成 Hangfire 分布式任务调度库,AI 能够自主创建、管理和触发周期性自动任务,让智能体不仅能实时响应,还能按预定计划自动完成日常工作(如定时生成报告、数据同步、内容总结等)。本文将详细介绍如何在 NetCoreKevin 中实现 AI 与 Hangfire 的完美结合。


    2. 架构说明

    整体架构分为三层:

    • AI 工具层 (KevinAIAllTools) :负责将服务接口中的方法注册为 AI 可调用的函数工具。
    • 任务服务接口 (IKevinAITasksService) :定义了定时任务的增删改查及手动触发操作。
    • 任务执行层 (KevinAITasksService) :基于 Hangfire 的 IRecurringJobManager 实现任务的持久化调度,并通过 RunTask 方法真正执行任务内容(可接入 AI 处理逻辑)。

    调用流程:
    用户自然语言指令 → AI Agent 解析 → 调用对应工具函数 → 操作 Hangfire 任务 → 定时/手动触发 RunTask → 执行实际任务(可调用 AI 或其他服务)。


    3. 环境与依赖

    3.1 安装 Hangfire

    需安装以下 NuGet 包(根据存储后端选择相应包):

    dotnet add package Hangfire.Core
    dotnet add package Hangfire.SqlServer   # 以 SQL Server 为例,也可选 Redis/PostgreSQL 等
    

    3.2 配置服务注册

    Startup.csProgram.cs 中注册 Hangfire 服务、任务服务以及框架所需的其他服务:

    services.AddHangfire(config =>
    {
        config.UseSqlServerStorage("YourConnectionString");
    });
    services.AddHangfireServer(); // 启动 Hangfire 后台处理服务器
    
    // 注册自定义任务服务(生命周期需与 Hangfire 匹配,建议 Scoped 或 Singleton)
    services.AddScoped();
    // 确保 IHttpContextAccessor 已注入(BaseService 依赖)
    services.AddHttpContextAccessor();
    

    KevinAITasksService 的构造函数注入了 IRecurringJobManagerJobStorage,这些由 Hangfire 自动提供。


    4. 核心代码解析

    4.1 任务服务接口 IKevinAITasksService

    /// 
    /// 用于给AI使用的自动任务服务接口,提供自动任务相关的功能和操作
    /// 你可以让它在每天、每周、每月,或者某个固定时间自动运行,帮助你完成常见的日常工作。
    /// 
    public interface IKevinAITasksService
    {
        /// 
        /// 创建或更新一个周期性自动任务
        /// 
        Task<string> AddOrUpdateCronTask(
            [Description("任务名称,不可为空")] string name,
            [Description("任务内容,不可为空")] string content,
            [Description("Cron 表达式,定义执行周期")] string cronExpression);
    
        /// 
        /// 移除周期性任务
        /// 
        Task<string> RemoveCronTask([Description("任务名称")] string name);
    
        /// 
        /// 立即触发某个周期性任务一次
        /// 
        Task<string> TriggerCronTask([Description("任务名称")] string name);
    
        /// 
        /// 获取当前用户的所有周期性任务列表
        /// 
        Taskstring>> GetTaskList();
    
        /// 
        /// 执行具体的任务内容(由 Hangfire 调度调用)
        /// 
        Task<string> RunTask(string taskName, string taskContent);
    }
    

    4.2 任务服务实现 KevinAITasksService

    该实现通过 Hangfire 的 IRecurringJobManager 完成周期性任务的管理,并用 CurrentUser.UserId 作为任务 ID 前缀实现用户隔离。

    public class KevinAITasksService : BaseService, IKevinAITasksService
    {
        private readonly IRecurringJobManager _recurringJobManager;
        private readonly JobStorage _jobStorage;
    
        public KevinAITasksService(IHttpContextAccessor httpContextAccessor,
                                   IRecurringJobManager recurringJobManager,
                                   JobStorage jobStorage) : base(httpContextAccessor)
        {
            _recurringJobManager = recurringJobManager;
            _jobStorage = jobStorage;
        }
    
        public Task<string> AddOrUpdateCronTask(string name, string content, string cronExpression)
        {
            _recurringJobManager.AddOrUpdate(
                recurringJobId: CurrentUser.UserId + name,   // 用户隔离
                methodCall: s => s.RunTask(name, content),
                cronExpression: cronExpression,
                options: new RecurringJobOptions { TimeZone = TimeZoneInfo.Local }
            );
            return Task.FromResult($"添加或更新定时任务成功:{name} - {content}");
        }
    
        public Taskstring>> GetTaskList()
        {
            var storage = _jobStorage ?? JobStorage.Current;
            var connection = storage.GetConnection();
            var recurringJobs = connection.GetRecurringJobs();
    
            var result = recurringJobs
                .Where(t => t.Id.StartsWith(CurrentUser.UserId.ToString()))
                .Select(r => $"name:{r.Id} | Cron:{r.Cron} | Next:{r.NextExecution?.ToLocalTime():u} | Last:{r.LastExecution?.ToLocalTime():u}")
                .ToList();
            return Task.FromResult(result);
        }
    
        public Task<string> RemoveCronTask(string name)
        {
            _recurringJobManager.RemoveIfExists(CurrentUser.UserId + name);
            return Task.FromResult($"移除定时任务成功:{name}");
        }
    
        public Task<string> TriggerCronTask(string name)
        {
            _recurringJobManager.Trigger(CurrentUser.UserId + name);
            return Task.FromResult($"手动触发任务成功:{name}");
        }
    
        public Task<string> RunTask(string taskName, string taskContent)
        {
            // 此处可接入真实的 AI 处理逻辑,例如:
            // var aiService = GetRequiredService();
            // string result = await aiService.ProcessTaskAsync(taskContent);
            Console.WriteLine($"[{CurrentUser.UserId}] 执行任务:{taskName},内容:{taskContent}");
            return Task.FromResult($"任务已执行:{taskName}");
        }
    }
    

    注意RunTask 方法是任务真正执行的入口,可以根据项目需求注入其他服务(如 AI 对话客户端、数据库操作等)来完成复杂工作。

    4.3 AI 工具注册 KevinAIAllTools

    在框架的工具聚合类中,通过依赖注入获取 IKevinAITasksService 实例,并将其方法注册为 AI 可识别的工具函数。

    public class KevinAIAllTools
    {
        public async Task> GetKevinAIAllTools(IServiceProvider serviceProvider)
        {
            var tools = new List
            {
                // ... 其他工具(HTTP、Shell、Python 等)
            };
    
            // 如果服务容器中存在 IKevinAITasksService,注册任务相关工具
            var taskService = serviceProvider.GetService();
            if (taskService != null)
            {
                tools.Add(AIFunctionFactory.Create(
                    taskService.AddOrUpdateCronTask,
                    new AIFunctionFactoryOptions
                    {
                        Name = "AddOrUpdateCronTask",
                        Description = "创建或更新一个周期性自动任务"
                    }));
                tools.Add(AIFunctionFactory.Create(
                    taskService.RemoveCronTask,
                    new AIFunctionFactoryOptions { Name = "RemoveCronTask", Description = "移除周期性任务" }));
                tools.Add(AIFunctionFactory.Create(
                    taskService.TriggerCronTask,
                    new AIFunctionFactoryOptions { Name = "TriggerCronTask", Description = "立即触发某个周期性任务一次" }));
                tools.Add(AIFunctionFactory.Create(
                    taskService.GetTaskList,
                    new AIFunctionFactoryOptions { Name = "GetTaskList", Description = "获取我的所有周期性任务列表" }));
            }
    
            return tools;
        }
    }
    

    这样,当 AI Agent 初始化时,就会自动加载这些定时任务管理工具。


    5. AI 调用流程示例

    5.1 用户下达自然语言指令

    用户
    “帮我创建一个任务,每天早上8点总结前一天的AI领域新闻,并将结果保存到桌面。”

    5.2 AI Agent 内部处理

    1. 识别意图:创建周期性任务。
    2. 提取参数:
      • 任务名称:每日AI新闻总结
      • 任务内容:搜索并总结过去24小时AI领域的重要新闻,生成简报并保存为桌面文件
      • 执行周期:0 0 8 * * ?(每天8点)
    3. 调用工具 AddOrUpdateCronTask(name, content, cronExpression),底层通过 Hangfire 创建循环作业。

    5.3 Hangfire 定时触发

    当时间到达时,Hangfire 会自动调用 IKevinAITasksService.RunTask("每日AI新闻总结", "搜索并总结过去24小时...")
    你可以在 RunTask 方法中实现真正的业务逻辑,例如调用 OpenAI 接口生成总结,再利用 WriteTextToDesktop 工具写入文件。

    5.4 其他管理操作

    • 查看任务:用户说“我有哪些定时任务?” → AI 调用 GetTaskList 返回列表。
    • 删除任务:用户说“删除每日AI新闻总结” → AI 调用 RemoveCronTask("每日AI新闻总结")
    • 立即执行一次:用户说“马上执行一下新闻总结任务” → AI 调用 TriggerCronTask("每日AI新闻总结")

    6. 用户隔离与安全

    • 用户 ID 前缀:所有 Hangfire 循环作业的 ID 均采用 CurrentUser.UserId + name 的形式,确保不同用户的任务互不干扰。GetTaskList 也通过过滤 ID 前缀返回当前用户的任务。
    • Cron 表达式校验:虽然代码未显式校验,但建议在 AddOrUpdateCronTask 中增加格式检查,防止非法表达式导致异常。
    • 权限控制KevinAITasksService 依赖于当前登录用户(通过 IHttpContextAccessor),确保任务管理限制在用户自身范围内。

    7. 总结与扩展

    通过 NetCoreKevin 框架与 Hangfire 的集成,AI 智能体获得了“计划未来”的能力,从被动的对话交互升级为能主动按计划执行任务的智能代理。你可以轻松扩展以下能力:

    • 任务内容模板化:将常用任务(如周报生成、数据备份)封装为固定流程,由 AI 自动填充参数。
    • 任务链:一个任务完成后触发另一个任务,实现复杂工作流。
    • 失败重试:利用 Hangfire 自带的重试机制保证任务可靠性。
    • 通知提醒:执行完毕后通过邮件、消息等方式通知用户。

    这种设计极大地提升了 AI Agent 的实用性和自动化水平,适用于个人助理、运维监控、数据分析等多种场景。

  • 相关阅读:
    superset支持Kylin4.0.0(兼容处理日期分组功能)
    TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension “.ts“ for xxx
    Pytest----如何通过filterwarnings配置不显示告警或将告警报错
    《C++设计模式》——创建型
    frp内网穿透—将kali代理在公网中进行渗透测试
    Bezier曲线与B-Spline曲线
    C++,STL,,vector容器
    Docker安装和配置nginx服务
    神经网络建模的基本思想,神经网络建模数据分析
    PostgreSQL sequence cache 参数导致的数值序列不连续 有间隔 gap
  • 原文地址:https://www.cnblogs.com/net-kevin-li/p/20056384