当前位置: 首页 > news >正文

DeepSeek RAGMCP + Agent智能体项目 —— 引入定时任务组件并完成管理端接口

一、前言

这一节将引入扳手工程中的定时任务,可用于自动定时执行发帖以及其他MCP服务,原理很简单,就是通过定时执行调度器,同时向调度器中传预制的数据,最终会让调度器定时执行相同的任务。

二、定时任务

1.配置文件

这里面主要要去完成关于定时部分的配置,比如时间间隔等,这个配置文件最终会写入扳手工程的定时任务配置类中。

# 小傅哥扳手通用组件配置 xfg: wrench: # 任务调度配置 task: job: enabled: true pool-size: 5 thread-name-prefix: "test-task-scheduler-" wait-for-tasks-to-complete-on-shutdown: true await-termination-seconds: 30 refresh-interval: 30000 clean-invalid-tasks-cron: "0 0/5 * * * ?"

2.填充定时任务

其实整体流程在前言部分就已经讲完了,现在主要是看看怎么实施,首先是定时执行调度器,这个需要借助扳手工程中的TaskScheduleVO来实现,这个值对象中主要包含以下内容,很显然的我们需要借助数据库中对定时任务的配置信息来填充VO。

@Data public class TaskScheduleVO { /** 任务ID */ private Long id; /** 任务描述 */ private String description; /** Cron表达式 */ private String cronExpression; /** 任务参数 */ private String taskParam; /** 任务执行器函数式接口 */ private Supplier<Runnable> taskExecutor; public TaskScheduleVO() { } /** * 便捷方法:设置任务执行逻辑 * @param taskLogic 任务执行逻辑 */ public void setTaskLogic(Runnable taskLogic) { this.taskExecutor = () -> taskLogic; } /** * 便捷方法:设置带参数的任务执行逻辑 * @param taskLogic 任务执行逻辑,接收taskId和taskParam */ public void setTaskLogic(BiConsumer<Long, String> taskLogic) { this.taskExecutor = () -> () -> taskLogic.accept(this.id, this.taskParam); } @Override public String toString() { return "TaskScheduleVO{" + "id=" + id + ", description='" + description + '\'' + ", cronExpression='" + cronExpression + '\'' + ", taskParam='" + taskParam + '\'' + ", hasTaskExecutor=" + (taskExecutor != null) + '}'; } }

因此我们需要去仓储层新增一些查询方法,不过还是比较简单的,所以这里就不细讲了。

最核心的是下面的AgentTaskJob类,在这个类中我们要实现ITaskDataProvider接口,这个接口用于提供定时任务的数据,因此TaskScheduleVO就要在这里装填了,同时在taskLogic字段中要填充执行调度的方法。

@Service @Slf4j public class AgentTaskJob implements ITaskDataProvider { @Resource private ITaskService taskService; @Resource private IAgentDispatchService dispatchService; @Override public List<TaskScheduleVO> queryAllValidTaskSchedule() { List<AiAgentTaskScheduleVO> aiAgentTaskScheduleVOS = taskService.queryAllValidTaskSchedule(); List<TaskScheduleVO> result = new ArrayList<>(); for (AiAgentTaskScheduleVO aiAgentTaskScheduleVO : aiAgentTaskScheduleVOS) { TaskScheduleVO taskScheduleVO = new TaskScheduleVO(); taskScheduleVO.setId(aiAgentTaskScheduleVO.getId()); taskScheduleVO.setDescription(aiAgentTaskScheduleVO.getDescription()); taskScheduleVO.setCronExpression(aiAgentTaskScheduleVO.getCronExpression()); taskScheduleVO.setTaskParam(aiAgentTaskScheduleVO.getTaskParam()); taskScheduleVO.setTaskLogic(() -> { try { dispatchService.dispatch( ExecuteCommandEntity.builder() .aiAgentId(aiAgentTaskScheduleVO.getAgentId()) .sessionId(String.valueOf(System.nanoTime())) .maxStep(1) .build(), new ResponseBodyEmitter()); } catch (Exception e) { log.error("任务执行失败", e); } }); result.add(taskScheduleVO); } return result; } @Override public List<Long> queryAllInvalidTaskScheduleIds() { return taskService.queryAllInvalidTaskScheduleIds(); } }

3.定时任务走的固定执行链

这是一个新的执行模式,与ReAct Loop和Plan-and-Execute是同级的,是最简单的一种,单纯就是和一个AgentClient对话,并且没有预设任何的提示词,提示词仅为用户的(用户在数据库中固定设置的),也没有记忆,单纯只有一轮对话,但是可以调MCP工具,这个需要依靠在数据库中配置。

/** * @author 印东升 * @description * @create 2026-06-10 17:46 */ @Slf4j @Service("fixedAgentExecuteStrategy") public class FixedAgentExecuteStrategy implements IExecuteStrategy { @Resource protected ApplicationContext applicationContext; @Resource protected IAgentRepository repository; public static final String CHAT_MEMORY_CONVERSATION_ID_KEY = "chat_memory_conversation_id"; public static final String CHAT_MEMORY_RETRIEVE_SIZE_KEY = "chat_memory_response_size"; @Override public void execute(ExecuteCommandEntity requestParam, ResponseBodyEmitter emitter) throws Exception { List<AiAgentClientFlowConfigVO> agentClientFlowConfigVOList = repository.queryAiClientByAgentId(requestParam.getAiAgentId()); String content = ""; for (AiAgentClientFlowConfigVO configVO : agentClientFlowConfigVOList) { ChatClient chatClient = getChatClientByClientId(configVO.getClientId()); content = chatClient.prompt(requestParam.getMessage() + "," + content) .system(s -> s.param("current_date", LocalDate.now().toString())) .advisors(a -> a .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, requestParam.getSessionId()) .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100)) .call().content(); } } protected ChatClient getChatClientByClientId(String clientId) { return getBean(AiAgentEnumVO.AI_CLIENT.getBeanName(clientId)); } protected <T> T getBean(String beanName) { return (T) applicationContext.getBean(beanName); } }

三、管理端接口

其实就是写CRUD的一个一个接口,一堆Controller,没有复杂的业务逻辑。

同时使用flowgram.ai框架去做前端页面对接,最终效果如下:

完结撒花!!!

http://www.zskr.cn/news/1511073.html

相关文章:

  • 暗黑破坏神2存档编辑器终极指南:如何轻松修改角色和物品
  • MC68HC16Z1 QSM模块深度解析:QSPI与SCI集成通信实战指南
  • 5分钟免费扩展Windows桌面:虚拟显示器终极解决方案
  • 汽车电子核心动力:MPC565/566微控制器架构、外设与开发实战解析
  • 5分钟打造你的象棋AI军师:Vin象棋智能连线工具深度指南
  • 2026 福州黄金回收服务测评:上门速度、验金透明度对比 - 奢侈品回收评测
  • 从PlenOctrees到3DGS:手把手拆解球面谐波(SH)系数在代码里到底怎么存怎么算
  • 深度学习目标检测中利用脑肿瘤目标检测数据集训练识别3类’glioma_tumor’, ‘meningioma_tumor’,‘pituitary_tumor’2908张图像txt格式的脑肿瘤数据集
  • 泉盛UV-K5/K6固件深度探索:解锁专业无线电的终极潜能
  • League-Toolkit:英雄联盟玩家的智能本地化效率革命
  • Onekey Steam Depot清单下载工具:三步获取完整游戏清单的终极指南
  • FbxFormatConverter架构解析:FBX文件格式转换的技术实现与性能优化
  • 2026 佛山黄金回收机构盘点 权威鉴定团队 全品类黄金一站式回收 - 奢侈品回收测评
  • 128.配置qt(交叉)编译的路径---解决无法编译的问题
  • 终极防撤回神器:Android免Root防撤回完全指南
  • 亚马逊家具卖家,为什么一定要做CPF气候友好绿标?
  • VMware ESXi macOS解锁实战教程:在虚拟化平台运行苹果系统的完整方案
  • 2026年6月最新| 杭州注册公司代办哪家靠谱?避开这3个低价陷阱 - 商业新知
  • 5分钟掌握Bebas Neue字体:设计师必备的免费商用字体解决方案
  • 2026年目的地婚礼实战攻略:纪梵希旅拍从三亚婚纱照到新疆旷野的一站式婚礼旅拍方案深度拆解 - 深度智识库
  • 5分钟快速上手:Unity游戏汉化神器XUnity.AutoTranslator终极指南
  • 从推荐系统到A/B测试:聊聊MCMC在互联网公司里的那些‘隐形’应用
  • 数据科学与大数据技术专业学习数据分析的价值
  • 终极指南:3步轻松提取Xbox Game Pass游戏存档,实现跨平台进度迁移
  • 纯PHP单文件成绩工资查询工具:Excel直读、无数据库、手机电脑都能用
  • SpringAI配置使用类openai大模型规范
  • 2026年 平谷区长途搬家推荐榜单:专业打包全程保险、省心无忧的跨城搬迁优选! - 企业推荐官【官方】
  • NXP 22W无线快充方案解析:MWCT101x芯片与MP-A11拓扑实战指南
  • Vin象棋:3步快速上手的智能象棋助手,免费开源让普通玩家享受大师级分析体验
  • 微信好友批量添加神器:3分钟掌握Python自动化操作,效率提升10倍!