
Veuillez lire la série de blogs "Rags to Riches" complets:
https://dev.to/aws-heroes/rags-to-riches-part-1-generative-ai-reprieval-4pd7
Cette application de chat RAG basée sur Openai qui peut vous aider à découvrir les modèles de récupération d'IA. Les technologies ici sont conviviales et faciles à déployer pour AWS Lambda. Au fur et à mesure que vos besoins augmentent, n'hésitez pas à produire cette application avec des composants plus robustes. Qu'est-ce qu'un chiffon? De la recherche IBM:
Le RAG est un cadre d'IA pour récupérer les faits d'une base de connaissances externe à des modèles de grande langue (LLM) sur les informations les plus précises et à jour et pour donner aux utilisateurs un aperçu du processus génératif de LLMS.


Vous devez avoir une touche API OpenAI pour exécuter cette application. Vous pouvez en obtenir un gratuitement en utilisant ceci où puis-je trouver ma clé API secrète? guide. Une fois que vous avez votre clé Openai, créez un fichier .env.development.local à la racine de ce projet avec les suivants, en remplaçant sk... par votre clé:
OPENAI_API_KEY=sk...
Ce projet prend en charge les conteneurs de développement, ce qui signifie que vous pouvez utiliser VS Code pour ouvrir ce dossier dans un conteneur et que votre environnement de développement sera créé pour vous. Exécutez les commandes suivantes dans votre terminal intégré ou sur votre machine locale en supposant que vous avez installé le nœud.
./bin/setup
./bin/serverLa commande Server démarrera à la fois un serveur de développement avant et arrière. Utilisez cette URL pour accéder à votre application. http: // localhost: 5173
Cette application de démonstration utilise une architecture à stockage fractionné. Ce qui signifie qu'il y a un front-end et un back-end distinct. Le front-end est une application Vue.js avec? PINIA pour l'état et ⚡️ Vite pour le développement. Le frontal utilise également? CSS du vent arrière avec? Daisyui pour le style. Le back-end est un? Application Node.js qui utilise ❎ Express pour le framework HTTP, et? Sqlite3 vss avec? Better-Sqlite3 pour le stockage et la recherche vectoriels.
Tout au long du post, nous explorerons plus en détail diverses technologies et comment elles nous aident à créer une application de chiffon tout en apprenant les bases des intégrations axées sur l'IA et de l'ingénierie rapide. C'est un espace tellement amusant. J'espère que vous l'apprécierez autant que moi!
Commençons donc par la fin. Notre démo Lambdarag fonctionne localement pour le rendre facile à développer et à apprendre. À un moment donné, vous voudrez peut-être l'expédier en production ou partager votre travail avec d'autres. Alors pourquoi se déployer sur Lambda et quels avantages cette option de déploiement offre-t-elle? Quelques pensées:
De tous ces éléments, je pense que le streaming de réponse est le plus puissant. Une fonctionnalité relativement nouvelle pour Lambda, cela permet à notre chiffon de diffuser du texte au client Web comme Chatgpt. Il permet également à Lambda de rompre la charge utile de réponse de 6 Mo et la limite de délai d'expiration des 30. Ces quelques lignes dans le template.yaml du projet.yaml ainsi que l'adaptateur Web Lambda rendent tout possible.
FunctionUrlConfig :
AuthType : NONE
InvokeMode : RESPONSE_STREAM Avant de courir ./bin/deploy pour la première fois. Assurez-vous de vous connecter à la console AWS et de passer au magasin de paramètres SSM en premier. De là, créez un paramètre de chaîne secrète avec le chemin /lambda-rag/OPENAI_API_KEY et collez dans votre touche API OpenAI.
Notre backend a un module src/utils/openai.js très basique. Cela exporte un client OpenAI ainsi qu'une fonction d'assistance pour créer des intégres. Nous couvrons brièvement les intégres dans la section architecte de base de la première partie de cette série. Cette fonction transforme simplement la requête d'un utilisateur en une incorporation de vecteur qui est plus tard interrogé dans notre base de données SQLite. Il existe de nombreuses façons de créer et d'interroger des intérêts. Pour l'instant, nous allons rester simples et utiliser le modèle text-embedding-ada-002 d'OpenAI qui publie des incorporations dimensionnelles 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 ) ;
} ;Alors, comment les API d'Openai fonctionnent-elles pour créer une interface de chat et comment la fenêtre de contexte discutée dans la première partie est-elle en jeu? Considérez la capture d'écran suivante où je dis à Lambdarag mon nom, puis demandez si cela se souvient.
Chatgpt est sans état, comme la plupart des applications Web. Il n'a pas de session pour le modèle LLM. Chaque fois que vous envoyez un message, vous devez envoyer tous les messages (contextes) précédents au point de terminaison des achèvements. C'est pourquoi nous utilisons? PINIA pour la gestion de l'état côté client. Donc, du point de vue de l'API, cela ressemblerait à ceci ci-dessous.
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?" } ,
]
} ) ; Avez-vous remarqué comment l'assistant a répondu non seulement avec mon nom, mais nous savions également que c'était là pour nous aider avec des vêtements de luxe? Ceci est une technique appelée le rôle d'incitation. Nous le faisons dans la démo Lambdarag en ajoutant ce rôle au premier message de l'utilisateur dans le fichier src-frontend/utils/roleprompt.js .
Vous avez peut-être remarqué que la démo Lambdarag est entièrement écrite? JavaScript vs Python. Au fur et à mesure que vous en savoir plus sur la création d'applications d'IA, vous devrez peut-être éventuellement apprendre le python ainsi que des cadres plus avancés comme? ️? Langchain ou étreignant le visage? Transformers.js. Tous ont des versions JavaScript. J'espère que cette tendance à fournir des clients JavaScript se poursuivra. Cela ressemble à une langue plus accessible.
Dans la section suivante, nous couvrirons comment créer des intégres avec vos données et votre requête pour des documents à l'aide de la nouvelle extension VSS de SQLite.
? ️ L'application de démonstration de lambdarag contient une base de données SQLite prête à l'emploi avec environ 5 000 produits de l'ensemble de données de vêtements de luxe sur Kaggle. Il a également des intérêts vectoriels pré-grassés et prêts à l'emploi!
Avant de fouiller dans SQLite-VSS, je voudrais expliquer pourquoi je pense que cette extension est si incroyable. À ce jour, j'ai trouvé Sqlite-VSS le moyen le plus simple et le plus rapide d'explorer les intégres vectoriels. De nombreux projets Genai utilisent Supabase qui semble génial mais qui est difficile à exécuter localement. Le but ici est d'apprendre!
Au fur et à mesure que votre application se développe, je recommande fortement de regarder Amazon OpenSearch Serverless. Il s'agit d'un service entièrement géré, hautement évolutif et rentable qui prend en charge la recherche de similitude vectorielle. Il prend même en charge le pré-filtrage avec Faish.
Regardons SQLite-VSS un peu plus près. Cet article a une extension SQLite pour la recherche vectorielle fait un travail incroyable couvrant la création de tables standard ainsi que des tables virtuelles pour les intérêts et comment les interroger tous les deux. La démo lambdarag suit de près tous ces modèles dans notre fichier db/create.js . Notre schéma résultant est:
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 )
); Si vous souhaitez recréer la base de données SQLite ou créer un ensemble de données personnalisé, vous pouvez le faire en modifiant le db/create.js et en exécutant npm run db:create . Cela supprimera la base de données existante et les recréera avec les données de n'importe quel (s) fichier (s) CSV, le schéma de support ou le processus que vous êtes prêt à coder.
> 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 Ensuite, vous devez exécuter le script npm run db:embeddings qui utilise l'API OpenAI pour créer des incorporations pour chaque produit. Cela prend quelques minutes pour terminer tous les appels d'API. La tâche comprend un cache local pour faciliter la réévaluation. Enfin, il y a un Script npm run db:clean qui appelle un VACUUM sur la base de données pour supprimer l'espace gaspillé pour les tables virtuelles. Encore une fois, tout cela n'est requis que si vous souhaitez recréer la base de données ou créer un ensemble de données personnalisé. Il y a un script de wrapper ./bin/setup-db qui fait toutes ces étapes pour vous.
OK, nous avons donc une base de données de produits et leurs incorporations vectorielles correspondantes à utiliser pour la recherche sémantique. Comment codons-nous du chat pour récupérer les éléments de la base de données? Openai a cette fonctionnalité étonnante nommée Function Calling. Dans notre démo, il permet au LLM de rechercher des produits et de vous décrire les résultats.
Mais comment sait-il? Vous décrivez simplement un tableau de fonctions que votre application implique et lors d'un appel API de complétion de chat. OpenAI 1) prendra automatiquement une détermination, une fonction doit être appelée 2) Renvoie le nom de la fonction à appeler avec les paramètres nécessaires. Votre demande ressemble à ceci.
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." }
]
} ) ; Si une fonction a été sélectionnée, la réponse inclura le nom de la fonction et des paramètres. Votre responsabilité est de vérifier cela, puis d'appeler le code de votre application correspondant à la fonction et aux paramètres. Pour Lambdagpt, cela interrogera la base de données et renvoie les lignes correspondantes. Nous le faisons dans notre fichier src/models/products.js .
Pour que OpenAI réponde avec les résultats, nous lui envoyons une autre demande qui a maintenant deux messages supplémentaires inclus. Le premier est de type "fonction" et comprend le nom et les paramètres de la fonction que vous avez demandé d'appeler. Le second est de type "utilisateur" qui comprend les données JSON des produits renvoyés de notre processus de récupération. Openai répondra désormais comme s'il avait toujours cette connaissance!
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..."}]' } ,
]
} ) ; Étant donné que tous les messages sont maintenus à l'état côté client, vous pouvez les voir utiliser une technique de débogage soignée. Ouvrez le fichier src-frontend/components/Message.vue et effectuez la modification suivante.
'border-b-base-300': true,
'bg-base-200': data.role === 'user',
- 'hidden': data.hidden,
+ 'hidden': false,Vous pouvez maintenant voir tous les états des messages dans l'interface utilisateur. C'est un excellent moyen de déboguer votre demande et de voir ce qui se passe.
J'espère que vous avez trouvé cet aperçu rapide de la façon dont les compléments de chat d'Openai peuvent être augmentés pour la récupération des connaissances. Il y a tellement plus à explorer et à faire. Voici quelques idées pour vous aider à démarrer:
fetchResponse dans le src-frontend/stores/messages.js PINIA Store fait tout le travail ici et gère l'état côté client.src/utils/functions.json . Par exemple, une méthode find_style by id qui interrogerait directement la base de données.❤️ J'espère que vous avez apprécié ces messages et que vous trouverez l'application de démonstration de lambdarag utile pour apprendre à utiliser l'IA pour la recherche de connaissances. N'hésitez pas à poser des questions et à partager vos réflexions sur ce post. Merci!