package com.ai.aiagent.app; import com.ai.aiagent.advisor.MyLoggerAdvisor; import com.ai.aiagent.advisor.ReReadingAdvisor; import com.ai.aiagent.chatmemory.FileBasedChatMemory; import com.ai.aiagent.rag.LoveAppRagCustomAdvisorFactory; import com.ai.aiagent.rag.QueryRewriter; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.chat.client.advisor.api.Advisor; import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor; import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository; import org.springframework.ai.chat.memory.MessageWindowChatMemory; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.stereotype.Component; import java.util.List; @Component @Slf4j public class LoveApp { private final ChatClient chatClient; private static final String SYSTEM_PROMPT="扮演深耕恋爱心理领域的专家。开场向用户表明身份,告知用户可倾诉恋爱难题。" + "围绕单身、恋爱、已婚三种状态提问:单身状态询问社交圈拓展及追求心仪对象的困扰;" + "恋爱状态询问沟通、习惯差异引发的矛盾;已婚状态询问家庭责任与亲属关系处理的问题。" + "引导用户详述事情经过、对方反应及自身想法,以便给出专属解决方案。"; /** * 初始化 ChatClient * @param dashscopeChatModel */ public LoveApp(ChatModel dashscopeChatModel){ String fileDir=System.getProperty("user.dir")+"/tmp/chat-memory"; // ChatMemory chatMemory = new FileBasedChatMemory(fileDir); ChatMemory chatMemory= MessageWindowChatMemory.builder() .chatMemoryRepository(new InMemoryChatMemoryRepository()) .build(); chatClient=ChatClient.builder(dashscopeChatModel) .defaultSystem(SYSTEM_PROMPT) .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build(), //自定义日志 Advisor new MyLoggerAdvisor() // //自定义推理增强 Advisor // ,new ReReadingAdvisor() ) .build(); } /** * AI 基础对话(支持多轮对话记忆) * @param message * @param chatId * @return */ public String doChat(String message,String chatId){ ChatResponse response=chatClient .prompt() .user(message) .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId)) .call() .chatResponse(); String content=response.getResult().getOutput().getText(); log.info("content:{}",content); return content; } record LoveReport(String title, List suggestions){} /** * AI 恋爱报告功能(结构化输出) * @param message * @param chatId * @return */ public LoveReport doChatWithReport(String message,String chatId){ LoveReport loveReport=chatClient .prompt() .system(SYSTEM_PROMPT+"每次对话后都要生成恋爱结果,标题为{用户名}的恋爱报告,内容为建议列表") .user(message) .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId)) .call() .entity(LoveReport.class); log.info("content:{}",loveReport); return loveReport; } @Resource private VectorStore loveAppVectorStore; @Resource private Advisor loveAppRagCloudAdvisor; @Resource private VectorStore pgVectorVectorStore; @Resource private QueryRewriter queryRewriter; public String doChatWithRag(String message,String chatId){ String rewrittenMessage=queryRewriter.doQueryRewrite(message); ChatResponse response=chatClient .prompt() .user(rewrittenMessage) .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId)) // 开启日志,便于观察结果 .advisors(new MyLoggerAdvisor()) // 应用 RAG 知识库回答 .advisors(new QuestionAnswerAdvisor(loveAppVectorStore)) // 应用 RAG 检索增强服务(基于云知识库) // .advisors(loveAppRagCloudAdvisor) // 应用 RAG 检索增强服务(基于 PgVector 向量存储) // .advisors(new QuestionAnswerAdvisor(pgVectorVectorStore)) // 应用自定义的 RAG 检索增强服务(文档查询器 + 上下文增强器) // .advisors( // LoveAppRagCustomAdvisorFactory.createLoveAppRagCustomAdvisor( // loveAppVectorStore,"单身" // ) // ) .call() .chatResponse(); String content=response.getResult().getOutput().getText(); log.info("content:{}",content); return content; } // AI 调用工具能力 @Resource private ToolCallback[] allTools; /** * AI 恋爱报告功能(支持调用工具) * * @param message * @param chatId * @return */ public String doChatWithTools(String message, String chatId) { ChatResponse chatResponse = chatClient .prompt() .user(message) .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId)) // 开启日志,便于观察效果 .advisors(new MyLoggerAdvisor()) .toolCallbacks(allTools) .call() .chatResponse(); String content = chatResponse.getResult().getOutput().getText(); log.info("content: {}", content); return content; } }