在企业级 AI 应用中,大语言模型(LLM)常面临两大痛点:知识时效性不足(如训练数据截止到 2023 年)和领域知识缺失(如企业内部文档未被模型学习)。检索增强生成(RAG)技术通过将外部知识库与 LLM 结合,实现了 "模型推理 + 事实检索" 的闭环,显著提升回答的准确性和可信度。
本文将以LangChain为框架,结合Ollama轻量级模型和Chroma向量数据库,从零搭建一个支持本地知识库的 RAG 问答系统。代码经过实战验证,并包含模块迁移避坑指南和性能优化技巧,适合 AI 开发者和技术爱好者快速上手。
bash
# 基础框架
pip install langchain-core langchain-community
# 模型与向量库
pip install -U langchain-ollama langchain-chroma chromadb
# 文档处理
pip install langchain-text-splitters python-multipart
bash
# 启动Ollama服务
ollama serve
# 拉取模型(根据硬件选择)
ollama pull qwen2.5:0.5b # 轻量级模型(推荐Mac/CPU)
ollama pull qwen2:7b # 中量级模型(需GPU支持)
python
# 加载指定目录下的所有txt文件
loader = DirectoryLoader(
"/path/to/knowledge_base",
glob="*.txt",
loader_cls=TextLoader
)
documents = loader.load()
# 文本分割(平衡上下文连贯性与token消耗)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=20,
length_function=len
)
splits = text_splitter.split_documents(documents)
python
# 连接Chroma服务
chroma = chromadb.HttpClient(host="localhost", port=8000)
# 创建/清空索引
chroma.delete_collection(name="ragdb")
collection = chroma.get_or_create_collection(
name="ragdb",
metadata={"hnsw:space": "cosine"} # 使用余弦相似度
)
# 构建向量存储
db = Chroma(
client=chroma,
collection_name="ragdb",
embedding_function=OllamaEmbeddings(model="nomic-embed-text:latest")
)
db.add_documents(splits)
python
# 从LangChain Hub拉取RAG模板
prompt = hub.pull("rlm/rag-prompt")
# 定义RAG流程
rag_chain = (
{
"context": db.as_retriever() | (lambda docs: "\n\n".join(doc.page_content for doc in docs)),
"question": RunnablePassthrough()
}
| prompt
| Ollama(model="qwen2.5:0.5b")
| StrOutputParser()
)
# 交互循环
while True:
user_input = input("问题:")
if user_input.lower() == 'exit':
break
response = rag_chain.invoke(user_input)
print("AI助手:", response)
python
# 原导入方式(错误)
from langchain_community.llms import Ollama
from langchain_community.vectorstores import Chroma
# 新导入方式(正确)
from langchain_ollama import OllamaLLM as Ollama
from langchain_chroma import Chroma
bash
# 设置环境变量(永久生效)
echo "export LANGCHAIN_API_KEY=your_api_key" >> ~/.bash_profile
source ~/.bash_profile
python
# 使用持久化客户端
chroma = chromadb.PersistentClient(path="/path/to/chromadb_data")
python
# 启用混合检索(向量+BM25)
retriever = db.as_retriever(
search_type="mmr",
search_kwargs={"k": 5, "fetch_k": 10}
)
python
# 使用LLM生成摘要
from langchain.chains.summarize import load_summarize_chain
summarizer = load_summarize_chain(
llm=Ollama(model="qwen2.5:0.5b"),
chain_type="map_reduce"
)
context = summarizer.run(docs)
python
# 加载图片(需安装Pillow)
from langchain_community.document_loaders import UnstructuredImageLoader
image_loader = UnstructuredImageLoader("/path/to/image.png")
image_docs = image_loader.load()
python
# 结合搜索引擎(需安装SerpAPI)
from langchain_community.document_loaders import SerpAPILoader
loader = SerpAPILoader(query="2024年北京房价趋势")
web_docs = loader.load()
python
# 加载代码仓库(需安装GitPython)
from langchain_community.document_loaders import GitLoader
loader = GitLoader(
repo_path="https://github.com/langchain-ai/langchain",
branch="main",
file_filter=lambda file_path: file_path.endswith(".py")
)
code_docs = loader.load()
组件 | 优势 | 适用场景 |
---|---|---|
Ollama | 本地部署、模型丰富 | 中小型企业 / 个人开发者 |
Chroma | 轻量级、支持 HTTP 接口 | 快速原型开发 |
LangChain | 标准化组件、生态完善 | 复杂 RAG 系统开发 |
模型 | 上下文窗口 | 生成速度(token/s) | 内存占用 |
---|---|---|---|
qwen2.5:0.5b | 2048 | 15-20 | 1.2GB |
qwen2:7b | 8192 | 5-8 | 7GB |
Q:如何处理中文文档?
A:使用RecursiveCharacterTextSplitter
并设置is_separator_regex=True
。
Q:如何调试 RAG 链?
A:启用 LangSmith 跟踪,在代码中添加:
python
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
Q:向量数据库如何选择?
A:- 轻量级:Chroma(本地)/Pinecone(云)
通过本文的实战指南,你可以快速搭建一个基于本地知识库的 RAG 问答系统,并通过优化策略提升系统性能。欢迎在评论区分享你的实践经验或提出改进建议!