Transcript for:
Creating a Free Vector Store with Supabase

Hey guys, and welcome to this crash course, where you're going to learn everything you need to know about creating a free vector store over in Supabase, how to save data and embeddings to this vector store. And finally, how you can use RAC to start chatting with your data. And by the end of this video, you're going to have built a mini full stack application that allows you to start saving emails to this vector store and start chatting with all of your previous emails. So you can start asking questions to them and don't worry, I'm going to be going through this step by step together with you guys. and I'm going to be giving away all the source code completely for free. Just check that link down in the description below. But with all that out of the way, let's go ahead and dive into the video. All right, guys. So let me give you a step-by-step walkthrough of everything that we're about to do together inside of this tutorial. So first things first, we are going to set up a Supabase project together. It's completely free to do, and I'll give you a brief overview of everything we can do inside this platform, just in case you haven't used them before. Now, What we're going to do once we've created our account is we're going to move over to the database side of Supabase, where we're going to start creating our own tables to start storing all of our information. Specifically, we're going to be using Supabase Postgres database to store our emails and store our embeddings for our emails. And just a quick recap in case it's been a minute since you've heard embeddings. An embedding is nothing more than a numerical representation of text. And the reason why it exists is because... computers love comparing numbers to numbers. So whenever we start making queries to our database, it makes it very easy for a computer to go like, oh, this query looks a lot like this content. Here you go. So that's why we're using vector stores to store our embedding. So we're going to learn all about this in the database section. Then we are going to move over to quickly creating a Next.js project. And what we're going to be doing is we're just want to make it very easy to go off and send our emails to our database. And this is where you're going to learn how to send up email to a backend function. That backend function is going to then take that text, save it to a database. And then what it's also going to do is break up that email into smaller pieces and embed each piece of the email. So you'll see this in action. And this is where we're really going to start diving into working with like cool text embeddings, save it to a vector store. Like this is where, you know, the rubber meets the road. So I'm very excited for you guys to see this section. And then finally, this is where. we get to reap the rewards of using a vector store. And this is by far my favorite part of the whole video is the last part. And here's exactly what we're going to do. You are going to learn how to start making RAG queries. So retrieval augmented generation, which very fancy for just saying like, we want to ask a question. And what we want to do is pull out relevant information from our vector store, throw that information over to ChachubiT and ChachubiT give us back an answer that sounds nice. That's all that's happening. But the reason why I'm so excited to show you this specific setup is because you're going to learn how you can combine all the power of a SQL database with a vector store. And what I mean is you're going to learn how we can start querying to say like, hey, I actually don't want to look through the entire vector store to figure out where Brandon wants to live. I specifically only want to look at emails where the sender or recipient is from, you know, Brandon at gmail.com. And once I'm specifically looking at a particular client of mine that I've been working with, then I want to start doing RAG. So this is why I'm so excited because with Pinecone and a lot of these other vector stores, you can't easily do this. And Supabase, the fact that it's free and we get to combine SQL plus vector store querying, like this is awesome. So I am so excited for you guys to see this. This is by far the best part of the whole video. So hopefully now that you're hyped as I am, let's go ahead and hop over to phase number one, where we're going to start setting up. your own Supabase account and create your first project. So let's go ahead and head over to phase number one. All right, guys. So welcome to Supabase. And what we're going to do in this section is we're going to go ahead and sign in and we're going to create our first project together. So what you're going to do over in Supabase, I'll have a link to it down in the description below, but let's go ahead and click that and take you over to Supabase. And then you're going to log in. So just feel free to sign in with your GitHub or your Google account or whatever else it offers you. Then once you're done, you're going to click dashboard. to go over to your dashboard, where you're going to see a page that looks just like this. If it is your first time using it, it is going to ask you to create a new organization. So feel free to call it whatever you want. I just did AI with Brandon. So feel free to just do AI with, and then throw your name in there. Cool. Once you have set up an organization, it's now time for us to go off and create a project. So I'm just going to do this with you guys so we can go through it step by step. And just remember our ultimate goal is we're trying to set up a super based project so that we can start creating our new. database that's going to allow us to start adding and storing our embeddings. So that's our, what we're trying to do and ultimate goal. So let's go ahead and say, I want to create a new project. And then we're just going to call this together. So we're going to do AI email, auto responder, and I'm going to call mine YouTube. And then when it comes to a database strong, basically for your database password, just click generate password. copy it, and then just save it elsewhere. You don't really need this and you can access it later on, but just feel free to just save that password that it generates elsewhere, because there is a chance you could use it later on. So copy it, save it to another file. Then when it comes to region, I'm just going to click the one, the default, the East US. All right, let's go ahead and click create new project. And what this is going to do is create a new Supabase project that will basically have all the core functionality. So it's going to love Supabase for this, but. It already comes with a database. It already, and I was walking through this here, just as quick overview, but inside of our new project, you can see we now have a database and this is where we're going to be doing all of our work, where we go off and create everything in just a little bit, but we can also go ahead and include authentication. We can do storage. We can do edge functions. There's a lot that we can do inside of here. So Supabase is a super powerful platform. It does kind of have a little bit of a steeper learning curve, just because everything is given to you out of the box. but it's up to you to learn everything at the same time. It is awesome, but it just takes a little bit more of a setup. So what I'm going to do, I'm going to pause real fast because it's going to take a few minutes to go ahead and create your project. So as soon as it's done, I'll hop back over and show you what we need to do next. So see you in a second. All right, guys. So after about another 10, 15 seconds of waiting, everything worked out and you should see a page that looks just like this, where it's just going to say, hey, welcome to our new project. Here's the title of it. And it's going to give you some information about your project status and show you how you can easily start connecting to everything. And one of the things I want to show you guys is we are going to start going ahead in the next video and next section, going to go ahead and start creating our own tables. So I'm super excited for you guys to learn how to go ahead and start setting these up. So let's go ahead and dive over to phase number two. All right, guys, welcome to phase number two, where we're going to start working on setting up your database inside of Supabase. And before we get super technical with like writing out all of our SQL commands to create our tables and everything, let's just keep everything high level first, understand what we're ultimately trying to do. So whenever we do start creating our tables, we'll know exactly what's going on. So first things first, our North star and what we're ultimately trying to achieve is we want to start saving our emails to our database. So we want to start saving, you know, who sent the email, who were they sending it to? What was the subject line? What was the actual text inside of the email? So we need to go off and create a table inside of Supabase to store all of this information. So pretty much just copy it over and paste it into our database. Super simple. We'll create that email table. Now here's where we get to put on our AI developer hats and start thinking. So as an AI developer, we know that we need to start working with some of our embeddings. So basically we need to take the body of this email, embed it, and actually start saving it inside of our database. Now, what are some constraints that we're going to run into? Well, the The first big one is when it comes to embedding, our current models can only accept up to about 8,000 tokens. And the best way to think of it is a token is usually, let's see, two to four tokens make up a word. So let's just say in general, this is only going to allow us to write 2,000 words. We can embed 2,000 words in one little chunk. So that means we need the ability if we, for example, just get a super long email. That's 10,000 words. It's a book. It's a lot of text in this email. So it's 10,000 words. Well, that means we need to start breaking up that big email into a bunch of smaller chunks that we're just going to call email sections. And all we're going to do is just say, hey, every 2,000 characters or so, I want to break up this email into an email section. And once I have that small section that I know will fit inside of our embedding model that you'll see this in a lot more detail later on. But just note. i want to start breaking this up into smaller chunks every time i get like a small snippet that's safe to embed i'm then going to you know make sure that this content plus its embedding representation are saved to the database that way later on whenever i have a question such as hey where does brandon live and i can easily start searching through all of our emails to say like okay well i want to make sure the recipients from brandon and whenever Now what I can start doing is making a request to say, where does Brandon live? And I can start comparing that request and embedded version of it to this one and go, oh, it looks like Brandon lives in Georgia. Okay, cool. So now what I can do is go, all right, this embedding, ding, ding, ding. It matches my initial question. Cool. I will then give back this content. And that's exactly how the full circle is going to work. So hopefully this is all making sense. Quick recap, what we need to do. We need to go create a new email table. This email table is going to store it. everything from the raw original email. And then what we're going to do is say, all right, each email is going to have multiple email sections where these email sections are going to store some content and the vector representation of that content. So I know there's a lot, but you're going to see that now, whenever we hop over to Supabase and start creating these tables, it'll all start clicking. I just want to keep everything high level first. And I did just want to mention, if you like, and this like kind of like diving deep into like. data and setting up models i have a over inside of the school community inside of the course i have set up i actually made a free version of the first few sections where we actually do a huge deep dive into talking about how you can set up models and views and what are all the different types of model relationships that you're probably going to start working with inside of building these full stack applications so definitely recommend checking out these two mini classroom sections right here just to get a much deeper understanding of how the heck all these different models and tables work together so link down in the description below it's completely free okay so with all that out of the way let's go ahead and start working on setting up and creating our new tables And before we just start clicking around, I just want to show you that there are two ways that you can go off and create these tables inside of Supabase. Option one is the user input route where you can actually come in and click like create new table. Once you're in here, you can go off and give tables names. You can give things policies. So this is the manual route. You can add each column individually, give the types. So this is how you can like the GUI representation of this. But we are going to be programmers and create everything programmatically. So. What are we going to do? Well, we're going to head over to the SQL editor and we're going to start going through this line by line and this entire SQL snippet I'm going to provide to you guys. Once again, I'm going to be giving away all of this and the source code down below completely for free. So feel free. You don't have to copy this and type it up line by line. Just let's watch and then understand what's going on. So you can later go off and do it on your own. So first things first, what are we trying to do? Well, whenever we're working inside of Supabase, We are actually working with a Postgres database, which is just a type of SQL databases. Just know, quick crash course, it basically just provides a lot more functionality than the normal types of SQL. So like MySQL, SQLite, those are all kind of structured databases. Postgres just provides a lot more functionality. Specifically, it also includes support for working with vector stores. It's just up to us to add in the extension to go off and add. this specific type of functionality. So what are we gonna do? Well, first things first, we are going to make sure our Postgres database supports working with vectors. So all we have to do is paste in this command right here. And I want to show you two specific things real fast. So inside of super base, you have two ways of running commands. You can just click run, which will run the entire SQL command, or you can actually start highlighting text and then just run selected. So I just want to show you that that is something that you can do when you're in here inside of your SQL editor. So to start, we just have one command we want to run. So we're just going to go ahead and run it. Now, this is going to go off and say, all right, cool. It was a success. I have no rows to return, which is great. That's exactly what we would expect. So now that we have that set up, let's go ahead and start working on creating our two new tables. So if you remember, what we wanted to do was create two tables, which were going to allow us to go off and create our two new email and email sections. So let me show you what these are. line by line. So what are we trying to do? Well, for our email, going back to our original drawing, what do we want to store? Well, we wanted to store everything that was all the raw information about the email. So like what was the subject? Who sent it? Who did it get sent to? What you'll notice for these out the gate when it comes to our subject, what you'll notice is right now that this is just going to be text and text is just going to basically say you can store a ton. of characters. So, and like, without getting too deep into database terminology, text basically just means you can store like basically, I think almost gigabytes worth of text. It's crazy how much you can store in one of these text fields. So just know you can store a lot of information. Now, what you'll also notice is it makes sense. An email has a subject and a sender, but when it comes to recipients, you actually could have an email that got sent out to me, to you, our friend together. So that's why this, we're going to say our recipients. is going to be an array of text. Cool. Makes total sense. And then we're just adding all the other random fields just so we can capture them. So it's just, you know, who is cc'd, bcc'd. And then finally, what we're going to do is say, all right, well, what is the actual body of the entire email? So this is, if you remember, we just want to store everything that initially got stored in the raw email. And we also just want to know, hey, when did this email basically created at? And we're just going to say, whenever this email got sent to us, that's where we're going to store the created at time. Okay. Pretty basic, straightforward. Now, this is where things get a little bit more interesting, where we're going to start saying, okay, now what I want to do is also create a new table called email sections. Now, if you remember, the whole point of email sections was to store two pieces of information. First, we wanted to store what piece of content, like the smaller chunk of content that was associated from the big email, we want to store that. We also want to store the vector representation of that piece of content. So this is where we're going to go off and store our embeddings. Now, here's a few questions that might be going through your head right now. First things first, what the heck is 1536? Well, whenever it comes to working with OpenAI and specifically their embedding model, they have what is called a number of dimensions when it comes to analyzing text. So think of like a 2D graph. It has two dimensions where right out the gate, like let's say dog landed up here and... cat was right here and then home was over here. Well, it's very easy to see that like, oh yeah, these two are very similar to each other and these are not very similar to each other. So, but we're doing is basically just adding the more dimensions you give in order to like compare things, the more detailed we can do a comparison. So just know all this is, is a bunch of dimensions that we're using to basically store and represent our long chunks of text. And it'll eventually help us later compare how similar things are. So 1536, it actually comes from their documentation. Didn't pull it out of thin air. Okay. What are some other key pieces of information that you're probably wondering like, hey, what the heck's going on? So the other thing is whenever it comes to this model, well, what you notice is like, A, we're going to have our own ID. The other thing that we needed to add is it's called a foreign key. So basically what we're trying to say is like, hey, this email section actually belongs to another email. Specifically, it references like this email ID that we're going to store. It's going to be a foreign key that's going to point at our emails table. And specifically. point at the ID of the emails table. Because if you remember this email section, sorry, one email is going to be referenced by multiple email sections. Because if someone ever sends us like a huge 30,000 word email, well, we're going to break it up into probably like 10, 15 chunks. And each one of these chunks is going to point right back at this parent email right here. Okay, cool. Hopefully this is all making sense. Everything else looks pretty similar. Yeah, when it comes to section order, we're also just going to store like Like, oh, was this the first email, second, third, fourth, fifth? That part isn't super important. Okay, so now that we've talked about models at a high level, we're going to do a quick pause, head over to the documentation because we have to start working on how the heck do we actually want to properly compare our different, basically our embedding. So whenever we're looking at, you know, Brandon lives in Atlanta and Brandon's favorite food is Mexican. Well, those two. aren't the most similar things. So how do we compare those two different pieces of information? So that's where we're going to start working on adding indexes into our database. So let me show you a quick crash course on setting up indexes right now. All right, guys. So welcome to the Supabase Vector Store Indexes. Now, what the heck is going on? Why is this even important? Well, whenever it comes to working with our embeddings, we have to pick how do we want to compare embedding A against embedding B. Now, there are... four or sorry, there's three main ways that we can compare these different embeddings, which are going to be Euclidean distance, negative inner product and cosine distance. Now, these are very math oriented operators. So I wanted to just show you guys what the heck are each one of these and when do you use them. So when it comes to the three different indexes that we just looked up Euclidean distance to like, I mean, there's a math equation behind this, I'm not going to dive into it. But basically, it's great for comparing images. Negative inner product. This is great for recommendation systems and scoring models, not what we're trying to use. Cosine distance. Well, it's great for working with embeddings and semantic search. So basically in our case, like, hey, does this phrase look like and mean the same thing as this phrase? Great. That's go ahead and return that. So that's why inside of our vector store, we need to set up our embeddings to be compared based on a... using cosine distance. Specifically, we need to paste in that we are using this for comparing our different embeddings. So let's go ahead, hop back over and I'll start adding in this index. So back over in Supabase, what we're going to want to do at the very end of this file, let's give ourselves a little bit more space. We're going to paste this line right here. Now, I'm not going to go super detailed into it because this comes straight from the Supabase documentation. But the important part is what we're trying to do. is we're trying to create an index that is going to allow us to compare our embeddings using the correct operator. So in our case, we're trying to say, I want to compare our embeddings using the vector cosine operator. That's basically what we're trying to do here. And when do I want to use this embedding operator? Well, on the email section, so email section on this table, I want to use this, specifically on the embedding part right here. So that's exactly what's going on. And like I said, there's a lot more going on under the hood, but I don't want to get too deep in the weeds with everything that's actually happening inside. If you want to learn more, the entire vector index page inside of Supabase provides a lot more information on like why to use this type of index in this type of database. Check out the performance. So there's a lot more reading. I'll have a link to this whole page down in the description below if you want to go more deep into it. But just know right now you need to create an index to allow you to compare embedding A to embedding B. That's all we're trying to do. Cool. Now, what are we going to do next? Well, we can go ahead and click run. And when we click run, it's going to go off and create this table. It's going to create this table. And then once it's finally done, it's going to create this index, which is going to allow us to start comparing our different emails embeddings together. So let's go ahead and click run together and wait for it to finish. So bada bing, it was super fast. And now what we can do is actually head over to our... table editor and we should start to see our two new tables. So you can see we now have an email section table. This is awesome. And we now have an emails table. So this is looking great guys. So now we are completely done with phase number two, and now we're going to head over to phase number three, where we're going to start setting up and creating our full stack Next.js application. That's going to go ahead and start creating emails and then sending them to the back, basically sending them to a backend API where we're going to embed stuff and save it to this database. So let's go ahead and hop over to. Phase number three. All right, guys, welcome to phase number three. And this whole phase is focused on creating the initial part where we're going to start saving our emails off to our backend database. And here's how we're going to do that. First, we're going to create a Next.js application that's connected to Supabase. Then we're going to go off and create a quick page that's going to allow us to store our emails. So we're going to be able to type them up. And from there, we're going to create a backend route, which is going to take those emails, split them up. store them off to our database and actually embed everything and store it to our vector store. So a lot is about to happen in this phase, but I'm going to walk you guys through it step by step. So let's go ahead and dig in and start creating our Next.js application. So I'll actually have a link to the page that you're looking at right now down in the description below. But we need to start with step number two, which is all about creating a Next.js application. So we're going to go ahead and click copy. And just a quick overview, this is going to by default create a Next.js application. that's using TypeScript and Tailwind CSS. So we can go ahead, hop over to a editor, and we're going to go ahead and paste in that command. Now we do need to make a quick fix and specify the project name that we're going to work with. So we're going to call it Supabase Vector Store. So that's going to be the name of our project. And then we're going to go ahead and hit enter, and this will go off and create a new project on our behalf. So it's going to take a few seconds to go off, download all the necessary packages and everything. Now, while that's spinning up, I do want to mention that it will write out the gate work, which is very cool. So we can go ahead and just type in NPM. Sorry. First, we have to actually see it into the project. So we're going to do cursor. And what this will do is cursor Supabase. And this will go ahead and just open up a new code instance of this project. So now you can see, ta-da, we are now inside of Supabase and our new project. Now, here's what we need to do next. According to the documentation, we need to go off and update. our environment variables in our project to start using the environment variables for the project we just created. So here's how we do that. If we head over to our project, I'll zoom in for you guys, and head over to our.emd file, first thing we need to do is change this to env.local. The reason why is the example environment variable is just like a placeholder for us, and whenever we change it to.emd local, this will actually get used by our project. So here's what we need to do. First, we need to come back over to Supabase, and then what we can do is select the project that we want to use. So in our case, it is the AI email auto responder YouTube. And once we do that, you'll see that there is a project URL and an anonymous key. So we're going to go ahead and copy these over here into our project. Looks great for the URL. Looks great for the anonymous key. Let's go and paste both of these in. Looks great. Now what we can do that we've set that up, we can go ahead and actually try to run our project. So go ahead and open up your terminal and we can just type in npm run dev. and this will go off and create your local project and start running it on local host 3000 so you can go ahead and see localhost 3000 awesome so this will go ahead and actually spin up your project it usually takes a few seconds to load the first time but all of this is looking great so now what we're going to do is start moving on to the next part where we're actually going to start setting up your pages moving off to creating those back end routes and go off to start creating and managing and sending everything off to our database All right, guys, so let me walk you through how you can quickly go ahead and start creating our new send email page inside of our Next.js project. So first things first, you're going to head over to app and then you're going to create a new folder called send email. Inside of send email, you're going to create a new page called page.tsx. The reason we do this is because inside of Next.js, they do file based path routing, which means we're now going to have a new URL. where we can go to localhost forward slash 3000, send email, and it'll actually show this page right here. Okay, now what we wanna do next, we're actually going to lean on cursor to go off and create this single form for us that's going to submit information back over to our database. So what do we need to do? We're going to open up cursor's chat window and start telling it what we want to happen. And hopefully you find this helpful, just hearing me talk about how I would create this quick form. So here we go. Could you please help me create a new page? inside of my Next.js 14 application. It is important to note that I am using app router version of Next.js. And inside of this page, what I would like you to do is have a single form that stores all the information about an email that I would eventually like you to go off and send to a backend route called API forward slash store email, period. Here's a few other important pieces of information for you to note. I'm using Tailwind CSS, so when you are trying to make the page and the form look nice, please use this type of styling. Additionally, here is the email. data type that we are trying to capture all the information for and then eventually send it off to our back end so that we can save it to a database cool so what we're going to do next is if we hop back over to super base we can go ahead and actually just capture our email table send it over here paste it in and that way it knows exactly what are the different you know input fields we need to make so we can say when you're creating your form please create an input field for each one of the different properties on our email table, period. Do you have any questions before you go off and generate this new page with our form? Cool, so we're using ChuggyPT 4.0 to do all the work for us. I like to use 4.0 whenever I'm like doing a little bit more critical thinking. Then I like to do 4.0 mini for quick fixes. And if any of this is confusing, don't worry. I have a full video using v0, Claude, and Cursor where I go a lot deeper into starting to use some of these, what I call AI code stacks. to help crank out beautiful code for you guys so it's done a initial job of stubbing out this component so our page so we can click apply and i'll go ahead and put all the code right here on our screen and now we can quickly go through it and tell it what we want to see differently so let's see what are the few things first i don't like how everything is stored inside of here i don't like how handle change actually isn't sending any maybe it is well sorry handle change is how we're changing each one of these fields so let's just go ahead and we're going to tell it to break all this up in just a second Then outside of that, handle submit looks pretty good. All looks pretty good. All right, so we're just gonna make a few quick changes and so you can see it in action. All around this looks pretty good. It is important to mention that I am using TypeScript, but it looks like you started to go down that route, which looks great. The piece of information I do want you to change is the fact that for our form, we currently just have one single state to manage all of our different fields, such as subject, recipient, sender, and the rest. if you could actually break these up into their own pieces of state that would be great outside of that could you please add in a is loading or is sending state so that whenever we are sending off our data to our back-end database we can make our submit button at the very bottom have some sort of loader all right cool so now we're going to go ahead and send this off we're going to let ai do all the work for us it changed all of our use states to look appropriate It's handling everything. It's looking great. So what we can do now is like, yeah, and it's even tracking is loading to show sending or send email. Looks great. So we'll click apply. Once again, go ahead, make all these code changes, save it. Now what we can do is let's go ahead and type in npm run dev. And the only other change that we would need to make just because cursor and some of these other AI tools do not do the best job of understanding Next.js 14 app router. So it's up to us to know that like, hey, this is a client page. because like we're handling state so we need to add use client or else it'll throw an error at us and to actually just show you this in action let's actually look at it together so let's go over to yeah you can see it right here you're trying to import a component that uses state you need to add use client to make this work so we'll go ahead and make that change now it's not angry at us anymore and it'll work so now we can go over to send email and this will go ahead and show our nice looking form looks awesome guys so i'm curious if we just click send email Oh, well, it's making us put all the information in, but okay. We'll come back to actually getting this working in just a second, but let's go ahead and hop over to our backend where we're going to create a new function that's going to receive these emails that we're sending off. Once it receives them is going to embed and split up this email and then save it off to our database. So let's go ahead and hop over to our backend code and start creating that new function. All right, guys. So now it's time for us to create that backend API function. So what do we need to do? First things first, we need to open up our. file explorer and we are going to create a new route this route is going to be api because this is where we're going to send our api request and specifically we are going to create a new folder to store our emails this same path right here we're going to create it so store email looks great and then inside of here what we can do is go ahead and create a new route.ts okay so what i'm going to do for the sake of time i'm going to go ahead and put the final code in here but don't worry i'm going to walk you guys through this step by step so you know exactly what to do when you're going off on your own, creating your own backend functions inside of Supabase. So first things first, we need to go off and actually go ahead and install a few packages to get rid of these errors that you see right here, Zod and OpenAI. So let me walk you through which each one of these is first, explain what they're needed for and how we can fix it. Zod is how we can create a schema to make sure that information that's being sent up to us is valid. So whenever on our front end, we're like, oh yeah, I'm going to send you a subject, a sender, all of this information. We can actually use the Zod library to validate like, yeah, that is what you sent me. Okay. So you'll see that just in a second. Outside of that, we need to be using OpenAI. Now OpenAI is how we're going to actually take those emails, embed them, and eventually store them over inside of our database. So how do we fix this? First things first, let's go ahead and open up our terminal. And then we're just going to type in npm. for node package manager install and then we're just going to type in zod and open ai this will go ahead and install these two packages for us really quickly and if we head over to our package json you can see down at the bottom zod is in and so is open ai great so now we are cruising and zod should hopefully eventually in just a few seconds get rid of that error we'll actually try re-importing it to see if that'll work let's see from import Z from Zod. And there we go. Sometimes it just takes a few seconds. So if you get a red squiggly, don't worry, happens to the best of us. Okay. So let's walk through this part by part together guys, so that we know exactly what's going on. And I think the best place to start is at the beginning of this post request. So what we're doing is inside of Next.js, we are creating a post request. So a post request is where we're sending data from our client to our backend. We're posting data. So in our case, what we're going to do is we're going to go, all right, in this request, I was sent some data. What was I sent? Well, I was sent a, basically in our case, we know an email, but what we can do is start to use Zod to go, okay, I know that you sent me up an email. What I'm going to do is I just want to verify that that is what you sent me. So using Zod, we created something called an email schema. So when we go look at this email schema, what we have done is said, all right, when I receive an email. I would expect there to be a subject line, which is going to be a string, a sender, which is also going to be string. And Zod's so nice because it also allows us to go like, oh, yeah, my sender is also going to have an email address. And then same for when it comes to recipients. Each one of these is going to be an email and so forth and so forth. So it's just nice. We can verify that what's being sent up to us is valid. Great. Now, what else are we going to do? Well, in case whatever information they sent to us isn't correct, we can just do a quick check to say like, hey. Did we successfully parse out information? Oops, no, we didn't. Okay, let's just return an error saying, hey, you guys did not give me valid email data. All right, now if that doesn't work, or sorry, if that does work, what we're gonna do is we're just going to pull out all the data from that email. And then what we're going to do is first, we are going to store all of that information into our email database table. So back over here in, let's see, in email land right here. In our table, you can see that we have, you know, basically all these values right here. We're going to go off and store them right now. So store all the information off in our database. Great. What we're going to do is once it gets done, and just to give you guys a little bit more information for this, we're actually using the Supabase client. Now, where did this come from? Well, if you actually hop back up to the top of the file, what you'll notice is we did, we imported two pieces of two packages, libraries from Supabase, specifically Supabase.js. What we did is we said we want to import create client and super base client. So let's go ahead and see where they get used. So create client is where we are going to pass in those environment variables that we set up ourselves earlier, that public URL and that anonymous key. We're going to pass those in to create our super base client, which is going to give us access to go off and write to our database, handle authentication, just basically do everything that we need inside a super base. So that's exactly what we're going to get here. Then once we have this super base client. we can go off and pretty much do anything. So in our case, back down here, we're gonna say, all right, using the Supabase client, which is connected up to our specific project, what I want to do is inside of the emails table, I would like to insert data, specifically all of these pieces of information right here. Then what I would like to do is just say, basically at the very end, I would like to grab the email that gets returned. So what you'll see, let me show you real fast. And real quick, just to make this a little bit more clear what's going on. So not only are we just inserting data, once we are done creating this new email, what we're going to do is we're going to use the select function, which is going to say, okay, cool. You gave me back an entire email. Well, out of that entire new email object that you gave me back, I only want to pull out the ID. That's the only thing I care about from that email object because I'm going to eventually use it later on. So that's the important part. Outside of that, we're just saying, I expect there to be a single object to get returned because we're creating one email. So we're only going to get back one email. Cool. Hopefully we're on the same page. Now here's what's so nice. Once we go off and actually use Supabase to create this new email, we're going to get back two pieces of information. Piece number one is the actual data. And the other part is going to be an error. It's like, Hey, did something go wrong? Okay, cool. We're going to have the ability to check. And just to like, hopefully make things connect. You can see right now when I hover over email. It's showing ID. The reason why is because of select right here. If we actually drop select, you can actually see we're gonna get back no information. So we can actually, if you wanted to do more, you can actually go in and select a few more pieces of information. But I just wanna show you, that's kind of like, it's real cool that it's like in real time pulling out, hey, I want an ID and it's updating the type we get back. So I thought that was pretty cool. All right, so let's keep chugging along. and also real fast if you do want to go off and learn more about what i'm talking about i have a link to this page right here which talks about all the possible ways you can interface with super bases database so getting information in our case inserting information because that's exactly what we're doing together right now so i have a link to this page right here if you want to go get a lot smarter on working with super base database all right so what we're gonna do next well now we have created a new email we have the id of this email And now we get to start working with a little bit more of our AI expertise. So this is where we're going to go. Okay, up to this point, I now have an email that's saved. And what I want to do is start breaking up our emails over into all of those email sections. And if you remember, each one of these emails can save around close to about 8,000 tokens. So we need to be breaking this up. So what do we want to do? First things first, we're going to split everything up, like the body of the email, into chunks. because each one of these chunks is going to get saved off into its own email section here in just a little bit. So what are we going to do? Well, over here, in our case, we're actually going to break it up even smaller, 5,000 chunks, just to be safe. But let me walk you through what's going on. We're basically going to be running through each one of these pieces of text. So we're going to be given a huge string. And then what we're going to do is start iterating through this part by part. So let's walk through this from top to bottom. So we understand exactly what's going on. And here's a quick overview of what's happening. First off, This text is going to be the entire body of the email. And right out of the gate, we're going to split it up. So every space inside of this email, that's how we're just going to grab all the separate words inside of this email. Then we're going to create a chunks list. And this chunk is where we're going to store all of our different split up version of the email. So every like few thousand characters, that's going to be a chunk that's going to get saved off to a database. The next chunk is going to be saved up to the database. And each one of these chunks eventually will get stored right here inside of this section content. So hopefully all the dots are starting to click. All right, let's dive back into splitting this up because this is pretty important whenever we start to work with larger emails. And what we wanna do is go, okay, I want to iterate through each word in the email and there's pretty much two things that need to happen. First, if we're under our chunk size, just keep adding the words and just keep continually adding new words and new words and new words until eventually we hit option two, which is once we get too big of a chunk, we need to go, okay, cool, this current chunk, let's add it to our list. and then let's start working on building out the next chunk so hopefully that two-phase approach makes sense and that's exactly what we're saying right here we're saying okay if the current chunk that we're working on plus the new word we're adding is going to be over the chunk size hey just add this current long section of the email to our list and then let's restart making our next chunk that's exactly what's going on right here and then down here we're going to say okay if we're under the size like we're on word 50. out of 2000 5000 what i want to do is just add the new word to the end so here's the new word we're looking at i just want to go ahead and add this word to the current chunk so that's exactly what's going on and yeah i'm going to keep it there and just to be extra safe guys i'm going to drop this chunk size down to 2000 just because we saw earlier a single word can be anywhere from two to four tokens and just to give you guys a heads up right now we're just doing this very rough what you would actually want to do If you're getting a little bit more deep with it, it is actually using a library like tick token, which will actually count exactly how many tokens are inside of a piece of text. This is just a, the poor man's way and just a quick hack way to be like, Oh yeah, one word equals four tokens. Okay, cool. This is how I'm going to stay under the limit. All right. So now that we've talked about splitting things up into chunks, what we're going to do is end up with a list of strings. Now, this is where we actually get to start working with open AI. So let me walk you through this guys, part by part. So what we're going to do is go, okay, OpenAI. First off, I want to initialize you so that I can start actually calling different functions that you offer. And one of the first things that we need to do in order for OpenAI to successfully work is we need to go off and add in a OpenAI key. So I've already created an OpenAI account and created a key. There's tons of YouTube videos on that, but I just want to show you, you do want to add your key to your environment variables. So let me show you how to do that real fast. You're just going to open up your file explorer and go. over to your dot env, which should be towards the bottom. And then you are just going to paste in your open AI key. It should look something just like this, you know, SK project, and then go off and have the actual rest of the environment variable. And it just needs to say open AI key. And like I said, there's plenty of tutorials showing you how to create and grab your first open AI key. Okay. So hopping back to the code now that we have open AI, which is going to work because we've passed in our environment variable by default, it just looks for that open AI key. What we can do is start setting up and creating our first embedding. So here's exactly how it works. We're going to pull out the first chunk. So the first part of the email, the first little tiny chunk, and we're going to go, okay, OpenAI, can you please create an embedding using this specific model? And there's three current models out right now. There's like Ada, Text Embedding 3 Small, and Text Embedding 3 Large. I just went ahead and used Text Embedding 3 because it's newer. From what I can tell on... previous tests that are coming out that it performs better than ada so that's exactly what we're sticking with so we're going to say all right open ai using this model i want you to embed this chunk okay once it gets done it's going to take a few seconds once we get back the the actual embedding for this chunk of the email we're going to go okay cool i now have the numerical representation of this email And what I can do is go off and create everything that we need for our new email section to go ahead and save that off to our table right here. Because if you remember what we're ultimately trying to do is go, okay, here's the text, here's the embedding. And later on, I'm going to be able to search against this. So hopefully this is making sense. If not, Hey, don't worry. We've got comments down below. Ask me a question there or over in the free school community. Super happy to help either way. Then once we've created this new email section, what we can go ahead and do is go. all right, well, what I would like to do is once again, use the Supabase client. And this time, I'm just going to go ahead and paste in and create in the email section table. I want to insert in this new section. And what we're going to do is actually loop through this for each chunk inside of our email. So if our email was super long, this piece of logic will probably get called, you know, three, four times. Awesome. Now. once it's done, what we're going to do is return a success code back to our front end client. So we're going to go, Hey, everything went great. I stored the email. I broke everything up into embeddings and I saved those embeddings off to our database. So now that we have all this set up, what we can do is actually hop over to the front end and actually see if our AI generated code will properly go off and send all this information to our backend. So what we're going to do, go ahead and open up a terminal, hop over and look. at our logs and that's what we're going to do. Just go ahead and close things out, clear it. We're going to run it once again. And now what I'm going to do is hop over to our code right here. And actually we're going to try debugging it live together just to make sure it works. So what we're going to do is just make a super quick test email. So we're just going to say real estate one-on-one. This is going to be sent from, I'll do from myself and over to a agent. And then what we're going to do is just go ahead and leave the rest blank. And then we're just going to say, Hey, I would like to purchase a new home in Atlanta, Georgia for around $400,000. And I would like to make sure the house has a yard for my dogs. And I would also like to make sure that I'm within 45 minutes of the airport. Cool. Now what we can do, I'm actually just going to save this just in case something goes wrong, but we can now go ahead and click send. and let's go and open up the logs before we do it just to make sure we can see what's going wrong just because hey fingers crossed ai did everything right but we can never be too sure so send it's going to say sending and it said fail to submit email data so we can go off and check real fast to see what went wrong and we got a status code of 400 so what i can do real fast guys is i will go back and actually just add some quick logs and heck what we can do is actually have ai to it force real fast we can do this Hey, can you please add a bunch of logs in here so I can see when things go wrong? So this is how we'll add routes, basically add logs to our backend. And this is exactly what I would do on my own if you guys weren't watching. So hopefully you find this helpful. Like I said, it's going to go off and add a bunch of different console.logs. And then we're going to go off and do the same thing for our front end in just a second. So it looks like that's finished. Apply all those changes and then same here. We'll do the same. Hey, can you please add some logs to the handle submit function so I can see what's going wrong in case something breaks when trying to send information off to our back end database, specifically our API endpoint. Cool. So it's going to take a few seconds to once again generate and update this code. Takes a few seconds, add all the console.logs. Great. So we're going to apply those changes. Yep, looks great. And now what we're going to do is try to resend it. So we're going to go open up console.log, send it off. Takes a few seconds, but now we can start to see, all right, here's the data we're trying to send. We got a bad request, specifically a 400, which makes me think we were trying to send information over to the backend that wasn't proper. So I think we're probably not, yeah, bad request. So I'll pause real fast and I'll find the error and show you guys how we can fix it. So the error actually has to do with our schema validation. The second you go back over and look at our logs, you'll see this, Hey, it failed because invalid string. So what we can do is this is one of the nice parts about working with inside of cursor. We can open this up and just say, all right, I would like to make sure that our schema that we have right here is compliant with the data we're passing up to it. So here's what we're going to do. Can you please look at the email schema that I've created because I'm currently getting this error. And then you can come back over here, guys, and we're just going to copy the error we're getting. Open it up. paste it in. And then what we can do is say, and then please look at the send email form and page we've created where we're actually sending off this email. And please make sure that the actual types I'm sending to the backend that you're validating match up. So please investigate this issue and make the appropriate changes. Great. And then what we need to do, guys, is we just need to add the specific page that we're looking at. So in our case, you'll just hit at and then we know that we're in the send email page right here. Then great. So it's already showing it. Now we can send it off and it'll go ahead and actually figure out what's going wrong. So it just looks like back in validation and it's going to go off and figure out the error for us. So in our case, it's going to update our handle submit to make sure that it properly creates and sends off. this piece of information so in our case it's just splitting it trimming it and then yeah filtering it just in case it didn't exist so we'll hop back over to our page and we'll go ahead and click apply update the changes save it looking great now whenever we try to resend it fingers crossed things are looking good email data successfully sent to our backend database guys this is awesome so gotta love ai doing all the hard work heavy lifting for us and now whenever we hop back over to superbase we can go to our table editor inside of here. We can start looking at our emails today. We have our first email saved guys. Everything's looking great inside of here. It even has the body. Then we can go look at our email sections and you can see once again, just cause we did such a short email, it's working properly. But what's super cool is this section of the email is also embedded. So we know open AI is working. We know saving our, to our multiple tables is working. So this is a huge success guys. So. like I said, hopefully you're enjoying this so far and I will have all the code that you're looking at right now down in the source code below. So feel free, just go ahead and just copy that and start using it on your own. Now, now that we have all this set up guys, what we're going to do is hop over and actually start setting up in base for a new page that we can start actually chatting with all the information and our backend database. And then we can go ahead and set up those API routes and new pages. So let's go ahead and hop over so you guys can start seeing how we can. converse with our data. All right, guys, welcome to phase four, where we're going to start setting up our own Q&A area where we can start asking questions about our embeddings in our Supabase vector store. So by the end, we're going to have this component set up right here, where we can start asking questions and getting answers. So super excited for you guys to see this in action. And first things first, we're going to create our page that's going to have all the UI components so that we can type in our question and send it off to our backend database. Now, how the heck do we do this? Well, first things first, you're going to scroll up inside of your app folder, and we're going to create a new page. So this time we're going to call it ask question. And then inside of there, we need to create a new page. Perfect. TSX. Now for brevity, what I'm going to do is I'm just going to go ahead and give you guys the end code, but I'm going to walk you guys through it once again, step-by-step, just because I want to focus more on the rag setup that I do the next JS part. So the important part of this entire page is that you should be able to type your question and you should be able to submit. your question to the back end, and once you get the answer, it should show up down here. And that's exactly what we have inside of our code. At a high level, you should be able to go ahead and type in your question right here. That's exactly what happens. You should be able to submit your question. And then once we finally get back an answer from our vector store, our back end, we should just go ahead and show it right here. And that's exactly what's happening. And the important part for you guys is this part right here, which is the actual functionality where we're gonna go, okay. Cool. You would like to ask a question. Great. I'm going to put together all of the text that you had, and I'm going to send this off to our API ask question, which we'll set up in just a second together. And what we're going to do is it's going to take a few seconds is with once we finally get back data, we know that that is our answer. If everything went great. So that's what will show up. If not, we're going to show some error messages. Okay, cool. Hopefully this makes sense because what we're going to do next is start setting up this API route. right here. And in order to do that, we're just going to hop over to our API route that we created earlier. And this time we're going to create a new folder, which is called ask question. Now what we're going to do inside of here is we are going to create a new route. So this route.ts just like this. And then what we're going to do is add in once again, a bunch more code specifically relating to taking in a question and betting it and then passing it into our database to figure out, hey, what's the most similar email. that we have in the database. Now I'm going to walk you through this part by part. So don't worry, this part is not too crazy, but it is this point because it's kind of very similar to the code you've already seen before. First things first, we are posting data up to our backend database. So we're saying, Hey, here's my question. Please take it. And what I want you to do with this question is a few fold. So first things first, we're going to go, all right, here's my question, which is in English. Can you please convert this English question over to an embedding? so that eventually we can go off and start comparing my question to everything in our vector store and seeing what's similar. That's what we're ultimately shooting for. So a few pieces of information that are super important for you to note is that we need to be using the same model. A lot of times I've seen people try to use one model for, you know, creating and storing everything to the vector store and another embedding model for asking the question, and you're just not going to get good results. So make sure you're using the exact same model to get the same result. Awesome. So once we have created this embedding, what we're going to do is start trying to find relevant emails that are basically very similar to the question we just asked. Now, here is where things are going to get a little bit more in the weeds, and I'm going to walk you through it part by part. We are going to be using our Supabase client once again. However, what we're going to do is start making a new call to our database, which is going to be a new database function. which is going to be match filtered email sections. So this one's going to be a little bit more in the weeds, but just as a high level before we dive into the code, what we're ultimately trying to do is combine SQL and our vector store. So what we're trying to do is say, hey, on the SQL side of things, I only want to get pieces of information that are from or include Brandon at gmail.com. So this is SQL side that we're going to set up. And inside of this function, we're also going to set up, hey, I want. to specifically only get pieces of information back from the vector store that are similar to the question i'm asking so hopefully that makes sense our north star is sql database give me brandon's information and also give me information that's similar to the email that i'm asking so with all that out of the way let's go ahead and hop back over to super base so that we can create this new cloud function for our database so let's hop back over to super base super fast and what we're going to do this time is we are going to create a new query. So make sure you're inside the SQL editor. And this one's a doozy. I'm just going to shoot you straight. This one is a lot. So what I'm going to do, I'm going to show you the end code and don't worry, you can actually per usual, go ahead and grab this from the source code down below so that you guys can use it on your own. Now I'm going to walk you through this part by part, just because it is confusing. There's no way around it. So here's what's going on. What we're trying to do is inside of our SQL database, we're trying to create a new function. This is You might be like, wait, I'm working with a database, but I can create a function. Yes, this is one of the parts that's pretty nice about working with Postgres. They allow us to add in a lot more fancy additional functionality. So in our case, we're going to say, all right, I would like to create a new function for my database or replace it if it already exists. The name of this new function is going to be match filtered email sections. So what do we want to do? Well, we are going to say this function is going to take in a embeddings. So it's going to take in a threshold. So like, hey, I only want to get back results that are super similar. And it's a little, you know, we can fine tune it. Also, we want to say, I only want to get back the top three most important results, the top 10, five we can pick. And finally, we can pick the email that we're searching for. Cool. Hopefully this is making sense so far. Then once we've created this, we're going to go, all right, well, what specifically table are we working on? Well, in our case, we're trying to return the ID. We're trying to return the email ID. the section content and the similarity so these are all the outputs so hopefully this makes sense this is inputs that we're passing into our function and this is outputs that we're going to get back now what we're going to do is start diving into more sql and this is it's it is gross guys i'm going to be honest this is one of my least favorite parts of this whole project because you're combining a bunch of technology so your postgres functions with sql databases is just a lot but this is what we have to do to start working with some of this more advanced technologies so Next, what we're going to do now that we've kind of defined our function and what we want out of it, we're then going to start diving into setting up a SQL query. Now, here's what we're shooting for. We are trying to select basically all the pieces of information we need in order to perform a query. So we're just trying to grab the email of the email section. So ES is the email section. This is basically we're setting up this variable right here. And we're saying, all right, for this email section, I just want to grab the email, the email ID. So what parent email do I belong to? this section content so this is actually the text then what i want to do and this is the most important part guys this is where we're going to start actually setting up and calculating the similarity score so what we're trying to do is say all right using the email sections embedding that was already saved i want to use that cosine similarity score that we talked about which is like how do you compare one piece of content to another this was the operator for it we already saw this earlier in the instructions when we were looking at the euclidean distance and all the other ways you can compare different embeddings so this is how we're going to check to see does this embedding have the same embedding as the question we're asking because this query embedding is what's getting passed in up here. This is our question that we've taken in. So like, hey, where does Brandon want to live? Oh, it's Atlanta. Okay, well, what we're doing is we've converted that English into an embedding. And now what we're trying to do is for each email section, for each one of the embeddings on every email section, we're just trying to say like, hey, how similar are these? And what we're going to do is just, don't worry about the math, but we're just basically saying like, how similar are they? And it's gonna put it into a score. The score is gonna be from positive one to negative one. One, if they're identical, negative one, if they're completely opposite. So hopefully this is all making sense so far. It is in the weeds, but you guys are chugging along super proud of y'all. Then what we're going to do is just a, some basic SQL commands from here to where we're going to start going off and joining. So we're going to say like, okay, well, this email section belongs to an actual email. So I want to combine these together so that I can ultimately get back all the necessary information. And then what we're going to do is set up some, some SQL where we're actually going to start basically doing some SQL filtering. So quick recap, everything up to this point has been to go, okay, I want to make sure that whenever I do find pieces of information that I can go off and do a proper vector store comparison. That's exactly what we're trying to do. And before I go off and compare everything for, to make sure the embeddings are similar, we're going to use some regular SQL commands to check to see, all right, I only want to look at. entries into our database where the sender or the recipient includes the email that I'm passing up. So this is how whenever you go off to build a much larger application that has hundreds of thousands or millions of rows, you can go, hey, I'm only trying to work for my client. Here's the client ID and oh, here's their email. Yeah, I only want to grab out of this million table that would take forever to compare. Yeah, I only want to grab the pieces of information that match my query. where we go oh that's only like 100 emails this is super easy to compare now so that's exactly why we're setting up sql plus our embedding vector store because we can now start working with huge production great applications which would take forever to compare and this query is going to go oh here's the small chunk of information you need now go off and compare each one of your embeddings to the question you're trying to ask to get the relevant information all right hopefully this makes sense guys final thing what we're trying to do is just say all right cool let's go ahead and return all the relevant results by the most most similar up top. And we only want to return a max number of results that we passed in. So our match count. All right, guys, this was an absolute doozy. Don't worry if this was confusing. Seriously, what I would do just to make this make sense, because you could spend a lot of time on this, please copy and paste this code over to ChachiBT and just ask it to walk you through it 10 times. That's what I had to do the first time I went through this, just because it is not clear is the best way I'd like to describe it. But hopefully this helped. Made some sense. And now if there's any loose ends, definitely Chachaputee can take you, take it home. So what we're going to do, once we have this set up, you're going to click run. This will go off and actually create a new function inside of your database. Huge success. Congrats getting through the beefiest part. And now that we have this set up, we can hop back over to our code, which is where we are initially trying to call this function that you just created together. So now you can see, oh, it makes sense. that i'm trying to pass in these four pieces of information because in our function this is exactly what we had right here these four inputs into this function cool now what's going to happen is we are going to get back two items we're going to get back matching sections so if the emails were similar to the question we'll get those back if not we'll get an error so we're just going to do just normal error handling and then this is where we get into rag guys so up to this point things are going great we asked a question to our back end vector store And then what's going to happen is it's going to give us back like, oh, yeah, you asked a question about where does the brain want to live? Well, here's email one, two and three. Here's the text. Then what we can do is go, OK, I'd like to combine all those pieces of information into what we're going to call its context. That way we can hop over to working with OpenAI and go, OK, it is your job. And this is RAG, Retrieval Augmented Generation. It is your job to answer the user's question based on the. information I just pulled from a vector store. So we're going to go, okay. hey please with the best of your abilities go off and answer the following question so we're going to say use the following information to answer the following question so then we're going to pass in the context which will be an email saying hey i want to live in atlanta near an airport and then the initial user's question which is where does brandon want to live so basically just giving ai the relevant information so that it can go off and answer the question then we're just going to have open ai take a few seconds to go off and perform a chat completion to basically just go off and answer this question And then we're just going to return it back to the front end. So that was a doozy, guys. But hopefully it all made sense. So now what we can do is start putting it into practice. So let's go ahead and make sure our application is running. Looks like it is. Now what we can do is head over to our new page, which is where we were setting up our ask questions. So this is looking great. Now what we can do is first off, we'll just ask a random question. So we'll just say, who was the first? president of the U S and then what it'll do is it's going to try and search through our vector store. And actually it didn't find it, but that was a relevant question. So what we can do is let's ask another question such as where does Brandon want to live next to? Then what we can do is go ahead and submit it. And this one should go off and hit our vector store. So you guys can see, I hope you guys are pumped. This is, Oh, I'm so excited because what it just did is it went off and. grabbed information from our vector store, passed it into OpenAI, then performed and generated a factual and basically reasonable answer to our question. And if you hop back over to our logs, I just want to show you this in action, guys, because you can see whenever we asked a question, what was the matching email from our vector store? It was this one. Hey, I'd like to purchase a home in Atlanta, Georgia for around $400,000. So I can even ask a follow-up question. So you can see it's not working. What? color house does Brandon want? So this one will not work because I haven't actually provided the information. Yeah. Hey, this isn't, this wasn't provided. So you can see like, oh yeah, like it doesn't always have answers. And, but you can see how much does Brandon want to spend on a house in Atlanta? That's good enough. And then once again, it'll go off and find the appropriate information from the vector store and you can see that it works. Okay, guys, this was awesome. So I hope you guys are super excited to see like basic end to end going from our computer to where we save an email to our API. API takes it in, splits thing up into smaller email chunks, embeds them, saves it to our database. Once we have our database set up for success with all of our emails and our vectors, sorry, our embeddings, then what we can do is. come from the other way where we go, I have a question, submit it to our backend. Our backend goes, cool, you want to ask this question. I will convert it to an embedding over to numbers. Then using our new fancy Postgres function that we worked on together, we can then start doing our fancy query to go, okay, I would like to look up all emails for this user. And here's the embedding question that they have. And then we combine SQL to go, cool, only get information for this specific email. Once you have that subset of information from our database, I then want to start comparing all the embeddings to our question. And then we're only going to return the most relevant information back to our user. And what we're going to do is that relevant information, we're going to store the information plus the question, throw it all over to ChatGPT and let ChatGPT generate a reasonable answer and send it back to the front end. So that is a crazy core loop, guys. And I hope you guys are starting to see a lot of dots click. And once again, if you have any questions on any of this, please drop a comment down below, hop over to our free school community. We can talk more about this. We have weekly coaching calls every Tuesday, completely for free. So yeah, I'm super excited for you guys to actually go off and start playing around with this on your own. And once again, yeah, that was, this was awesome. Super proud of you guys. And that's a wrap for this video, guys. I hope you enjoyed it. And I hope you are super excited to go off and create your own Supabase vector store so that you can start chatting with your own data. And just as a quick heads up, this was a prerequisite video for my next YouTube video coming up shortly, where you're going to learn how to build an email autoresponder using everything we just learned in this video so that you can hopefully go off and start selling email autoresponders to local businesses. And you can start racking up your first AI clients and making the dollars. So with all that out of the way, I'm super excited for you guys. And if you have any questions, like I said, please hop over to that free school community that I have for you guys linked down below. And also, if you love this video, you're going to love the other AI content I have on this channel. Feel free to check out whatever videos are popping up and being suggested to you now. And finally, if you do want additional support and all this next JS type script, everything's going over your head. I do have that full stack AI marketing platform, crash course over inside a school where I walk you from beginning to end. to creating a real world full stack application. Let me know if you have any questions. If not, I cannot wait to see you guys in the next video. See ya.