当前位置: 首页 > 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.jsqmd.com/news/999299/

相关文章:

  • 暗黑破坏神2存档编辑器终极指南:如何轻松修改角色和物品
  • 瑞沃金刚S1-YCF25耐用抗造,破解工地运输难题 - 资讯纵览
  • 2026 年许昌市复卷纸加工设备厂家排名榜:卫生纸加工机器与生产线实力盘点 - 品研笔录
  • MC68HC16Z1 QSM模块深度解析:QSPI与SCI集成通信实战指南
  • Codex-Bridge实现API协议双向转换
  • 2026昆明十佳医疗纠纷律师精选推荐|5家专攻医患维权靠谱团队盘点 - GEO真实测评
  • Windows平台C# WinForm人脸检测与识别演示工程(含阅面SDK接入和Token配置指南)
  • 别再死记公式了!用Python和TensorFlow 2.x从零搭建一个神经网络(附咖啡豆分类实战)
  • 2026推荐:游泳池高危证检测|卫生证水质检测|房屋安全性检测 - 公共场所卫生检测
  • 腾讯会议同传工具推荐
  • 双管板换热器厂家推荐 - 多才菠萝
  • 实战踩坑:在Qt Widgets和QML混编项目里,如何正确使用Q_PROPERTY实现数据绑定与同步?
  • QorIQ LS2处理器:异构计算架构如何实现40Gbps网络加速
  • 从星巴克排队到云服务器扩容:聊聊马尔可夫模型在真实场景里的那些事儿
  • 2026年电商仓配解决方案深度解析:中小企业如何选对仓配服务商 - 深度智识库
  • 5分钟免费扩展Windows桌面:虚拟显示器终极解决方案
  • 56F8357混合信号控制器:DSP与MCU融合架构解析与电机控制实战
  • 百度地图infoBox弹窗组件:带关闭按钮和多图示例的轻量级实现
  • 汽车电子核心动力:MPC565/566微控制器架构、外设与开发实战解析
  • 良品率提至99.3%:高周波塑胶熔接机汽车内饰案例 - 资讯快报
  • 2026 福州黄金回收服务测评:上门速度、验金透明度对比 - 奢侈品回收评测
  • 5分钟打造你的象棋AI军师:Vin象棋智能连线工具深度指南
  • GreenBox 3开发平台:基于S32E288的汽车中央计算架构实战指南
  • 口碑好的杭州搬家公司汇总 本地用户真实推荐 - 资讯纵览
  • 深入解析D3D8到D3D9转换引擎:经典游戏兼容性解决方案
  • 从PlenOctrees到3DGS:手把手拆解球面谐波(SH)系数在代码里到底怎么存怎么算
  • STM32F103滚球平衡台固件:MPU6050姿态解算+OLED实时显示+双串口调试
  • Umi-OCR:如何实现高效离线文字识别与自动化处理?
  • 深度学习目标检测中利用脑肿瘤目标检测数据集训练识别3类’glioma_tumor’, ‘meningioma_tumor’,‘pituitary_tumor’2908张图像txt格式的脑肿瘤数据集
  • 泉盛UV-K5/K6固件深度探索:解锁专业无线电的终极潜能