RAG检索增强生成 | 豆包MarsCode AI刷题

244 阅读3分钟

一、RAG简介

  1. RAG定义

    • RAG,全称为检索增强生成(Retrieval-Augmented Generation),结合了检索生成两种能力。
    • 在处理任务时,RAG从外部知识库中动态检索相关信息,结合生成模型生成答案。
  2. RAG工作流程

    1. 检索:通过向量搜索(如ChromaDB、Qdrant、Faiss)从文档集合中查找相关段落。
    2. 上下文编码:将检索到的文档与用户输入一起编码。
    3. 生成:利用编码的信息,通过大语言模型生成答案。
  3. RAG特点

    • 不依赖仅从训练数据中学习的知识。
    • 动态引入外部知识库信息,适合处理具体、细节化的任务。

二、LangChain实现RAG的核心步骤

1. 文档加载
  • LangChain提供多种文档加载器,支持HTML、PDF、Word等格式。
  • 示例代码:
    from langchain.document_loaders import PyPDFLoader, Docx2txtLoader, TextLoader
    
    documents = []
    base_dir = './OneFlower'
    for file in os.listdir(base_dir):
        file_path = os.path.join(base_dir, file)
        if file.endswith('.pdf'):
            loader = PyPDFLoader(file_path)
        elif file.endswith('.docx'):
            loader = Docx2txtLoader(file_path)
        elif file.endswith('.txt'):
            loader = TextLoader(file_path)
        documents.extend(loader.load())
    
2. 文本分割
  • 将长文档分割为适合上下文窗口的小块,避免模型上下文限制问题。
  • 采用 RecursiveCharacterTextSplitter 进行分割,示例如下:
    from langchain.text_splitter import RecursiveCharacterTextSplitter
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10)
    chunked_documents = text_splitter.split_documents(documents)
    
3. 嵌入与向量存储
  • 将分割后的文档转为向量表示并存储到向量数据库(如Qdrant)。
  • 示例代码:
    from langchain.vectorstores import Qdrant
    from langchain.embeddings import OpenAIEmbeddings
    
    vectorstore = Qdrant.from_documents(
        documents=chunked_documents,
        embedding=OpenAIEmbeddings(),
        location=":memory:",
        collection_name="my_documents"
    )
    
4. 检索器与大模型生成
  • 构建检索器从数据库中检索相关文档。
  • 利用大模型(如GPT)生成答案。
  • 示例代码:
    from langchain.chat_models import ChatOpenAI
    from langchain.retrievers.multi_query import MultiQueryRetriever
    from langchain.chains import RetrievalQA
    
    llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
    retriever = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(), llm=llm)
    qa_chain = RetrievalQA.from_chain_type(llm, retriever=retriever)
    
5. 用户交互与问答系统
  • 基于Flask框架实现简单的Web应用:
    from flask import Flask, request, render_template
    
    app = Flask(__name__)
    
    @app.route('/', methods=['GET', 'POST'])
    def home():
        if request.method == 'POST':
            question = request.form.get('question')
            result = qa_chain({"query": question})
            return render_template('index.html', result=result)
        return render_template('index.html')
    
    if __name__ == "__main__":
        app.run(host='0.0.0.0', port=5000)
    

三、技术关键点

1. 文本分割策略
  • 基于LLM的上下文限制,需确保每段文本在嵌入和检索时不超出上下文窗口。
  • 可根据任务类型调整分割策略:
    • 细粒度分割:适合文本分析、语法检查等任务。
    • 粗粒度分割:适合机器翻译、问答等任务。
2. 嵌入与向量检索
  • 词嵌入
    • 生成词或段落的向量表示。
    • 可用于语义搜索,通过余弦相似度或欧氏距离进行向量匹配。
  • 向量数据库选择
    • 常见向量数据库包括Chroma、Qdrant、Pinecone等。
    • 选择时需综合考虑数据规模、性能需求和成本等因素。
3. 检索增强生成
  • 用户问题嵌入与文档向量库比较,提取相关信息。
  • 使用大模型结合检索信息生成精准答案。

四、应用场景

  1. 知识库问答

    • 提供基于公司内部文档的智能问答服务。
    • 动态获取最新文档内容,支持政策更新或SOP手册的查询。
  2. 非结构化数据检索

    • 处理大规模文本数据,如客服记录、研究论文等。
  3. 行业定制化解决方案

    • 例如鲜花销售平台,可关联花语、库存、颜色等信息,为客户提供定制服务。

五、总结

RAG结合了检索与生成能力,通过动态引入外部知识库提升模型回答的准确性和丰富性。LangChain提供了强大的封装功能,从文档加载、文本分割、嵌入到生成问答系统,流程简单、易用。

通过本次学习,我们掌握了从头搭建一个基于LangChain的知识库问答系统的完整流程。未来可进一步深入学习LangChain组件,如模型、链、内存、代理等,开发更多场景化的智能应用。