
请阅读完整的“ Rags to Riches”博客系列:
https://dev.to/aws-heroes/rags-to-part-part-part-1-generative-ai-retreeval-4pd7
这个基于OpenAI的RAG聊天应用程序,可以帮助您了解AI检索模式。这里的技术是初学者友好的,易于部署到AWS Lambda。随着您的需求增长,可以随意使用更强大的组件生产此应用程序。什么是抹布?来自IBM研究:
RAG是将事实从外部知识库中检索到最准确,最新信息的大型语言模型(LLM)的AI框架,并使用户深入了解LLMS的生成过程。


您必须有一个OpenAI API键来运行此应用程序。您可以使用此处免费获得一个,我可以在哪里找到我的秘密API密钥?指导。拥有OpenAi密钥后,请在此项目的根部创建一个.env.development.local文件,并用您的键代替sk...
OPENAI_API_KEY=sk...
该项目支持开发容器,这意味着您可以使用VS代码在容器中打开此文件夹,并将为您创建开发环境。假设您已经安装了节点,请在集成终端或本地计算机上运行以下命令。
./bin/setup
./bin/server服务器命令将启动前端和后端开发服务器。使用此URL访问您的应用程序。 http:// localhost:5173
该演示应用程序使用拆分堆栈体系结构。这意味着有独特的前端和后端。前端是vue.js应用程序吗? Pinia用于状态,⚡️Vite进行开发。前端还使用?尾风CSS以及? Daisyui用于造型。后端是? Node.js应用程序,该应用程序用于HTTP框架,以及? sqlite3 vss与? Better-Sqlite3用于矢量存储和搜索。
在整个帖子中,我们将更详细地探索各种技术,以及它们如何帮助我们在学习AI驱动的集成和及时工程的基础上构建抹布应用程序。这是一个有趣的空间。希望您和我一样喜欢它!
因此,让我们从最后开始。我们的Lambdarag演示在本地运行,以使开发和学习变得易于发展。在某个时候,尽管您可能想将其运送到生产或与他人分享您的工作。那么,为什么要部署到Lambda,该部署选项提供什么好处?一些想法:
在所有这些中,我认为响应流是最强大的。这是Lambda的一个相对较新的功能,它使我们的抹布可以像chatgpt一样将文本流回Web客户端。它还允许Lambda打破6MB响应有效载荷和30S超时限制。项目template.yaml中的这几行与lambda Web适配器一起使一切成为可能。
FunctionUrlConfig :
AuthType : NONE
InvokeMode : RESPONSE_STREAM在您首次./bin/deploy之前。确保您登录AWS控制台,然后首先导航到SSM参数存储。从那里创建一个使用路径/lambda-rag/OPENAI_API_KEY的秘密字符串参数,并在OpenAI API密钥中粘贴。
我们的后端有一个非常基本的src/utils/openai.js模块。这将导出OpenAI客户端以及辅助功能以创建嵌入。我们在本系列第一部分的基本建筑师部分中简要介绍嵌入。此功能只需将用户的查询变成矢量嵌入,后来对我们的SQLite数据库进行了查询。有很多方法可以创建和查询嵌入。目前,我们将保持简单,并使用OpenAI的text-embedding-ada-002型号,该型号输出1536个维嵌入。
import { OpenAI } from "openai" ;
export const openai = new OpenAI ( {
apiKey : process . env . OPENAI_API_KEY ,
} ) ;
export const createEmbedding = async ( query ) => {
const response = await openai . embeddings . create ( {
model : "text-embedding-ada-002" ,
input : query ,
} ) ;
return JSON . stringify ( response . data [ 0 ] . embedding ) ;
} ;那么,OpenAI的API如何创建聊天界面?第一部分中讨论的上下文窗口如何发挥作用?考虑以下屏幕截图,我告诉Lambdarag我的名字,然后询问是否记得。
像大多数Web应用程序一样,Chatgpt是无状态的。 LLM模型没有会话。每次发送消息时,都必须将所有先前的消息(上下文)发送到完成点。这就是为什么我们使用? PINIA用于客户端州管理。因此,从API的角度来看,它在下面看起来像这样。
await openai . chat . completions . create ( {
model : "gpt-3.5-turbo-16k" ,
messages : [
{ role : "user" , content : "Hello my name is Ken Collins." } ,
{ role : "assistant" , content : "Hello Ken Collins! How can I..." } ,
{ role : "user" , content : "Do you remember my name?" } ,
]
} ) ;您是否注意到助手不仅对我的名字做出了回应,而且知道这是为了帮助我们穿着豪华服装吗?这是一种称为角色提示的技术。我们在lambdarag演示中做到这一点,通过将此角色预先在src-frontend/utils/roleprompt.js文件中预先准备到用户的第一个消息。
您可能已经注意到Lambdarag演示完全写在其中? JavaScript对Python。当您了解有关构建AI应用程序的更多信息时,您可能最终必须学习Python以及更高级的框架??兰链还是拥抱脸?变形金刚。所有这些都有JavaScript版本。我希望提供JavaScript客户的这种趋势将继续。感觉就像是一种更容易获得的语言。
在下一部分中,我们将介绍如何使用SQLite的新VSS扩展名来使用您的数据创建嵌入式文档。
lambdarag演示应用程序包含一个现成的SQLite数据库,其中包含来自Kaggle豪华服装数据集的5,000个产品。它还具有预先种子的矢量嵌入式嵌入,并可以使用!
在我们深入研究sqlite-vss之前,我想解释为什么我认为这个扩展是如此的惊人。迄今为止,我发现SQLite-VSS是探索向量嵌入的最简单,最快的方法。许多Genai项目都使用Supabase,这似乎很棒,但很难在本地运行。这里的目标是学习!
随着您的应用程序的增长,我强烈建议您查看Amazon OpenSearch无服务器。这是一项完全管理,高度可扩展且具有成本效益的服务,可支持向量相似性搜索。它甚至支持Faiss进行预过滤。
让我们看一下Sqlite-VSS。本文介绍了矢量搜索的SQLITE扩展名,涵盖了标准表的创建以及用于嵌入的虚拟表以及如何查询它们的虚拟表。 lambdarag演示在我们的db/create.js文件中遵循所有这些模式。我们由此产生的模式是:
CREATE TABLE products (
id INTEGER PRIMARY KEY ,
name TEXT ,
category TEXT ,
subCategory TEXT ,
description TEXT ,
embedding BLOB
);
CREATE TABLE IF NOT EXISTS " vss_products_index " (rowid integer primary key autoincrement, idx);
CREATE TABLE sqlite_sequence (name,seq);
CREATE TABLE IF NOT EXISTS " vss_products_data " (rowid integer primary key autoincrement, _);
CREATE VIRTUAL TABLE vss_products using vss0 (
embedding( 1536 )
);如果要重新创建SQLITE数据库或构建自定义数据集,则可以通过更改db/create.js并运行npm run db:create来做到这一点。这将删除现有数据库,并使用来自任何CSV文件,支持模式或您愿意编码的过程的数据重新创建它。
> npm run db:create
> [email protected] db:create
> rm -rf db/lambdarag.db && node db/create.js
Using sqlite-vss version: v0.1.1
Inserting product data...
██████████████████████████████████░░░░░░ 84% | ETA: 2s | 4242/5001之后,您需要运行npm run db:embeddings脚本,该脚本使用OpenAI API为每种产品创建嵌入式。这需要几分钟才能完成所有API调用。该任务包括本地缓存,以使重新运行更快。最后,有一个npm run db:clean Script,该脚本调用DB上的VACUUM ,以删除虚拟表的浪费空间。同样,仅当您要重新创建数据库或构建自定义数据集时,才需要所有这些。有一个./bin/setup-db包装器脚本可以为您完成所有这些步骤。
好的,所以我们有一个产品数据库及其匹配的向量嵌入,用于语义搜索。我们如何从聊天到从数据库中检索项目进行编码? Openai具有这个名为函数调用的惊人功能。在我们的演示中,它允许LLM搜索产品并向您描述结果。
但是它怎么知道?您只需描述应用程序所隐含的一系列功能以及在聊天完成API调用中即可。 OpenAI将会1)自动确定函数应调用2)返回所需参数的函数名称。您的要求看起来像这样。
await openai . chat . completions . create ( {
model : "gpt-3.5-turbo-16k" ,
functions : '[{"search_products":{"parameters": {"query": "string"}}}]' ,
messages : [
{ role : "user" , content : "I need a cool trucker hat." }
]
} ) ;如果选择了函数,则响应将包括函数和参数的名称。您的责任是检查此问题,然后调用与功能和参数匹配的应用程序代码。对于lambagpt,这将是查询数据库并返回任何匹配行。我们在src/models/products.js文件中执行此操作。
为了使OpenAI响应结果,我们向其发送了另一个请求,现在还包括另外两条消息。第一个是类型“函数”,包括要求您致电的函数的名称和参数。第二个是类型的“用户”,其中包括从我们的检索过程中返回的产品的JSON数据。 Openai现在将响应,好像它一直都有这些知识!
await openai . chat . completions . create ( {
model : "gpt-3.5-turbo-16k" ,
functions : '[{"search_products":{"parameters": {"query": "string"}}}]' ,
messages : [
{ role : "user" , content : "I need a cool trucker hat." } ,
{ role : "function" , name : "search_products" , content : '{"query":"trucker hats"}' } ,
{ role : "user" , content : '[{"id":3582,"name":"Mens Patagonia Logo Trucker Hat..."}]' } ,
]
} ) ;由于所有消息都保持在客户端状态,因此您可以使用整齐的调试技术看到它们。打开src-frontend/components/Message.vue文件并进行以下更改。
'border-b-base-300': true,
'bg-base-200': data.role === 'user',
- 'hidden': data.hidden,
+ 'hidden': false,现在,您可以在UI中查看所有消息的状态。这是调试应用程序并查看正在发生的事情的好方法。
我希望您能找到有关如何增强OpenAI聊天完成方式以获取知识检索的快速概述。还有很多要探索和做的事情。这里有一些想法可以让您入门:
src-frontend/stores/messages.js Pinia商店中的fetchResponse在这里完成了所有工作并管理客户端状态。src/utils/functions.json文件中添加更多检索方法。例如,通过ID方法的find_style可以直接查询数据库。❤️我希望您喜欢这些帖子,并找到Lambdarag演示应用程序,可用于学习如何使用AI进行知识检索。随时提出问题并分享您对此帖子的想法。谢谢你!