跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

基于 Chroma 和 Ollama 搭建本地 RAG 应用

如何使用 Ollama 本地部署大语言模型,结合 ChromaDB 向量数据库和 LangChain 框架构建本地 RAG 问答应用。内容包括环境配置、模型加载、网页内容解析与分块、向量化存储、提示词工程以及使用 Gradio 构建交互界面。通过该方案可实现基于私有数据的离线智能问答,无需依赖云端 API。同时补充了常见问题处理与性能优化建议,帮助用户更好地落地本地 AI 应用。

花里胡哨发布于 2025/2/6更新于 2026/10/25112 浏览
基于 Chroma 和 Ollama 搭建本地 RAG 应用

本篇文章我们将基于 Ollama 本地运行大语言模型(LLM),并结合 ChromaDB、LangChain 来建立一个小型的基于网页内容进行本地问答的 RAG 应用。

概念介绍

先简单了解下这些术语:

LLM (Large Language Model) 是通过使用海量的文本数据集(书籍、网站等)训练出来的,具备通用语言理解和生成的能力。虽然它可以推理许多内容,但它们的知识仅限于特定时间点之前用于训练的数据。

LangChain 是一个用于开发由大型语言模型(LLM)驱动的应用程序的框架。提供了丰富的接口、组件、能力简化了构建 LLM 应用程序的过程。

Ollama 是一个免费的开源框架,可以让大模型很容易的运行在本地电脑上。

RAG(Retrieval Augmented Generation)是一种利用额外数据增强 LLM 知识的技术,它通过从外部数据库获取当前或相关上下文信息,并在请求大型语言模型(LLM)生成响应时呈现给它,从而解决了生成不正确或误导性信息的问题。

工作流程如下:

  1. 加载并解析网页内容。
  2. 将文本分割成块(Chunking)。
  3. 使用嵌入模型将文本转换为向量。
  4. 将向量存储到向量数据库(Chroma)。
  5. 用户提问时检索相关向量。
  6. 结合检索内容与 Prompt 生成回答。

基于上述 RAG 步骤,接下来我们将使用代码完成它。

开始搭建

1. 环境准备

依据 Ollama 使用指南完成大模型的本地下载和运行。

# LLM
ollama pull llama3
# Embedding Model
ollama pull nomic-embed-text
2. 安装依赖

安装 langchain、langchain-community、bs4 等库。

pip install langchain langchain-community bs4
3. 初始化 LangChain 对象

初始化 langchain 提供的 Ollama 对象,配置流式输出。

from langchain_community.llms import Ollama
from langchain.callbacks.manager import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler

# 1. 初始化 llm, 让其流式输出
llm = Ollama(
    model="llama3", 
    temperature=0.1, 
    top_p=0.4, 
    callback_manager=CallbackManager([StreamingStdOutCallbackHandler()])
)

参数说明:

  • temperature: 控制文本生成的创造性。为 0 时响应是可预测,始终选择下一个最可能的单词,这对于事实和准确性非常重要的答案是非常有用的。为 1 时生成文本会选择更多的单词,会产生更具创意但不可能预测的答案。
  • top_p: 核心采样决定了生成时要考虑多少可能的单词。高 top_p 值意味着模型会考虑更多可能的单词,甚至是可能性较低的单词,从而使生成的文本更加多样化。

较低的 temperature 和较高的 top_p,可以产生具有创意的连贯文字。由于 temperature 较低,答案通常具有逻辑性和连贯性,但由于 top_p 较高,答案仍然具有丰富的词汇和观点。比较适合生成信息类文本,内容清晰且能吸引读者。

4. 获取 RAG 检索内容并分块

使用 BeautifulSoup 解析网页内容,按照标签、类名、ID 等方式来定位和提取需要的内容。

import bs4
from langchain_community.document_loaders import WebBaseLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

loader = WebBaseLoader(
    web_paths=("https://vuejs.org/guide/introduction.html#html",),
    bs_kwargs=dict(
        parse_only=bs4.SoupStrainer(
            class_=("content",),
        )
    ),
)
docs = loader.load()

# chunk_overlap:分块的重叠部分
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)

参数说明:

  • chunk_overlap: 分块的重叠部分,重叠有助于降低将语句与与其相关的重要上下文分开的可能性。
  • chunk_size: 分块的大小,合理的分词设置会提高 RAG 的效果。
5. 向量化存储

内容基于本地的词嵌入模型 nomic-embed-text 嵌入向量数据库中。

from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import OllamaEmbeddings

vectorstore = Chroma.from_documents(
    documents=splits,
    embedding=OllamaEmbeddings(model="nomic-embed-text")
)

此处的嵌入模型也可以使用其他的比如 llama3、mistral,但是在本地运行太慢了,它们和 nomic-embed-text 一样不支持中文的词嵌入。如果想试试建立一个中文的文档库,可以试试 herald/dmeta-embedding-zh 词嵌入的模型,支持中文。

ollama pull herald/dmeta-embedding-zh:latest
6. 设置 Prompt 规范输出
from langchain_core.prompts import PromptTemplate

prompt = PromptTemplate(
    input_variables=['context', 'question'],
    template=
    """You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the 
    question. you don't know the answer, just say you don't know 
    without any explanation Question: {question} Context: {context} Answer:""",
)
7. 实现检索问答

基于 langchain 实现检索问答。

from langchain.chains import RetrievalQA

retriever = vectorstore.as_retriever()

qa_chain = RetrievalQA.from_chain_type(
    llm,
    retriever=retriever,
    chain_type_kwargs={"prompt": prompt}
)

question = "what is vue?"
result = qa_chain.invoke({"query": question})
print(result["result"])

如果问的问题与文档无关,它的回答会怎样呢?

question = "what is react?"
result = qa_chain.invoke({"query": question})
print(result["result"])

最终执行后输出了 I don't know.。

构建用户界面

Gradio 是一个用于构建交互式机器学习界面的 Python 库。Gradio 使用非常简单。你只需要定义一个有输入和输出的函数,然后 Gradio 将自动为你生成一个界面。用户可以在界面中输入数据,然后观察模型的输出结果。

整合上述代码,构建可交互的 UI:

import gradio as gr
from langchain_community.llms import Ollama
from langchain.callbacks.manager import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
from langchain_community.document_loaders import WebBaseLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import OllamaEmbeddings
from langchain.chains import RetrievalQA
from langchain_core.prompts import PromptTemplate

def init_ollama_llm(model, temperature, top_p):
    return Ollama(
        model=model,
        temperature=temperature,
        top_p=top_p,
        callback_manager=CallbackManager([StreamingStdOutCallbackHandler()])
    )

def content_web(url):
    loader = WebBaseLoader(web_paths=(url,))
    docs = loader.load()
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
    splits = text_splitter.split_documents(docs)
    return splits

def chroma_retriever_store_content(splits):
    vectorstore = Chroma.from_documents(
        documents=splits,
        embedding=OllamaEmbeddings(model="nomic-embed-text")
    )
    return vectorstore.as_retriever()

def rag_prompt():
    return PromptTemplate(
        input_variables=['context', 'question'],
        template=
        """You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the 
        question. you don't know the answer, just say you don't know 
        without any explanation Question: {question} Context: {context} Answer:""",
    )

def ollama_rag_chroma_web_content(web_url, question, temperature, top_p):
    llm = init_ollama_llm('llama3', temperature, top_p)
    splits = content_web(web_url)
    retriever = chroma_retriever_store_content(splits)
    qa_chain = RetrievalQA.from_chain_type(llm, retriever=retriever, chain_type_kwargs={"prompt": rag_prompt()})
    return qa_chain.invoke({"query": question})["result"]

demo = gr.Interface(
    fn=ollama_rag_chroma_web_content,
    inputs=[
        gr.Textbox(label="web_url", value="https://vuejs.org/guide/introduction.html", info="爬取内容的网页地址"),
        "text",
        gr.Slider(0, 1, step=0.1),
        gr.Slider(0, 1, step=0.1)
    ],
    outputs="text",
    title="Ollama+RAG Example",
    description="输入网页的 URL,然后提问,获取答案"
)

demo.launch()

运行后会输出网页地址 Running on local URL: http://127.0.0.1:7860,打开后即可进行交互。

常见问题与优化建议

在实际部署过程中,可能会遇到以下问题及优化方案:

  1. 显存不足:本地运行大模型对 GPU 显存有一定要求。如果显存不足,可以尝试使用量化版本的小模型(如 llama3:8b-instruct-q4_0),或者减少 chunk_size 以降低内存占用。
  2. 检索效果不佳:如果检索到的上下文不相关,可以尝试调整 chunk_overlap 的值,增加重叠部分以保留更多上下文信息;也可以尝试不同的嵌入模型,如 bge-m3 等性能更好的开源模型。
  3. 响应速度慢:本地推理速度受硬件限制。可以通过预加载模型到内存中减少启动延迟,或者使用更快的 CPU 指令集优化推理过程。
  4. 中文支持:默认英文模型对中文理解有限。务必使用支持中文的嵌入模型(如 dmeta-embedding-zh)和适合中文语境的 LLM,并在 Prompt 中明确指示使用中文回答。

通过以上步骤,即可完成一个功能完备的本地 RAG 问答系统。

目录

  1. 概念介绍
  2. 开始搭建
  3. 1. 环境准备
  4. LLM
  5. Embedding Model
  6. 2. 安装依赖
  7. 3. 初始化 LangChain 对象
  8. 1. 初始化 llm, 让其流式输出
  9. 4. 获取 RAG 检索内容并分块
  10. chunk_overlap:分块的重叠部分
  11. 5. 向量化存储
  12. 6. 设置 Prompt 规范输出
  13. 7. 实现检索问答
  14. 构建用户界面
  15. 常见问题与优化建议

更多推荐文章

查看全部
  • 5 款免费跨平台 SSH 工具横评:连接稳定性与功能对比
  • Python Selenium 浏览器自动化入门与实战
  • 前端面试深度解析:核心概念与代码实践
  • FPGA 侧 XDMA 接口时序约束与收敛实践
  • Claude Code 进阶指南:配置 Everything 插件打造有记忆的 AI 助手
  • 前端面试题 JavaScript 核心知识点详解
  • gRPC 同步 Server 与 Client 编写示例
  • CRITIC 模型与 AI 助手:程序员认知架构重构实战
  • Linux 进程与线程的区别与联系:定义、资源与调度
  • Python 中使用 HTML 模板的完整指南
  • OpenClaw 开源 AI 助手平台架构与部署指南
  • Python 输入 input 函数及字符串处理:大小写与 strip()
  • Dify 工作流发布为 MCP Server 实战指南
  • Linux 进程间通信进阶:管道与共享内存详解
  • ToDesk 顺网云海马云部署 DeepSeek 大模型对比评测
  • 深度学习模型优化策略与实战调参
  • 基于 AI 大模型的培训题库自动生成方案与实践
  • C++ 多态详解:虚函数机制与底层原理实现
  • C++11 左值右值引用区别与移动语义解决传值返回对象销毁问题
  • 网络安全入门:黑客技术体系与自学路径解析

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online