从零构建个人知识库助手:基于 RAG 的本地文档问答系统实战

# 从零构建个人知识库助手:基于 RAG 的本地文档问答系统实战

## 背景介绍

在日常工作和学习中,我们会积累大量的文档资料:技术笔记、项目文档、会议记录、阅读笔记等。当这些文档散落在各个角落时,想要快速找到需要的信息就变得困难重重。虽然市面上有各种笔记软件和搜索工具,但它们通常只能进行简单的关键词匹配,无法真正理解我们的查询意图。

近年来,大语言模型(LLM)快速发展,一种名为 RAG(Retrieval-Augmented Generation,检索增强生成)的技术方案逐渐成为构建知识库问答系统的首选。RAG 的核心思想是将文档先进行向量化处理并存入向量数据库,当用户提问时,系统会从知识库中检索最相关的内容,然后将这些内容作为上下文提供给大语言模型,从而生成更加准确和有依据的回答。

本文将手把手教你如何使用 Python 从零构建一个基于 RAG 的个人知识库问答系统,能够对你的本地文档进行智能问答。

## 问题描述

传统的关键词搜索存在以下几个明显痛点:

1. **语义理解缺失**:无法理解同义词和近似表达,例如搜索”机器学习”时,找不到”ML”或”机器学习算法”相关的内容
2. **上下文丢失**:搜索结果往往是孤立的文档片段,缺乏全局视角
3. **无法推理**:不能进行多步推理和综合分析
4. **体验单一**:仅仅返回搜索结果,没有对话式的交互体验

基于 RAG 的问答系统则能很好地解决这些问题。它支持语义检索、对话式交互、答案溯源,并且可以处理本地文档(PDF、Markdown、TXT 等)。

## 详细步骤

### 1. 环境准备

首先安装必要的依赖库。推荐使用 Python 3.10 及以上版本。

“`bash
pip install langchain langchain-community langchain-huggingface
pip install chroma qdrant-client
pip install sentence-transformers
pip install unstructured[md] pdfminer
pip install openai tiktoken
“`

### 2. 文档加载与处理

使用 LangChain 提供的文档加载器可以方便地处理各类文档。以下是处理 Markdown 和纯文本文件的示例:

“`python
from langchain_community.document_loaders import TextLoader, DirectoryLoader
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
import os

# 配置文档目录
DOCS_DIR = “./my-knowledge-base”

# 加载文档
def load_documents():
“””加载指定目录下的所有文档”””
loader = DirectoryLoader(
DOCS_DIR,
glob=”**/*.md”,
loader_cls=TextLoader,
encoding=”utf-8″
)
documents = loader.load()
return documents

# 文档分块
def split_documents(documents):
“””将长文档分割成较小的块”””
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
length_function=len,
)
chunks = text_splitter.split_documents(documents)
return chunks

print(f”成功加载 {len(documents)} 个文档”)
“`

### 3. 向量数据库构建

将文档块转换为向量并存储到向量数据库中:

“`python
# 初始化 Embedding 模型
def get_embedding_model():
“””获取嵌入模型”””
model_name = “sentence-transformers/all-MiniLM-L6-v2”
embeddings = HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs={device: cpu}
)
return embeddings

# 构建向量数据库
def build_vector_store(chunks, embeddings):
“””构建 Chroma 向量数据库”””
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory=”./vector_store”
)
vectorstore.persist()
return vectorstore
“`

### 4. 构建 RAG 问答链

整合检索和大语言模型,构建完整的问答系统:

“`python
from langchain_community.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate

# 配置 LLM
llm = ChatOpenAI(
model_name=”gpt-3.5-turbo”,
openai_api_key=”your-api-key”,
temperature=0
)

# 自定义提示词模板
qa_prompt = PromptTemplate(
template=”””你是一个专业的知识库助手。请根据以下参考文档回答用户的问题。

参考文档:
{context}

用户问题:{question}

请基于参考文档给出准确回答。如果文档中没有相关信息,请明确告知用户。”””,
input_variables=[“context”, “question”]
)

# 构建问答链
def build_qa_chain(vectorstore, llm):
“””构建 RAG 问答链”””
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type=”stuff”,
retriever=vectorstore.as_retriever(
search_kwargs={“k”: 3}
),
chain_type_kwargs={“prompt”: qa_prompt},
return_source_documents=True
)
return qa_chain
“`

### 5. 完整示例

以下是一个完整的、可直接运行的示例:

“`python
from langchain_community.document_loaders import TextLoader, DirectoryLoader
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA

class KnowledgeBaseQA:
“””个人知识库问答系统”””

def __init__(self, docs_dir, api_key):
self.docs_dir = docs_dir
self.llm = ChatOpenAI(
model_name=”gpt-3.5-turbo”,
openai_api_key=api_key,
temperature=0
)
self.embeddings = HuggingFaceEmbeddings(
model_name=”sentence-transformers/all-MiniLM-L6-v2″,
model_kwargs={device: cpu}
)
self.vectorstore = None
self.qa_chain = None

def build_knowledge_base(self):
“””构建知识库”””
# 1. 加载文档
loader = DirectoryLoader(
self.docs_dir,
glob=”**/*.md”,
loader_cls=TextLoader,
encoding=”utf-8″
)
documents = loader.load()
print(f”加载了 {len(documents)} 个文档”)

# 2. 分割文档
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = text_splitter.split_documents(documents)
print(f”分割成 {len(chunks)} 个文本块”)

# 3. 构建向量数据库
self.vectorstore = Chroma.from_documents(
documents=chunks,
embedding=self.embeddings,
persist_directory=”./chroma_db”
)
self.vectorstore.persist()
print(“向量数据库构建完成”)

# 4. 构建问答链
self.qa_chain = RetrievalQA.from_chain_type(
llm=self.llm,
chain_type=”stuff”,
retriever=self.vectorstore.as_retriever(search_kwargs={“k”: 3}),
return_source_documents=True
)
print(“问答链构建完成”)

def ask(self, question):
“””提问”””
if not self.qa_chain:
raise ValueError(“请先构建知识库”)

result = self.qa_chain({“query”: question})
return {
“answer”: result[“result”],
“sources”: [doc.metadata.get(“source”, “未知”)
for doc in result[“source_documents”]]
}

# 使用示例
if __name__ == “__main__”:
qa_system = KnowledgeBaseQA(
docs_dir=”./my-knowledge-base”,
api_key=”your-openai-api-key”
)

# 构建知识库(首次运行需要执行)
qa_system.build_knowledge_base()

# 提问
result = qa_system.ask(“什么是 RAG 技术?”)
print(f”\n回答:{result[answer]}”)
print(f”参考来源:{result[sources]}”)
“`

## 运行结果

准备好文档并配置好 API Key 后,运行上述代码:

“`
加载了 15 个文档
分割成 287 个文本块
向量数据库构建完成
问答链构建完成

回答:RAG(Retrieval-Augmented Generation,检索增强生成)是一种将信息检索与文本生成相结合的技术方案。它首先从知识库中检索相关文档,然后将这些文档作为上下文提供给大语言模型,从而生成更加准确和有依据的回答。RAG 技术可以有效解决大语言模型知识过时、幻觉、胡编乱造等问题。

参考来源:[./my-knowledge-base/ai/rag-intro.md, ./my-knowledge-base/notes/llm-study.md]
“`

系统不仅给出了准确的回答,还列出了参考来源,方便追溯原始文档。

## 总结

通过本文我们学习了如何从零构建一个基于 RAG 的个人知识库问答系统。这个系统具有以下特点:

1. **语义检索**:基于向量的相似度匹配,能够理解语义相近的表达
2. **对话式交互**:像与人对话一样获取知识,而不是简单的关键词搜索
3. **答案可溯源**:每条回答都标注了参考来源,便于核实
4. **本地部署**:文档存储在本地,保护隐私安全

在实际使用中,可以根据自己的需求进行扩展:添加 PDF、Word 等格式支持、切换不同的 Embedding 模型、使用本地部署的开源大模型等。RAG 技术的应用场景非常广泛,除了个人知识库,还可以用于企业知识管理、智能客服、辅助编程等场景。

暂无评论

发送评论 编辑评论


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