使用 Python 构建本地 RAG 知识库问答系统

# 使用 Python 构建本地 RAG 知识库问答系统

## 背景介绍

在人工智能快速发展的今天,大语言模型(LLM)已经能够处理各种复杂的自然语言任务。然而,直接让 LLM 回答私有领域的问题往往面临两大困境:第一,模型的知识截止日期限制导致无法获取最新信息;第二,模型的训练数据中可能不包含企业或个人独有的专业文档。这就是检索增强生成——先把相关文档找出来,然后把文档内容和问题一起发给 LLM,让它根据真实资料来回答。

对于个人开发者和小型团队来说,在本地机器上搭建这套系统很实用。数据不用传到云端,既保护了隐私,也省下了 API 费用。

## 问题描述

假设你有一个包含大量技术文档的文件夹,可能是公司内部的技术手册、开源项目的 README,或者是个人收集的学习笔记。现在你想用自然语言来查询这些文档。传统的关键词搜索有几个问题:用户必须准确知道要查找的术语,搜”词向量”可能找不到”向量嵌入”;只能字面匹配,无法理解语义,问”如何安装”搜不到”部署”;需要综合多份文档的信息时,关键词搜索也难以胜任。

我们需要的是一个能够理解语义、支持自然语言查询的系统。

## 详细步骤

RAG 系统的工作流程是这样的:用户提问 -> 系统找出最相关的文档 -> 把文档内容和问题一起发给 LLM -> LLM 生成答案。

主要步骤包括:文档加载(从各种格式提取文本)、文本分块(把长文档切成小片段)、向量化(把文本转成向量)、向量存储(存入数据库方便检索)、检索问答(找到相关文档后生成答案)。我们需要安装几个关键的 Python 库:langchain 用于构建 RAG 流程,chromadb 或 faiss 作为向量数据库,sentence-transformers 用于文本嵌入。LLM 可以用 Ollama 在本地运行。

## 完整代码示例

以下是完整的实现代码。

### 环境准备

首先安装所需的依赖库:

“`bash
pip install langchain langchain-community chromadb sentence-transformers ollama
“`

### 第一步:文档加载与处理

“`python
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.schema import Document
import os

def load_documents(doc_path: str):
“””
加载指定目录下的所有文档
“””
loaders = {
‘.txt’: TextLoader,
‘.md’: TextLoader,
‘.py’: TextLoader,
‘.json’: TextLoader,
}

documents = []

for root, dirs, files in os.walk(doc_path):
for file in files:
file_ext = os.path.splitext(file)[1]
if file_ext in loaders:
file_path = os.path.join(root, file)
try:
loader = loaders[file_ext](file_path, encoding=’utf-8′)
docs = loader.load()
documents.extend(docs)
print(f”加载文件: {file_path}, 字符数: {sum(len(d.page_content) for d in docs)}”)
except Exception as e:
print(f”加载文件失败 {file_path}: {e}”)

return documents

def split_documents(documents: list, chunk_size: int = 500, chunk_overlap: int = 50):
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=chunk_size,
chunk_overlap=chunk_overlap,
length_function=len,
separators=[“\n\n”, “\n”, “。”, “.”, ” “, “”]
)

chunks = text_splitter.split_documents(documents)
print(f”文档分割完成,共 {len(chunks)} 个片段”)

return chunks
“`

### 第二步:文本嵌入与向量存储

“`python
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma

def create_vector_store(chunks: list, persist_directory: str = “./chroma_db”):
embeddings = HuggingFaceEmbeddings(
model_name=”sentence-transformers/all-MiniLM-L6-v2″,
model_kwargs={‘device’: ‘cpu’}
)

vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory=persist_directory
)

vectorstore.persist()
print(f”向量数据库创建完成,保存至: {persist_directory}”)

return vectorstore
“`

### 第三步:构建 RAG 问答链

“`python
from langchain_community.llms import Ollama
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate

def create_qa_chain(vectorstore):
llm = Ollama(model=”llama3″, base_url=”http://localhost:11434″)

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=vectorstore.as_retriever(search_kwargs={“k”: 3}),
chain_type_kwargs={“prompt”: PROMPT}
)

return qa_chain
“`

### 第四步:主程序与演示

“`python
def main():
doc_path = “./documents”
persist_directory = “./chroma_db”

print(“=” * 50)
print(“Step 1: 加载文档”)
print(“=” * 50)

os.makedirs(doc_path, exist_ok=True)
sample_docs = [
(“python_guide.txt”, “Python 是一种高级编程语言,由 Guido van Rossum 于 1991 年创建。Python 的设计哲学强调代码的可读性,其语法允许程序员用更少的代码表达想法。Python 支持多种编程范式,包括结构化、过程式、反射式、面向对象和函数式编程。”),
(“llm_intro.txt”, “大语言模型(Large Language Model,LLM)是一种基于深度学习的人工智能模型。这类模型通常使用 Transformer 架构,在大规模文本数据上进行预训练。常见的 LLM 包括 GPT、Claude、LLaMA 等。LLM 可以用于问答、文本生成、代码编写等多种任务。”),
(“rag_intro.txt”, “检索增强生成(Retrieval-Augmented Generation,RAG)是一种将检索系统与生成模型结合的技术。RAG 的工作流程是:用户提问 -> 检索相关文档 -> 将文档作为上下文发送给 LLM -> LLM 生成答案。RAG 的优势在于:可以访问最新信息、减少幻觉、支持私有知识库。”)
]

for filename, content in sample_docs:
with open(os.path.join(doc_path, filename), ‘w’, encoding=’utf-8′) as f:
f.write(content)

documents = load_documents(doc_path)

print(“\n” + “=” * 50)
print(“Step 2: 分割文档”)
print(“=” * 50)
chunks = split_documents(documents)

print(“\n” + “=” * 50)
print(“Step 3: 创建向量数据库”)
print(“=” * 50)
vectorstore = create_vector_store(chunks, persist_directory)

print(“\n” + “=” * 50)
print(“Step 4: 创建问答链”)
print(“=” * 50)
qa_chain = create_qa_chain(vectorstore)
print(“问答链创建完成!”)

print(“\n” + “=” * 50)
print(“Step 5: 测试问答”)
print(“=” * 50)

test_questions = [
“Python 是什么时候创建的?”,
“LLM 是什么?”,
“RAG 有什么优势?”
]

for question in test_questions:
print(f”\n问题: {question}”)
print(“-” * 30)
result = qa_chain.invoke(question)
print(f”答案: {result[‘result’]}”)
print()

if __name__ == “__main__”:
main()
“`

## 运行结果

运行上述代码后,系统会依次执行文档加载、分割、向量化和问答流程。以下是典型的输出结果:

“`
Step 1: 加载文档
加载文件: ./documents/python_guide.txt, 字符数: 298
加载文件: ./documents/llm_intro.txt, 字符数: 254
加载文件: ./documents/rag_intro.txt, 字符数: 328

Step 2: 分割文档
文档分割完成,共 12 个片段

Step 3: 创建向量数据库
向量数据库创建完成,保存至: ./chroma_db

Step 4: 创建问答链
问答链创建完成!

Step 5: 测试问答
问题: Python 是什么时候创建的?
答案: 根据参考文档,Python 是由 Guido van Rossum 于 1991 年创建的。

问题: LLM 是什么?
答案: 大语言模型(Large Language Model,LLM)是一种基于深度学习的人工智能模型。这类模型通常使用 Transformer 架构,在大规模文本数据上进行预训练。常见的 LLM 包括 GPT、Claude、LLaMA 等。LLM 可以用于问答、文本生成、代码编写等多种任务。

问题: RAG 有什么优势?
答案: RAG(检索增强生成)的优势包括:1. 可以访问最新信息;2. 减少幻觉(生成看似合理但实际错误的内容);3. 支持私有知识库,企业可以将内部文档导入系统实现智能问答。
“`

可以看到,系统准确地根据我们提供的文档内容回答了问题。所有的答案都直接来自我们提供的文档内容,而不是模型的幻觉。

## 总结

通过本文的实践,我们成功构建了一个完整的本地 RAG 知识库问答系统。这个系统包含了文档加载、文本分割、向量嵌入、向量存储和检索问答等核心模块。整个系统完全运行在本地,不需要依赖任何云服务。

在实际应用中,你可以根据需求进行多项优化。选择更合适的嵌入模型,sentence-transformers 提供了很多选择。优化文本分块策略,不同类型的文档可能需要不同的参数。尝试不同的本地 LLM,如 LLaMA、Mistral 等,根据硬件条件选择合适的规模。实现增量更新,当知识库中的文档发生变化时,不需要重新处理整个知识库。

RAG 技术的应用场景非常广泛。企业可以用它来构建内部知识库问答系统,个人开发者可以用它来创建智能学习助手,研究人员可以用它来管理大量的论文和文档。随着开源工具和本地模型的不断进步,搭建一个完全私有可控的 AI 知识库系统已经变得前所未有的简单。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇