LangChain4j 基础系列

LangChain4j 基础 08:链式调用与会话检索

阅读 ConversationalChain 和 ConversationalRetrievalChain,梳理模型、记忆与检索的组合。

本讲介绍原材料中的两种 Chain:ConversationalChain 和 ConversationalRetrievalChain,对照它们如何组合模型、对话记忆与检索。类名和 API 对应原文版本,使用时需核对实际依赖。

链式调用与会话检索示意 1

原文配图:链式调用与会话检索示意 1。

ConversationalChain示例

    @GetMapping(value = "/chat/chain", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> chatChain(@RequestParam String query) {
        try {
            String responseText = ConversationalChain.builder()
                    .chatModel(ollamaChatModel)
                    .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
                    .build()
                    .execute(query);
            return ResponseEntity.ok(responseText);
        } catch (Exception e) {
            log.error("chatChain", e);
            return ResponseEntity.ok("{\"error\":\"chatChain error: " + e.getMessage() + "\"}");
        }
    }

这段链式调用把模型配置、对话记忆和查询执行组织在一起。

ConversationalRetrievalChain示例

    /**
     * 示例用测试文本data.txt向量化存储(按行分隔)
     * @return
     */
    EmbeddingStore<TextSegment> getEmbeddingStore() {
        Resource resource = resourceLoader.getResource("classpath:data.txt");
        File file = null;
        try {
            file = resource.getFile();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String path = file.getAbsolutePath();

        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
        Document document = FileSystemDocumentLoader.loadDocument(path);
        DocumentByLineSplitter splitter = new DocumentByLineSplitter(100, 0);
        List<TextSegment> split = splitter.split(document);
        for (TextSegment textSegment : split) {
            Embedding embedding = ollamaEmbeddingModel.embed(textSegment).content();
            embeddingStore.add(embedding, textSegment);
        }
        return embeddingStore;
    }

    @GetMapping(value = "/rag/chain", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> ragChain(@RequestParam String query) {
        try {
            String answer = ConversationalRetrievalChain.builder()
                    .chatModel(ollamaChatModel)
                    .contentRetriever(EmbeddingStoreContentRetriever
                            .builder()
                            .embeddingModel(ollamaEmbeddingModel)
                            .embeddingStore(getEmbeddingStore())
                            .maxResults(1)
                            .build())
                    .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
                    .build()
                    .execute(query);
            return ResponseEntity.ok(answer);
        } catch (Exception e) {
            log.error("argChain", e);
            return ResponseEntity.ok("{\"error\":\"argChain error: " + e.getMessage() + "\"}");
        }
    }

与ConversationalChain相比,ConversationalRetrievalChain新增了RAG的链式处理。

文本示例完整代码:https://github.com/yjmyzz/langchain4j-study/tree/day08

参考:https://docs.langchain4j.dev/tutorials/ai-services