AI教学实战:用Python和LangChain构建企业级RAG知识库,实现智能问答系统

智能摘要
AI

从零到一:用PythonLangChain构建企业级RAG知识库,实现智能问答系统

在2025年,企业数字化转型已进入深水区,大量非结构化数据(如PDF、Word、网页内容)被闲置,传统搜索工具无法满足精准问答需求。RAG(Retrieval-Augmented Generation)技术通过结合检索与生成,成为构建智能知识库的首选方案。本文将从零开始,手把手教你使用Python和LangChain框架,搭建一个生产级RAG问答系统,涵盖数据加载、向量化、检索优化与部署全流程。

一张展示RAG系统架构的示意图,包含文档输入、<a href=向量数据库、检索模块和LLM输出,风格为扁平化信息图,主色调蓝色系,构图从左到右流程化展示” />
一张展示RAG系统架构的示意图,包含文档输入、向量数据库、检索模块和LLM输出,风格为扁平化信息图,主色调蓝色系,构图从左到右流程化展示

技术选型与环境准备

选择LangChain作为核心框架,因其模块化设计支持多种数据源与LLM(如OpenAI、本地模型)。推荐使用Python 3.10+,并安装以下依赖:

  • langchain:基础框架
  • chromadb:轻量级向量数据库
  • sentence-transformers:本地嵌入模型
  • pypdf:PDF解析
  • unstructured:通用文档解析

安装命令:pip install langchain chromadb sentence-transformers pypdf unstructured。若使用OpenAI模型,还需pip install openai。确保Python环境隔离,避免版本冲突。

数据加载与预处理

企业数据通常分散在PDF、网页或Markdown文件中。以下示例演示加载PDF并分割为块:

from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

loader = PyPDFLoader("企业知识手册.pdf")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
docs = text_splitter.split_documents(documents)

关键点:chunk_size控制块大小(建议500-1500字符),chunk_overlap保留上下文连贯性。对于混合格式,使用DirectoryLoader批量加载。

向量化与存储

将文本块转换为向量嵌入,并存入向量数据库。使用本地模型降低API成本:

from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma

embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
vectordb = Chroma.from_documents(docs, embeddings, persist_directory="./chroma_db")
vectordb.persist()

选择all-MiniLM-L6-v2因其轻量且效果稳定,适合企业内网部署。若需更高精度,可替换为BAAI/bge-large-zh。存储后,通过Chroma(persist_directory="./chroma_db", embedding_function=embeddings)恢复。

检索增强生成(RAG)链

构建检索链,结合查询上下文生成答案。以下使用OpenAI模型示例:

from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate

llm = ChatOpenAI(model="gpt-4", temperature=0.1)
retriever = vectordb.as_retriever(search_kwargs={"k": 3})

prompt_template = """使用以下上下文回答用户问题。如果上下文无相关信息,请回答“暂无相关信息”。
上下文:{context}
问题:{question}
答案:"""
PROMPT = PromptTemplate(template=prompt_template, input_variables=["context", "question"])

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever,
    return_source_documents=True,
    chain_type_kwargs={"prompt": PROMPT}
)

参数k=3控制检索文档数量,temperature=0.1保证答案确定性。链类型stuff适合小量文档,若上下文超出模型窗口,可改用map_reduce

检索优化策略

基础RAG可能面临检索不精准问题,以下为三种优化方案:

  • 混合检索:结合关键词(BM25)和向量检索,提升召回率。LangChain集成EnsembleRetriever
    from langchain.retrievers import BM25Retriever, EnsembleRetriever
    bm25_retriever = BM25Retriever.from_documents(docs)
    ensemble_retriever = EnsembleRetriever(retrievers=[bm25_retriever, vector_retriever], weights=[0.3, 0.7])
  • 查询重写:使用LLM将用户问题改写为更利于检索的形式,例如“去年的营收”转为“2024年企业营收数据”。
  • 元数据过滤:在文档块中添加标签(如部门、日期),检索时通过filter参数限定范围:
    retriever = vectordb.as_retriever(search_kwargs={"k": 3, "filter": {"部门": "技术部"}})

部署与性能调优

将系统封装为API服务,推荐使用FastAPI:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()
class Query(BaseModel):
    question: str

@app.post("/qa")
async def ask(query: Query):
    result = qa_chain({"query": query.question})
    return {"answer": result["result"], "sources": [doc.page_content[:100] for doc in result["source_documents"]]}

性能优化要点:缓存频繁查询(使用Redis或内存),异步加载文档解析,批量处理嵌入生成。对于高并发场景,部署在Docker容器中,结合Nginx负载均衡。

常见问题与调试

  • 检索结果不相关:调整块大小(500-800字符),或改用更精准的嵌入模型(如text-embedding-3-small)。
  • 答案重复或错误:降低temperature至0,或增加chunk_overlap到300。
  • 性能瓶颈:使用向量数据库的索引(如HNSW),或切换到Milvus等分布式方案。

通过以上步骤,你已掌握构建企业级RAG知识库的核心技能。实际应用中,建议结合用户反馈持续优化检索与生成逻辑,实现真正的智能问答。

本站代码模板仅供学习交流使用请勿商业运营,严禁从事违法,侵权等任何非法活动,否则后果自负!
© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
相关推荐
评论 抢沙发

请登录后发表评论

    暂无评论内容