Skip to content

基于LangChain的简易RAG实现

1. RAG简介

RAG (Retrieval Augmented Generation) 是一种结合检索系统和大语言模型的架构模式,用于增强AI回答的准确性和可靠性。

2. 系统架构

RAG系统主要包含两个阶段:

  1. 索引阶段(离线处理)
  2. 查询阶段(在线处理)

3. 详细实现

3.1 环境准备

python
# 安装必要的包
!pip install langchain chromadb ollama sentence_transformers

# 导入所需库
from langchain.document_loaders import DirectoryLoader, PDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OllamaEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain.llms import Ollama
from langchain.prompts import PromptTemplate

3.2 文档处理

3.2.1 文档加载和分割

python
# 文档加载器配置
loader = DirectoryLoader(
    "./docs",
    glob="**/*.pdf",
    loader_cls=PDFLoader
)
documents = loader.load()

# 文档分割器配置
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    length_function=len,
    separators=["\n\n", "\n", " ", ""]
)
splits = text_splitter.split_documents(documents)

文档处理流程:

3.3 向量化和存储

python
# 初始化embedding模型
embeddings = OllamaEmbeddings(model="qwen")

# 创建向量存储
vectorstore = Chroma.from_documents(
    documents=splits,
    embedding=embeddings,
    persist_directory="./chroma_db"
)

向量化流程:

3.4 提示模板设计

python
# 创建提示模板
prompt_template = """使用以下上下文来回答问题。如果不知道答案,就说不知道。

上下文: {context}

问题: {question}

回答:"""

PROMPT = PromptTemplate(
    template=prompt_template, 
    input_variables=["context", "question"]
)

提示模板处理流程:

3.5 检索链配置

python
# 创建检索问答链
qa_chain = RetrievalQA.from_chain_type(
    llm=Ollama(model="qwen"),
    chain_type="stuff",
    retriever=vectorstore.as_retriever(
        search_type="similarity",
        search_kwargs={"k": 3}
    ),
    chain_type_kwargs={
        "prompt": PROMPT
    },
    return_source_documents=True
)

检索链执行流程:

3.6 查询接口实现

python
class RAGSystem:
    def __init__(self, qa_chain):
        self.qa_chain = qa_chain
    
    def query(self, question: str) -> dict:
        """
        处理用户查询
        
        Args:
            question: 用户问题
            
        Returns:
            dict: 包含答案和源文档的字典
        """
        try:
            result = self.qa_chain({
                "query": question
            })
            
            return {
                "answer": result["result"],
                "sources": [
                    {
                        "content": doc.page_content,
                        "metadata": doc.metadata
                    } for doc in result["source_documents"]
                ]
            }
        except Exception as e:
            return {
                "error": f"查询处理失败: {str(e)}"
            }

4. 使用示例

python
# 创建RAG系统实例
rag_system = RAGSystem(qa_chain)

# 示例查询
question = "什么是机器学习?"
response = rag_system.query(question)

print("答案:", response["answer"])
print("\n参考源文档:")
for source in response["sources"]:
    print(f"- {source['content'][:100]}...")

5. 性能优化建议

  1. 文档分割优化

    • 根据文档特点调整chunk大小
    • 保持适当的重叠度
    • 考虑语义完整性
  2. 向量检索优化

    • 调整k值
    • 实现检索缓存
    • 考虑混合检索策略
  3. 提示工程优化

    • 优化提示模板
    • 添加系统指令
    • 处理边界情况

6. 完整系统流程

总结

基于LangChain实现RAG系统的优势:

  1. 模块化设计,易于扩展
  2. 丰富的组件选择
  3. 简化的接口调用
  4. 完善的文档支持

通过合理配置和优化,可以构建一个高效、可靠的RAG系统,提升AI应用的准确性和可用性。

许可协议

本文章采用 CC BY-NC-SA 4.0 许可协议进行发布。您可以自由地:

  • 共享 — 在任何媒介以任何形式复制、发行本作品
  • 演绎 — 修改、转换或以本作品为基础进行创作

惟须遵守下列条件:

  • 署名 — 您必须给出适当的署名,提供指向本许可协议的链接,同时标明是否(对原始作品)作了修改。您可以用任何合理的方式来署名,但是不得以任何方式暗示许可人为您或您的使用背书。
  • 非商业性使用 — 您不得将本作品用于商业目的。
  • 相同方式共享 — 如果您再混合、转换或者基于本作品进行创作,您必须基于与原先许可协议相同的许可协议分发您贡献的作品。

上次更新时间: