package com.ard.agent.service;
|
|
import jakarta.annotation.Resource;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.ai.chat.client.ChatClient;
|
import org.springframework.ai.chat.prompt.Prompt;
|
import org.springframework.ai.chat.prompt.PromptTemplate;
|
import org.springframework.ai.document.Document;
|
import org.springframework.ai.vectorstore.SearchRequest;
|
import org.springframework.ai.vectorstore.VectorStore;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.stereotype.Service;
|
import reactor.core.publisher.Flux;
|
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
@Slf4j
|
@Service
|
public class RagChatService {
|
@Resource
|
private ChatClient chatClient;
|
@Resource
|
private VectorStore vectorStore;
|
|
/**
|
* RAG问答流式方法(推荐使用)
|
*/
|
public Flux<String> chatStream(String question) {
|
log.info("收到RAG流式请求,question={}", question);
|
|
// 1. 向量检索:召回Top3相关文档(同步执行)
|
List<org.springframework.ai.document.Document> similarDocs = vectorStore.similaritySearch(
|
SearchRequest.builder()
|
.query(question)
|
.topK(3)
|
.build()
|
);
|
|
// 2. 拼接上下文
|
String context = similarDocs.stream()
|
.map(doc -> "【参考内容】:" + doc.getText())
|
.collect(Collectors.joining("\n\n"));
|
|
log.info("检索到{}条相关文档,开始流式生成回答", similarDocs.size());
|
|
// 3. 构建Prompt模板
|
String promptText = """
|
你是专业知识库助手,基于以下参考内容回答用户问题,禁止编造,答案必须准确:
|
{context}
|
用户问题:{question}
|
""";
|
PromptTemplate promptTemplate = new PromptTemplate(promptText);
|
promptTemplate.add("context", context);
|
promptTemplate.add("question", question);
|
Prompt prompt = promptTemplate.create();
|
|
// 4. 流式调用大模型
|
return chatClient.prompt(prompt)
|
.stream()
|
.content()
|
.doOnNext(chunk -> log.debug("输出数据块: {}", chunk))
|
.doOnComplete(() -> log.info("流式输出完成"))
|
.doOnError(error -> log.error("流式输出出错: {}", error.getMessage()));
|
}
|
|
}
|