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 SupplierRunnable taskExecutor; public TaskScheduleVO() { } /** * 便捷方法设置任务执行逻辑 * param taskLogic 任务执行逻辑 */ public void setTaskLogic(Runnable taskLogic) { this.taskExecutor () - taskLogic; } /** * 便捷方法设置带参数的任务执行逻辑 * param taskLogic 任务执行逻辑接收taskId和taskParam */ public void setTaskLogic(BiConsumerLong, 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 ListTaskScheduleVO queryAllValidTaskSchedule() { ListAiAgentTaskScheduleVO aiAgentTaskScheduleVOS taskService.queryAllValidTaskSchedule(); ListTaskScheduleVO 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 ListLong 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 { ListAiAgentClientFlowConfigVO 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框架去做前端页面对接最终效果如下完结撒花