/**
* 构建AI Service
*
* @param model 流式聊天模型
* @param req 聊天请求对象
* @param conversationId 会话ID
* @return LangChatAgent实例
*/
public LangChatAgent build(
StreamingChatModel model,
LcChatReq req,
String conversationId
) {
log.info("开始构建AiService: conversationId={}, modelId={}, userId={}",
conversationId, req.getModelId(), req.getUserId());
var builder = AiServices.builder(LangChatAgent.class)
.streamingChatModel(model)
.chatMemoryProvider(memoryId -> buildChatMemory(conversationId, req));
// 1. 配置SystemMessage
var prompt = promptProcessor.process(req);
if (StrUtil.isNotBlank(prompt)) {
builder.systemMessageProvider(memoryId -> prompt);
log.debug("系统提示词已配置: conversationId={}, promptLength={}",
conversationId, prompt.length());
} else {
log.debug("未配置系统提示词: conversationId={}", conversationId);
}
// 2. 动态构建Tools
if (CollUtil.isNotEmpty(toolFactoryList)) {
toolFactoryList.forEach(factory -> {
try {
factory.dynamicTools(req, builder);
} catch (Exception e) {
log.error("动态工具构建失败: conversationId={}, factoryClass={}",
conversationId, factory.getClass().getSimpleName(), e);
}
});
log.debug("工具工厂配置完成: conversationId={}, factoryCount={}",
conversationId, toolFactoryList.size());
}
// 3. 构建RAG
var ragComponents = ragRetrieverBuilder.build(req);
if (CollUtil.isNotEmpty(ragComponents.retrievers())) {
var augmentor = DefaultRetrievalAugmentor.builder()
.contentAggregator(ragComponents.aggregator())
.queryRouter(new DefaultQueryRouter(ragComponents.retrievers()))
.build();
builder.retrievalAugmentor(augmentor);
log.info("RAG配置完成: conversationId={}, retrieverCount={}, hasRerank={}",
conversationId,
ragComponents.retrievers().size(),
ragComponents.aggregator() != null);
} else {
log.debug("未配置RAG: conversationId={}", conversationId);
}
// 4. 构建Agent
var agent = builder.build();
log.info("AiService构建完成: conversationId={}, modelId={}, userId={}, hasPrompt={}, toolFactoryCount={}, retrieverCount={}",
conversationId,
req.getModelId(),
req.getUserId(),
StrUtil.isNotBlank(prompt),
toolFactoryList != null ? toolFactoryList.size() : 0,
ragComponents.retrievers().size());
return agent;
}