LangChain4j 开发Java Agent智能体- RAG(检索增强生成)

大家好,我是Java1234_小锋老师,最近更新《2027版本 LangChain4j 开发Java Agent 智能体 视频教程》专辑,感谢大家支持。

在这里插入图片描述

本课程主要介绍和讲解 LangChain4j 简介,阿里云百炼大模型 平台接入,Ollama简介以及安装和使用,HelloWorld 实现,日志配置,集成SpringBoot,Ai Service 使用,对话与提示词工程(Prompt),结构化输出,会话记忆,工具调用(Function Calling),嵌入模型 与向量数据库,RAG(检索增强生成),MCP(模型上下文协议),多模态支持

视频教程+课件+源码打包下载:

链接:https://pan.baidu.com/s/1o-zRfndo1HHrS_uFroOiCw?pwd=1234
提取码:0000

LangChain4j 开发Java Agent智能体- RAG(检索增强生成)

RAG(Retrieval-Augmented Generation,检索增强生成) 是在大模型回答前,先从外部知识库检索相关内容,再把这些内容作为上下文交给 LLM 生成答案。

在这里插入图片描述

这是目前最经典的AI应用架构,可以清晰地看到嵌入模型和向量数据库是如何配合的。

场景:构建一个基于公司内部知识库的智能问答机器人。

第一步:数据预处理与索引(入库阶段)
  1. 准备文档:收集所有公司文档(PDF、Word、内部Wiki等)。
  2. 文本分块:将长文档切分成更小的段落或“块”。
  3. 生成嵌入:使用嵌入模型,为每一个文本块生成一个向量。
  4. 存储:将生成的向量,连同原始的文本块和相关的元数据(如文档来源、页码),一起存入向量数据库
第二步:用户提问与检索(查询阶段)
  1. 用户提问:用户问:“我们公司的年假政策是什么?”
  2. 问题嵌入:使用相同的嵌入模型,将用户的这个问题也转换成一个向量。
  3. 向量检索:将这个代表问题的向量发送到向量数据库进行查询。数据库会迅速返回与问题向量最相似的K个文本块向量。
  4. 获取上下文:根据返回的向量ID,取出对应的原始文本块内容。
第三步:生成答案(生成阶段)
  1. 构建提示词:将用户的问题 + 检索到的相关文本块(作为上下文)组合成一个提示词。
  2. 调用大语言模型:将提示词发送给大语言模型(如GPT-4),并指示它“请根据提供的上下文回答问题”。
  3. 返回答案:大模型阅读并理解上下文后,生成一个准确、有据可依的答案返回给用户。

技术背景

随着大语言模型(LLM)快速普及,**RAG(检索增强生成)**技术成为解决大模型幻觉、私有化知识库落地的核心方案。传统本地知识库开发存在文档适配单一、向量库部署复杂、代码冗余度高等问题。

实现目标

手把手搭建工业级轻量化RAG工程,完整实现以下核心能力:

  • 多格式文档解析:支持PDF、Word(DOC)、纯文本(TXT)、Markdown(MD)四种主流文档格式;
  • 智能文本切分:基于令牌数实现语义分片,避免语义割裂,适配大模型上下文限制;
  • Redis向量存储:文档切片生成向量,持久化存入Redis向量数据库;
  • 标准化RAG架构:遵循ETL(抽取-转换-加载)流程,代码可直接生产复用;
  • 极简接口调试:提供文件上传、向量检索、知识库清空接口,方便测试验证。

RAG执行流程

本项目严格遵循标准RAG的ETL执行流程,流程简洁清晰:

  1. E抽取(Extract):读取本地上传的PDF/DOC/TXT/MD文件,提取纯文本内容,过滤乱码、格式符号、空白行;
  2. T转换(Transform):通过分词器将长文本切分为固定大小的文本切片,补充切片元数据(文件名、格式、上传时间);
  3. L加载(Load):调用Embedding模型将文本切片转为浮点型向量,存入Redis向量索引;
  4. 检索问答:用户提问时,将问题转为向量,在Redis中相似度匹配,召回相似文档片段,结合大模型生成答案。

文档加载和解析器

组件职责类比
DocumentLoader(加载器)从某个来源找到文件,读取字节流,附带 metadata(文件名、路径等)「把文件从磁盘/Classpath 拿出来」
DocumentParser(解析器)把字节流按格式解析成纯文本,封装成 Document「把 PDF/Word/TXT 转成可读文字」

Document Loader(文档加载器)

加载器负责从哪里读,不负责怎么解析格式。

  1. 内置加载器(langchain4j 主模块,你项目已有)
加载器来源典型场景
ClassPathDocumentLoaderclasspath 资源Spring Boot 的 resources/upload/
FileSystemDocumentLoader本地磁盘路径服务器上的绝对路径目录
UrlDocumentLoaderHTTP/HTTPS URL网页、远程文件

Document Parser(文档解析器)

解析器Maven 模块支持格式说明
TextDocumentParserlangchain4j(已有)TXT、MD、HTML 等纯文本最简单,按字符流读
MarkdownDocumentParserlangchain4j-document-parser-markdownMarkdown专门处理 MD 结构
ApachePdfBoxDocumentParserlangchain4j-document-parser-apache-pdfboxPDF基于 PDFBox
ApachePoiDocumentParserlangchain4j-document-parser-apache-poiDOC/DOCX/PPT/XLS 等Office 文档
ApacheTikaDocumentParserlangchain4j-document-parser-apache-tika几乎全格式自动识别类型,万能解析
YamlDocumentParserlangchain4j-document-parser-yamlYAML配置文件类文档
DoclingDocumentParserlangchain4j-document-parser-docling多种格式基于 Docling

首先我们使用ApacheTikaDocumentParser解析器,所以pom.xml加下对应的依赖

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-document-parser-apache-tika</artifactId>
    <version>1.15.0-beta25</version>
</dependency>

接着MyEmController里加上addDocs方法

@RequestMapping("/addDocs")
    public String addDocs() {
        try {
            // 1. 读取 upload 下所有文件(txt / md 等)
            List<Document> documents = ClassPathDocumentLoader.loadDocuments("upload",new ApacheTikaDocumentParser());
            // 2. 构建入库管道:切分 -> 向量化 -> 写入 Redis
            EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                    .embeddingStore(embeddingStore) // 存储
                    .embeddingModel(embeddingModel) // 模型
                    // 小文档可 300~500 字符一段,重叠 50 提升检索效果
                    .documentSplitter(DocumentSplitters.recursive(400, 50)) // 切分
                    .build();
            ingestor.ingest(documents); // 入库
            return "OK,已入库 " + documents.size() + " 个文件";
        } catch (Exception e) {
            e.printStackTrace();
            return "入库失败: " + e.getMessage();
        }
    }

再新建一个RagConfig ,配置内容检索器

package com.java1234.config;

import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 *  rag 配置
 */
@Configuration
public class RagConfig {

    /**
     *   rag 内容检索器
     */
    @Bean
    EmbeddingStoreContentRetriever embeddingStoreContentRetriever(EmbeddingStore<TextSegment> embeddingStore, EmbeddingModel embeddingModel) {
        return EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore) // 存储
                .embeddingModel(embeddingModel) // 模型
                .maxResults(2) // 最大结果数
                .minScore(0.5) // 最小分数
                .build();
    }
}

再新建一个RagService,AiService里要配置内置内容检索器contentRetriever

package com.java1234.service;

import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
import reactor.core.publisher.Flux;

@AiService(
        wiringMode = AiServiceWiringMode.EXPLICIT, // 手动指定接入模型 手动装配
        streamingChatModel = "openAiStreamingChatModel", // 配置流式模型
        contentRetriever = "embeddingStoreContentRetriever" // 指定内容检索器
)
public interface RagService {

    @SystemMessage("""
            你是 Java1234 知识库助手。
            请根据检索到的资料回答问题,资料不足时如实说明,不要编造。
            """)
    Flux<String> chat(String question);
}

最后MyEmController里加下RagService注入,以及新增search方法:

@Autowired
private RagService ragService;
@RequestMapping(value ="/search",produces = "text/html;charset=utf-8")
    public Flux<String> search() {
        String question="介绍下java1234";
        return ragService.chat(question);
    }

接下来我们测试下:http://localhost:8080/addDocs ,已经入库。

在这里插入图片描述

我们在测试下搜索:http://localhost:8080/search

在这里插入图片描述

我们在看下控制台输出,来剖析下底层运行机制:

首先把用户问题,提交嵌入模型,生成向量。

在这里插入图片描述

接着用返回的用户提问向量去redis向量库里去检索两条最相关的文档。

然后就是 带这个用户问题和向量数据库返回的相关文档再次向大模型请求。

在这里插入图片描述

最后就是大模型响应,流式返回结果。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值