深入理解 RAG(LangChain4j+Milvus)的实现与应用

深入解析RAG(LangChain4j+Milvus)实现与应用

在这里插入图片描述

一、概述:什么是 RAG?

检索增强生成(Retrieval-Augmented Generation,简称 RAG)是一种结合信息检索与文本生成的技术范式。它通过以下两个关键步骤显著提升大语言模型(LLM)的响应质量:

  1. 检索阶段:从知识库中检索与用户查询相关的文档片段
  2. 生成阶段:将检索到的内容作为上下文,指导LLM生成更准确的回答

与直接使用LLM相比,RAG具有三大优势:

  • 知识更新便捷:只需更新文档库而无需重新训练模型
  • 回答可追溯:能提供回答所依据的文档来源
  • 成本效益高:减少对模型参数规模的依赖

本文将基于LangChain4j框架,详细解析一个完整的RAG实现方案。

二、环境准备与依赖配置

2.1 核心依赖说明

<dependencies>
    <!-- LangChain4j核心库 -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-spring-boot-starter</artifactId>
        <version>1.0.0-beta3</version>
    </dependency>
    
    <!-- 嵌入模型实现 -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId>
        <version>1.0.0-beta3</version>
    </dependency>
    
    <!-- RAG增强组件 -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-easy-rag</artifactId>
        <version>1.0.0-beta3</version>
    </dependency>
    
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-milvus</artifactId>
        <version>1.0.0-beta3</version>
    </dependency>
</dependencies>

关键依赖说明:

  • langchain4j-easy-rag:提供文档分块、向量化等RAG核心功能
  • langchain4j-embeddings-all-minilm-l6-v2:轻量级嵌入模型(AllMiniLM-L6-v2)
  • langchain4j-open-ai-spring-boot-starter:OpenAI API集成(实际使用DeepSeek)
  • langchain4j-milvus:Milvus集成

2.2 Milvus安装

不详细展开,我本地使用WSL2安装的docker安装的milvus,可参考博文:https://blog.csdn.net/qq_34908167/article/details/148920103

docker 结果:
在这里插入图片描述

生产建议

  1. 调优配置:修改milvus.yaml中的

    proxy.rateLimit.qps=100
    

    避免限流报错

  2. 持久化方案:挂载/var/lib/milvus目录防止容器重启数据丢失

  3. 监控集成:通过http://localhost:9091/webui实时查看检索延迟与负载

三、RAG核心组件实现

3.1 创建Milvus的Collection并且插入简单数据验证

import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
import dev.langchain4j.store.embedding.EmbeddingSearchResult;
import dev.langchain4j.store
<think>我们正在构建一个基于PDF的RAG应用,使用LangChainMilvus和BGE-M3嵌入模型。以下是步骤和示例代码:###步骤概述1.**环境准备**:安装必要的库。2.**加载PDF文档**:使用LangChain的文档加载器读取PDF文件。3.**文档切分**:将文档分割成适合处理的块。4.**嵌入模型**:使用BGE-M3模型生成文本嵌入(稠密向量和稀疏向量)。5.**向量存储**:将嵌入向量存入Milvus向量数据库。6.**检索生成**:构建检索链,根据用户查询检索相关文档片段,并生成回答。###详细步骤代码示例####1.环境准备安装所需库:```bashpipinstalllangchainlangchain-communitypymilvusunstructuredpython-dotenvtransformerstorch```####2.加载PDF文档使用LangChain的`PyPDFLoader`加载PDF文件:```pythonfromlangchain_community.document_loadersimportPyPDFLoaderloader=PyPDFLoader("example.pdf")documents=loader.load()```####3.文档切分使用文本分割器将文档分割成较小的块:```pythonfromlangchain.text_splitterimportRecursiveCharacterTextSplittertext_splitter=RecursiveCharacterTextSplitter(chunk_size=1000,chunk_overlap=200,)docs=text_splitter.split_documents(documents)```####4.嵌入模型我们使用BGE-M3嵌入模型。注意:BGE-M3支持生成稠密向量和稀疏向量。Milvus支持混合检索(稠密+稀疏),但需要Milvus2.4以上版本。首先,我们需要一个自定义的嵌入类来使用BGE-M3模型:```pythonfromlangchain.embeddingsimportEmbeddingsfromtypingimportListimporttorchfromtransformersimportAutoModel,AutoTokenizerclassBGEM3Embeddings(Embeddings):def__init__(self,model_name="BAAI/bge-m3",device="cuda"iftorch.cuda.is_available()else"cpu"):self.tokenizer=AutoTokenizer.from_pretrained(model_name)self.model=AutoModel.from_pretrained(model_name).to(device)self.device=devicedefembed_documents(self,texts:List[str])->List[List[float]]:#生成稠密向量inputs=self.tokenizer(texts,padding=True,truncation=True,return_tensors="pt",max_length=8192).to(self.device)withtorch.no_grad():outputs=self.model(**inputs)#使用[CLS]token的表示作为文档向量dense_embeddings=outputs.last_hidden_state[:,0].cpu().numpy().tolist()returndense_embeddingsdefembed_query(self,text:str)->List[float]:returnself.embed_documents([text])[0]```####5.向量存储初始化Milvus向量数据库,并存储嵌入向量。首先,确保Milvus服务正在运行。然后,使用LangChainMilvus集成:```pythonfromlangchain.vectorstoresimportMilvus#初始化嵌入模型embeddings=BGEM3Embeddings()#连接Milvusvector_db=Milvus.from_documents(documents=docs,embedding=embeddings,connection_args={"host":"localhost","port":"19530"},collection_name="pdf_rag_collection",auto_id=True)```####6.检索生成构建一个检索问答链,使用检索到的文档片段生成答案。```pythonfromlangchain.chainsimportRetrievalQAfromlangchain.llmsimportOpenAI#这里可以使用其他LLM,比如ChatGLM#假设使用OpenAI,但也可以替换为本地模型如ChatGLMimportosos.environ["OPENAI_API_KEY"]="your-openai-api-key"llm=OpenAI(temperature=0)#创建检索链qa_chain=RetrievalQA.from_chain_type(llm=llm,chain_type="stuff",retriever=vector_db.as_retriever(),return_source_documents=True)#进行提问query="文档中主要讨论了哪些内容?"result=qa_chain({"query":query})print("答案:",result["result"])print("来源文档:",result["source_documents"])```###注意事项1.**BGE-M3模型**:它支持长文本(最多8192个token),适合处理文档块。2.**Milvus配置**:确保Milvus服务运行,并注意集合(collection)的配置(如索引类型)以支持混合检索(如果使用稀疏向量)。上述示例仅使用了稠密向量。3.**本地LLM**:如果需要使用本地大模型(如ChatGLM),只需替换`llm`部分。例如,使用`langchain.llms`中的`ChatGLM`类(如果有)或自定义LLM封装。###优化方向-**混合检索**:BGE-M3也生成稀疏向量,可以改进存储和检索部分以同时利用稠密和稀疏向量,提高召回率。-**多模态**:BGE-M3是多模态嵌入模型,但本示例仅处理文本。如需处理图像,需要扩展。###引用以上实现参考了LangChainMilvus的官方文档,以及BGE-M3的相关资料[^4]。§§相关问题§§1.如何优化基于PDF的RAG应用的检索效果?2.在Milvus中如何同时存储和检索稠密向量和稀疏向量?3.如何将本地大模型(如ChatGLM)集成到LangChainRAG应用中?</think>### 使用LangChain + Milvus + BGE-M3构建基于PDF的RAG应用教程 #### 1. 环境准备 ```bash # 安装核心依赖 pip install langchain langchain-community pymilvus unstructured python-dotenv transformers ``` #### 2. 初始化向量数据库 (Milvus) ```java // MilvusConfig.java (Spring Boot配置) import io.milvus.v2.client.ConnectConfig; import io.milvus.v2.client.MilvusClientV2; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MilvusConfig { @Bean public MilvusClientV2 milvusClient() { return new MilvusClientV2( ConnectConfig.builder() .uri("http://localhost:19530") // Milvus地址 .build() ); } } ``` #### 3. PDF处理向量化 ```python # PDF加载切分 from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter loader = PyPDFLoader("path/to/document.pdf") documents = loader.load() text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, chunk_overlap=200 ) docs = text_splitter.split_documents(documents) # BGE-M3嵌入模型 from langchain.embeddings import HuggingFaceBgeEmbeddings model_name = "BAAI/bge-m3" encode_kwargs = {'normalize_embeddings': True} embeddings = HuggingFaceBgeEmbeddings( model_name=model_name, encode_kwargs=encode_kwargs ) ``` #### 4. 向量存储检索 ```python # 存储向量到Milvus from langchain.vectorstores import Milvus vector_db = Milvus.from_documents( documents=docs, embedding=embeddings, connection_args={"host": "localhost", "port": "19530"}, collection_name="pdf_rag", auto_id=True ) # 创建检索器 retriever = vector_db.as_retriever( search_type="mmr", # 最大边际相关性 search_kwargs={"k": 5} ) ``` #### 5. RAG问答链实现 ```python # 构建问答链 from langchain.chains import RetrievalQA from langchain_community.llms import ChatGLM llm = ChatGLM(endpoint_url="http://localhost:8000") # 本地ChatGLM服务 qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=True ) # 执行查询 query = "文档中提到的关键技术是什么?" result = qa_chain({"query": query}) print(f"答案: {result['result']}") print(f"来源: {result['source_documents'][0].page_content[:200]}...") ``` #### 6. 部署优化建议 1. **文档预处理**: ```python # 添加PDF元数据处理 loader = PyPDFLoader("file.pdf", extract_images=True) # 启用图像提取 ``` 2. **混合检索优化**: ```python # 同时使用稠密和稀疏向量 retriever = vector_db.as_retriever( search_type="hybrid", search_kwargs={ "k": 10, "dense_weight": 0.7, "sparse_weight": 0.3 } ) ``` 3. **性能监控**: ```python # 启用检索日志 import logging logging.basicConfig() logging.getLogger("langchain.retrievers").setLevel(logging.INFO) ``` ### 关键组件说明 | 组件 | 作用 | 推荐配置 | |------|------|----------| | **BGE-M3** | 多语言文本嵌入 | `normalize_embeddings=True` | | **Milvus** | 向量存储检索 | 启用混合索引(HNSW + BM25) | | **LangChain** | 流程编排 | 使用`RecursiveCharacterSplitter`处理长文本 | > 注意:BGE-M3支持**8192 Token长文本**和**多语言处理**,特别适合PDF文档的复杂内容[^4]。部署时建议使用GPU加速嵌入计算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

象话

打赏犹如太阳穴的枪口

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值