使用 LangChain + Ollama 构建本地知识库问答系统

在人工智能技术飞速发展的今天,大型语言模型(LLM)已经成为推动各行各业智能化转型的核心力量。然而,当我们需要处理企业内部的私密文档、技术手册或者业务数据时,使用云端 API 服务就会面临数据泄露的风险。

为什么需要本地知识库问答系统

Ollama 是一个开源项目,让用户能够在自己的电脑上运行各种主流的大语言模型,包括 Llama 2、Mistral、Gemma 等。这意味着你可以完全控制自己的数据,所有的文本处理、向量计算和答案生成都在本地完成。

LangChain 则是构建 LLM 应用的框架,提供了文档加载器、文本分割器、向量存储、检索链等组件。通过 LangChain,我们可以轻松地将 Ollama 提供的本地大模型与向量数据库结合起来,实现 RAG(检索增强生成)技术。

核心问题与解决方案

RAG 的原理是:当用户提出问题时,系统首先会在本地的知识库中检索出与问题最相关的文档片段,然后将这些片段作为上下文提供给大模型,让大模型基于这些真实的内容来生成答案。

完整实现代码

#!/usr/bin/env python3
"""
本地知识库问答系统
基于 LangChain + Ollama + Chroma
"""

import os
from pathlib import Path
from langchain_community.document_loaders import (
    TextLoader,
    PyPDFLoader,
    Docx2txtLoader
)
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_ollama import OllamaEmbeddings
from langchain.chains import RetrievalQA
from langchain_ollama import OllamaLLM

# 配置部分
DOCS_DIR = Path("docs")
DB_DIR = Path("vector_db")
MODEL_NAME = "mistral"
EMBEDDING_MODEL = "nomic-embed-text"

# 1. 文档加载
def load_documents(docs_path: Path):
    documents = []
    loaders = {
        ".txt": TextLoader,
        ".pdf": PyPDFLoader,
        ".docx": Docx2txtLoader,
    }
    for file_path in docs_path.rglob("*"):
        if file_path.suffix in loaders:
            try:
                loader = loaders[file_path.suffix](str(file_path))
                docs = loader.load()
                print(f"已加载: {file_path.name} ({len(docs)} 页/段)")
                documents.extend(docs)
            except Exception as e:
                print(f"加载 {file_path.name} 失败: {e}")
    return documents

# 2. 文本分割
def split_documents(documents, chunk_size=1000, chunk_overlap=200):
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=chunk_size,
        chunk_overlap=chunk_overlap,
        separators=["\n\n", "\n", "。", " ", ""]
    )
    return text_splitter.split_documents(documents)

# 3. 向量存储
def create_vector_store(texts, persist_directory: str):
    embeddings = OllamaEmbeddings(
        model=EMBEDDING_MODEL,
        base_url="http://localhost:11434"
    )
    vectordb = Chroma.from_documents(
        documents=texts,
        embedding=embeddings,
        persist_directory=persist_directory
    )
    return vectordb

# 4. 构建问答链
def create_qa_chain(vectordb):
    llm = OllamaLLM(
        model=MODEL_NAME,
        base_url="http://localhost:11434",
        temperature=0.7
    )
    retriever = vectordb.as_retriever(
        search_type="similarity",
        search_kwargs={"k": 3}
    )
    qa_chain = RetrievalQA.from_chain_type(
        llm=llm,
        chain_type="stuff",
        retriever=retriever,
        return_source_documents=True
    )
    return qa_chain

def main():
    print("=" * 50)
    print("本地知识库问答系统")
    print("=" * 50)
    
    if not DOCS_DIR.exists():
        DOCS_DIR.mkdir(parents=True)
        print(f"\n请在 {DOCS_DIR} 目录下放入文档文件")
        return
    
    print("\n[步骤1] 加载文档...")
    documents = load_documents(DOCS_DIR)
    if not documents:
        print("未找到任何文档")
        return
    print(f"共加载 {len(documents)} 个文档")
    
    print("\n[步骤2] 分割文本...")
    texts = split_documents(documents)
    print(f"共分割成 {len(texts)} 个文本块")
    
    print("\n[步骤3] 创建向量数据库...")
    vectordb = create_vector_store(texts, str(DB_DIR))
    print(f"向量数据库已保存到: {DB_DIR}")
    
    print("\n[步骤4] 初始化问答系统...")
    qa_chain = create_qa_chain(vectordb)
    print("问答系统已准备就绪!")
    
    print("\n" + "=" * 50)
    print("问答系统已启动! 输入问题开始咨询 (输入 q 退出)")
    print("=" * 50)
    
    while True:
        query = input("\n你: ").strip()
        if query.lower() == "q":
            print("再见!")
            break
        if not query:
            continue
        print("\n思考中...")
        try:
            result = qa_chain.invoke({"query": query})
            print("\n" + "-" * 40)
            print("回答:")
            print(result["result"])
            print("-" * 40)
        except Exception as e:
            print(f"发生错误: {e}")

if __name__ == "__main__":
    main()

部署步骤

  1. 安装依赖pip install langchain langchain-community langchain-ollama ollama chromadb beautifulsoup4 pypdf python-docx
  2. 下载模型ollama pull mistral
  3. 准备文档:在 docs 目录下放入 TXT、PDF、Word 文件
  4. 运行系统python rag_demo.py

总结

本文详细介绍了如何使用 LangChain 和 Ollama 在本地构建知识库问答系统。通过这个方案,可以实现数据隐私安全、成本显著降低、响应速度快、定制化灵活等目标。

这个方案特别适合企业内部知识库建设、个人文档助手、私密数据的智能问答、开发者本地调试等场景。

暂无评论

发送评论 编辑评论


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