Python使用Ollama实现私有大模型知识库

 更新时间:2025年04月01日 16:38:42   作者:一笑  
这篇文章主要介绍了Python使用Ollama实现私有大模型知识库,在不依赖LangChain、LlamaIndex等框架的前提下,尽量减少第三方库的使用,仅通过Ollama和NumPy两个外部库来实现RAG,需要的朋友可以参考下

在不依赖 LangChain、LlamaIndex 等框架,以及各种知识问答软件的情况下,尽量减少第三方库的使用,仅通过 Ollama 和 NumPy 两个外部库来实现 RAG(Retrieval-Augmented Generation)应用。

一、安装python

下载:https://python.org/downloads/

安装:一路下一步即可,安装完成后运行以下代码,即可查看对应版本号

python --version

二、安装PyCharm

(推荐,也可以用vscode或windows记事本等编辑软件)

PyCharm的优点:

  • 自动提示
  • 创建项目时自动创建python虚拟环境
  • 整合本地终端(且基于python对应本项目的虚拟环境)

三、安装ollama

下载:https://ollama.com/download

安装:一路下一步。安装完成后用以下命令检验

ollama --version

四、在ollama中安装开源chat大模型

在ollama中安装开源chat大模型:qwen2.5 或deepseek-r1

ollama官网models(https://ollama.com/search)页面可以找到很多开源大模型,我们下载用的比较多的千问中文大模型(显卡差的建议安装ollama2.5:0.5b)

ollama run qwen2.5

五、在ollama中安装开源embedding大模型

在ollama中安装开源embedding大模型:milkey/m3e nomic-embed-text

embedding作用是将问题和知识库文本转换成向量,便于查询。

原本打算使用nomic-embed-text模型,但是使用时效果不好,发现m3e的效果不错,所以改用m3e

ollama run milkey/m3e

六、在项目python虚拟环境中安装ollama

pip install ollama

七、安装numpy

pip install numpy

八、编写代码

项目文件目录结构如下图

1. kb.py

import numpy as np
from ollama import embeddings
class Kb:
    def __init__(self, filepath):
        # 读取文件内容
        content = self.read_file(filepath)
        # print(content)
        # 读取拆分好的数组
        self.chunks = self.split_content(content)
        # print(chunks)
        # for chunk in chunks:
        #     print(chunk)
        #     print('=' * 10)
        # 转换成向量
        self.embeds = self.get_embeddings(self.chunks)
    # 读取文件
    def read_file(self, filepath):
        with open(filepath, 'r', encoding='utf-8') as f:
            content = f.read()
        return content
    # 拆分知识库
    @staticmethod
    def split_content(content):
        chunks = content.split('# ')
        # 过滤掉空块
        chunks = [chunk.strip() for chunk in chunks if chunk.strip()]
        return chunks
    # 字符串转向量(embeddings)
    def get_embedding(self, chunk):
        # milkey/m3e    0.642084887746903
        # bge-m3    0.6073383067378445
        # nomic-embed-text  完全找不到
        res = embeddings(model='milkey/m3e', prompt=chunk)
        # print(chunk)
        # print(res)
        # print(res['embedding'])
        return res['embedding']
    def get_embeddings(self, chunks):
        embeds = []
        for chunk in chunks:
            embed = self.get_embedding(chunk)
            embeds.append(embed)
        return np.array(embeds)
    # 查询相似性向量
    def search(self, text):
        print(text)
        max_similarity = 0
        max_similarity_index = 0
        ask_embed = self.get_embedding(text)
        for kb_embed_index, kb_embed in enumerate(self.embeds):
            similarity = self.similarity(kb_embed, ask_embed)
            # print(similarity)
            # print(self.chunks[kb_embed_index])
            if similarity > max_similarity:
                max_similarity = similarity
                max_similarity_index = kb_embed_index
        print(max_similarity)
        print(self.chunks[max_similarity_index])
        # print(self.embeds[max_similarity_index])
        # 返回查到的相关文本
        return self.chunks[max_similarity_index]
    # 相似度
    @staticmethod
    def similarity(A, B):
        # 计算点积
        dot_product = np.dot(A, B)
        # 计算范数
        norm_A = np.linalg.norm(A)
        norm_B = np.linalg.norm(B)
        # 计算余弦相似度
        cosine_sim = dot_product / (norm_A * norm_B)
        return cosine_sim

2. rag.py

from kb import Kb
from ollama import chat, Message
class Rag:
    def __init__(self, model, kb_filepath):
        self.kb_filepath = kb_filepath
        self.kb = Kb(kb_filepath)
        self.model = model
        self.prompt_template = """
        基于:%s
        回答:%s
        """
    def chat(self, message):
        # 用户消息检索相关上下文
        context = self.kb.search(message)
        # print(context)
        # prompt = self.prompt_template % (context, message)
        prompt = '请基于以下内容回答问题:\n' + context
        response = chat(self.model, [Message(role='system', content=prompt), Message(role='user', content=message)])
        return response['message']

3. index.py

from rag import Rag
rag = Rag('deepseek-r1:14b', '私人知识库.txt')
msg = rag.chat('请介绍下刘芳')
print(msg)

4. 私人知识库.txt

MIS部门人员名单

# 1. 张小刚
姓名:张小刚
性别:男
爱好:打篮球、踢足球
电话:132233444
籍贯:山东菏泽

# 2. 李光亮
姓名:李光亮
性别:男
爱好:踢足球、打排球
电话:15959595
籍贯:河南平顶山

# 3. 王丽丽
姓名:王丽丽
性别:女
爱好:游泳、阅读
电话:138123456
籍贯:江苏南京

# 4. 陈大明
姓名:陈大明
性别:男
爱好:跑步、爬山
电话:139876543
籍贯:浙江杭州

# 5. 刘芳
姓名:刘芳
性别:女
爱好:瑜伽、绘画
电话:137112233
籍贯:广东深圳

# 6. 赵强
姓名:赵强
性别:男
爱好:打羽毛球、钓鱼
电话:135665544
籍贯:四川成都

# 7. 孙婷婷
姓名:孙婷婷
性别:女
爱好:跳舞、唱歌
电话:136778899
籍贯:福建厦门

# 8. 周伟
姓名:周伟
性别:男
爱好:打乒乓球、下棋
电话:134556677
籍贯:湖南长沙

# 9. 吴晓梅
姓名:吴晓梅
性别:女
爱好:摄影、旅行
电话:133445566
籍贯:湖北武汉

# 10. 郑小龙
姓名:郑小龙
性别:男
爱好:打篮球、游泳
电话:132334455
籍贯:陕西西安

# 11. 高静
姓名:高静
性别:女
爱好:阅读、写作
电话:131223344
籍贯:辽宁沈阳

# 12. 林浩
姓名:林浩
性别:男
爱好:踢足球、跑步
电话:130112233
籍贯:广西南宁

# 13. 黄雅婷
姓名:黄雅婷
性别:女
爱好:跳舞、瑜伽
电话:139001122
籍贯:云南昆明

# 14. 徐志强
姓名:徐志强
性别:男
爱好:打排球、爬山
电话:138990011
籍贯:贵州贵阳

# 15. 何丽
姓名:何丽
性别:女
爱好:绘画、摄影
电话:137889900
籍贯:江西南昌

# 16. 马超
姓名:马超
性别:男
爱好:打篮球、钓鱼
电话:136778899
籍贯:山西太原

# 17. 郭晓燕
姓名:郭晓燕
性别:女
爱好:唱歌、旅行
电话:135667788
籍贯:河北石家庄

# 18. 罗志勇
姓名:罗志勇
性别:男
爱好:踢足球、下棋
电话:134556677
籍贯:吉林长春

# 19. 邓丽丽
姓名:邓丽丽
性别:女
爱好:瑜伽、阅读
电话:133445566
籍贯:黑龙江哈尔滨

# 20. 许文强
姓名:许文强
性别:男
爱好:打羽毛球、跑步
电话:132334455
籍贯:安徽合肥

# 21. 韩雪
姓名:韩雪
性别:女
爱好:跳舞、摄影
电话:131223344
籍贯:甘肃兰州

# 22. 曹阳
姓名:曹阳
性别:男
爱好:打篮球、爬山
电话:130112233
籍贯:青海西宁

# 23. 谢婷婷
姓名:谢婷婷
性别:女
爱好:唱歌、绘画
电话:139001122
籍贯:宁夏银川

# 24. 董志刚
姓名:董志刚
性别:男
爱好:踢足球、钓鱼
电话:138990011
籍贯:新疆乌鲁木齐

# 25. 苏静
姓名:苏静
性别:女
爱好:阅读、旅行
电话:137889900
籍贯:内蒙古呼和浩特

# 26. 潘伟
姓名:潘伟
性别:男
爱好:打乒乓球、下棋
电话:136778899
籍贯:海南海口

# 27. 钟丽
姓名:钟丽
性别:女
爱好:瑜伽、摄影
电话:135667788
籍贯:重庆

# 28. 田小龙
姓名:田小龙
性别:男
爱好:打篮球、游泳
电话:134556677
籍贯:天津

# 29. 白晓梅
姓名:白晓梅
性别:女
爱好:跳舞、唱歌
电话:133445566
籍贯:北京

# 30. 石浩
姓名:石浩
性别:男
爱好:踢足球、跑步
电话:132334455
籍贯:上海

通过以上代码,可基本实现用RAG技术,搭建本地知识库问答AI助理,非流式回复(steam=False)。需要等待大模型输出所有文字之后,才能全部返回,太慢,肯定要实现一般聊天大模型的流式回复(steam=True)

首先,在rag.py中增加以下方法

    def stream_chat(self, message):
        context = self.kb.search(message)
        prompt = '请基于以下内容回答问题:\n' + context
        response = chat(self.model, [Message(role='system', content=prompt), Message(role='user', content=message)], stream=True)
        # 遍历流式响应
        for chunk in response:
            print(chunk['message']['content'], end='', flush=True)  # 实时打印输出
        print()  # 输出完成后换行

然后,调整index.py代码为

from rag import Rag
rag = Rag('deepseek-r1:14b', '私人知识库.txt')
rag.stream_chat('请介绍下刘芳')

经过以上的修改,就可以看到AI的流式答复了。

注:以上RAG只是获取到了本地知识库中的最为匹配的一条记录,如果需要实现一次性获取多个关联内容,并根据多个关联内容进行答复,需要使用向量数据库。

以上就是Python使用Ollama实现私有大模型知识库的详细内容,更多关于Python Ollama实现知识库的资料请关注脚本之家其它相关文章!

相关文章

  • Python基于OpenCV实现人脸检测并保存

    Python基于OpenCV实现人脸检测并保存

    这篇文章主要介绍了Python基于OpenCV实现人脸检测并保存,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • Python中配置文件的全面解析与使用

    Python中配置文件的全面解析与使用

    在Python开发中,配置文件扮演着举足轻重的角色,它们允许开发者在不修改代码的情况下调整应用程序的行为,下面我们就来看看常见Python配置文件格式的使用吧
    2025-03-03
  • 使用Python NumPy库绘制渐变图案

    使用Python NumPy库绘制渐变图案

    NumPy(Numerical Python)是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵。但其实NumPy还可以绘制图画,本文将为大家介绍如何通过NumPy绘制彩色图画,感兴趣的小伙伴可以了解一下
    2021-12-12
  • Python 将json序列化后的字符串转换成字典(推荐)

    Python 将json序列化后的字符串转换成字典(推荐)

    这篇文章主要介绍了Python 将json序列化后的字符串转换成字典,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • python语言time库和datetime库基本使用详解

    python语言time库和datetime库基本使用详解

    这篇文章主要介绍了python语言time库和datetime库基本使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Windows 8.1 64bit下搭建 Scrapy 0.22 环境

    Windows 8.1 64bit下搭建 Scrapy 0.22 环境

    这篇文章主要介绍了Windows 8.1 64bit下搭建 Scrapy 0.22 环境,需要的朋友可以参考下
    2018-11-11
  • Python数学建模学习模拟退火算法旅行商问题示例解析

    Python数学建模学习模拟退火算法旅行商问题示例解析

    模拟退火算法不仅可以解决连续函数优化问题,KIRKPATRICK在1983年成功将其应用于求解组合优化问题,现已成为求解旅行商问题的常用方法,通常采用反序、移位和交换等操作算子产生新解
    2021-10-10
  • 如何理解python接口自动化之logging日志模块

    如何理解python接口自动化之logging日志模块

    代码需要经历开发、调试、审查、测试或者上线等不同阶段,在“测试”时,可能只想看警告和错误信息,然而在“调试”时,可能还想看到跟调试相关的信息。如果想打印出使用的模块以及代码运行的时间,那么代码很容易变得混乱。使用logging日志模块,就能很容易地解决
    2021-06-06
  • jupyter notebook读取/导出文件/图片实例

    jupyter notebook读取/导出文件/图片实例

    这篇文章主要介绍了jupyter notebook读取/导出文件/图片实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • python实现聚类算法原理

    python实现聚类算法原理

    这篇文章主要为大家详细介绍了python实现聚类算法原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02

最新评论