使用golang 基于 OpenAI Embedding + qdrant 实现k8s本地知识库

news2024/12/27 12:05:42

使用golang 基于 OpenAI Embedding + qdrant 实现k8s本地知识库

文章博客地址:套路猿-使用golang 基于 OpenAI Embedding + qdrant 实现k8s本地知识库

流程

  1. 将数据集 通过 openai embedding 得到向量+组装payload,存入 qdrant
  2. 用户进行问题搜索,通过 openai embedding 得到向量,从 qdrant 中搜索相似度大于0.8的数据
  3. 从 qdrant 中取出相似度高的数据
  4. 将获取到的QA,组装成 prompt 向chatgpt进行提问,得到回答

向量数据库 qdrant

  • qdrant 是一个开源的向量搜索引擎,支持多种向量距离计算方式
  • 官方文档:https://qdrant.tech/documentation/quick_start/
  • 本节 介绍 qdrant 都是基于官方文档的例子,如已熟悉可以直接阅读下一节 [数据导入k8s知识库]

安装 qdrant

docker 安装

docker pull qdrant/qdrant && \
docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant

collection 说明

collection 是 qdrant 中的一个概念,类似于 mysql 中的 database,用于区分不同的数据集合
官方文档:https://qdrant.tech/documentation/collections/#collections
collection 下面是 collection 字段说明,以创建 collection 为例

PUT /collections/{collection_name}
{
    "name": "example_collection",
    "vectors": {
      "size": 300,
      "distance": "Cosine"
    }
}

name: collection 名称
vectors: 向量的配置
size: 向量的维度
distance: 向量的距离计算方式,Cosine(余弦距离), Euclidean(欧式距离),Dot product(点积)
如果需要将 openai embedding 后 存入 qdrant,需要将 size 设置为 1536openai embedding

插入数据

这个是官网 http add point 的例子,可以看到 payload 是可以存储任意的 json 数据,这个数据可以用于后续的过滤

curl -L -X PUT 'http://localhost:6333/collections/test_collection/points?wait=true' \
    -H 'Content-Type: application/json' \
    --data-raw '{
        "points": [
          {"id": 1, "vector": [0.05, 0.61, 0.76, 0.74], "payload": {"city": "Berlin" }},
          {"id": 2, "vector": [0.19, 0.81, 0.75, 0.11], "payload": {"city": ["Berlin", "London"] }},
          {"id": 3, "vector": [0.36, 0.55, 0.47, 0.94], "payload": {"city": ["Berlin", "Moscow"] }},
          {"id": 4, "vector": [0.18, 0.01, 0.85, 0.80], "payload": {"city": ["London", "Moscow"] }},
          {"id": 5, "vector": [0.24, 0.18, 0.22, 0.44], "payload": {"count": [0] }},
          {"id": 6, "vector": [0.35, 0.08, 0.11, 0.44]}
        ]
    }'
  • id:唯一
  • vector:向量,可在HuggingFace 找相应的模型训练,获取,也可以 openai embedding 得到
  • payload:任意的自定义 json 数据

搜索数据

这是 qdrant 官方搜索数据的例子

curl -L -X POST 'http://localhost:6333/collections/test_collection/points/search' \
    -H 'Content-Type: application/json' \
    --data-raw '{
        "vector": [0.2,0.1,0.9,0.7],
        "limit": 3
    }'

vector:向量,通过 openai embedding 得到
limit:返回的数据条数

数据导入k8s知识库

// 模拟数据集 question:answer
var questions = []string{
	"什么是Kubernetes中的Deployment?",
	"Kubernetes中的Service有什么作用?",
}

var answers = []string{
	"Deployment是Kubernetes中用于管理应用程序副本的资源对象。它提供了副本的声明性定义,可以实现应用程序的部署、扩展和更新。",
	"Service用于定义一组Pod的访问方式和网络策略。它为Pod提供了一个稳定的网络地址,并可以实现负载均衡、服务发现和内部通信。",
}

func main() {
// 第一步:自己创建 一个collection:  kubernetes
	var err error
	err = qdrant.Collection("kubernetes").Create(1536)
	if err != nil {
		log.Fatalln("创建collection出错:", err.Error())
	}

	points := []*pb.PointStruct{}
	// 批量 进行BuildQdrantPoint
	for index, question := range questions {
		if index < 9 {
			continue
		}
		p, err := BuildQdrantPoint(question, answers[index])
		if err != nil {
			log.Fatalln("创建point出错:", err.Error())
		}
		fmt.Println(p.Id)
		points = append(points, p)

	}
	err = qdrant.FastQdrantClient.CreatePoints("kubernetes", points)
	if err != nil {
		log.Fatalln("批量创建point出错:", err.Error())
	}
}
  • 模拟数据集,将数据集导入到 k8s 知识数据库中
  • BuildQdrantPoint 函数是将问题和答案转换成 qdrant 的 point
  • 其中 vector 是通过 openai embedding 得到的,这里使用的是 openai embedding

搜索数据

代码实现

import (
	"fmt"

	myai "embedding-knowledge-base/ai"
	"embedding-knowledge-base/qdrant"
)

func main() {
	prompt := "什么是Kubernetes中的DaemonSet?"
	// prompt := "苹果不削皮能吃吗"
	p_vec, err := myai.SimpleGetVec(prompt)
	if err != nil {
		panic(err)
	}
	points, err := qdrant.FastQdrantClient.Search("kubernetes", p_vec)
	if err != nil {
		panic(err)
	}

	fmt.Printf("用户的问题是:%s\n", prompt)
	if points[0].Score < 0.8 {
		fmt.Println("违规问题或者超纲问题")
		return
	}
	answer := points[0].Payload["answers"].GetStringValue()
	fmt.Printf("知识库答案是:%s\n", answer)
	tmpl := "question: %s\n" + "reference answer: %s\n"
	finalPrompt := fmt.Sprintf(tmpl, prompt, points[0].Payload["question"].GetStringValue(), answer)
	fmt.Println("------------------------")
	fmt.Printf("结合知识库参考答案:chatgpt的回答是:%s\n", myai.K8sChat(finalPrompt))
	// 不结合知识库参考答案
	fmt.Printf("不依赖本地知识库, chatgpt的直接回答是:%s\n", myai.K8sChat(prompt))
}
  • 通过 prompt 搜索qdrant 知识库,如果相似度小于 0.8,有可能是用户乱提问,或问知识库无关的问题,直接返回
  • 取相似度度大于 0.8,则取第一条数据,组装成promot向gpt进行提问,得到回答
  • 具体的实现可以参考 main.go 的代码

示例

  1. 问无关的问题,比如:苹果不削皮能吃吗

    可以看到 相似度太低,提示违规问题或者超纲问题
  2. 问k8s 本地知识库的问题,比如:什么是Kubernetes中的Deployment?
  3. 问k8s本地知识库的问题,但单独向chatgpt提问,得到的答案 并不是已定与k8s相关,比如问 网关是什么
  • 可以看到,红线部分,是直接将用户问题 向 chatgpt 请求 得到的答案,跟k8s无关
  • 红线前面的回答:是正确的,结合k8s本地知识库,可以让回答偏向 数据集设定的主题

示例源码地址及使用

源码地址:embedding-knowledge-base
进入根目录,将目录 ai/common.go 的 以下 const改成自己的

    SocksProxy = "socks5://127.0.0.1:1080"
	AIKey      = "your api key"

docker 安装 qdrant

make install-qdrant

数据集导入qdrant

  • 导入 adrant,我这边就是模拟 了十几条k8s相关的问题,在 prebuild/prebuild.go
  • 更多的数据集,需要自己用脚本抓取,然后导入qdrant
make import-qdrant

搜索

make search

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“Jmeter WebSocket协议压测”,助你轻松应对高并发场景!

目录 引言 背景说明 步骤1&#xff1a;安装插件JMeter WebSocket Samplers 步骤2&#xff1a;采集器使用 步骤3&#xff1a;脚本执行 结语 引言 在当今高并发的网络环境下&#xff0c;WebSocket协议已经成为了最受欢迎的实时通信技术之一。然而&#xff0c;对于开发人员来…

CorelDRAW2023序列号及下载安装条件

始于1989年并不断推陈出新,致力为设计工作者提供更高效的设计工具&#xff01;CorelDRAW滋养并见证了一代设计师的成长&#xff01;在最短的时间内交付作品&#xff0c;CorelDRAW的智能高效会让你一见钟情&#xff01;CorelDRAW 全称“CorelDRAW Graphics Suite“&#xff0c;也…

Linux:命令tar、zip、unzip对文件或文件夹进行压缩与解压

Linux&#xff1a;命令tar、zip、unzip对文件或文件夹进行压缩与解压 .tar压缩操作&#xff1a; 创建要进行压缩的文件&#xff1a; 对文件进行压缩&#xff1a; 将三个文件压缩成text.tar文件&#xff0c;压缩到当前路径下(默认也是在当前路径) 对比体积&#xff1a; 发现&…

关于f-stack转发框架的几点分析思考

使用DPDK收包&#xff0c;想要用到TCP协议栈&#xff0c;可选的方案有linux原生的tun/tap口以及DPDK自带的KNI驱动&#xff0c;这两种都是通过将DPDK收到的报文注入到linux内核来使用TCP协议栈的功能&#xff0c;然后&#xff0c;用户态协议栈可以考虑开源的f-stack&#xff0c…

在页面使用富文本编译器

富文本编译器的选择 Editor.mdTinyMCESimpleMDECKEditor 还有一些&#xff0c;这里讲的是我用的TinyMCE 1、下载 下载地址&#xff1a;下载tiny | TinyMCE中文文档中文手册 下载开发版本&#xff0c;我下载的最新版 tinymce_6.4.2_dev.zip 将压缩包解压后可以看到下面目录&…

(哈希表 ) 202. 快乐数——【Leetcode每日一题】

❓202. 快乐数 难度&#xff1a;简单 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到…

Groovy系列一 Groovy基础语法

目录 为什么要学习Groovy Groovy 介绍 Groovy 特点 Groovy 实战 动态类型 简单明了的list,map类型 在groovy世界任何东西都是对象 属性操作变得更容易 GString 闭包 委派&#xff1a;delegate Switch变得更简洁 元编程 强制类型检查 Elvis Operator 安全访问 为…

【五】设计模式~~~创建型模式~~~单例模式(Java)

【学习难度&#xff1a;★☆☆☆☆&#xff0c;使用频率&#xff1a;★★★★☆】 5.1. 模式动机 对于系统中的某些类来说&#xff0c;只有一个实例很重要&#xff0c;例如&#xff0c;一个系统中可以存在多个打印任务&#xff0c;但是只能有一个正在工作的任务&#xff1b;一…

一波三折,终于找到 src 漏洞挖掘的方法了【建议收藏】

0x01 信息收集 1、Google Hack 实用语法 迅速查找信息泄露、管理后台暴露等漏洞语法&#xff0c;例如&#xff1a; filetype:txt 登录 filetype:xls 登录 filetype:doc 登录 intitle:后台管理 intitle:login intitle:后台管理 inurl:admin intitle:index of /查找指定网站&…

C++:征服C指针:指针(二)

指针二 1. 指向数组的指针2. 多维数组三级目录 上一篇文章我们介绍了&#xff1a;什么是指针&#xff0c;指针常见的问题&#xff0c;本篇我们主要介绍 &#xff1a;指针与数组。 1. 指向数组的指针 int *p[n] : 指针数组&#xff0c; 它包括 n 个成员&#xff0c;每个成员都是…

探索Maven创建项目全过程(超详细~~~)

文章目录 1.Maven介绍2.Servlet介绍2.1 Servlet定义2.2 Servlet的主要任务 3.创建Servlet程序步骤3.1 创建项目3.2 引入依赖3.3 创建目录3.4编写代码3.5 打包程序3.6 部署程序3.7 验证结果 4.更方便的部署方式4.1.下载Tomcat插件4.2 配置Tomcat插件4.3运行项目 1.Maven介绍 Ma…

认识Tomcat

hi,大家好,今天为大家带来Tomcat的相关知识 &#x1f36d;1.Tomcat是什么 &#x1f36d;2.Tomcat的下载安装 &#x1f36d;3.Tomcat的目录结构 &#x1f36d;4.启动Tomcat &#x1f36d;5.部署博客系统到Tomcat &#x1f349;1.Tomcat是什么 我们之前也已经学了http,http…

【JAVAWEB】HTML的常见标签

目录 1.HTML结构 1.1认识HTML标签 1.2HTML文件基本结构 1.3标签层次结构 1.4快速生成代码框架 2.HTML常见标签 注释标签 标题标签&#xff1a;h1-h6 段落标签:p 换行标签&#xff1a;br 格式化标签 图片标签 超链接标签&#xff1a;a 表格标签 列表标签 表单标…

Windows 同时安装 MySQL5 和 MySQL8 版本

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是Rockey&#xff0c;不知名企业的不知名开发着 &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;联系方式&#xff1a;he18339193956&#xff0c;…

MySQL 00 : MySQL_数据库shell登录时遇到的问题

问题1描述&#xff1a;输入链接数据块的命令提示 sh:mysgl:command not found 解决:第一步配置环境变量来解决 1、vim /etc/profile 2、末尾写入export PATH$PATH:/usr/local/mysql/bin 3、保存 4、执行 source /etc/profile 第二部 问题描述 Mac通过MAMP安装MySQL时&#…

K8s之Replicaset控制器详解

文章目录 一、ReplicaSet 控制器介绍二、ReplicaSet案例1、Pod副本扩缩容案例2、Pod更新版本案例 一、ReplicaSet 控制器介绍 官方中文参考文档&#xff1a; ReplicaSet是k8s中一种资源对象&#xff0c;简写 rs&#xff0c;用于管理Pod副本数量和健康状态&#xff0c;在spec.…

MySQL如何导入大量数据?

有时我们会遇到需要将大量数据导入MySQL的需求&#xff0c;一般数据存储在csv或者txt中&#xff0c;数据由","分隔。这里提供两种方案供大家选择。 一、创建测试表 为了测试&#xff0c;我们先创建数据库和表&#xff0c;并创建一个用户。 create database loadda…

js的BOM对象中的window、location使用

说明&#xff1a;BOM的全称是Browser Object Model&#xff0c;浏览器对象模型&#xff0c;有Window&#xff08;浏览器窗口&#xff09;、Navigator&#xff08;浏览器&#xff09;、Screen&#xff08;屏幕&#xff09;、History&#xff08;历史记录&#xff09;和Location&…

js函数、Array和String的定义和使用

函数 js中的函数&#xff0c;类似java中的方法 <script>// 定义函数方式一function addA(x, y) {return x y;}// 定义函数方式二&#xff0c;注意addB是函数的名称&#xff0c;不是返回值let addB function(x, y) {return x * y;}</script><script>docume…

vscode语音插件开发-在nodejs里面转换音频文件格式并压缩导出zip格式

继我的上一篇文章&#xff1a;&#xff01;vscode录音及语音实时转写插件开发并在工作区生成本地mp3文件 踩坑日记 音频格式转换这里我使用的是ffmpeg第三方库&#xff0c;官网文档。 ffmpeg简介 FFmpeg是一个跨平台的自由软件&#xff0c;用于实时音频、视频流以及音频、视频…