RAG + Langchain Python Project: Easy AI/Chat For Your Docs

pixegami
20 Nov 202316:41

Summary

TLDREste video ofrece una guía paso a paso para construir una aplicación de generación aumentada por recuperación (RAG) utilizando Langchain y OpenAI. La aplicación es ideal para interactuar con grandes volúmenes de datos textuales, como colecciones de libros, documentos o conferencias. La demostración incluye la preparación de los datos, la creación de una base de datos vectorial con ChromaDB y el uso de técnicas de búsqueda para encontrar información relevante. El resultado es una respuesta coherente y personalizada basada en la fuente de datos proporcionada. Además, se explora la generación de consultas y la respuesta a preguntas utilizando un modelo de lenguaje grande (LLM). El video finaliza con un ejemplo práctico de cómo usar la documentación de AWS Lambda como fuente de datos para la aplicación.

Takeaways

  • 🚀 **Construimos una aplicación de generación aumentada por recuperación** usando Langchain y OpenAI para interactuar con documentos o fuentes de datos personales.
  • 📚 **La aplicación es ideal para manejar grandes volúmenes de datos textuales**, como colecciones de libros, documentos o conferencias.
  • 🤖 **Ejemplo de uso**: crear un chatbot de soporte al cliente que siga un conjunto de instrucciones o hacer preguntas sobre los datos.
  • 💡 **Técnica utilizada**: RAG (Retrieval Augmented Generation), que permite al agente utilizar la documentación para responder y citar la fuente de la información.
  • 📁 **Preparación de datos**: Se necesita una fuente de datos como archivos PDF, texto o markdown, que se divide en diferentes bloques de texto.
  • 📚 **Uso de Langchain**: El módulo de carga de directorios de Langchain se utiliza para convertir archivos markdown en documentos que contienen contenido y metadatos.
  • 🔍 **Creación de una base de datos vectorial**: Los bloques de texto se transforman en una base de datos usando ChromaDB, que utiliza vectores de incrustación como clave.
  • 📊 **Vectores de incrustación**: Son representaciones vectoriales del texto que capturan su significado y se calculan a través de funciones de OpenAI.
  • 🔗 **Búsqueda de datos relevantes**: Se utiliza una función de incrustación para convertir una consulta en un vector y buscar en la base de datos los bloques más cercanos en términos de distancia de incrustación.
  • 📝 **Generación de respuestas**: Se utiliza la información relevante encontrada para crear una respuesta personalizada usando un modelo de LLM como OpenAI.
  • 📜 **Inclusión de referencias**: La respuesta final incluye referencias a los materiales fuente utilizados, proporcionando trazabilidad y confianza en la información.
  • 🔧 **Disponibilidad del código**: El código de la aplicación se comparte en GitHub para que los espectadores puedan probarlo con sus propios conjuntos de datos.

Q & A

  • ¿Qué es una aplicación de generación aumentada por recuperación y cómo se utiliza?

    -Una aplicación de generación aumentada por recuperación es una herramienta que utiliza la inteligencia artificial para interactuar con grandes cantidades de datos de texto, como colecciones de libros, documentos o conferencias. Se puede utilizar para hacer preguntas sobre los datos o para construir un chatbot de soporte al cliente que siga un conjunto de instrucciones.

  • ¿Qué técnica se utiliza para construir la aplicación mostrada en el video?

    -Se utiliza la técnica llamada RAG, que significa 'generación aumentada por recuperación'. Esta técnica permite que el agente utilice una documentación para proporcionar una respuesta y citar la fuente de la información original.

  • ¿Cómo se carga y se divide el contenido de los documentos en la aplicación?

    -Se utiliza el módulo de carga de directorios de Langchain para cargar datos de markdown desde una carpeta en Python. Cada archivo de markdown se convierte en un 'documento' que contiene todo el contenido de la página y se puede dividir en 'chunks' más pequeños para una búsqueda más eficiente.

  • ¿Qué es un 'chunk' y cómo se determina su tamaño?

    -Un 'chunk' es una porción de texto que puede ser un párrafo, una oración o incluso varias páginas. Se determina su tamaño en número de caracteres y se establece una superposición entre cada 'chunk' para mantener la coherencia del texto.

  • ¿Cómo se convierte el contenido en una base de datos consultable?

    -Se utiliza ChromaDB, una base de datos que utiliza vectores de incrustación como clave. Se generan vectores de incrustación para cada 'chunk' utilizando la función de incrustación de OpenAI y se almacenan en la base de datos para su posterior consulta.

  • ¿Qué son los vectores de incrustación y cómo se relacionan con el significado del texto?

    -Los vectores de incrustación son representaciones vectoriales del texto que capturan su significado. Son listas de números que actúan como coordenadas en un espacio multidimensional. Si dos piezas de texto están relacionadas en significado, sus vectores también estarán cerca en el espacio.

  • ¿Cómo se genera un vector a partir de una palabra o un texto?

    -Para generar un vector se requiere un modelo de lenguaje grande (LLM) como OpenAI. Se puede utilizar una API o una función para convertir una palabra o un texto en un vector de incrustación, que es en realidad una lista de números.

  • ¿Cómo se utiliza la base de datos para responder a una consulta?

    -Se toma una consulta, se convierte en un vector utilizando la misma función que se utilizó para crear la base de datos y luego se busca en la base de datos para encontrar los 'chunks' de información más cercanos en distancia de vector a la consulta. Estos 'chunks' se utilizan para crear una respuesta personalizada.

  • ¿Cómo se crea una respuesta de calidad utilizando los datos relevantes?

    -Se utiliza un modelo de lenguaje grande (LLM) como OpenAI con un prompt que incluye el contexto relevante extraído de la base de datos y la consulta original. OpenAI utiliza estos datos para crear una respuesta que utiliza la información de la fuente.

  • ¿Cómo se puede proporcionar una referencia de volta a la fuente material en la respuesta final?

    -Se puede extraer la información de la metadata de cada 'chunk' de documento utilizado para responder la consulta. Esta información se puede incluir en la respuesta final para proporcionar una referencia de volta a la fuente material.

  • ¿Dónde puedo encontrar el código fuente de este proyecto?

    -El código fuente del proyecto se publicará en GitHub y se incluirá un enlace en la descripción del video. Puedes clonar el repositorio y probar el proyecto con tu propio conjunto de datos.

  • ¿Cómo puedo saber si este tipo de aplicación es adecuada para mi caso de uso?

    -Si tienes una gran cantidad de datos de texto y deseas interactuar con ellos de manera eficiente, como hacer preguntas o construir un chatbot de soporte al cliente, una aplicación de generación aumentada por recuperación puede ser una excelente opción.

Outlines

00:00

🚀 Introducción a la construcción de una aplicación de generación mejorada por recuperación

El primer párrafo presenta el objetivo del video, que es mostrar cómo construir una aplicación de generación mejorada por recuperación utilizando Langchain y OpenAI. Destacan la utilidad de este tipo de aplicación para manejar grandes volúmenes de datos textuales, como colecciones de libros, documentos o conferencias. La aplicación puede ser útil para hacer preguntas sobre los datos o para crear un chatbot de soporte al cliente que siga un conjunto de instrucciones. El vídeo guía a los espectadores a través de cada paso del proyecto, desde la preparación de los datos hasta la creación de una base de datos vectorial y la búsqueda de datos relevantes para formar una respuesta coherente.

05:02

📚 Preparación y división de los datos fuente

Se describe el proceso de preparación de los datos fuente, que puede incluir archivos PDF, textos o archivos de markdown. Se sugiere encontrar archivos markdown para usar en el proyecto y se menciona el uso de la biblioteca Langchain para cargar estos datos en Python. Cada archivo se convierte en un 'documento' que contiene todo el contenido y metadatos como el nombre del archivo fuente. Además, se destaca la necesidad de dividir documentos largos en 'chunks' más pequeños para mejorar la relevancia en búsquedas, utilizando un 'recursive character text splitter' con un tamaño de chunk y una superposición específicos.

10:03

🗃️ Creación de una base de datos vectorial con ChromaDB

Para consultar los 'chunks' de texto, se necesita una base de datos. Se utiliza ChromaDB, que utiliza vectores de incrustación como claves. Se explica cómo crear una base de datos de Chroma a partir de los 'chunks' utilizando el método de incrustación de OpenAI para generar vectores. Se discute la importancia de las incrustaciones vectoriales, que son representaciones vectoriales del texto que capturan su significado, y cómo se pueden calcular las distancias entre vectores usando similitud coseno o distancia euclidiana. Se proporciona un ejemplo de cómo generar vectores y comparar la distancia entre ellos utilizando una función de evaluador de Langchain.

15:07

🔍 Búsqueda y generación de respuestas con OpenAI

Se describe cómo buscar en la base de datos los 'chunks' más relevantes en relación con una consulta y cómo usar esta información para crear una respuesta personalizada utilizando OpenAI. Se menciona la necesidad de un modelo de LLM (Modelo de Lenguaje Grande) y cómo se puede usar para responder a una pregunta basada en el contexto proporcionado. Se muestra cómo crear una plantilla de prompt para OpenAI con los datos relevantes y la consulta, y cómo enviar esta prompt a OpenAI para obtener una respuesta. Además, se explica cómo extraer y proporcionar referencias de los materiales fuente utilizados en la respuesta.

🌟 Ejemplos y recursos adicionales

Se presentan ejemplos de cómo la aplicación puede utilizarse con diferentes fuentes de datos, como la documentación de AWS Lambda. Se muestra cómo la aplicación puede encontrar información relevante y publicar una respuesta resumida. Se alentará a los espectadores a probar el proyecto con sus propios conjuntos de datos y a dejar comentarios sobre los temas de tutoriales que les gustaría ver a futuro. Se ofrece un enlace a GitHub con el código del video en la descripción.

Mindmap

Keywords

💡Retrieval Augmented Generation (RAG)

Retrieval Augmented Generation (RAG) es una técnica que combina la generación de texto con la búsqueda de información relevante en una base de datos. En el vídeo, se utiliza RAG para permitir que el agente AI encuentre y utilice información específica de una fuente de datos, como la documentación de AWS Lambda, para responder a consultas de manera precisa y contextualizada.

💡Langchain

Langchain es una biblioteca de programación que se utiliza para manejar tareas relacionadas con el lenguaje natural y la generación de texto. En el contexto del vídeo, Langchain se utiliza para cargar, analizar y manipular datos de documentos de manera eficiente, permitiendo la creación de una aplicación de generación aumentada de recuperación.

💡OpenAI

OpenAI es una organización líder en el campo de la inteligencia artificial, conocida por sus modelos de lenguaje avanzados. En el vídeo, se utiliza OpenAI principalmente para generar vectores de embeddings, que son representaciones numéricas de texto que capturan su significado y se utilizan para comparar similitudes y relevancia en la base de datos.

💡Vector Embeddings

Los vectores de embeddings son representaciones vectoriales del texto que encapsulan su significado en una lista de números. Estos vectores se utilizan para medir la similitud entre diferentes textos. En el vídeo, los vectores de embeddings son fundamentales para la creación de la base de datos y para la búsqueda de información relevante en la misma.

💡ChromaDB

ChromaDB es una base de datos especial que utiliza vectores de embeddings como claves para almacenar y recuperar información. En la aplicación presentada en el vídeo, ChromaDB se utiliza para almacenar y consultar los fragmentos de texto de la documentación, permitiendo una búsqueda eficiente basada en la similitud semántica.

💡Metadata

Los metadatos son datos que proporcionan información sobre otros datos. En el vídeo, los metadatos incluyen el nombre del archivo de origen y el índice de inicio de cada fragmento de texto. Estos metadatos son cruciales para que el agente AI pueda proporcionar referencias precisas a la fuente de la información utilizada en sus respuestas.

💡Querying

La consulta (querying) es el proceso de buscar información específica dentro de una base de datos. En el contexto del vídeo, la consulta implica la generación de un vector de consulta a partir del texto de pregunta del usuario y la búsqueda de los fragmentos de la base de datos más cercanos a ese vector en términos de similitud semántica.

💡Document Chunking

El chunking de documentos se refiere a la práctica de dividir un documento en partes más pequeñas o 'chunks', que pueden ser párrafos, oraciones o incluso varias páginas. Esto se hace para mejorar la relevancia y la precisión en la búsqueda de información, como se muestra en el vídeo donde los documentos de AWS Lambda son divididos en chunks para su posterior búsqueda y análisis.

💡Embedding Distance

La distancia de embeddings es una medida de la similitud entre dos vectores de embeddings. Se utiliza para determinar qué tan relacionados son dos fragmentos de texto en términos de su contenido y significado. En el vídeo, la distancia de embeddings es crucial para la selección de los 'chunks' de texto más relevantes en respuesta a una consulta.

💡Prompt Template

Un template de prompt es una estructura predefinida que se utiliza para generar una solicitud (prompt) que se enviará a un modelo de lenguaje. En el vídeo, el template de prompt incluye marcadores de posición para el contexto y la consulta del usuario, lo que permite crear una solicitud coherente y completa para el modelo de OpenAI.

💡Source Material

El material de origen hace referencia a la información o los datos originales de donde se extrae y utiliza la información. En el vídeo, el material de origen incluye la documentación de AWS Lambda y el libro 'Alice en Wonderland', que son utilizados para construir la base de datos y proporcionar respuestas precisas a consultas específicas.

Highlights

Se muestra cómo construir una aplicación de generación aumentada por recuperación usando Langchain y OpenAI.

La aplicación es útil para interactuar con grandes cantidades de datos de texto, como colecciones de libros, documentos o conferencias.

Se utiliza una técnica llamada RAG (retrieval augmented generation) para responder a preguntas basadas en la documentación proporcionada.

El agente podrá citar la fuente de la información utilizada, evitando respuestas inventadas.

Se detalla cómo preparar los datos, convertirlos en una base de datos vectorial y consultarla para obtener respuestas coherentes.

Se necesita una fuente de datos como archivos PDF o una colección de archivos de texto o markdown.

Se utiliza el módulo directory loader de Langchain para cargar datos de markdown en Python.

Los documentos cargados se dividen en trozos más pequeños para una búsqueda más eficiente.

Se utiliza un separador de texto por caracteres recursivo para dividir los documentos en trozos con un tamaño y una superposición definidos.

ChromaDB se utiliza para crear una base de datos vectorial de los trozos de texto.

Se requiere una cuenta de OpenAI para generar las incrustaciones vectoriales de cada trozo usando la función de incrustación de OpenAI.

Las incrustaciones vectoriales son representaciones vectoriales del texto que capturan su significado.

La distancia entre vectores se calcula usando similitud coseno o distancia euclidiana.

Langchain proporciona una función utilitaria para comparar la distancia de incrustación directamente usando OpenAI.

Se busca en la base de datos los trozos más relevantes para la consulta del usuario.

Se utiliza una plantilla de prompt para crear una pregunta y se alimenta a OpenAI para obtener una respuesta de calidad.

Se puede proporcionar referencias de volta a los materiales fuente en los metadatos de cada trozo de documento.

Se muestra un ejemplo de cómo se utiliza la documentación de AWS Lambda para responder a consultas específicas.

El resultado final es una respuesta basada en la información de la fuente y una lista de referencias a los archivos fuente utilizados.

Transcripts

play00:00

Hey everyone, welcome to this video where I'm going

play00:02

to show you how to build a retrieval augmented

play00:05

generation app using Langchain and OpenAI.

play00:07

You can then use this app to interact with your

play00:10

own documents or your own data source.

play00:12

This type of application is great for when

play00:14

you have a lot of text data to work with.

play00:16

For example, a collection of books, documents or lectures. And

play00:20

you want to be able to interact with that data using AI.

play00:23

For example, you might want to be able to ask

play00:26

questions about that data or perhaps build

play00:28

something like a customer support chatbot that

play00:31

you want to follow a set of instructions.

play00:33

Today, we're going to learn how to build this using

play00:36

OpenAI and the Langchain library in Python.

play00:38

We're going to be using a technique called RAG, which

play00:41

stands for retrieval augmented generation.

play00:43

In this example, the data source I've given it is the AWS documentation for Lambda.

play00:49

And here I'm asking it a question based on that documentation.

play00:53

The agent will be able to use that documentation

play00:56

to give me a response as well as quote the source

play00:59

where it got that information from originally.

play01:01

This way, you always know that it's using data from the sources

play01:05

you provided it with rather than hallucinating the response.

play01:08

If this project sounds complex or difficult to you, then

play01:11

don't worry because it's a lot easier than you think.

play01:14

I'll walk you through every step of the project, starting

play01:17

with how to prepare the data that you want to use

play01:19

and then how to turn that into a vector database.

play01:22

Then we'll also look at how to query that database for relevant pieces of data.

play01:26

Finally, you can then put all those pieces together to form a coherent response.

play01:31

If that sounds good, then let's get started.

play01:33

To begin, we'll first need a data source like a

play01:38

PDF or a collection of text or markdown files.

play01:42

This can be anything.

play01:43

For example, it could be documentation files for your software.

play01:46

It could be a customer support handbook, or it

play01:49

could even be transcripts from a podcast.

play01:51

First, find some markdown files you want to use as data for this project.

play01:55

But if you want some ideas, then here I've got the Alice

play01:59

in Wonderland book as a markdown file, or I also have

play02:03

the AWS documentation as a bunch of markdown files.

play02:06

And I have each of them in their own separate

play02:09

folder under this data folder in my project.

play02:11

So make sure you have a setup like this first before you start.

play02:14

Once you have that source material, we're going to need to load

play02:17

it up and then split it into different chunks of text.

play02:19

To load some markdown data from your folder into Python,

play02:23

you can use this directory loader module from Langchain.

play02:26

Just update this data path variable with wherever you've decided to put your data.

play02:31

Here I'm using data/books.

play02:33

If you only have one markdown file in that folder, it's okay.

play02:36

Or if you have multiple markdown files, then

play02:39

this will load everything and turn each of those

play02:41

files into something called a document.

play02:43

If I use this piece of code on my AWS Lambda

play02:46

documents folder instead, then each of these

play02:48

markdown files will become a document.

play02:51

And a document is going to contain all of the content on this page.

play02:54

So basically all of the text you see here.

play02:57

And it's also going to contain a bunch of metadata.

play03:00

For example, the name of the source file where the text originally came from.

play03:04

And after you've created your document, you can also choose

play03:07

to add any other metadata you want to that document.

play03:10

Now the next problem we encounter is that a

play03:13

single document can be really, really long.

play03:16

So it's not enough that we load each markdown file into one document.

play03:20

We have to also split each document if they're too long on their own.

play03:24

With something as long as this, we're going to want

play03:27

to split this big document into smaller chunks.

play03:30

And a chunk could be a paragraph, it could be a

play03:32

sentence, or it could be even several pages.

play03:35

It depends on what we want.

play03:36

By doing this, the outcome that we're looking

play03:39

for is that when we search through all of this

play03:41

data, each chunk is going to be more focused

play03:44

and more relevant to what we're looking for.

play03:46

To achieve this, we can use a recursive character text splitter.

play03:50

And here we can set the chunk size in number of characters

play03:53

and then the overlap between each chunk.

play03:56

So in this example, we're going to make the chunk

play03:58

size about 1000 characters, and each chunk

play04:00

is going to have an overlap of 500 characters.

play04:03

So I've just ran the script to split up my text into several chunks.

play04:07

And here I've printed out the number of original documents

play04:11

and the number of chunks it was split into.

play04:14

Since I used this on the Alice in Wonderland

play04:17

text, it split one document into 282 chunks.

play04:20

And down here, I've just picked a random chunk as

play04:22

a document and I printed out the page content and

play04:24

the metadata so you could see what it looks like.

play04:27

So the page content is just literally a part of the text taken out of that chunk.

play04:32

So here you can see that it's about one or two paragraphs of the story.

play04:37

And the metadata right now, it only has the source, which is

play04:40

the path of the file it got this from, and the start index.

play04:44

So where in that source does this particular chunk begin?

play04:48

And if you try the same code with the AWS Lambda docs

play04:51

instead, you'll see that the source also points to

play04:55

the file that the information of each chunk is from.

play04:58

So this is also useful if you have a lot of different files,

play05:01

rather than just one big file splitting into smaller chunks.

play05:05

To be able to query each chunk, we're going to need to turn this into a database.

play05:09

We'll be using ChromaDB for this, which is a special kind

play05:12

of database that uses vector embeddings as the key.

play05:15

This is the code that you can use to create a Chroma database from our chunks.

play05:19

For this, you're going to need an OpenAI account because

play05:22

we're going to use the OpenAI embeddings function

play05:25

to generate the vector embeddings for each chunk.

play05:27

I'm also going to create a Chroma path and set that

play05:30

as the persistent directory so that when we create

play05:33

this database, I have a bunch of folders on my

play05:36

disk that I can use to load the data later on.

play05:39

This is useful because normally I might want to

play05:42

put this database into a Lambda function or I

play05:44

might want to put it in the cloud somewhere.

play05:47

So I want to be able to save it to disk so

play05:49

that I can copy it or deploy it as a file.

play05:51

Now before I create the database or before I save

play05:53

it to disk, I can also use this code snippet

play05:56

to remove it first if it already exists.

play05:58

This is useful if I want to clear all of my previous versions

play06:01

of the database before I run the script to create a new one.

play06:03

Now the database should save automatically after we create it,

play06:07

but you can also force it to save using this persist method.

play06:10

So once you've put all of that together and then

play06:13

you've run your script to generate your database,

play06:16

you should see this line where it's saved

play06:18

all of your chunks to the Chroma database.

play06:21

And you can see here on your disk that the data should be there as well.

play06:24

And here it's going to be saved as a SQLite3 file.

play06:27

So now at this point we have our vector database

play06:30

created and we're ready to start using it.

play06:32

But first you're probably going to want to know what a vector embedding is.

play06:36

If you already know what embedding vectors are,

play06:38

then feel free to skip the section entirely.

play06:41

Otherwise, I'll give you a really quick explanation just to bring you up to speed.

play06:45

Embeddings are vector representations of text that capture their meaning.

play06:49

In Python, this is literally a list of numbers.

play06:52

You can think of them as sort of coordinates in multi-dimensional

play06:56

space and if two pieces of text

play06:58

are closely related to each other in meaning, then

play07:00

those coordinates will also be close together.

play07:03

The distance between these vectors can then be calculated pretty

play07:07

easily using cosine similarity or Euclidean distance.

play07:10

We don't need to do that ourselves though, because there's a

play07:13

lot of existing functions that can do that for us already.

play07:15

And this will give us a single number that tells

play07:18

us how far these two vectors are apart.

play07:20

To actually generate a vector from a word, we'll need an LLM, like OpenAI.

play07:25

And this is usually just an API or a function we can call.

play07:27

For example, you can use this code to turn

play07:30

the word "apple" into a vector embedding.

play07:32

And this is the result I get from using that function.

play07:35

So you could see that the vector here is literally a really long list of numbers.

play07:41

And the first number is 0.007 something-something, but

play07:45

I truncated the rest because the list is quite long.

play07:48

In fact, if you print the length of the vector, you

play07:51

could see that the list has 1536 characters.

play07:54

So this is basically a list of one and a half thousand numbers.

play07:58

The numbers themselves aren't interesting though.

play08:00

What's really interesting is the distance between two vectors themselves.

play08:05

And this is quite hard to calculate from scratch, but

play08:08

Langchain actually gives us a utility function to compare

play08:11

the embedding distance directly using OpenAI.

play08:14

So it's called an evaluator and this is how you can create one.

play08:17

And here's the code to run an evaluation.

play08:20

So here I'm comparing the distance of the word "apple" to the word "orange".

play08:26

And running this, the result is a score of 0.13.

play08:30

So we don't actually know whether that's good or not

play08:33

by comparing an apple to an orange, because we don't

play08:36

know where 0.13 sits on the scale of other words.

play08:38

So let's try a couple of other words just to see what's a better

play08:42

match with apple than orange, and what's a worse match.

play08:45

Here, if I compare "apple" to the word "beach", it's actually 0.2.

play08:49

So "beach" is further away from "apple" than "orange"

play08:52

is, I suppose because one is a fruit.

play08:54

So that naturally makes it more similar.

play08:56

Now if I compare the word "apple" to itself, this should

play08:58

technically be 0 because it's literally the same word.

play09:01

But in this case, it's close enough.

play09:02

It's 2.5 x 10^-6.

play09:05

Now what about if we compare the word "apple" to "iPhone"?

play09:08

In this case, the score is even better than when we compared it with "orange".

play09:11

The score is 0.09.

play09:13

And this is really interesting as well, because in our

play09:16

first example with apples and oranges, they were

play09:18

both fruits, so they were similar in that respect.

play09:21

But here, we're sort of interpreting the word "apple" from a different perspective.

play09:25

We're seeing it as the name of the company "apple" instead.

play09:28

So when you compare it with the word "iPhone",

play09:31

the association is actually much stronger.

play09:33

So now that you understand what embeddings are,

play09:35

let's see how we can use it to fetch data.

play09:38

To query for relevant data, our objective is to find

play09:41

the chunks in our database that will most likely contain

play09:44

the answer to the question that we want to ask.

play09:47

So to do that, we'll need the database that we created

play09:50

earlier, and we'll need the same embedding

play09:52

function that we used to create that database.

play09:54

Our goal now is to take a query, like the one

play09:57

on the left here, and then turn that into

play10:00

an embedding using the same function, and

play10:02

then scan through our database and find

play10:05

maybe five chunks of information that are

play10:08

closest in embedding distance from our query.

play10:11

So here, in this example, I might ask the question

play10:13

like, "How does Alice meet the Mad Hatter in Alice

play10:16

in Wonderland?" And when we scan our database,

play10:19

we might get maybe four or five snippets of

play10:22

text that we think is similar to this question.

play10:24

And from that, we can put that together, have

play10:27

the AI read all of that information, and decide

play10:30

what is the response to give to the user.

play10:32

So although we're not just simply returning the

play10:35

chunks of information verbatim, we're actually

play10:38

using it to craft a more custom response

play10:40

that is still based on our source information.

play10:42

To load the Chroma database that we created, we're

play10:45

first going to need the path, which we have from

play10:47

earlier, and we're going to need an embedding

play10:49

function, which should be the same one we used

play10:51

to create the database with in the first place.

play10:53

So here, I'm just going to use the OpenAI embeddings function again.

play10:56

This should load your database from that path.

play10:58

If it doesn't, then just check that the path exists,

play11:00

or just go back to the previous chapter and

play11:03

run the script to create the database again.

play11:05

Once the database is loaded, we can then search for the

play11:08

chunk that best matches our query by using this method.

play11:11

We need to pass in our query text as an argument and

play11:14

specify the number of results we want to retrieve.

play11:17

So in this example, we want to retrieve three best matches for our query.

play11:21

The results of the search will be a list of tuples where

play11:24

each tuple contains a document and its relevance score.

play11:27

Before actually processing the results though, we can also add some checks.

play11:31

For example, if there are no matches or if the

play11:34

relevant score of the first result is below

play11:36

a certain threshold, we can return early.

play11:39

This will help us to make sure that we actually

play11:41

find good, relevant information first before

play11:44

moving to the next step of the process.

play11:46

So now let's go to our code editor and put all that together and see what we get.

play11:50

So here I've got the main function.

play11:52

I just made a quick argument parser so I can

play11:54

input the query text in the command line.

play11:56

I've got my embeddings function and I'm going to

play11:59

search the database that I've loaded and I'm

play12:01

just going to print the content for each page.

play12:04

So I'm going to find the top three results for my query.

play12:07

So that's my script. Let's give it a go.

play12:09

So here I'm running my script with the query,

play12:11

which is how does Alice meet the mad hatter?

play12:13

Here it's returned the three most relevant chunks

play12:16

in the text that it thought best match our query.

play12:19

So we have this piece of information, this piece

play12:22

of information, and then this one here.

play12:24

Now here the chunk size is quite small, so it doesn't

play12:27

have the full context of each part of the text.

play12:30

So if you want to edit that you can play with

play12:32

that chunk size variable and make it either

play12:34

bigger or smaller, depending on what

play12:36

you think will give you the best results.

play12:38

But for now, let's move on to the next step

play12:41

and see if we can get the AI to use this

play12:44

information and give us a direct response.

play12:47

Now that we have found relevant data chunks for our

play12:50

query, we can feed this into OpenAI to create a high

play12:53

quality response using that data as our source.

play12:55

First, we'll need a prompt template to create a prompt with.

play12:58

You can use something like this.

play13:00

Notice that there's placeholders for this template.

play13:02

The first is the context that we're going to pass in.

play13:05

So that's going to be the pieces of information that we got from the database.

play13:09

And then the second is the actual query itself.

play13:11

Next, here's the code to actually use that data to create the

play13:15

actual prompt by formatting the template with our keys.

play13:19

So after running this, you should have a single piece of string.

play13:22

It's going to be quite a long string, but it's going

play13:25

to be the entire prompt with all the chunks of information

play13:28

and the query that you asked at the beginning.

play13:30

After running that piece of code, you should

play13:32

get a prompt that looks something like this.

play13:34

So you're going to have this initial prompt, which is to

play13:37

answer the question based on the following context.

play13:40

And then we're going to have our three pieces of information.

play13:43

And this can be as big or as little as we want

play13:45

it to be, but here this is what we've chosen.

play13:47

And then the question that we originally asked.

play13:50

So here's our query.

play13:51

How does Alice meet the Mad Hatter?

play13:53

So this is the overall prompt that we're about to send to OpenAI.

play13:58

This is actually the easy part.

play14:00

So simply just call the LLM model of your choice with that prompt.

play14:03

So here I'm using chatOpenAI, and then you'll have your response.

play14:07

Finally, if you want to provide references back to

play14:10

your source material, you can also find that in

play14:13

the metadata of each of those document chunks.

play14:16

So here's the code on how you can extract that out and print it out as well.

play14:19

And going back to our code editor, this is what my script

play14:22

looks like with all of those pieces put together.

play14:25

So I've got my prompt template here.

play14:27

I've got my main argument here, which takes the query, searches

play14:31

the database for the relevant chunks, creates the

play14:35

prompt, and then uses the LLM to answer the question.

play14:38

And then here I'm collecting all the sources that were used

play14:41

to answer the prompt and print out the entire response.

play14:44

Let's go ahead and run that.

play14:45

And here's the result of running that script.

play14:48

So again, we see the entire prompt here, and this is the final response.

play14:52

The response is Alice meets the Mad Hatter by walking in

play14:56

the direction where the March Hare was set to live.

play14:58

And obviously it took this from the first piece of the context.

play15:02

And here we also have a list of the source references that it got it from.

play15:07

This is pretty much pointing to the same file because I only

play15:10

made it print out the actual file itself and not the index.

play15:13

But this is pretty good already because you can

play15:15

see how it's using our query to search for

play15:18

pieces of information from our source material

play15:20

and then answer based on that information.

play15:23

Now let me switch up my data source and show you

play15:25

a different example just so you can see what

play15:27

else you can do with something like this.

play15:29

I switched my database to one I prepared earlier, which

play15:32

uses the AWS Lambda documentation as a source.

play15:35

And here the query I'm going to ask it is what

play15:38

languages or runtimes does AWS Lambda support?

play15:41

So after I ran this, you can see that the chunks

play15:43

I use here are much bigger than in the previous

play15:46

example, but it still managed to find three relevant

play15:49

chunks of my information and it's published

play15:51

a response that summarizes that information.

play15:53

So here it says AWS Lambda supports Java, C#, Python, and etc.

play15:58

You can read the rest here.

play16:00

But this is more interesting because unlike in the first

play16:03

example, the sources were actually from different files.

play16:06

So you can see here that each of the source is its own file.

play16:09

So this is useful as well.

play16:11

If you have data source that spread out across a lot of different

play16:14

files and you want to see how to reference the source.

play16:17

So we just covered how you can use the line chain and OpenAI

play16:20

to create a retrieval augmented generation app.

play16:23

I'll post a link to the GitHub code in the video

play16:26

description and I encourage you to try this

play16:28

out for yourself and with your own data set.

play16:30

If you want to see more tutorials like this, then please let

play16:32

me know what type of topics you'd be interested to see next.

play16:35

Otherwise, I hope you found this useful and thank you for watching.

Rate This

5.0 / 5 (0 votes)

Related Tags
Aplicaciones de IALangchainOpenAIRAGDocumentación AWSChatbotsVector DatabaseEmbeddingsChromaDBData RetrievalAI GeneraciónTutorías de ProgramaciónInteracción con DatosLLM
Do you need a summary in English?