首页 > 其他分享 >构建本地知识库:基于 LangChain 和 Ollama 的 RAG 实现教程

构建本地知识库:基于 LangChain 和 Ollama 的 RAG 实现教程

时间:2025-01-15 12:28:41浏览次数:3  
标签:RAG self LangChain st 文档 file path Ollama

构建本地知识库:基于 LangChain 和 Ollama 的 RAG 实现教程

简介

在这个教程中,我们将学习如何构建一个本地运行的知识库系统,它能够让用户上传 PDF 或 TXT 文档,并通过自然语言与文档内容进行交互。这个系统使用了 RAG(检索增强生成)技术,结合了 LangChain、Ollama 和 Streamlit 等现代工具,实现了一个完整的本地知识库解决方案。

技术栈

  • LangChain: 用于构建 LLM 应用的框架
  • Ollama: 本地运行的 LLM 模型服务
  • FastEmbed: 高效的文本嵌入模型
  • Chroma: 向量数据库
  • Streamlit: Web 界面框架

系统架构

该系统主要包含以下几个核心组件:

  1. 文档处理器: 支持 PDF 和 TXT 文件的加载和处理
  2. 文本分割器: 将文档分割成适当大小的块
  3. 向量存储: 使用 Chroma 存储文档块的向量表示
  4. 检索器: 基于相似度搜索相关文档块
  5. LLM 接口: 与 Ollama 模型交互生成回答
  6. Web 界面: 用户友好的交互界面

实现步骤

1. 环境配置

首先,创建一个新的 Python 环境并安装必要的依赖:

# 创建虚拟环境
python -m venv .venv

# 激活环境
# Windows:
.venv\Scripts\activate
# Linux/Mac:
source .venv/bin/activate

# 安装依赖
pip install -r requirements-windows.txt

requirements-windows.txt

aiohappyeyeballs>=2.4.0
aiohttp>=3.10.5
aiosignal>=1.3.1
altair>=5.4.1
annotated-types>=0.7.0
anyio>=4.6.0
asgiref>=3.8.1
attrs>=24.2.0
backoff>=1.11.1
bcrypt>=4.2.0
blinker>=1.8.2
build>=1.2.2
cachetools>=5.5.0
certifi>=2024.8.30
charset-normalizer>=3.3.2
chroma-hnswlib>=0.7.6
chromadb>=0.5.7
click>=8.1.7
coloredlogs>=15.0.1
dataclasses-json>=0.6.7
Deprecated>=1.2.14
distlib>=0.3.8
durationpy>=0.7
fastapi>=0.115.0
fastembed>=0.3.6
filelock>=3.16.1
flatbuffers>=24.3.25
frozenlist>=1.4.1
fsspec>=2024.9.0
gitdb>=4.0.11
GitPython>=3.1.43
google-auth>=2.35.0
googleapis-common-protos>=1.65.0
grpcio>=1.66.1
h11>=0.14.0
httpcore>=1.0.5
httptools>=0.6.1
httpx>=0.27.2
huggingface-hub>=0.25.0
humanfriendly>=10.0
idna>=3.10
importlib_metadata>=8.4.0
importlib_resources>=6.4.5
Jinja2>=3.1.4
jsonpatch>=1.33
jsonpointer>=3.0.0
jsonschema>=4.23.0
jsonschema-specifications>=2023.12.1
langchain>=0.1.12
langchain-community>=0.0.27
langchain-core>=0.1.30
langsmith>=0.1.27
markdown-it-py>=3.0.0
MarkupSafe>=2.1.5
marshmallow>=3.20.2
mdurl>=0.1.2
monotonic>=1.6
mpmath>=1.3.0
multidict>=6.0.5
mypy-extensions>=1.0.0
numpy>=1.26.4
oauthlib>=3.2.2
onnxruntime>=1.17.1
openai>=1.12.0
opentelemetry-api>=1.23.0
opentelemetry-instrumentation>=0.44b0
opentelemetry-semantic-conventions>=0.44b0
overrides>=7.7.0
packaging>=23.2
pandas>=2.2.0
Pillow>=10.2.0
pip>=24.0
platformdirs>=4.2.0
posthog>=3.4.1
protobuf>=4.25.3
pulsar-client>=3.4.0
pyarrow>=15.0.0
pydantic>=2.6.1
pydantic_core>=2.16.2
pydeck>=0.8.1b0
Pygments>=2.17.2
PyJWT>=2.8.0
pyparsing>=3.1.1
python-dateutil>=2.8.2
python-dotenv>=1.0.1
pytz>=2024.1
PyYAML>=6.0.1
referencing>=0.33.0
regex>=2023.12.25
requests>=2.31.0
requests-oauthlib>=1.3.1
rich>=13.7.0
rpds-py>=0.17.1
rsa>=4.9
setuptools>=69.0.3
six>=1.16.0
smmap>=5.0.1
sniffio>=1.3.0
SQLAlchemy>=2.0.25
starlette>=0.35.1
streamlit>=1.31.0
streamlit-chat>=0.1.1
sympy>=1.12
tenacity>=8.2.3
tiktoken>=0.6.0
tokenizers>=0.15.2
toml>=0.10.2
toolz>=0.12.1
tornado>=6.4
tqdm>=4.66.2
typing_extensions>=4.9.0
typing-inspect>=0.9.0
tzdata>=2024.1
tzlocal>=5.2
urllib3>=2.2.0
validators>=0.22.0
watchdog>=3.0.0
websockets>=12.0
wheel>=0.42.0
wrapt>=1.16.0
yarl>=1.9.4
zipp>=3.17.0

2. RAG 实现(rag.py)

RAG 实现的核心是 ChatPDF 类,它处理文档的加载、向量化和查询:

class ChatPDF:
    def __init__(self, llm_model: str = "qwen2.5"):
        # 初始化 LLM 模型
        self.model = ChatOllama(model=llm_model)
        
        # 配置文本分割器
        self.text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=1024, 
            chunk_overlap=100
        )
        
        # 设置提示模板
        self.prompt = ChatPromptTemplate([
            ("system", "You are a helpful assistant that can answer questions about the PDF document that uploaded by the user."),
            ("human", "Here is the document pieces: {context}\nQuestion: {question}")
        ])

    def ingest(self, file_path: str):
        # 加载文档
        if file_path.lower().endswith('.pdf'):
            docs = PyPDFLoader(file_path=file_path).load()
        elif file_path.lower().endswith('.txt'):
            docs = TextLoader(file_path=file_path).load()
            
        # 分割文档
        chunks = self.text_splitter.split_documents(docs)
        chunks = filter_complex_metadata(chunks)
        
        # 创建向量存储
        self.vector_store = Chroma.from_documents(
            documents=chunks,
            embedding=FastEmbedEmbeddings(),
            persist_directory="./chroma_db"
        )
        self.vector_store.persist()

    def ask(self, query: str):
        # 初始化检索器
        if not self.vector_store:
            self.vector_store = Chroma(
                persist_directory="./chroma_db",
                embedding=FastEmbedEmbeddings()
            )
            
        # 配置检索参数
        self.retriever = self.vector_store.as_retriever(
            search_type="similarity_score_threshold",
            search_kwargs={"k": 10, "score_threshold": 0.0}
        )
        
        # 构建查询链
        self.chain = (
            {"context": self.retriever, "question": RunnablePassthrough()}
            | self.prompt
            | self.model
            | StrOutputParser()
        )
        
        return self.chain.invoke(query)

3. Web 界面实现(app.py)

使用 Streamlit 构建用户界面:

def page():
    if len(st.session_state) == 0:
        st.session_state["messages"] = []
        st.session_state["assistant"] = ChatPDF()

    st.header("本地知识库")

    # 文件上传组件
    st.subheader("上传文件 PDF/TXT")
    st.file_uploader(
        "上传文件",
        type=["pdf", "txt"],
        key="file_uploader",
        on_change=read_and_save_file,
        accept_multiple_files=True
    )

    # 显示对话历史
    display_messages()
    
    # 用户输入框
    st.text_input("Message", key="user_input", on_change=process_input)

核心功能说明

1. 文档处理

系统支持 PDF 和 TXT 格式的文档处理。文档首先被加载,然后使用 RecursiveCharacterTextSplitter 分割成较小的块,每个块大小为 1024 个字符,相邻块之间有 100 个字符的重叠,以保持上下文的连贯性。

2. 向量化和存储

使用 FastEmbed 模型将文本块转换为向量表示,并存储在 Chroma 向量数据库中。Chroma 提供了高效的相似度搜索功能,使我们能够快速找到与用户查询最相关的文档片段。

3. 检索增强生成

当用户提出问题时,系统会:

  1. 搜索最相关的文档片段(检索 top-10 个相关度最高的片段)
  2. 将这些片段与用户的问题组合成提示
  3. 使用 Ollama 模型生成回答

4. 用户界面

Streamlit 提供了简洁的用户界面,包括:

  • 文件上传功能
  • 聊天历史显示
  • 实时对话交互

运行项目

  1. 确保已安装 Ollama 并运行了所需的模型(默认使用 qwen2.5)
  2. 运行 Web 应用:
streamlit run app.py

最佳实践

  1. 文档预处理

    • 合理设置文档分块大小
    • 保持适当的块重叠以维持上下文
  2. 检索优化

    • 调整检索数量(k值)和相似度阈值
    • 根据实际需求平衡召回率和精确度
  3. 提示工程

    • 使用清晰的系统提示
    • 在提示中包含充分的上下文信息

扩展建议

  1. 添加文档管理功能(删除、更新)
  2. 实现多种文档格式支持
  3. 添加文档预处理选项
  4. 支持多语言处理
  5. 添加对话历史持久化

结论

这个项目展示了如何使用现代工具构建一个实用的本地知识库系统。通过结合 RAG 技术和本地 LLM,我们能够创建一个既保护隐私又高效的文档问答系统。这个实现方案可以作为构建更复杂知识库系统的基础。

标签:RAG,self,LangChain,st,文档,file,path,Ollama
From: https://blog.csdn.net/hzether/article/details/145157864

相关文章

  • 用于与多个数据库聊天的智能 SQL 代理问答和 RAG 系统(4) —— 利用大型语言模型(LLM)生成
    实现一个与旅行相关的SQL数据库交互的工具,利用大型语言模型(LLM)生成和执行SQL查询,并通过语言模型处理查询结果生成最终答案。完整代码:fromlangchain_core.toolsimporttoolfromlangchain_community.utilitiesimportSQLDatabasefromlangchain.chainsimportcreate_......
  • Pinia 替代 localStorage 的常规使用场景
    在现代Vue工程化项目中,通常推荐使用Pinia(或Vuex)来管理状态,而不是直接使用localStorage。我来解释下具体原因和使用方式:1、为什么使用Pinia替代localStorage://使用Pinia的优势:-状态集中管理,更容易维护-支持响应式-支持开发工具调试-支持TypeScript-可以配......
  • 【向量数据库】搭建RAG架构,如何选择向量数据库产品?
    搭建RAG架构应用时,选择合适的向量数据库是关键。向量数据库是RAG系统的核心组件,负责存储和检索高维向量数据,从而支持高效的语义搜索和信息检索功能。那么今天与大家分享下如何选择向量数据库,以及主流向量数据库产品的推荐,供您参考学习。如何选择向量数据库?性能与延迟:向量数据库......
  • vscode插件continue结合ollama自动生成代码
    vscode插件continue结合ollama自动生成代码ollama安装ollama安装见https://www.cnblogs.com/jokingremarks/p/18151827中的前部分,懒得再写了vscode中continue的安装可以直接在vscode的扩展中安装插件,也可以去下载这个插件,然后应用在vscode中一般都会选择直接去扩展中安装,在......
  • 从零开始的LangChain开发教程:快速上手指南
    快速上手LangChain:轻松构建LLM应用在构建基于语言模型(LLM)的应用时,LangChain提供了一套功能强大的工具集,帮助开发者快速实现从文本处理、对话生成到复杂的问答系统等各类任务。本文将从基础入门到复杂场景应用,带你快速掌握LangChain的核心能力。1.技术背景介绍LangChain......
  • 利用 LangChain 与 Eden AI 模型进行交互的完整指南
    利用LangChain与EdenAI模型进行交互的完整指南EdenAI是一个颠覆性的AI平台,通过统一多个提供商的优秀AI模型,简化了开发者的工作流。凭借单一API,开发者可以快速将强大的AI功能整合到生产环境中,轻松实现多样化的AI能力。本文将介绍如何使用LangChain与Eden......
  • 如何贡献开源项目LangChain:完整指南
    LangChain是一个快速发展的开源项目,旨在构建强大的AI应用程序框架。作为一名开发者或技术爱好者,你或许希望为这个项目贡献力量,无论是开发新功能、修复bug、改进文档,还是参与讨论和设计。这篇文章将详细介绍如何高效地加入LangChain的开发与贡献,帮助你事半功倍。1.......
  • 借助 LangGraph、OpenAI 和 Tavily 构建自适应 RAG 系统(含代码)
    自适应RAG系统(Multi-AgenticRAG:探索智能问答系统的新边界(含代码))是一种能够根据用户查询的具体语境,动态选择检索策略与生成方式的人工智能系统。它结合了先进的自然语言处理技术和信息检索算法,能够在海量数据中快速定位相关信息,并基于这些信息生成准确、连贯的回答。LangGraph......
  • TrustRAG:增强RAG系统鲁棒性与可信度的创新框架
    在人工智能飞速发展的今天,大语言模型(LLMs)凭借其强大的语言处理能力在诸多领域大放异彩。检索增强生成(RAG)系统(面向企业RAG(RetrievalAugmentedGeneration)系统的多维检索框架)的出现,通过整合外部知识源进一步提升了LLMs的性能,使其能针对用户查询提供更准确、更具上下文相关性的......
  • DraggableSheetContext
    DraggableSheetContext基础库3.2.0开始支持,低版本需做兼容处理。相关文档:draggable-sheetDraggableSheet实例,可通过wx.createSelectorQuery的NodesRef.node方法获取。方法DraggableSheetContext.scrollTo(Objectobject)滚动到指定位置。size取值[0,1],size......