使用langchain ollama gradio搭建一个本地基于deepseek r1的RAG问答系统

目录

简介

环境配置

具体实现

安装依赖

定义模型和prompt

加载检索文档

切割

向量存储

创建检索器

实例化

前端搭建

实现效果

小tips


简介

首先介绍一下使用的几个工具,模型和rag的步骤,注:这里只是简单描述一下,不展开讲解。

langchain是一个开源的大语言模型开发框架,其可以帮助开发人员轻松构建基于语言模型的应用。

ollama也是一个开源框架,其是专为在本地机器上方便部署和运行大语言模型而设计。

gradio是一个用于创建模型交互的python库,其可以快速地为模型构建一个可视化的、易于使用的Web界面。

deepseek r1是一个具体的模型,其以超低的训练成本,高超的推理能力,在近期瞬间火爆各大平台以及海内外。(这里不详细介绍模型以及训练方法)

RAG(检索增强生成):

RAG是一个参数附加微调技术,其应用在大语言模型完成训练后,在prompt中增加文本内容以使得大预言模型可以根据增加的文本做出合适的回答(就好比上考场做英语阅读理解)。

RAG可以有效的增加模型的性能,降低模型的幻觉,同时其也可以避免大模型信息过时,数据隐私等问题。

RAG技术主要有四个步骤:

切片,embedding后存储到向量数据库,检索,召回。

切片是将一整个大的文档切分成几个小的片段,其称为chunk。

embedding是词嵌入的意思,文本片段不能直接存储在计算机中,所以会将其向量化,其就是用一组向量数字来表示这一个片段,相似的片段在向量化后会更相近。经过embedding化后,我们就可以将所有的向量数字存储到向量数据库中。

检索是将用户提问的问题也经过embedding,然后和向量数据库中的其他数字向量计算距离,距离越近就证明这个片段和我们提问的问题越相近,大模型可以在这些片段中找到答案。

召回是在向量数据库中找到与问题最相近的片段后,将片段取出,和问题拼接成一个prompt喂给大模型。

环境配置

首先需要下载ollama,ollama的安装直接到其官网download即可。

Ollama

安装完ollama后,打开cmd,可以输入ollama list查看模型。

 我这里已经安装了我们项目需要的两个模型,安装也非常简单,我们进到ollama的官网,然后将下载命令复制到cmd中点击运行即可。

nomic这个模型也这样下载即可,其中deepseek-r1为聊天模型,而nomic为embedding模型。

红框左侧也可以选择模型的尺寸,我这里选择使用的是7B的模型。若内存不够,可以选择小一点的模型。

具体实现

安装依赖

首先就是pip所需要的依赖包。

from langchain.embeddings import OllamaEmbeddings
from langchain.vectorstores import FAISS
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.llms import Ollama
from langchain.prompts import PromptTemplate
from langchain.chains import RetrievalQA
from langchain.docstore.document import Document
import gradio as gr

定义模型和prompt

# 定义embedding模型,对话模型和提示词
embedder = OllamaEmbeddings(model="nomic-embed-text:latest")
llm = Ollama(model="deepseek-r1:7b")
prompt_template = PromptTemplate(
    input_variables=["context", "question"],
    template="""
    请根据上下文内容回答问题,若根据上下文内容无法得到问题答案,请输出此问题在上下文中无法获得,不要思考其他知识给出回答:
    上下文:{context}
    问题:{question}
    回答:
    """
)

这里就是用langchain框架加载我们使用ollama下载的两个模型,以及定义一个提示词模板后期供我们使用。

加载检索文档

# 加载检索文档
with open('content.txt', 'r', encoding='utf-8') as file:
    content = file.read()
document = Document(page_content=content)

这里是加载具体的供检索文档,具体以txt格式,也可以加载pdf,doc格式的文档,这里不做展开讲解,我加载的具体文档内容为斗罗大陆里面最开始的一个片段,后续会看到。

切割

# 将文档分割成chunk
splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=20)
split_docs = splitter.split_documents([document])

由于一整个文本不一定所有的内容都与我们的问题相关,所以这里需要将文本切割成片段。

chunk_size这个参数指定了每个文本块的大小。

chunk_overlap这个参数定义了相邻文本块之间的重叠程度。

向量存储

# 创建向量存储
vector_store = FAISS.from_documents(split_docs, embedder)

这一行代码就是将我们上面切割后的每个文本片段通过embedding向量化后存储到向量数据库。

创建检索器

# 创建检索器
retriever = vector_store.as_retriever(search_type="similarity", search_kwargs={"k": 3})

这里我们创建了一个检索器,用于根据我们所问的问题去向量数据库中寻找与问题最相近的文本片段。

实例化

# 创建QA实例
qa_chain = RetrievalQA.from_llm(
    llm=llm,
    retriever=retriever,
    prompt=prompt_template
)

最后一步就是将我们上述的模型,检索器和提示词工程用来创建一个基于检索的问答系统(QA System)实例。

前端搭建

def chat(message, history):
    result = qa_chain.run(message)
    print(result)
    result = result.split("</think>")[-1]
    return result


gr.ChatInterface(fn=chat, title="deepseek-r1").launch()

最后就是用gradio这个包起一个简单的Web交互界面。

实现效果

将上述所有的代码片段合并到一起就可以运行完整的RAG程序了,让我们一起来看看运行效果如何:

这里根据文档内容,问大模型唐门暗器和圣魂村,可以看到,它都按照文档的内容回答出来了。

我们在试几个文档中没有的内容:

 

 这里,我们询问大模型中国最高的山是什么山,可以看到,大模型根据我们给的文本并不能回答这个问题,由于我们的prompt中严格明确了,若通过文本找不到问题的答案,则输出无法获得问题答案,可见效果还是不错的。

小tips

1,本项目中将检索的文档写到python代码里面了,其是可以使用gradio从前端读入文档的。

2,最后的chat函数中,有一个print,我这里没有贴命令行的运行截图,大家可以看一下,在命令行中可以看到deepseek的思考过程,其会被两个</think>包住。

3,最后的输出那里,我加了个字符串的split操作,这是因为我发现如果直接return result的话,在前端界面中将没有输出,推测可能是</think>这个特殊字符搞的鬼,于是进行切分后就发现可以在前端正常显示了,由于本人并不是专门学Web的,路过的大佬看到也可以在评论区解释下,小编先提前感谢啦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/961924.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python中的函数(下)

函数返回值 返回单个值 函数可以通过 return 语句返回一个值。一旦执行到 return 语句&#xff0c;函数就会停止执行&#xff0c;并将指定的值返回给调用者。例如&#xff1a; 返回多个值 实际上&#xff0c;Python函数只能返回一个值&#xff0c;但可以通过返回一个元组来模…

Spring Boot + Facade Pattern : 通过统一接口简化多模块业务

文章目录 Pre概述在编程中&#xff0c;外观模式是如何工作的&#xff1f;外观设计模式 UML 类图外观类和子系统的关系优点案例外观模式在复杂业务中的应用实战运用1. 项目搭建与基础配置2. 构建子系统组件航班服务酒店服务旅游套餐服务 3. 创建外观类4. 在 Controller 中使用外…

安卓(android)实现注册界面【Android移动开发基础案例教程(第2版)黑马程序员】

一、实验目的&#xff08;如果代码有错漏&#xff0c;可查看源码&#xff09; 1.掌握LinearLayout、RelativeLayout、FrameLayout等布局的综合使用。 2.掌握ImageView、TextView、EditText、CheckBox、Button、RadioGroup、RadioButton、ListView、RecyclerView等控件在项目中的…

Prompt提示词完整案例:让chatGPT成为“书单推荐”的高手

大家好&#xff0c;我是老六哥&#xff0c;我正在共享使用AI提高工作效率的技巧。欢迎关注我&#xff0c;共同提高使用AI的技能&#xff0c;让AI成功你的个人助理。 许多人可能会跟老六哥一样&#xff0c;有过这样的体验&#xff1a;当我们遇到一个能力出众或对事物有独到见解的…

智慧园区管理平台实现智能整合提升企业运营模式与管理效率

内容概要 在当今数字化的背景下&#xff0c;智慧园区管理平台正逐渐成为企业提升运营效率和管理模式的重要工具。这个平台汇聚了多种先进技术&#xff0c;旨在通过智能整合各类资源与信息&#xff0c;帮助企业实现全面的管理创新。 智慧园区管理平台不仅仅是一个数据处理工具…

Baklib如何提升企业知识管理效率与市场竞争力的五大对比分析

内容概要 在信息化时代&#xff0c;企业在知识管理方面面临着巨大的挑战与机遇。为了有效应对这些挑战&#xff0c;“Baklib”作为一个知识中台&#xff0c;通过其高度集成的数字化平台&#xff0c;为企业提供全方位的知识管理解决方案。特别是在以下五个领域&#xff0c;它展…

c++:vector

1.使用 1.1构造函数 常见的三种构造方式&#xff1a;空构造&#xff0c;拷贝构造&#xff0c;指定元素构造 1.2iterator begin和end也分为正向和反向。 注意&#xff1a;反向迭代器可以反向遍历是因为在定义rbegin和rend函数的时候把尾地址给到了rbegin&#xff0c;而不是说改…

C++17 搜索器教程:解锁高效搜索新姿势

C17搜索器教程&#xff1a;解锁高效搜索新姿势 C17搜索器简介 在C的发展历程中&#xff0c;C17是一个重要的里程碑&#xff0c;它引入了诸多实用的新特性&#xff0c;搜索器功能便是其中之一。此功能着重对std::search算法进行了强化&#xff0c;使其支持多种搜索策略&#x…

Transformer+vit原理分析

目录 一、Transformer的核心思想 1. 自注意力机制&#xff08;Self-Attention&#xff09; 2. 多头注意力&#xff08;Multi-Head Attention&#xff09; 二、Transformer的架构 1. 整体结构 2. 编码器层&#xff08;Encoder Layer&#xff09; 3. 解码器层&#xff08;Decoder…

C语言自定义数据类型详解(二)——结构体类型(下)

书接上回&#xff0c;前面我们已经给大家介绍了如何去声明和创建一个结构体&#xff0c;如何初始化结构体变量等这些关于结构体的基础知识。下面我们将继续给大家介绍和结构体有关的知识&#xff1a; 今天的主题是&#xff1a;结构体大小的计算并简单了解一下位段的相关知识。…

【ComfyUI专栏】如何使用Git命令行安装非Manager收录节点

当前的ComfyUI的收录的自定义节点很多&#xff0c;但是有些节点属于新出来&#xff0c;或者他的应用没有那么广泛&#xff0c;Manager管理节点 有可能没有收录到&#xff0c;这时候 如果我们需要安装需要怎么办呢&#xff1f;这就涉及到我们自己安装这些节点了。例如下面的内容…

【Block总结】PKI 模块,无膨胀多尺度卷积,增强特征提取的能力|即插即用

论文信息 标题: Poly Kernel Inception Network for Remote Sensing Detection 作者: Xinhao Cai, Qiuxia Lai, Yuwei Wang, Wenguan Wang, Zeren Sun, Yazhou Yao 论文链接&#xff1a;https://arxiv.org/pdf/2403.06258 代码链接&#xff1a;https://github.com/NUST-Mac…

[OO ALV] OO ALV 基础显示

程序代码 REPORT z437_test_2025.DATA gt_spfli TYPE STANDARD TABLE OF spfli. " 内表DATA go_alv TYPE REF TO cl_gui_alv_grid. " 创建和管理ALV表格DATA gs_layout TYPE lvc_s_layo. " 存储ALV表格的布局信息*---------------------…

jQuery小游戏(二)

jQuery小游戏&#xff08;二&#xff09; 今天是新年的第二天&#xff0c;本人在这里祝大家&#xff0c;新年快乐&#xff0c;万事胜意&#x1f495; 紧接jQuery小游戏&#xff08;一&#xff09;的内容&#xff0c;我们开始继续往下咯&#x1f61c; 游戏中使用到的方法 key…

Linux的常用指令的用法

目录 Linux下基本指令 whoami ls指令&#xff1a; 文件&#xff1a; touch clear pwd cd mkdir rmdir指令 && rm 指令 man指令 cp mv cat more less head tail 管道和重定向 1. 重定向&#xff08;Redirection&#xff09; 2. 管道&#xff08;Pipes&a…

蓝桥杯之c++入门(一)【C++入门】

目录 前言5. 算术操作符5.1 算术操作符5.2 浮点数的除法5.3 负数取模5.4 数值溢出5.5 练习练习1&#xff1a;计算 ( a b ) ⋆ c (ab)^{\star}c (ab)⋆c练习2&#xff1a;带余除法练习3&#xff1a;整数个位练习4&#xff1a;整数十位练习5&#xff1a;时间转换练习6&#xff…

51单片机开发:定时器中断

目标&#xff1a;利用定时器中断&#xff0c;每隔1s开启/熄灭LED1灯。 外部中断结构图如下图所示&#xff0c;要使用定时器中断T0&#xff0c;须开启TE0、ET0。&#xff1a; 系统中断号如下图所示&#xff1a;定时器0的中断号为1。 定时器0的工作方式1原理图如下图所示&#x…

【设计测试用例自动化测试性能测试 实战篇】

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a; c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 设计测试用例…

指针(C语言)从0到1掌握指针,为后续学习c++打下基础

目录 一&#xff0c;指针 二&#xff0c;内存地址和指针 1&#xff0c;什么是内存地址 2&#xff0c;指针在不同系统下所占内存 三&#xff0c;指针的声明和初始化以及类型 1,指针的声明 2,指针 的初始化 1&#xff0c; 初始化方式优点及适用场景 4,指针的声明初始化类型…

利用Redis实现数据缓存

目录 1 为啥要缓存捏&#xff1f; 2 基本流程&#xff08;以查询商铺信息为例&#xff09; 3 实现数据库与缓存双写一致 3.1 内存淘汰 3.2 超时剔除&#xff08;半自动&#xff09; 3.3 主动更新&#xff08;手动&#xff09; 3.3.1 双写方案 3.3.2 读写穿透方案 3.3.…