diff --git a/src/main/java/xyz/wbsite/ai/TestRagNativeChat.java b/src/main/java/xyz/wbsite/ai/TestRagNativeChat.java new file mode 100644 index 0000000..2199376 --- /dev/null +++ b/src/main/java/xyz/wbsite/ai/TestRagNativeChat.java @@ -0,0 +1,122 @@ +package xyz.wbsite.ai; + +import dev.langchain4j.data.document.Document; +import dev.langchain4j.data.document.DocumentParser; +import dev.langchain4j.data.document.DocumentSplitter; +import dev.langchain4j.data.document.loader.FileSystemDocumentLoader; +import dev.langchain4j.data.document.parser.TextDocumentParser; +import dev.langchain4j.data.document.splitter.DocumentSplitters; +import dev.langchain4j.data.embedding.Embedding; +import dev.langchain4j.data.message.ChatMessage; +import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.memory.chat.MessageWindowChatMemory; +import dev.langchain4j.model.embedding.EmbeddingModel; +import dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel; +import dev.langchain4j.model.openai.OpenAiChatModel; +import dev.langchain4j.model.openai.OpenAiStreamingChatModel; +import dev.langchain4j.rag.content.Content; +import dev.langchain4j.rag.content.retriever.ContentRetriever; +import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever; +import dev.langchain4j.rag.query.Query; +import dev.langchain4j.service.AiServices; +import dev.langchain4j.service.TokenStream; +import dev.langchain4j.store.embedding.EmbeddingStore; +import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; + +import java.util.List; + +import static dev.langchain4j.data.document.loader.FileSystemDocumentLoader.loadDocument; + +/** + * 主函数入口 + */ +public class TestRagNativeChat { + + public static void main(String[] args) { + OpenAiChatModel model = OpenAiChatModel.builder() + .baseUrl("http://36.138.207.178:11434/v1") + .apiKey("1") + .modelName("deepseek-r1:14B") + .build(); + + + + // Now, let's load a document that we want to use for RAG. + // We will use the terms of use from an imaginary car rental company, "Miles of Smiles". + // For this example, we'll import only a single document, but you can load as many as you need. + // LangChain4j offers built-in support for loading documents from various sources: + // File System, URL, Amazon S3, Azure Blob Storage, GitHub, Tencent COS. + // Additionally, LangChain4j supports parsing multiple document types: + // text, pdf, doc, xls, ppt. + // However, you can also manually import your data from other sources. + DocumentParser documentParser = new TextDocumentParser(); + Document document = loadDocument("D:\\docs\\人才公共服务平台会议纪要20210720.txt", documentParser); + + + // Now, we need to split this document into smaller segments, also known as "chunks." + // This approach allows us to send only relevant segments to the LLM in response to a user query, + // rather than the entire document. For instance, if a user asks about cancellation policies, + // we will identify and send only those segments related to cancellation. + // A good starting point is to use a recursive document splitter that initially attempts + // to split by paragraphs. If a paragraph is too large to fit into a single segment, + // the splitter will recursively divide it by newlines, then by sentences, and finally by words, + // if necessary, to ensure each piece of text fits into a single segment. + DocumentSplitter splitter = DocumentSplitters.recursive(300, 0); + List segments = splitter.split(document); + + + // Now, we need to embed (also known as "vectorize") these segments. + // Embedding is needed for performing similarity searches. + // For this example, we'll use a local in-process embedding model, but you can choose any supported model. + // Langchain4j currently supports more than 10 popular embedding model providers. + EmbeddingModel embeddingModel = new BgeSmallEnV15QuantizedEmbeddingModel(); + List embeddings = embeddingModel.embedAll(segments).content(); + + + // Next, we will store these embeddings in an embedding store (also known as a "vector database"). + // This store will be used to search for relevant segments during each interaction with the LLM. + // For simplicity, this example uses an in-memory embedding store, but you can choose from any supported store. + // Langchain4j currently supports more than 15 popular embedding stores. + EmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>(); + embeddingStore.addAll(embeddings, segments); + + // We could also use EmbeddingStoreIngestor to hide manual steps above behind a simpler API. + // See an example of using EmbeddingStoreIngestor in _01_Advanced_RAG_with_Query_Compression_Example. + + + // The content retriever is responsible for retrieving relevant content based on a user query. + // Currently, it is capable of retrieving text segments, but future enhancements will include support for + // additional modalities like images, audio, and more. + ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder() + .embeddingStore(embeddingStore) + .embeddingModel(embeddingModel) + .maxResults(2) // on each interaction we will retrieve the 2 most relevant segments + .minScore(0.1) // we want to retrieve segments at least somewhat similar to user query + .build(); + + List retrieve = contentRetriever.retrieve(new Query("参会人员有哪些人?")); + System.out.println(); + + Assistant assistant = AiServices.builder(Assistant.class) + .chatLanguageModel(model) + .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) + .contentRetriever(contentRetriever) + .build(); + + // String chat = assistant.chat("参会人员有哪些人?"); + //System.out.println(chat); + } + + + // 创建一个助手接口 + interface Assistant { + + String chat(String userMessage); + + TokenStream chatStream(List messages); + + TokenStream chatStream(ChatMessage message); + + TokenStream chatStream(String message); + } +} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/ai/TestTool2Chat.java b/src/main/java/xyz/wbsite/ai/TestTool2Chat.java index ceeb357..d3144b0 100644 --- a/src/main/java/xyz/wbsite/ai/TestTool2Chat.java +++ b/src/main/java/xyz/wbsite/ai/TestTool2Chat.java @@ -30,7 +30,6 @@ public class TestTool2Chat { } }; - Assistant agent = AiServices.builder(Assistant.class) .chatLanguageModel(model) .tools(weatherTools)