V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
websong188

golang 结合 cobra 使用 chatgpt qdrant 实现 ai 知识库 cli

  •  1
     
  •   websong188 · Sep 22, 2023 · 1908 views
    This topic created in 949 days ago, the information mentioned may be changed or developed.

    golang 结合 cobra 使用 chatgpt qdrant 实现 ai 知识库 cli

    流程

    1. 将数据集 通过 openai embedding 得到向量+组装 payload,存入 qdrant
    2. 用户进行问题搜索,通过 openai embedding 得到向量,从 qdrant 中搜索相似度大于 0.8 的数据
    3. 从 qdrant 中取出数据得到参考答案
    4. 将问题标题+参考答案,组装成 promot 向 gpt 进行提问,得到偏向于 已有知识库设定的扩展知识回答

    kabi 知识库的导入和搜索

    仓库地址:https://github.com/webws/embedding-knowledge-base

    kabi 是使用 golang 基于 openai chatgpt embedding + qdrant 实现知识库的导入和问答

    ❯ kabi -h
    a local knowledge base, based on chatgpt and qdrant
    
    usage:
      kbai [flags]
      kbai [command]
    
    available commands:
      completion  generate the autocompletion script for the specified shell
      help        help about any command
      import      import data to vector database
      search      ask the knowledge base example: kbai ask --msg 'first, the chicken or the egg'
    
    flags:
          --apikey string       openai apikey:default from env apikey
          --collection string   qdrant collection name default: kubernetes (default "kubernetes")
      -h, --help                help for kbai
          --proxy string        http client proxy default:socks5://127.0.0.1:1080  (default "socks5://127.0.0.1:1080")
          --qdrant string       qdrant address default: 127.0.0.1:6334 (default "127.0.0.1:6334")
          --vectorsize uint     qdrant vector size default: 1536 (default 1536)
    
    use "kbai [command] --help" for more information about a command.
    

    启动向量数据库

    qdrant 是一个开源的向量搜索引擎,支持多种向量距离计算方式

    docker 运行 qdrant

    docker run --rm -p 6334:6334 qdrant/qdrant
    

    kbai 库导入数据到知识库

    clone 源码运行(后续提供二进制文件)

    git clone https://github.com/webws/embedding-knowledge-base.git
    
    cd ./embedding-knowledge-base
    

    这里使用的测试数据是 k8s 相关的知识库,真实数据需自己准备

    1.设置 openai apikey

    export apikey=xxx
    

    2.导入知识库(源码运行)

    go run ./ import --datafile ./example/data.json
    

    data.json 数据格式如下,为 真实数据需自己准备

    [
        {
            "questions": "这是问题",
            "answers": "这是答案"
        },
    ]
    

    说明:

    默认的 代理 是 "socks5://127.0.0.1:1080" 自定义 可使用 --proxy 指定
    

    kbai 搜索数据

    搜索问题(源码执行)

     go run ./ search --msg "网关是什么"
    

    回答

    the answer to the knowledge base:
    在 kubernetes 中,网关通常指的是 ingress (入 口)资源对象。ingress 是一种 kubernetes api 对象,用于配置和管理集群中的 http 和 https 流量入口。它充当了从集群外部访问集群内部服务的入口点
    
    results of chatgpt answers  with reference answers:
    ,同时提供负载均衡、ssl/tls 终止和基于域名的路由等功能。ingress 资源对象定义了一组规则,这些规则指定了通过特定 http 路径或主机名将请求路由到后端服务的方式。可以使用不同的 ingress 控制器实现这些规则,如 nginx 、traefik 等。这样就可以在集群中创建多个 ingress 资源对象来管理不同的流量入口。
    
    only chatgpt answers:
    网关是一种网络设备,用于连接两个或多个不同类型的网络,以便实现数据以不同协议进行传递和转换。网关起到了连接不同网络之间的桥梁作用,将两个或多个网络互相连接起来,并负责数据的路由和转发。网关可以是硬件设备,如路由器,也可以是软件程序,如互联网网关。网关通常用于连接本地网络与互联网,使得局域网中的计算机能够访问互联网上的资源。除了连接不同网络的功能,网关还可以实现安全性、负载均衡、数据过滤等功能。
    
    1. 第一个是知识库的回答(the answer to the knowledge base):
    2. 第二个 是结合知识库 chatgpt 的回答(results of chatgpt answers with reference answers)
    3. 第三个 仅 chatgpt 回答

    可以看出 直接问 chatgpt,得到的答案可能跟 k8s 无关,结合 k8s 本地知识库,可以让回答偏向 数据集设定的主题

    如果直接搜索 与知识库无关或违规问题,将搜索不到任务数据

    go run ./ search --msg "苹果不洗能吃吗"
    rearch term violation or exceeding category
    

    kabi golang 实现 ai 知识库导入原理

    导入

    1. 接入 qdrant 和 openai cleint
    2. 解释原始知识库数据 为 q(问) a(答)
    3. 将 问题 经过 openai embedding 得到向量+答案存入 qdrant

    以下是 kbai go 导入逻辑代码

                qdrantclient := qdrant.newqdrantclient(configflags.qdrant, configflags.collection, configflags.vectorsize)
    			defer qdrantclient.close()
    			aiclient, err := ai.newaiclient(configflags.proxy, configflags.apikey)
    			if err != nil {
    				return err
    			}
    			if err = qdrantclient.createcollection(configflags.collection, configflags.vectorsize); err != nil {
    				return err
    			}
    			qas, err := converttoqas(datafile)
    			if err != nil {
    				return err
    			}
    			points := []*pb.pointstruct{}
    			logger.infow("import", "data", qas)
    			qpslenth := len(qas)
    			for i, qa := range qas {
    				embedding, err := aiclient.simplegetvec(qa.questions)
    				if err != nil {
    					logger.errorw("simplegetvec", "err", err, "question", qa.questions, "index", i, "total", qpslenth)
    					return err
    				}
    				point := buildpoint(qa.questions, qa.answers, embedding)
    				points = append(points, point)
    			}
    

    搜索

    1. 问题搜索,通过 openai embedding 得到向量
    2. 根据向量 从 qdrant 中搜索相似度大于 0.8 的数据
    3. 根据 qdrant 里的知识库答案(参考答案) + 从 chatgpt 提问 得到扩展知识
    4 replies    2023-09-22 10:18:57 +08:00
    xyy003
        1
    xyy003  
    PRO
       Sep 22, 2023
    解释原始知识库数据 为 q(问) a(答) 这一步是怎么转变的
    websong188
        2
    websong188  
    OP
       Sep 22, 2023
    @xyy003 这个应该是原始数据。大概是 golang 将原始数据文件 转换为 qa 数组,再将 qa 中的 q 通过 openai 获取到 embeddin,和 a 一起存入 qdrant 知识库
    xyy003
        3
    xyy003  
    PRO
       Sep 22, 2023
    @websong188 那如何确保转换的 qa 数组的有效性呢 有相关的 prompt 吗
    websong188
        4
    websong188  
    OP
       Sep 22, 2023
    @xyy003 真实的知识库原始数据 需要自己提供,搜索的 prompt 规则是 用户问题+知识库的答案(参考答案) 的组合,得到偏向于 已有知识库设定的主题 扩展知识回答,当搜索的问题与 知识库的答案(参考答案) 相似度太低,就不给答案,防止问违规,知识库以外的问题
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3661 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 54ms · UTC 04:51 · PVG 12:51 · LAX 21:51 · JFK 00:51
    ♥ Do have faith in what you're doing.