RAG 实践(三)-基于Langchain的RAG demo

通常来说基于LangChain实现一个RAG的原理如下:

加载文件 -> 读取文本 -> 文本分割 -> 文本向量化 -> 问句向量化 -> 在文本向量中匹配出与问句向量最相似的top k个 -> 匹配出的文本作为上下文和问题一起添加到prompt中 -> 提交给LLM生成回答。

核心流程包括:

  1. 数据摄取:加载 PDF/Word/ 网页等格式文件
  2. 文本分块:将长文本拆分为 500-1000 字的语义片段
  3. 向量索引:通过 Embedding 模型生成向量存储到数据库
  4. 检索增强:根据用户问题检索相关文档片段
  5. 生成优化:将检索结果与问题结合生成最终回答
组件 推荐方案 替代方案
文本加载 PyPDF2/Unstructured BeautifulSoup(网页)
分块工具 RecursiveCharacterTextSplitter CharacterTextSplitter
Embedding BAAI/BGE-large-zh-v1.5 text-embedding-ada-002
向量数据库 FAISS(本地)/Pinecone(云端) Chroma/Qdrant
LLM Qwen-1.8/InternLM-3.0 GPT-4-Turbo
部署框架 FastAPI+Uvicorn Flask+Gunicorn

数据采集

from langchain_community.document_loaders import PyPDFLoader


# 1. 文本加载:加载 PDF 文件
def load_pdf(file_path):
    loader = PyPDFLoader(file_path)
    documents = loader.load()
    return documents

文本分块

from langchain.text_splitter import RecursiveCharacterTextSplitter

# 2. 文本分块
def split_text(documents, chunk_size=1000, chunk_overlap=200):
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
    chunks = text_splitter.split_documents(documents)
    return chunks

向量数据库初始化

from langchain_community.vectorstores import FAISS
from langchain_huggingface import HuggingFaceEmbeddings

# 3. 获取嵌入并存入 FAISS
def create_embeddings_and_store(chunks):
    embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-large-zh-v1.5")
    vectorstore = FAISS.from_documents(chunks, embeddings)
    vectorstore.save_local("faiss_index")
    return vectorstore

RAG 系统核心组件构建:

检索器配置

# 4. 配置检索器
def configure_retriever(vectorstore):
    retriever = vectorstore.as_retriever(
        search_type="similarity",
        search_kwargs={"k": 5, "score_threshold": 0.7})
    return retriever


云端模型调用:

from langchain_community.chat_models import ChatOpenAI

llm= ChatOpenAI(model="qwen-plus",
                   openai_api_key="sk-xxx”,
                   openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1")

RAG 链构建

from langchain.chains import RetrievalQA
 
prompt_template = """
已知信息:
{context}
用户问题:
{question}
请基于已知信息,以专业技术文档的格式回答用户问题,要求逻辑清晰、步骤明确。
"""
 
chain_type_kwargs = {
    "prompt": PromptTemplate.from_template(prompt_template),
    "verbose": True
}
 
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever,
    chain_type_kwargs=chain_type_kwargs
)

核心评估指标

指标 计算方法 优化方向
上下文召回率 检索到的关键信息数 / 总关键信息数 调整分块策略、优化 Embedding
答案忠实度 基于检索内容的事实数 / 答案总事实数 强化 prompt 约束、增加检索结果权重
响应相关性 人工标注相关性评分 优化检索排序、调整 prompt 模板

检索优化

# 混合检索(向量+关键词)
from langchain.retrievers import EnsembleRetriever
 
vector_retriever = vector_db.as_retriever()
bm25_retriever = BM25Retriever.from_documents(chunks)
 
ensemble_retriever = EnsembleRetriever(
    retrievers=[vector_retriever, bm25_retriever],
    weights=[0.7, 0.3]
)

生成优化

# 流式输出
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
 
llm = ChatOpenAI(
    streaming=True,
    callbacks=[StreamingStdOutCallbackHandler()],
    temperature=0.1
)

多模态支持:

from langchain.llms import OpenAI
from langchain.agents import initialize_agent, Tool
 
tools = [
    Tool(
        name="ImageSearch",
        func=lambda query: image_search_api(query),
        description="用于搜索与查询相关的图片"
    )
]
 
agent = initialize_agent(
    tools,
    OpenAI(temperature=0),
    agent="zero-shot-react-description",
    verbose=True
)

长期记忆增强:

from langchain.memory import ConversationBufferMemory
 
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)
 
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever,
    memory=memory
)
posted @ 2025-09-24 23:19  不负如来不负卿x  阅读(23)  评论(0)    收藏  举报