一、本章介绍
在应用启动阶段,加载智能体的 YAML 配置文件,完成整体装配过程。同时编写相应的测试用例,用于验证智能体加载与运行是否符合预期。
这部分内容将作为后续对话服务开发的基础,帮助明确对话执行的核心流程,包括会话的创建以及消息请求的处理方式。
二、流程设计
如图,智能体全部节点构建完成后,在程序启动的时候进行加载;

前面的章节已经完成了全部加载相关的步骤,现在可以将各个调用入口进行整合与串联。在程序启动阶段,实现自动化的加载流程。
在加载流程执行完毕之后,可以进行一次基础性的校验操作,即通过调用该智能体来体验整个对话过程,从而对系统运行情况有一个整体性的认识。
1. 工程结构
本节的流程相对简单,核心在于将已有功能进行整合,从而完成智能体的加载操作。
随后,可以通过一个测试类来观察智能体在加载完成后的实际使用情况。这个使用过程涵盖会话的创建与调用,对于后续单独实现会话服务接口具有重要参考价值。
2. 核心模块
2.1 数据加载
@Slf4j
@Configuration
@EnableConfigurationProperties(AiAgentAutoConfigProperties.class)
public class AiAgentAutoConfig implements ApplicationListener<ApplicationReadyEvent> {
@Resource
private AiAgentAutoConfigProperties aiAgentAutoConfigProperties;
@Resource
private IArmoryService armoryService;
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
try {
log.info("Ai Agent 智能体装配 {}", JSON.toJSONString(aiAgentAutoConfigProperties.getTables().values()));
armoryService.acceptArmoryAgents(new ArrayList<>(aiAgentAutoConfigProperties.getTables().values()));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}在程序启动阶段,
AiAgentAutoConfig会触发实现了ApplicationListener接口的onApplicationEvent方法,从而可以调用自定义的装配方法,完成智能体的初始化与装配。同时,
armoryService.acceptArmoryAgents也可以通过单独实现一个接口通知服务,让管理后台调用该接口,实现全量智能体的加载与管理。
2.2 补充代码
@Slf4j
@Service
public class AgentNode extends AbstractArmorySupport {
@Resource
private AgentWorkflowNode agentWorkflowNode;
// ... 省略部分代码
@Override
public StrategyHandler<ArmoryCommandEntity, DefaultArmoryFactory.DynamicContext, AiAgentRegisterVO> get(ArmoryCommandEntity requestParameter, DefaultArmoryFactory.DynamicContext dynamicContext) throws Exception {
return agentWorkflowNode;
}
}- 之前漏掉了一个从 AgentNode 流转到 AgentWorkflowNode 的操作。
四、测试验证
1. yml 配置
test-agent.yml 是一个预先配置好的智能体测试方案,需要注意的是,base-url 和 api-key 应根据你的实际测试环境进行调整。
另外,建议大家尝试配置其他智能体,通过实际配置和运行来验证自己对前面学习内容的理解是否扎实。
2. 单测方法
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class AiAgentAutoConfigTest {
@Resource
private ApplicationContext applicationContext;
@Test
public void test_agent() throws InterruptedException {
AiAgentRegisterVO aiAgentRegisterVO = applicationContext.getBean("100001", AiAgentRegisterVO.class);
String appName = aiAgentRegisterVO.getAppName();
InMemoryRunner runner = aiAgentRegisterVO.getRunner();
Session session = runner.sessionService()
.createSession(appName, "cactusli")
.blockingGet();
Content userMsg = Content.fromParts(Part.fromText("编写冒泡排序,加上注释!"));
Flowable<Event> events = runner.runAsync("cactusli", session.id(), userMsg);
List<String> outputs = new ArrayList<>();
events.blockingForEach(event -> outputs.add(event.stringifyContent()));
log.info("测试结果:{}", JSON.toJSONString(outputs));
new CountDownLatch(1).await();
}
}Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
26-05-12.16:30:55.170 [main ] INFO SpringAIObservabilityHandler - Request completed successfully: model=openai, type=chat, duration=5505ms, tokens=1392
26-05-12.16:30:57.030 [main ] INFO SpringAIObservabilityHandler - Request completed successfully: model=openai, type=chat, duration=1853ms, tokens=1900
26-05-12.16:31:03.470 [main ] INFO SpringAIObservabilityHandler - Request completed successfully: model=openai, type=chat, duration=6438ms, tokens=2216
26-05-12.16:31:03.472 [main ] INFO AiAgentAutoConfigTest - 测试结果:["```public class BubbleSort {
/**
* 使用冒泡排序算法对整数数组进行升序排序
* @param arr 待排序的数组
*/
public static void bubbleSort(int[] arr) {
int n = arr.length;
// 外层循环控制遍历的次数
for (int i = 0; i < n - 1; i++) {
// 标志优化:若本趟未发生交换,则数组已有序
boolean swapped = false;
// 内层循环进行相邻元素两两比较
for (int j = 0; j < n - 1 - i; j++) {
// 如果前一个数比后一个数大,则交换
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
// 如果没有发生任何交换,提前结束排序
if (!swapped) {
break;
}
}
}
// 测试用例
public static void main(String[] args) {
int[] nums = {5, 2, 9, 3, 7, 1};
System.out.print("排序前:");
for (int num : nums) {
System.out.print(num + " ");
}
System.out.println();
bubbleSort(nums);
System.out.print("排序后:");
for (int num : nums) {
System.out.print(num + " ");
}
System.out.println();
}
}```"]可以通过
ApplicationContext使用智能体的 ID 获取之前注册到 Spring 容器中的AiAgentRegisterVO对象。随后,利用
InMemoryRunner创建会话(Session),再根据会话服务和 Runner 发起具体的会话请求。new CountDownLatch(1).await();的作用是让程序保持运行状态,因为事件(event)是异步输出的,如果没有这一步,程序可能在事件处理完成前就直接退出了。