You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
4.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<TextSegment> segments = splitter.split(document);
//现在,我们需要嵌入(也称为“矢量化”)这些片段。
//执行相似性搜索需要嵌入。
//对于这个例子,我们将使用本地进程内嵌入模型,但您可以选择任何支持的模型。
//Langchain4j目前支持10多个流行的嵌入模型提供者。
EmbeddingModel embeddingModel = new BgeSmallEnV15QuantizedEmbeddingModel();
List<Embedding> embeddings = embeddingModel.embedAll(segments).content();
//接下来,我们将把这些嵌入存储在嵌入存储中(也称为“向量数据库”)。
//此存储将用于在每次与LLM交互时搜索相关细分市场。
//为简单起见,此示例使用内存中的嵌入存储,但您可以从任何支持的存储中进行选择。
//Langchain4j目前支持超过15个流行的嵌入商店。
InMemoryEmbeddingStore<TextSegment> 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);
}
}

Powered by TurnKey Linux.