package xyz.wbsite.ai; import dev.langchain4j.data.document.Document; import dev.langchain4j.data.document.DocumentSplitter; import dev.langchain4j.data.document.splitter.DocumentSplitters; import dev.langchain4j.data.embedding.Embedding; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.memory.ChatMemory; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel; import dev.langchain4j.rag.content.retriever.ContentRetriever; import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever; import dev.langchain4j.service.AiServices; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; import java.util.List; /** * 主函数入口 */ public class Naive_RAG_Example { public static void main(String[] args) { // 加载文档 Document document = Helper.getDocument(); //现在,我们需要将此文档拆分为更小的部分,也称为“块” //这种方法允许我们仅向LLM发送相关段以响应用户查询, //而不是整个文档。例如如果用户询问取消政策, //我们将仅识别并发送与取消相关的片段。 //一个好的起点是使用递归文档拆分器,最初尝试 //按段落分割。如果一个段落太大而无法放入单个片段中, //拆分器将递归地按换行符、句子和单词进行划分, //如有必要,确保每段文本都适合一个片段。 DocumentSplitter splitter = DocumentSplitters.recursive(300, 0); List segments = splitter.split(document); //现在,我们需要嵌入(也称为“矢量化”)这些片段。 //执行相似性搜索需要嵌入。 //对于这个例子,我们将使用本地进程内嵌入模型,但您可以选择任何支持的模型。 //Langchain4j目前支持10多个流行的嵌入模型提供者。 EmbeddingModel embeddingModel = new BgeSmallEnV15QuantizedEmbeddingModel(); List embeddings = embeddingModel.embedAll(segments).content(); //接下来,我们将把这些嵌入存储在嵌入存储中(也称为“向量数据库”)。 //此存储将用于在每次与LLM交互时搜索相关细分市场。 //为简单起见,此示例使用内存中的嵌入存储,但您可以从任何支持的存储中进行选择。 //Langchain4j目前支持超过15个流行的嵌入商店。 InMemoryEmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>(); embeddingStore.addAll(embeddings, segments); // 我们还可以使用EmbeddingStoreIngestor将上面的手动步骤隐藏在更简单的API后面。 // 请参阅_01_Advanced_RAG_with_Query_Compression_example中使用嵌入式存储器的示例。 //内容检索器负责根据用户查询检索相关内容。 //目前,它能够检索文本段,但未来的增强功能将包括支持 //其他模态,如图像、音频等。 ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder() .embeddingStore(embeddingStore) .embeddingModel(embeddingModel) .maxResults(2) // 在每次交互中,我们将检索2个最相关的片段 .minScore(0.1) // 我们希望检索至少与用户查询有些相似的段 .build(); //我们可以选择使用聊天存储器,与LLM进行来回对话 //并允许它记住之前的交互。 //目前,LangChain4j提供了两种聊天内存实现: //MessageWindowChatMemory和TokenWindowChatMemory。 ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10); //最后一步是构建我们的人工智能服务, //配置它以使用我们上面创建的组件。 Assistant assistant = AiServices.builder(Assistant.class) .chatLanguageModel(Helper.getChatModel()) .contentRetriever(contentRetriever) .chatMemory(chatMemory) .build(); String chat = assistant.chat("你是谁?"); System.out.println(chat); } // 创建一个助手接口 interface Assistant { String chat(String userMessage); } }