OpenAI 上线新功能力捧 RAG,开发者真的不需要向量数据库了?

news2024/11/27 0:44:22

近期, OpenAI 的开发者大会迅速成为各大媒体及开发者的热议焦点,有人甚至发出疑问“向量数据库是不是失宠了?”

这并非空穴来风。的确,OpenAI 在现场频频放出大招,宣布推出 GPT-4 Turbo 模型、全新 Assistants API 和一系列增强功能。其中,王炸功能 Assistants API 的内置工具支持了代码解释器、知识库检索以及函数调用,允许接入外部知识(文档)、使用更长的提示和集成各种工具。它能够帮助开发者分担繁重的工作,并构建高质量的 AI 应用。

乍一看,OpenAI Assistants 自带的检索功能十分强大,但如果对行业足够了解,便会发现其仍存在诸多限制。OpenAI Assistants 检索严格限制了数据规模,且缺乏定制化的能力。因此,搭建高效的应用还需要使用自定义的检索器。所幸,OpenAI 的函数调用能力允许开发者无缝接入自定义的检索器,从而打破对于知识库数据量的限制,更好地适应多样化的用例。

今天我们就来聊聊 OpenAI Assistants 内置检索功能的限制及其解决方案——用 Milvus 向量数据库实现自定义检索功能。

01.OpenAI Assistants 检索存在局限性?试试自定义检索

OpenAI Assistants 内置的检索工具突破了模型固有知识库的限制,支持用户通过额外数据(如内部产品信息或用户提供的文档)来增强大模型。但是,OpenAI Assistants 检索仍然具有局限性。

限制 1: 可扩展性

OpenAI Assistants 内置检索对文件大小和数量都有限制。这些限制不利于大型文档仓库:

  • 每个 Assistant 最多支持 20 个文件

  • 每个文件最大为 512 MB

  • 我们在测试中发现了关于 Token 的隐藏限制——每个文件最多 200 万个 Token

  • 每个企业账号下文件大小总和最多 100 GB

上述限制会严重限制拥有大量数据的组织机构。在此情况下,就需要使用一套可以摆脱存储上限、支持灵活扩展的解决方案——集成 Milvus(https://zilliz.com/what-is-milvus)或 Zilliz Cloud(https://cloud.zilliz.com.cn/signup)这样的向量数据库检索更大体量的知识库。

限制 2: 无法定制检索

虽然 OpenAI Assistants 的内置检索是一套开箱即用的解决方案,但它无法根据每个应用的特殊需求(如:搜索延时、索引算法)进行定制。使用第三方向量数据库,可以帮助开发者灵活配置、调优检索过程,从而满足生产环境中的各种需求,提升应用的整体效率。

限制3 :缺乏多租户支持

OpenAI Assistants 中内置的检索功能绑定 Assistant,每个知识库产生的费用按 Assistant 个数成倍增长。如果开发者的应用需要为数百万用户提供共享文档,或者为特定用户提供私人化的信息,OpenAI Assistants 的内置检索功能就无法满足需求了。

下表显示了在 OpenAI Assistants 中存储文档的成本:

alt

根据上表的定价计算,其代价十分高昂——每月每 GB 的存储需要花费 6 美元。(参考 AWS S3 的收费仅为 0.023 美元。)具体 Assistants API 定价可在此 (https://openai.com/pricing)获取。如果将共享文档复制到每个 Assistant 中,会显著增加存储成本,所以在 OpenAI 上存储重复的文档是一种不现实的方案。但是,如果让所有用户都共享同一个 Assistant,那么将无法支持用户检索自己的私有文档。

因此,对于需要检索大量数据集的应用来说,选择一个可扩展、高效、具有高性价比的检索器显得尤为重要。

值得庆幸的是,OpenAI 灵活的函数调用功能支持开发者在 OpenAI Assistants 中无缝集成自定义的检索器 。这套解决方案一方面保留了 OpenAI 出色的 AI 能力,另一方面又可以满足应用可扩展性的需求。

02.使用 Milvus 实现 OpenAI Assistants 检索定制化

Milvus 是一款高度灵活、可扩展的开源向量数据库,毫秒内即可实现十亿级别向量的存储和检索。由于优秀的扩展性和超低的查询延时,Milvus 是定制 OpenAI Assistants 检索的首选。

alt |OpenAI Assistant 函数调用的工作原理

用 OpenAI 函数调用和 Milvus 向量数据库搭建自定义检索器

在接下来的教程中,我们将展示构建自定义检索器、并将其集成到 OpenAI Assistants 的具体步骤。

  1. 配置环境。
pip install openai==1.2.0
pip install langchain==0.0.333
pip install pymilvus

export OPENAI_API_KEY=xxxx  # Enter your OpenAI API key here
  1. 使用向量数据库构建自定义检索器。我们选择 Milvus 作为向量数据库、 LangChain 作为调用框架。
from langchain.vectorstores import Milvus
from langchain.embeddings import OpenAIEmbeddings


# Prepare retriever
vector_db = Milvus(
   embedding_function=OpenAIEmbeddings(),
   connection_args = {'host''localhost''port''19530'}
   )
retriever = vector_db.as_retriever(search_kwargs={'k'5})  # change top_k here
  1. 将文档导入 Milvus。LangChain 会解析文档、将其切分成片段,并转换为向量。随后这些文档片段和相应的向量会被导入 Milvus 向量数据库。当然,我们也可以自定义每个步骤,进一步提高检索质量。
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter


# Parsing and chunking the document.
filepath = 'path/to/your/file'
doc_data = TextLoader(filepath).load_and_split(
   RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
   )


# Embedding and insert chunks into the vector database.
vector_db.add_texts([doc.page_content for doc in doc_data])

至此,一个自定义的检索器已经搭建完成,可以支持私有数据下的语义搜索。接下来,我们需要将这个检索器集成到 OpenAI Assistants,从而实现内容生成。

  1. 使用 OpenAI 的函数调用功能创建一个 Assistant,并提示 Assistant 在回应请求时使用名为 CustomRetriever的函数工具。
import os
from openai import OpenAI


# Setup OpenAI client.
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

# Create an Assistant.
my_assistant = client.beta.assistants.create(
   name='Chat with a custom retriever',
   instructions='You will search for relevant information via retriever and answer questions based on retrieved information.',
   tools=[
     {
       'type''function',
       'function': {
         'name''CustomRetriever',
         'description''Retrieve relevant information from provided documents.',
         'parameters': {
             'type''object',
             'properties': {'query': {'type''string''description''The user query'}},
             'required': ['query']
         },
       }
     }
   ],
   model='gpt-4-1106-preview',  # Switch OpenAI model here
)
  1. Assistant 采用异步方式调用函数工具。首先开启线程并调用 Assistant,其状态存储在名为Run 的对象中。在运行过程中,如果 Assistant 认为有必要调用CustomRetriever函数,会暂停运行等待异步提交函数调用结果。通过轮询来获取Assistant 发出调用的命令。
QUERY = 'ENTER YOUR QUESTION HERE'

# Create a thread.
my_thread = client.beta.threads.create(
 messages=[
   {
     'role''user',
     'content': QUERY,
   }
 ]
)

# Invoke a run of my_assistant on my_thread.
my_run = client.beta.threads.runs.create(
   thread_id=my_thread.id,
   assistant_id=my_assistant.id
)

# Wait until my_thread halts.
while True:
   my_run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=my_run.id)
   if my_run.status != 'queued':
       break
  1. 当查询到 Assistant 正在等待函数调用结果,即可对查询语句进行向量搜索并通过 Run 提交结果至 Assistant,让其继续进行内容生成。
# Conduct vector search and parse results when OpenAI Run ready for the next action
if my_run.status == 'requires_action':
   tool_outputs = []
   for tool_call in my_run.required_action.submit_tool_outputs.tool_calls:
       if tool_call.function.name == 'Custom Retriever':
           search_res = retriever.get_relevant_documents(QUERY)
           tool_outputs.append({
               'tool_call_id': tool_call.id,
               'output': ('\n\n').join([res.page_content for res in search_res])
               })


   # Send retrieval results to your Run service
   client.beta.threads.runs.submit_tool_outputs(
       thread_id=my_thread.id,
       run_id=my_run.id,
       tool_outputs=tool_outputs
   )
  1. 最终,提取并解析与 OpenAI Assistant 的完整对话。
messages = client.beta.threads.messages.list(thread_id=my_thread.id)

for m in messages:
   print(f'{m.role}{m.content[0].text.value}\n')

至此,我们已成功实现用自定义的检索功能来增强 OpenAI Assistant 的回答能力。

alt

03.总结

看到这里,相信大家对于【是否需要向量数据库】已经有了答案:虽然 OpenAI Assistants 的内置检索工具令人眼前一亮,但它仍旧存在诸多存储限制,如:可扩展性较差,无法满足多样的、定制化的用户需求等。可以这样理解,OpenAI Assistants 适用于个人用户,但无法满足数据量更大、业务更复杂的应用需求。

如果想要克服 OpenAI Assistants 的种种限制和不利因素,开发者可以考虑使用例如 Milvus 或 Zilliz Cloud 等向量数据库搭建自定义检索功能,从而实现更灵活的问答应用。

做一波预告!在后续的文章中,我们将继续测评 OpenAI Assistants 内置检索和基于外部向量数据库的方案,从性能、成本和功能等维度进行详细比较。届时亦会发布一系列的性能测试结果,敬请关注!

本文由 mdnice 多平台发布

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

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

相关文章

初试 jmeter做压力测试

一.前言 压力测试是每一个Web应用程序上线之前都需要做的一个测试,他可以帮助我们发现系统中的瓶颈问题,减少发布到生产环境后出问题的几率;预估系统的承载能力,使我们能根据其做出一些应对措施。所以压力测试是一个非常重要的步…

【遗传算法】Genetic algorithms (GAs) 遗传算法原理入门与应用代码

目录 1 遗传算法 2 遗传算法的基本步骤 3 Python示例 4 遗传算法解决TSP(旅行商问题) 1 遗传算法 遗传算法是一种优化搜索算法,模拟自然选择和遗传机制来寻找问题的最优解。这种算法的设计灵感来自于达尔文的进化论和遗…

Android studio配置Flutter开发环境报错问题解决

博主前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住也分享一下给大家 👉点击跳转到教程 报错问题截图 报错原因已经给出: You need Java 11 or higher to build your app with this version of G…

一步路难倒英雄汉?app自动化测试,怎么从零搭建appium!

不少软件测试想进阶到自动化测试,没有前人知道,只能像个无头的苍蝇,到处乱转,根本不知道从何处下手 特别是自学路上碰到需要安装什么程序、工具的时候,一个报错就需要在百度上查个半天,这么浪费时间的事情…

FPGA时序约束与分析-简单入门

FPGA时序约束与分析-简单入门 文章目录 FPGA时序约束与分析-简单入门1. 本课程概述2. 时序约束简介2.1 什么是时序约束2.2 合理的时序约束2.3 *基于Vivado的时序约束方法 3. 时序分析的基本概念3.1 时钟与时钟偏差3.2 建立时间和保持时间3.3 时序分析中路径、沿和关系的定义 4.…

立体库堆垛机控制程序故障输出功能块

故障输出块 A "提升变频器故障" // O "提升变频器通讯故障" // ON "提升变频器准备好" "提升变频故障" A "水平变频器故障" // O "水平变频器通讯故障" // ON…

Spring源码—初识IOC

👽System.out.println(“👋🏼嗨,大家好,我是代码不会敲的小符,双非大四,Java实习中…”); 📚System.out.println(“🎈如果文章中有错误的地方,恳请大家指正&a…

水库大坝安全监测预警系统的重要作用

水库大坝建造在地质构造复杂、岩土特性不均匀的地基上,在各种荷载的作用和自然因素的影响下,其工作性态和安全状况随时都在变化。如果出现异常,又不被及时发现,其后果不堪设想。全天候实时监测,实时掌握水库水位、雨情…

基于JuiceFS 的低成本 Elasticsearch 云上备份存储

杭州火石创造是国内专注于产业大数据的数据智能服务商,为了解决数据存储及高效服务客户需求,选择了 Elasticsearch 搜索引擎进行云上存储。基于性能和成本的考虑,在阿里云选择用本地 SSD ECS 机型自建集群。但由于是自建集群,如何…

uniapp Android如何打开常用系统设置页面?

uniapp Android 如何打开常用系统设置页面? 在使用App过程时,有时候会对一些权限获取,比如打开蓝牙、打开通知栏通知等设置,我们如何快速跳转到需要的设置页面? 文章目录 uniapp Android 如何打开常用系统设置页面&…

μC/OS-II---消息队列管理2(os_q.c)

目录 消息队列的主要优点消息队列和消息邮箱消息队列相关操作向消息队列发送消息(FIFO)向消息队列发送消息(LIFO)向消息队列发送消息(扩展)消息队列获取/无等待清空消息队列消息队列信息获取消息队列中断等待 消息队列的主要优点 消息队列的主要优点是解耦和异步通…

rocketmq5.X 单机搭建 虚拟机搭建rocketmq5.1.4 搭建最新版本mq rocketmq5.1.4版本单体搭建 rocketmq(一)

1. 官网下载地址: 下载 | RocketMQ 2. 配置环境: 我是在/etc/profile.d 新建了一个rocketmq_env.sh 配置了jdk, maven, 以及mq. mq文件下载的 配置完之后,刷新环境source /etc/profile 3. 配置rocket mq 的jvm配置,就是两个启…

Docker Compose详细教程(从入门到放弃)

对于现代应用来说,大多都是通过很多的微服务互相协同组成的一个完整应用。例如, 订单管理、用户管理、品类管理、缓存服务、数据库服务等,它们构成了一个电商平台的应 用。而部署和管理大量的服务容器是一件非常繁琐的事情。而 Docker Compos…

基于安卓android微信小程序的装修家装小程序

项目介绍 巧匠家装小程序的设计主要是对系统所要实现的功能进行详细考虑,确定所要实现的功能后进行界面的设计,在这中间还要考虑如何可以更好的将功能及页面进行很好的结合,方便用户可以很容易明了的找到自己所需要的信息,还有系…

PLC电力载波通讯,一种新的IoT通讯技术

前言: PLC-IoT 是 PLC 技术应用在物联场景的创新实践,有效解决电力线路信号干扰、衰减问题,支持 IP 化通信能力,使能终端设备智能化,构建智慧边缘联接。PLC让传统IoT有了更多的连接可能: 电力线通信技术适用的场景包括电力配用电网络、城市智慧路灯、交通路口信号灯、园…

Python代码运行速度提升技巧!Python远比你想象中的快~

文章目录 前言一、使用内置函数二、字符串连接 VS join()三、创建列表和字典的方式四、使用 f-Strings五、使用Comprehensions六、附录- Python中的内置函数总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项…

基于SSM的药店药品销售系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

IDEA导入jar包

通过maven导入本地包 mvn install:install-file -DfileD:\WebProject\ERP\zhixing-heyue-erp-server\zxhy-service-api\src\main\java\com\zxhy\service\api\invoice\baiwang\lib\com_baiwang_bop_sdk_outer_3_4_393.jar -DgroupIdcom.baiwang -DartifactIdbaiwang.open -Dver…

C语言每日一题(29)合并两个有序链表

力扣网 21合并两个有序链表 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 思路分析 最基本的一种思路就是,遍历两个链表,将对应结点的值进行比较,题目要求是要升序排…

错误:ERROR:torch.distributed.elastic.multiprocessing.api:failed

在多卡运行时,会出现错误(ERROR:torch.distributed.elastic.multiprocessing.api:failed),但是单卡运行并不会报错,通常在反向梯度传播时多卡梯度不同步。但我是在多卡处理数据进行tokenizer阶段报错,这竟然…