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

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

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

花里胡哨发布于 2025/2/6更新于 2026/7/2439 浏览
基于 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=, 
    callback_manager=CallbackManager([StreamingStdOutCallbackHandler()])
)
0.4

参数说明:

  • 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. 常见问题与优化建议
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Protege 与 Neo4j 构建教育领域知识图谱及可视化实战
  • Git for Windows 安装与配置详解
  • 字节 Seedance 2.0 评测与多渠道使用指南
  • 使用自定义数据集微调 Stable Diffusion 3.5 LoRA 文生图模型
  • Python 爬虫实战:抓取图书馆图书信息与借阅评分
  • VsCode 集成 Claude Agent 报无效请求?参数配置与网络排查指南
  • AI 上下文优化实战:解决过载与不足的平衡之道
  • RAG 技术应对大模型敏感问题的知识幻觉难题
  • YOLOv8 目标追踪实战:卡尔曼滤波数学原理与 Python 实现
  • OpenClaw Web 控制台使用全解析:可视化配置与监控
  • Windows 系统安装 MySQL 5.7.44 图文教程
  • Stable Diffusion v1.5 部署指南:GPU 加速与 Web 服务启动
  • 基于 Trae 与 CMake 构建 AI 辅助的 Qt 开发环境
  • 力扣 Hot100 链表专题:反转与排序链表 (Python 版)
  • 并发限流的常见实现方案与架构实践
  • 有向无环图(DAG)介绍:环检测、DFS 法与 Kahn 算法
  • AI生成产品视频一键搞定!2026电商爆款视频秘籍
  • LVGL 嵌入式 GUI 开发指南:轻量高效开源方案
  • LIBERO:终身机器人学习数据集与基准测试平台简介
  • Java 获取 100 以内所有奇数的三种实现方式

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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