动态执行智能体任务
一、介绍
本节首先实现一个基于数据库固定配置步骤的简单循环执行智能体策略。
接着,结合数据库中配置的智能体定时执行参数,并引入动态任务组件,进一步实现对智能体动态任务的调度与执行。
二、功能流程
如图,Ai Agent 动态任务执行过程;

首先,我们在项目中引入任务调度组件。该组件能够自动检索数据库中可执行的任务及其对应参数,并由定时任务进行统一管理和调度。
在此基础上,本节我们新增了一种更为简洁的 Agent 执行策略。该策略会按照数据库中 Agent 配置的客户端顺序依次循环执行。此方案特别适用于 工作流编排场景——只需将需要按顺序执行的客户端固定配置到数据库中,系统即可按照既定步骤自动执行。这种方式也是我们在早期分析 Agent 执行机制时所考虑过的一种实现思路。
三、工程实现
1. 工程结构

本节在触发器层(trigger)和任务模块(job)中,新增了一个
AgentTaskJob实现类。该任务实现工程中任务调度组件的接口,并将被任务调度系统管理。此外,本节除了实现
job任务外,还引入了新的FixedAgentExecuteStrategy执行策略。该策略将按照数据库中配置的步骤执行 Agent 模型。
2. 修改说明
引入任务调度组件
将任务调度组件的源码复制到项目的在 types 模块 中直接使用。
配置任务调度参数
在 application-dev.yml 文件中,添加 小傅哥扳手工程 task.job 的任务配置项。
具体配置方式可参考课程示例代码进行设置。新增 FixedAgentExecuteStrategy 策略类
创建FixedAgentExecuteStrategy策略实现类,用于按顺序循环执行数据库中配置的客户端信息,实现固定顺序的 Agent 调度逻辑。实现任务查询逻辑
在domain/agent/task包下新增实现类,用于查询数据库表 ai_agent_task_schedule 中配置的任务执行数据。
通过该实现类,可将查询到的任务数据写入到任务调度组件中,实现动态调度执行。编写任务触发实现类
在trigger/job层新增一个实现了ITaskDataProvider接口的 AgentTaskJob 类,用于定义任务数据的加载和触发执行逻辑。
3. 库表数据

新增智能体配置
在 ai_agent 及相关配置表中,新增一条 智能体(Agent)ID = 6 的配置记录。该智能体为一个 自动发帖 Agent,用于实现内容自动发布的业务逻辑。相应的配置信息需完整包含执行参数、调用方式及运行环境等字段,以确保任务可被正确识别与调度组件执行。任务调度表配置
在 schedule(任务调度)表中,新增一条与智能体 ID = 6 对应的任务配置。
该表配置应包含以下关键字段:任务标识(task_code)
任务描述(task_desc)
智能体 ID(agent_id = 6)
执行表达式(cron_expression)
其中,cron 表达式 用于定义任务的执行频率与时间周期,是任务调度的核心配置项。
示例:cron_expression: 0 0/30 * * * ?每30分钟执行一次通过合理配置 cron 表达式,即可实现自动发帖 Agent 的周期性任务调度。
4. 核心实现
4.1 引入组件

该任务调度组件基于 Spring Scheduler 进行扩展,通过动态创建线程池任务调度器实例(
ThreadPoolTaskScheduler),实现灵活可控的任务管理机制。组件采用函数式任务调度的设计理念,可在运行时动态添加、删除或刷新任务,从而实现任务的动态注册与实时执行。在架构设计上,组件根据不同的应用诉求进行了模块化拆分。整体由自动化配置类、线程池任务调度器、任务调度服务、定时任务刷新器以及任务数据接口五个部分组成。自动化配置类负责组件的加载与初始化;线程池任务调度器提供并发执行能力;任务调度服务作为核心模块,统一管理任务的注册、调度与状态维护;定时任务刷新器则确保任务信息与外部配置源(如数据库)保持同步;而任务数据接口用于对接业务系统的数据输入,适用方可根据自身业务需求实现该接口,组件会将所有实现类以集合的形式注入并统一交由调度服务维护,从而实现可扩展的任务管理体系。
4.2 固定模式(Agent)
@Slf4j
@Service("fixedAgentExecuteStrategy")
public class FixedAgentExecuteStrategy implements IExecuteStrategy {
@Resource
private IAgentRepository repository;
@Resource
protected ApplicationContext applicationContext;
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 requestParameter, ResponseBodyEmitter emitter) throws Exception {
// 1. 获取配置客户端
List<AiAgentClientFlowConfigVO> aiAgentClientList = repository.queryAiAgentClientsByAgentId(requestParameter.getAiAgentId());
// 2. 循环执行客户端
String content = "";
for (AiAgentClientFlowConfigVO config : aiAgentClientList) {
ChatClient chatClient = getChatClientByClientId(config.getClientId());
content = chatClient.prompt(requestParameter.getMessage() + "," + content)
.system(s -> s.param("current_date", LocalDate.now().toString()))
.advisors(a -> a
.param(CHAT_MEMORY_CONVERSATION_ID_KEY, requestParameter.getSessionId())
.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
.call().content();
log.info("智能体对话进行,客户端ID {}", requestParameter.getAiAgentId());
}
log.info("智能体对话请求,结果 {} {}", requestParameter.getAiAgentId(), content);
}
private ChatClient getChatClientByClientId(String clientId) {
return getBean(AiAgentEnumVO.AI_CLIENT.getBeanName(clientId));
}
private <T> T getBean(String beanName) {
return (T) applicationContext.getBean(beanName);
}
}这个模式源自第三阶段早期的 ai-agent-station 简单执行方式。尽管结构相对固定,但能高效、准确地完成用户编排任务,意图清晰,并显著降低 AI 调用的 token 消耗。
注意:数据库表中需为此类 agent 配置相应策略,即 ai_agent -> fixedAgentExecuteStrategy。
4.3 任务调度
@Slf4j
@Service
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())
.message(taskScheduleVO.getTaskParam())
.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();
}
}- 实现任务调度组件 ITaskDataProvider 接口后,AgentTaskJob 类即可自动加载任务,并根据 cron 表达式设定的频率周期性执行。
四、测试验证
1. 配置说明
ai:
vectorstore:
pgvector:
table-name: vector_store_openai
openai:
base-url: https://api1.oaipro.com
api-key: sk-FtZfc3Lyr2RjMkT1TDMTuY73t2NDvyU5dDgqjt4ZqwdMAdNk3xAW
model: gpt-4.1-mini
embedding:
base-url: https://api1.oaipro.com
api-key: sk-FtZfc3Lyr2RjMkT1TDMTuY73t2NDvyU5dDgqjt4ZqwdMAdNk3xAW
options:
model: text-embedding-3-small
dimensions: 1536
agent:
auto-config:
enabled: true
# client-ids: 2101,2102,2103
# client-ids: 4101,4102,4103,4104
# client-ids: 3101,3102,3103,3104,4101,4102,4103,4104,5101,5102,5103,5104
client-ids: 6101- 配置客户端 ID 为 6101。另外需注意,该 Agent 依赖 CSDN MCP 与 微信公众号 MCP 服务。
2. 启动测试
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.9)
25-10-24.11:18:40.293 [main ] INFO Application - Starting Application using Java 17.0.6 with PID 22768 (D:\Personal_projects\ai-agent-station-study\ai-agent-station-study-app\target\classes started by Dell in D:\Personal_projects\ai-agent-station-study)
25-10-24.11:18:40.294 [main ] INFO Application - The following 1 profile is active: "dev"
25-10-24.11:18:41.563 [main ] INFO TomcatWebServer - Tomcat initialized with port 8091 (http)
25-10-24.11:18:41.571 [main ] INFO Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8091"]
25-10-24.11:18:41.572 [main ] INFO StandardService - Starting service [Tomcat]
25-10-24.11:18:41.573 [main ] INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.44]
25-10-24.11:18:41.629 [main ] INFO [/] - Initializing Spring embedded WebApplicationContext
25-10-24.11:18:41.629 [main ] INFO ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1275 ms
25-10-24.11:18:43.524 [main ] INFO PgVectorStore - Using the vector table name: vector_store_openai. Is empty: false
25-10-24.11:18:43.527 [main ] INFO PgVectorStore - Initializing PGVectorStore schema for table: vector_store_openai in schema: public
25-10-24.11:18:43.527 [main ] INFO PgVectorStore - vectorTableValidationsEnabled false
25-10-24.11:18:43.645 [main ] INFO TaskJobAutoConfig - cactusli-wrench,任务调度器初始化完成。线程池大小: 5, 线程名前缀: test-task-scheduler-
25-10-24.11:18:43.651 [main ] INFO TaskJobService - 开始初始化任务调度配置
25-10-24.11:18:43.671 [main ] INFO HikariDataSource - MainHikariPool - Starting...
25-10-24.11:18:43.855 [main ] INFO HikariPool - MainHikariPool - Added connection com.mysql.cj.jdbc.ConnectionImpl@2a1710b8
25-10-24.11:18:43.856 [main ] INFO HikariDataSource - MainHikariPool - Start completed.
25-10-24.11:18:43.886 [main ] INFO TaskJobService - 开始调度任务,ID: 1, 描述: 自动发帖和通知, Cron表达式: 0 */5 * * * ?
25-10-24.11:18:43.891 [main ] INFO TaskJobService - 任务调度成功(函数式),ID: 1
25-10-24.11:18:43.891 [main ] INFO TaskJobService - 任务调度配置初始化完成,已加载任务数: 1
25-10-24.11:18:43.892 [main ] INFO TaskJobAutoConfig - cactusli-wrench,任务调度作业初始化完成。刷新间隔: 30000ms, 清理cron: 0 0/5 * * * ?
25-10-24.11:18:43.973 [main ] INFO OptionalValidatorFactoryBean - Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
25-10-24.11:18:44.357 [main ] INFO Http11NioProtocol - Starting ProtocolHandler ["http-nio-8091"]
25-10-24.11:18:44.395 [main ] INFO TomcatWebServer - Tomcat started on port 8091 (http) with context path '/'
25-10-24.11:18:45.978 [main ] INFO Application - Started Application in 6.436 seconds (process running for 7.031)
25-10-24.11:18:45.979 [test-task-scheduler-1] INFO TaskJobService - 开始刷新任务调度配置(动态更新)
25-10-24.11:18:45.981 [main ] INFO AiAgentAutoConfiguration - AI Agent 自动装配开始,配置: AiAgentAutoConfigProperties(enabled=true, clientIds=[6101])
25-10-24.11:18:45.981 [main ] INFO AiAgentAutoConfiguration - 开始自动装配AI客户端,客户端ID列表: [6101]
25-10-24.11:18:45.983 [test-task-scheduler-1] INFO TaskJobService - 任务调度配置刷新完成,当前活跃任务数: 1
25-10-24.11:18:45.986 [pool-2-thread-1 ] INFO AiClientLoadDataStrategy - 查询配置数据(ai_client_api) [6101]
25-10-24.11:18:45.987 [pool-2-thread-2 ] INFO AiClientLoadDataStrategy - 查询配置数据(ai_client_model) [6101]
25-10-24.11:18:45.987 [pool-2-thread-3 ] INFO AiClientLoadDataStrategy - 查询配置数据(ai_client_tool_mcp) [6101]
25-10-24.11:18:45.987 [pool-2-thread-4 ] INFO AiClientLoadDataStrategy - 查询配置数据(ai_client_system_prompt) [6101]
25-10-24.11:18:45.987 [pool-2-thread-5 ] INFO AiClientLoadDataStrategy - 查询配置数据(ai_client_advisor) [6101]
25-10-24.11:18:45.987 [pool-2-thread-6 ] INFO AiClientLoadDataStrategy - 查询配置数据(ai_client) [6101]
25-10-24.11:18:46.133 [main ] INFO RootNode - Ai Agent 构建,数据加载节点 {"commandIdList":["6101"],"commandType":"client","loadDataStrategy":"aiClientLoadDataStrategy"}
25-10-24.11:18:46.133 [main ] INFO AiClientApiNode - Ai Agent 构建,API 构建节点 {"commandIdList":["6101"],"commandType":"client","loadDataStrategy":"aiClientLoadDataStrategy"}
25-10-24.11:18:47.207 [main ] INFO AbstractArmorySupport - 注册Bean: ai_client_api_1001 -> org.springframework.ai.openai.api.OpenAiApi@386c38ff
25-10-24.11:18:47.207 [main ] INFO AiClientToolMcpNode - Ai Agent 构建节点,Tool MCP 工具配置{"commandIdList":["6101"],"commandType":"client","loadDataStrategy":"aiClientLoadDataStrategy"}
25-10-24.11:18:47.335 [HttpClient-10-Worker-0] INFO McpAsyncClient - Server response with Protocol: 2024-11-05, Capabilities: ServerCapabilities[completions=CompletionCapabilities[], experimental=null, logging=LoggingCapabilities[], prompts=PromptCapabilities[listChanged=true], resources=ResourceCapabilities[subscribe=false, listChanged=true], tools=ToolCapabilities[listChanged=true]], Info: Implementation[name=mcp-server-csdn, version=1.0.0] and Instructions null
25-10-24.11:18:47.345 [main ] INFO AiClientToolMcpNode - Tool SSE MCP Initialized InitializeResult[protocolVersion=2024-11-05, capabilities=ServerCapabilities[completions=CompletionCapabilities[], experimental=null, logging=LoggingCapabilities[], prompts=PromptCapabilities[listChanged=true], resources=ResourceCapabilities[subscribe=false, listChanged=true], tools=ToolCapabilities[listChanged=true]], serverInfo=Implementation[name=mcp-server-csdn, version=1.0.0], instructions=null]
25-10-24.11:18:47.347 [main ] INFO AbstractArmorySupport - 注册Bean: ai_client_tool_mcp_5001 -> io.modelcontextprotocol.client.McpSyncClient@484a90bd
25-10-24.11:18:47.363 [HttpClient-11-Worker-2] INFO McpAsyncClient - Server response with Protocol: 2024-11-05, Capabilities: ServerCapabilities[completions=CompletionCapabilities[], experimental=null, logging=LoggingCapabilities[], prompts=PromptCapabilities[listChanged=true], resources=ResourceCapabilities[subscribe=false, listChanged=true], tools=ToolCapabilities[listChanged=true]], Info: Implementation[name=mcp-server-weixin, version=1.0.0] and Instructions null
25-10-24.11:18:47.366 [main ] INFO AiClientToolMcpNode - Tool SSE MCP Initialized InitializeResult[protocolVersion=2024-11-05, capabilities=ServerCapabilities[completions=CompletionCapabilities[], experimental=null, logging=LoggingCapabilities[], prompts=PromptCapabilities[listChanged=true], resources=ResourceCapabilities[subscribe=false, listChanged=true], tools=ToolCapabilities[listChanged=true]], serverInfo=Implementation[name=mcp-server-weixin, version=1.0.0], instructions=null]
25-10-24.11:18:47.366 [main ] INFO AbstractArmorySupport - 注册Bean: ai_client_tool_mcp_5002 -> io.modelcontextprotocol.client.McpSyncClient@7cfba241
25-10-24.11:18:47.366 [main ] INFO AiClientModelNode - Ai Agent 构建节点,Mode 对话模型{"commandIdList":["6101"],"commandType":"client","loadDataStrategy":"aiClientLoadDataStrategy"}
25-10-24.11:18:47.394 [main ] INFO AbstractArmorySupport - 注册Bean: ai_client_model_6001 -> OpenAiChatModel [defaultOptions=OpenAiChatOptions: {"streamUsage":false,"model":"gpt-oss-120b"}]
25-10-24.11:18:47.406 [main ] INFO AiClientAdvisorNode - Ai Agent 构建节点,Advisor 顾问角色{"commandIdList":["6101"],"commandType":"client","loadDataStrategy":"aiClientLoadDataStrategy"}
25-10-24.11:18:47.413 [main ] INFO AbstractArmorySupport - 注册Bean: ai_client_advisor_4001 -> org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor@1e9c4a0c
25-10-24.11:18:47.452 [main ] INFO AbstractArmorySupport - 注册Bean: ai_client_advisor_4004 -> cn.cactusli.ai.domain.agent.service.armory.factory.element.RagAnswerAdvisor@4c8f6208
25-10-24.11:18:47.452 [main ] INFO AiClientNode - Ai Agent 构建节点,客户端{"commandIdList":["6101"],"commandType":"client","loadDataStrategy":"aiClientLoadDataStrategy"}
25-10-24.11:18:47.457 [main ] INFO AbstractArmorySupport - 注册Bean: ai_client_6101 -> org.springframework.ai.chat.client.DefaultChatClient@46c3f144
25-10-24.11:18:47.457 [main ] INFO AiAgentAutoConfiguration - AI Agent 自动装配完成,结果: null
25-10-24.11:19:15.985 [test-task-scheduler-2] INFO TaskJobService - 开始刷新任务调度配置(动态更新)
25-10-24.11:19:15.992 [test-task-scheduler-2] INFO TaskJobService - 任务调度配置刷新完成,当前活跃任务数: 1
25-10-24.11:19:45.978 [test-task-scheduler-1] INFO TaskJobService - 开始刷新任务调度配置(动态更新)
25-10-24.11:19:45.980 [test-task-scheduler-1] INFO TaskJobService - 任务调度配置刷新完成,当前活跃任务数: 1
25-10-24.11:20:00.003 [test-task-scheduler-3] INFO TaskJobService - 开始清理无效的任务
25-10-24.11:20:00.003 [test-task-scheduler-4] INFO TaskJobService - 开始执行任务(函数式),ID: 1, 描述: 自动发帖和通知
25-10-24.11:20:00.007 [test-task-scheduler-3] INFO TaskJobService - 没有发现无效的任务需要清理
25-10-24.11:20:00.009 [test-task-scheduler-4] INFO TaskJobService - 任务执行完成(函数式),ID: 1
25-10-24.11:20:02.192 [pool-2-thread-7 ] INFO HikariDataSource - PgVectorHikariPool - Starting...
25-10-24.11:20:02.275 [pool-2-thread-7 ] INFO HikariPool - PgVectorHikariPool - Added connection org.postgresql.jdbc.PgConnection@186e96b7
25-10-24.11:20:02.275 [pool-2-thread-7 ] INFO HikariDataSource - PgVectorHikariPool - Start completed.
25-10-24.11:20:08.785 [pool-2-thread-7 ] INFO FixedAgentExecuteStrategy - 智能体对话进行,客户端ID 6
25-10-24.11:20:08.785 [pool-2-thread-7 ] INFO FixedAgentExecuteStrategy - 智能体对话请求,结果 6 文章已成功发布到 CSDN,标题为《互联网大厂Java面试实战:从Spring Boot到AI微服务的全链路问答》,并已发送微信公众号通知。祝阅读愉快!
25-10-24.11:20:15.987 [test-task-scheduler-2] INFO TaskJobService - 开始刷新任务调度配置(动态更新)
25-10-24.11:20:15.987 [test-task-scheduler-2] INFO TaskJobService - 任务调度配置刷新完成,当前活跃任务数: 1以上日志展示了系统的启动、构建与执行过程。随后,定时任务将按计划执行发帖操作。