
Lea la serie completa de blogs "Rags to Riches":
https://dev.to/aws-heroes/rags-to-riches-part-1-generative-ai-retrieval-4pd7
Esta aplicación de chat de trapo con sede en OpenAI que puede ayudarlo a aprender sobre los patrones de recuperación de AI. Las tecnologías aquí son amigables para principiantes y fáciles de implementar en AWS Lambda. A medida que sus necesidades crecen, no dude en producir esta aplicación con componentes más robustos. ¿Qué es un trapo? De la investigación de IBM:
RAG es un marco de IA para recuperar hechos de una base de conocimiento externa a modelos de lenguaje grande (LLM) en la información más precisa y actualizada y para dar a los usuarios una idea del proceso generativo de LLMS.


Debe tener una tecla API de OpenAI para ejecutar esta aplicación. Puedes obtener uno gratis usando esto, ¿dónde encuentro mi clave de API secreta? guía. Una vez que tenga su tecla OpenAI, cree un archivo .env.development.local en la raíz de este proyecto con lo siguiente, reemplazando sk... con su clave:
OPENAI_API_KEY=sk...
Este proyecto admite contenedores de desarrollo, lo que significa que puede usar el código VS para abrir esta carpeta en un contenedor y su entorno de desarrollo se creará para usted. Ejecute los siguientes comandos en su terminal integrado o en su máquina local suponiendo que haya instalado el nodo.
./bin/setup
./bin/serverEl comando del servidor iniciará un servidor de desarrollo frontal y de back -end. Use esta URL para acceder a su aplicación. http: // localhost: 5173
Esta aplicación de demostración utiliza una arquitectura de pila dividida. Lo que significa que hay un front-end y back-end distintos. El front-end es una aplicación Vue.js? PCINIA para el estado y ⚡️ Vite para el desarrollo. El front-end también usa? ¿CSS de viento de cola junto con? Daisyui para el estilo. El back-end es un? Aplicación node.js que usa ❎ express para el marco HTTP y? SQLITE3 VSS junto con? Mejor-SQLITE3 para el almacenamiento y búsqueda de vectores.
A lo largo de la publicación, exploraremos varias tecnologías con más detalle y cómo nos ayudan a construir una aplicación de trapo mientras aprendemos los conceptos básicos de las integraciones impulsadas por la IA y la ingeniería rápida. Este es un espacio muy divertido. ¡Espero que lo disfrutes tanto como yo!
Así que comencemos con el final en mente. Nuestra demostración de Lambdarag se ejecuta localmente para facilitar el desarrollo y aprender. En algún momento, es posible que desee enviarlo a producción o compartir su trabajo con otros. Entonces, ¿por qué implementar en Lambda y qué beneficios ofrece esa opción de implementación? Algunos pensamientos:
De todos estos, creo que la transmisión de respuesta es la más poderosa. Una característica relativamente nueva para Lambda, esto permite a nuestro trapo transmitir texto al cliente web al igual que ChatGPT. También permite que Lambda rompa la carga útil de la respuesta de 6 MB y el límite de tiempo de espera de los 30. Estas pocas líneas en la template.yaml del proyecto. Yaml junto con el adaptador web Lambda lo hacen posible.
FunctionUrlConfig :
AuthType : NONE
InvokeMode : RESPONSE_STREAM Antes de correr ./bin/deploy por primera vez. Asegúrese de iniciar sesión en la consola AWS y navegar primero hasta la tienda de parámetros SSM. Desde allí, cree un parámetro de cadena secreta con la ruta /lambda-rag/OPENAI_API_KEY y pegue en su tecla API OpenAI.
Nuestro backend tiene un módulo src/utils/openai.js muy básico. Esto exporta a un cliente OpenAI, así como una función de ayuda para crear incrustaciones. Cubrimos brevemente los incrustaciones en la sección Arquitecto Básico de la primera parte de esta serie. Esta función simplemente convierte la consulta de un usuario en una incrustación vectorial que luego se consulta con nuestra base de datos SQLite. Existen numerosas formas de crear y consultar incrustaciones. Por ahora, lo mantendremos simple y usar el modelo text-embedding-ada-002 de OpenAI que genera 1536 incrustaciones dimensionales.
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 ) ;
} ;Entonces, ¿cómo funciona la API de OpenAI para crear una interfaz de chat y cómo entra en juego la ventana de contexto discutida en la primera parte? Considere la siguiente captura de pantalla donde le digo a Lambdarag mi nombre y luego pregunte si recuerda.
ChatGPT es apátrate, como la mayoría de las aplicaciones web. No tiene sesión para el modelo LLM. Cada vez que envía un mensaje, debe enviar todos los mensajes anteriores (contexto) al punto final de finalización. ¿Por eso usamos? PCINIA para la gestión del estado del lado del cliente. Entonces, desde una perspectiva de API, se vería algo así a continuación.
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?" } ,
]
} ) ; ¿Notó cómo el asistente respondió no solo con mi nombre, sino que también sabía que estaba aquí para ayudarnos con ropa de lujo? Esta es una técnica llamada asignación de roles. Hacemos esto en la demostración de Lambdarag al preparar este papel con el primer mensaje del usuario en el archivo src-frontend/utils/roleprompt.js .
¿Es posible que haya notado que la demostración de Lambdarag está escrita por completo? JavaScript vs. Python. A medida que aprende más sobre la creación de aplicaciones de IA, es posible que eventualmente tenga que aprender Python, así como marcos más avanzados como? ¿Langchain o abrazando la cara? Transformers.js. Todos los cuales tienen versiones de JavaScript. Espero que esta tendencia de proporcionar a los clientes de JavaScript continúe. Se siente como un idioma más accesible.
En la siguiente sección, cubriremos cómo crear incrustaciones con sus datos y consultar los documentos utilizando la nueva extensión VSS de SQLITE.
? ️ La aplicación de demostración de Lambdarag contiene una base de datos SQLite lista para usar con ~ 5,000 productos del conjunto de datos de vestimenta de lujo en Kaggle. ¡También tiene insertos de vectores pre-sembrados y listos para usar!
Antes de profundizar en SQLite-VSS, me gustaría explicar por qué creo que esta extensión es tan sorprendente. Hasta la fecha, he encontrado que SQLite-VSS es la forma más fácil y rápida de explorar las integridades vectoriales. Muchos proyectos de Genai usan Supabase, que parece genial pero es difícil de ejecutar localmente. ¡El objetivo aquí es aprender!
A medida que su aplicación crece, recomiendo ver a Amazon OpenSearch Servidor sin servidor. Es un servicio totalmente administrado, altamente escalable y rentable que admite la búsqueda de similitud vectorial. Incluso admite el prefiltrado con FAISS.
Veamos SQLite-VSS un poco más cerca. Este artículo, una extensión de SQLite para la búsqueda de vectores, hace un trabajo increíble que cubre la creación de tablas estándar, así como tablas virtuales para incrustaciones y cómo consultar las dos. La demostración de Lambdarag sigue todos estos patrones de cerca en nuestro archivo db/create.js . Nuestro esquema resultante es:
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 desea recrear la base de datos SQLite o crear un conjunto de datos personalizado, puede hacerlo cambiando el db/create.js y ejecutando npm run db:create . Esto soltará la base de datos existente y la recreará con datos de cualquier archivo (s) de CSV, esquema de soporte o proceso que esté dispuesto 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 Después, necesitaría ejecutar el script npm run db:embeddings que utiliza la API de OpenAI para crear incrustaciones para cada producto. Esto lleva unos minutos completar todas las llamadas de API. La tarea incluye un caché local para que sea más rápido volver a ejecutar. Por último, hay un script npm run db:clean que llama un VACUUM en el DB para eliminar el espacio desperdiciado para las tablas virtuales. Nuevamente, todo esto solo se requiere si desea recrear la base de datos o crear un conjunto de datos personalizado. Hay un script de envoltura ./bin/setup-db que hace todos estos pasos por usted.
Ok, entonces tenemos una base de datos de productos y sus incrustaciones de vectores coincidentes para usar para la búsqueda semántica. ¿Cómo codificamos el chat de la recuperación de elementos de la base de datos? OpenAi tiene esta increíble característica llamada Function Calling. En nuestra demostración, permite que la LLM busque productos y describiera los resultados.
Pero, ¿cómo sabe? Simplemente describe una variedad de funciones que implica su aplicación y durante una llamada API de finalización de chat. OpenAI 1) tomará automáticamente una determinación, se debe llamar a una función 2) Devolver el nombre de la función para llamar junto con los parámetros necesarios. Su solicitud se parece a esto.
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 se ha seleccionado una función, la respuesta incluirá el nombre de la función y los parámetros. Su responsabilidad es verificar esto, luego llamar al código de su aplicación que coincida con la función y los parámetros. Para Lambdagpt, esto consultará la base de datos y devolverá cualquier fila coincidente. Hacemos esto en nuestro archivo src/models/products.js .
Para que Operai responda con los resultados, lo enviamos otra solicitud que ahora tiene dos mensajes adicionales incluidos. El primero es de tipo "función" e incluye el nombre y los parámetros de la función a la que se le pidió que llamara. El segundo es de tipo "usuario", que incluye los datos JSON de los productos devueltos de nuestro proceso de recuperación. ¡Openai ahora responderá como si tuviera este conocimiento todo el tiempo!
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..."}]' } ,
]
} ) ; Dado que todos los mensajes se mantienen en el estado del lado del cliente, puede verlos utilizando una técnica de depuración ordenada. Abra el archivo src-frontend/components/Message.vue y realice el siguiente cambio.
'border-b-base-300': true,
'bg-base-200': data.role === 'user',
- 'hidden': data.hidden,
+ 'hidden': false,Ahora puede ver todos los mensajes en la interfaz de usuario. Esta es una excelente manera de depurar su aplicación y ver lo que está sucediendo.
Espero que hayas encontrado esta visión general rápida de cómo se pueden aumentar las terminaciones de chat de Openai para la recuperación de conocimiento. Hay mucho más para explorar y hacer. Aquí hay algunas ideas para comenzar:
fetchResponse en la tienda src-frontend/stores/messages.js Pental hace todo el trabajo aquí y administra el estado del lado del cliente.src/utils/functions.json . Por ejemplo, un método find_style por ID que consultaría directamente la base de datos.❤️ Espero que hayas disfrutado de estas publicaciones y encuentre la aplicación de demostración de Lambdarag útil para aprender a usar AI para la recuperación de conocimiento. Siéntase libre de hacer preguntas y compartir sus pensamientos sobre esta publicación. ¡Gracias!