零基础实战:用 LangChain 搭建本地 RAG 知识库系统

在 AI 应用爆发的今天,大模型虽然拥有强大的语言理解能力,但往往面临"知识过时"、"一本正经地胡说八道(幻觉)"以及"无法读取企业私有数据"三大痛点。检索增强生成(RAG)技术正是解决这些问题的最佳方案。本文将带你使用 Python 和 LangChain 框架,从零搭建一套完全离线、免费、数据安全的本地 RAG 知识库问答系统。

一、 RAG 核心原理与架构设计

RAG(Retrieval-Augmented Generation)的核心思想是"先检索,再生成"。其标准工作流包含以下几个关键步骤:

数据准备:将本地的文档(如 TXT、Markdown、PDF 等)加载到系统中。

文本切块(Chunking):大模型有上下文窗口限制,且长文本检索精度低。因此需要将长文档按一定字符数(如 500 字)切分为小段,并设置一定的重叠区(Overlap)以保持语义连贯。

向量化(Embedding):使用嵌入模型将文本块转换为多维向量(一串数字)。这一步相当于将人类语言翻译成了机器能理解的"语义坐标"。

存入向量数据库:将生成的向量及其对应的原文存入向量数据库中。

检索与生成:当用户提问时,系统将问题转化为向量,在数据库中找出最相似的几个文本块,然后将"原文 + 问题"拼接成 Prompt 发送给大模型,大模型据此生成精准回答。

二、 技术栈选型与环境准备

为了降低入门门槛并保证数据绝对安全,本方案采用纯本地运行的技术栈:

流程编排:LangChain(大模型应用开发事实标准,组件丰富)

向量数据库:Chroma(嵌入式轻量级本地向量库,无需部署服务,开箱即用)

嵌入模型:all-MiniLM-L6-v2(开源轻量模型,本地离线运行,无需 API)

大语言模型:兼容 OpenAI 接口规范的任意模型(如本地部署的 Qwen-7B、Llama 3 等)

首先,确保你的电脑安装了 Python 3.9+,然后一键安装核心依赖:pip install langchain langchain-text-splitters langchain-chroma sentence-transformers openai python-dotenv

三、 核心代码实战:从文档入库到智能问答

以下是一个经过优化的、可直接复制运行的完整 RAG 系统代码。代码包含了文档加载、中文语义分割、向量库构建以及抗幻觉问答链。

python 复制代码
import os
from dotenv import load_dotenv
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain_community.document_loaders import DirectoryLoader, TextLoader

# ====================== 1. 核心配置项 ======================
KNOWLEDGE_DIR = "./knowledge_base"  # 你的本地文档文件夹
VECTOR_DB_PATH = "./chroma_vector_db" # 向量库持久化路径
CHUNK_SIZE = 500       # 文本块大小
CHUNK_OVERLAP = 50     # 文本块重叠大小
RETRIEVE_TOP_K = 3     # 检索最相关的片段数量

# 大模型配置(以本地 Ollama 或兼容 OpenAI 接口的服务为例)
LLM_BASE_URL = "http://localhost:11434/v1" 
LLM_API_KEY = "ollama" 
LLM_MODEL_NAME = "qwen2:7b" 

load_dotenv()

# ====================== 2. 文档加载与切分 ======================
def load_and_split_documents():
    loader = DirectoryLoader(KNOWLEDGE_DIR, glob="**/*.txt", loader_cls=TextLoader, loader_kwargs={"encoding": "utf-8"})
    documents = loader.load()
    
    # 针对中文优化的递归字符分割器
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=CHUNK_SIZE, chunk_overlap=CHUNK_OVERLAP,
        separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""]
    )
    chunks = text_splitter.split_documents(documents)
    print(f"文档处理完成,共生成 {len(chunks)} 个文本块")
    return chunks

# ====================== 3. 构建向量数据库 ======================
def build_vector_db(chunks):
    embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2", model_kwargs={"device": "cpu"})
    
    if os.path.exists(VECTOR_DB_PATH) and len(os.listdir(VECTOR_DB_PATH)) > 0:
        vector_db = Chroma(persist_directory=VECTOR_DB_PATH, embedding_function=embeddings)
        print("已加载本地已有向量库")
    else:
        vector_db = Chroma.from_documents(documents=chunks, embedding=embeddings, persist_directory=VECTOR_DB_PATH)
        print("向量库构建完成并已持久化")
    return vector_db

# ====================== 4. 初始化模型与问答链 ======================
def create_rag_chain():
    llm = ChatOpenAI(base_url=LLM_BASE_URL, api_key=LLM_API_KEY, model=LLM_MODEL_NAME, temperature=0)
    vector_db = build_vector_db(load_and_split_documents())
    
    retriever = vector_db.as_retriever(search_type="similarity", search_kwargs={"k": RETRIEVE_TOP_K})
    qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever, return_source_documents=True)
    return qa_chain

# ====================== 5. 交互式问答测试 ======================
if __name__ == "__main__":
    qa_chain = create_rag_chain()
    while True:
        question = input("\n请输入问题(输入 exit 退出):")
        if question.lower() == "exit": break
        result = qa_chain.invoke({"query": question})
        print(f"\n答案:{result['result']}")
        print("参考来源:", [doc.metadata['source'] for doc in result['source_documents']])

四、 避坑指南与进阶优化

在搭建本地 RAG 时,新手常遇到以下问题,需特别注意:

中文切分失效:默认的英文空格切分器会破坏中文语义,务必使用 RecursiveCharacterTextSplitter 并传入中文标点作为分隔符。

检索结果不准:如果切块太大(如超过 1000 字),向量语义会被稀释,导致检索不准;建议将 CHUNK_SIZE 控制在 300-500 之间。

大模型幻觉:在 Prompt 中必须加入约束,例如:"请仅根据以下参考内容回答问题,如果参考内容中没有相关信息,请直接回答'我不知道',不要编造。"

性能优化:如果文档量达到数万篇,建议将本地嵌入模型替换为针对中文优化的 m3e-base 或 bge-large-zh,并将向量库升级为 Milvus 或 Elasticsearch 以支持高并发检索。

通过上述步骤,你就能在本地快速搭建起一个专属的 AI 知识库。无论是用于个人学习笔记问答,还是企业内部规章制度检索,RAG 都是目前落地成本最低、效果最显著的技术方案。

相关推荐
可涵不会debug1 小时前
从向量嵌入到复杂 Agent:LLM、LangChain、LangGraph 完整科普
langchain·嵌入模型·langgraph
怕浪猫2 小时前
第13章 评估与评测:如何衡量Agent的好坏
langchain·openai·ai编程
Linging_242 小时前
基于Langchain得AI Agent相关知识学习
人工智能·学习·langchain
艾莉丝努力练剑20 小时前
【AI面试】AI八股文
人工智能·ai·面试·langchain·八股文
思考着亮1 天前
1.LangChain概述
langchain
马里马里奥-1 天前
大模型应用开发笔记03:LangChain 中间件实战
笔记·中间件·langchain
To_OC1 天前
手搓 LangChain 工具调用:原来 Agent 的核心逻辑,就是个 while 循环
人工智能·langchain·llm
Boop_wu2 天前
[LangChain]LangChain聊天模型
langchain
常常有2 天前
LangChain 学习记录 01:为什么需要 LangChain?从 API 调用到 AI 应用框架
人工智能·langchain