AI百事通

手把手教你用LangChain搭建本地知识库问答系统

📅 2026-07-06📰 ai_generated👁 0 次阅读
手把手教你用LangChain搭建本地知识库问答系统
LangChain知识库问答系统RAG本地部署

前言

随着大语言模型(LLM)的普及,如何让模型回答基于私有知识的问题成为刚需。检索增强生成(RAG) 是一种主流方案:先检索相关文档,再让LLM基于检索结果生成答案。本教程将使用LangChain框架,结合本地部署的嵌入模型和LLM,搭建一个完全离线的知识库问答系统。

环境准备

硬件要求

  • 至少8GB RAM(推荐16GB)
  • 有NVIDIA GPU(可选,但能加速嵌入和推理)

软件安装

# 创建虚拟环境
python -m venv rag_env
source rag_env/bin/activate  # Linux/Mac
# rag_env\Scripts\activate  # Windows

# 安装依赖
pip install langchain langchain-community chromadb sentence-transformers fastapi uvicorn

步骤一:选择嵌入模型

我们使用BAAI/bge-small-zh-v1.5,这是一个轻量级的中文嵌入模型,适合本地部署。

from langchain.embeddings import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(
    model_name="BAAI/bge-small-zh-v1.5",
    model_kwargs={'device': 'cpu'},  # 如果有GPU,改为'cuda'
    encode_kwargs={'normalize_embeddings': True}
)

步骤二:加载和分割文档

假设您的知识库是PDF或Markdown文件,放在./docs目录下。

from langchain.document_loaders import DirectoryLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

# 加载文档
loader = DirectoryLoader('./docs', glob="**/*.md", loader_cls=TextLoader)
documents = loader.load()

# 分割文档
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=50,
    separators=["\n\n", "\n", "。", "!", "?", ",", " ", ""]
)
splits = text_splitter.split_documents(documents)
print(f"文档被分割为 {len(splits)} 个块")

步骤三:创建向量数据库

使用Chroma作为向量数据库,将文档块嵌入并存储。

from langchain.vectorstores import Chroma

persist_directory = './chroma_db'
vectordb = Chroma.from_documents(
    documents=splits,
    embedding=embeddings,
    persist_directory=persist_directory
)
vectordb.persist()
print(f"向量数据库已保存至 {persist_directory}")

步骤四:设置本地LLM

这里使用Ollama运行Qwen2.5-7B模型,确保已安装Ollama并拉取模型。

from langchain.llms import Ollama

llm = Ollama(model="qwen2.5:7b", temperature=0.3)

步骤五:构建RAG链

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

# 自定义提示模板
prompt_template = """使用以下上下文来回答用户的问题。如果你不知道答案,就说你不知道,不要编造。
上下文:{context}
问题:{question}
答案:"""
PROMPT = PromptTemplate(
    template=prompt_template,
    input_variables=["context", "question"]
)

# 创建检索器
retriever = vectordb.as_retriever(search_kwargs={"k": 3})

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

步骤六:测试问答

query = "什么是LangChain?"
result = qa_chain({"query": query})
print(f"问题:{query}")
print(f"答案:{result['result']}")
print(f"来源文档:{result['source_documents']}")

步骤七:部署为API服务

使用FastAPI将系统封装成REST API。

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()

class Query(BaseModel):
    question: str

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

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

运行后,可通过http://localhost:8000/docs查看Swagger文档,发送POST请求即可问答。

总结

至此,您已成功搭建了一个本地知识库问答系统。所有数据均保留在本地,无需联网,保障了隐私安全。您可以根据需要替换为更强的嵌入模型或LLM,如bge-large或Qwen2.5-14B。祝您使用愉快!