
Leia a série de blogs completos "Rags to Riches":
https://dev.to/aws-heroes/rags-to-riches-part-1-generative-ai-revieval-4pd7
Este aplicativo de bate -papo de trapo baseado em OpenAI que pode ajudá -lo a aprender sobre os padrões de recuperação de IA. As tecnologias aqui são para iniciantes e fáceis de implantar na AWS Lambda. À medida que suas necessidades crescem, sinta -se à vontade para produzir esse aplicativo com componentes mais robustos. O que é um pano? Da pesquisa da IBM:
O RAG é uma estrutura de IA para recuperar fatos de uma base de conhecimento externa para aterrar grandes modelos de idiomas (LLMS) nas informações mais precisas e atualizadas e para fornecer aos usuários informações sobre o processo generativo da LLMS.


Você deve ter uma chave de API do OpenAI para executar este aplicativo. Você pode obter um de graça usando isso, onde encontro minha chave secreta da API? guia. Depois de ter sua chave OpenAI, crie um arquivo .env.development.local na raiz deste projeto com o seguinte, substituindo sk... pela sua chave:
OPENAI_API_KEY=sk...
Este projeto suporta contêineres de desenvolvimento, o que significa que você pode usar o código VS para abrir esta pasta em um contêiner e seu ambiente de desenvolvimento será criado para você. Execute os seguintes comandos em seu terminal integrado ou em sua máquina local, supondo que você tenha o nó instalado.
./bin/setup
./bin/serverO comando do servidor iniciará um servidor de desenvolvimento frontal e traseiro. Use este URL para acessar seu aplicativo. http: // localhost: 5173
Este aplicativo de demonstração usa uma arquitetura de pilha dividida. O que significa que há um front-end e back-end distinto. O front-end é um aplicativo vue.js com? Pinia para Estado e ⚡️ Vite para o desenvolvimento. O front-end também usa? Tailwind CSS junto com? Daisyui para estilo. O back-end é um? Aplicativo Node.js que usa ❎ Express para a estrutura HTTP e? Sqlite3 vss junto com? melhor-sqlite3 para armazenamento e pesquisa de vetores.
Ao longo da postagem, exploraremos várias tecnologias com mais detalhes e como elas nos ajudam a criar um aplicativo RAG enquanto aprendemos o básico das integrações orientadas pela IA e pronta a engenharia. Este é um espaço tão divertido. Espero que você goste tanto quanto eu!
Então, vamos começar com o fim em mente. Nossa demonstração de Lambdarag funciona localmente para facilitar o desenvolvimento e o aprendizado. Em algum momento, você pode enviá -lo para a produção ou compartilhar seu trabalho com outras pessoas. Então, por que implantar no Lambda e que benefícios essa opção de implantação oferece? Alguns pensamentos:
De tudo isso, acho que o streaming de resposta é o mais poderoso. Um recurso relativamente novo para o Lambda, isso permite que nosso RAG transmita texto de volta ao cliente da Web, como o ChatGPT. Ele também permite que o Lambda quebre a carga útil de 6 MB e o limite de tempo limite dos 30 anos. Essas poucas linhas no template.yaml do projeto.
FunctionUrlConfig :
AuthType : NONE
InvokeMode : RESPONSE_STREAM Antes de executar ./bin/deploy pela primeira vez. Certifique -se de fazer login no console da AWS e navegar para o SSM Parameter Store primeiro. A partir daí, crie um parâmetro de string secreto com o caminho /lambda-rag/OPENAI_API_KEY e cola na sua tecla API OpenAI.
Nosso back -end possui um módulo src/utils/openai.js muito básico. Isso exporta um cliente OpenAI, bem como uma função auxiliar para criar incorporações. Cobrimos brevemente as incorporações na seção básica do arquiteto da primeira parte desta série. Essa função simplesmente transforma a consulta de um usuário em uma incorporação de vetor que é posteriormente consultada no nosso banco de dados SQLite. Existem inúmeras maneiras de criar e consultar incorporações. Por enquanto, vamos simplificar e usar o modelo de text-embedding-ada-002 da OpenAI, que gera 1536 incorporações dimensionais.
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 ) ;
} ;Então, como funciona a API do OpenAI para criar uma interface de bate -papo e como a janela de contexto discutida na parte um entra em cena? Considere a seguinte captura de tela em que digo ao Lambdarag meu nome e pergunte se ele se lembra.
O ChatGPT é apátrida, como a maioria dos aplicativos da Web. Não tem sessão para o modelo LLM. Toda vez que você envia uma mensagem, você deve enviar todas as mensagens anteriores (contexto) para o terminal de conclusão. É por isso que usamos? Pinia para gerenciamento de estado do lado do cliente. Então, do ponto de vista da API, seria algo assim abaixo.
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?" } ,
]
} ) ; Você notou como o assistente respondeu não apenas com meu nome, mas também sabia que estava aqui para nos ajudar com roupas de luxo? Esta é uma técnica chamada função que promove. Fazemos isso na demonstração de Lambdarag, antecendendo essa função à primeira mensagem do usuário no arquivo src-frontend/utils/roleprompt.js .
Você deve ter notado que a demonstração de Lambdarag está inteiramente escrita? JavaScript vs. Python. Ao aprender mais sobre a criação de aplicativos de IA, você pode eventualmente aprender Python, além de estruturas mais avançadas como? Aste? Langchain ou o rosto de abraçar? Transformers.js. Todos os quais têm versões JavaScript. Espero que essa tendência de fornecer clientes JavaScript continue. Parece uma linguagem mais acessível.
Na próxima seção, abordaremos como criar incorporação com seus dados e consultas para documentos usando a nova extensão do VSS da SQLite.
? ♂️ O aplicativo Demo Lambdarag contém um banco de dados SQLite pronto para uso com ~ 5.000 produtos do conjunto de dados de roupas de luxo em Kaggle. Ele também possui incorporações vetoriais pré-semeadas e prontas para uso!
Antes de pesquisarmos no SQLITE-VSS, gostaria de explicar por que acho que essa extensão é tão incrível. Até o momento, encontrei o SQLITE-VSS a maneira mais fácil e rápida de explorar incorporações de vetor. Muitos projetos da Genai usam supabase, o que parece ótimo, mas é difícil de executar localmente. O objetivo aqui é aprender!
À medida que seu aplicativo cresce, eu recomendo olhar para o Amazon OpenSearch Serverless. É um serviço totalmente gerenciado, altamente escalável e econômico que suporta a pesquisa de similaridade vetorial. Até suporta pré-filtragem com o FAISS.
Vejamos o SQLITE-VSS um pouco mais perto. Este artigo, uma extensão sqlite para pesquisa vetorial, faz um trabalho incrível, cobrindo a criação de tabelas padrão, bem como tabelas virtuais para incorporações e como consultar as duas. A demonstração Lambdarag segue todos esses padrões de perto em nosso arquivo db/create.js . Nosso esquema resultante é:
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 )
); Se você deseja recriar o banco de dados SQLITE ou criar um conjunto de dados personalizado, poderá fazê-lo alterando o db/create.js e executando npm run db:create . Isso descartará o banco de dados existente e o recriará com dados de qualquer arquivo CSV, esquema de suporte ou processo que você está disposto a codificar.
> 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 Posteriormente, você precisaria executar o script npm run db:embeddings que usa a API do OpenAI para criar incorporações para cada produto. Isso leva alguns minutos para concluir todas as chamadas da API. A tarefa inclui um cache local para torná-lo mais rápido. Por fim, existe um script npm run db:clean que chama um VACUUM no banco de dados para remover espaço desperdiçado para as tabelas virtuais. Novamente, tudo isso só é necessário se você deseja recriar o banco de dados ou criar um conjunto de dados personalizado. Existe um script de wrapper ./bin/setup-db que faz todas essas etapas para você.
OK, então temos um banco de dados de produtos e suas incorporações de vetor correspondentes a serem usadas para pesquisa semântica. Como codificamos o chat e a recuperação de itens do banco de dados? O OpenAI tem esse recurso incrível chamado de função. Em nossa demonstração, permite que o LLM procure produtos e descreva os resultados para você.
Mas como isso sabe? Você simplesmente descreve uma variedade de funções que o seu aplicativo implementam e durante uma chamada da API de conclusão de bate -papo. OpenAI 1), automaticamente, uma determinação uma função deve ser chamada 2) retornar o nome da função para chamar junto com os parâmetros necessários. Seu pedido se parece com isso.
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." }
]
} ) ; Se uma função tiver sido selecionada, a resposta incluirá o nome da função e dos parâmetros. Sua responsabilidade é verificar se isso, ligue para o código do seu aplicativo correspondendo à função e aos parâmetros. Para o Lambdagpt, isso estará consultando o banco de dados e retornará todas as linhas correspondentes. Fazemos isso em nosso arquivo src/models/products.js .
Para que o OpenAi responda com os resultados, enviamos outra solicitação que agora possui duas mensagens adicionais incluídas. O primeiro é do tipo "função" e inclui o nome e os parâmetros da função que você foi solicitado a ligar. O segundo é do tipo "Usuário", que inclui os dados JSON dos produtos retornados do nosso processo de recuperação. O Openai agora responderá como se tivesse esse conhecimento o tempo todo!
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..."}]' } ,
]
} ) ; Como todas as mensagens são mantidas no estado do cliente, você pode vê-las usando uma técnica de depuração. Abra o arquivo src-frontend/components/Message.vue e faça a seguinte alteração.
'border-b-base-300': true,
'bg-base-200': data.role === 'user',
- 'hidden': data.hidden,
+ 'hidden': false,Agora você pode ver todas as mensagens do estado da interface do usuário. Esta é uma ótima maneira de depurar seu aplicativo e ver o que está acontecendo.
Espero que você tenha encontrado essa visão geral rápida de como as conclusões do Chat do OpenAI podem ser aumentadas para recuperação do conhecimento. Há muito mais para explorar e fazer. Aqui estão algumas idéias para você começar:
fetchResponse na loja src-frontend/stores/messages.js Pinia faz todo o trabalho aqui e gerencia o estado do lado do cliente.src/utils/functions.json . Por exemplo, um método find_style by id que consulteia diretamente o banco de dados.❤️ Espero que você tenha gostado dessas postagens e encontre o aplicativo Demo Lambdarag útil para aprender a usar a IA para recuperação do conhecimento. Sinta -se à vontade para fazer perguntas e compartilhar seus pensamentos sobre este post. Obrigado!