RAG with Embeddings and pgvector in Laravel 13 - Ship AI with Laravel EP5

Laravel News| 00:13:28|Apr 27, 2026
Chapters10
Explains the problem of agents making up information when lacking access to documentation, setting the stage for building a searchable knowledge base using embeddings and PostgreSQL vector support.

Laravel News shows how to build a semantic knowledge base in Laravel 13 using embeddings and PostgreSQL native vector support (pgvector) for fast, meaningful searches.

Summary

Haris from Laravel News walks through building a searchable knowledge base in Laravel 13 powered by embeddings and PostgreSQL's native vector support. He demonstrates turning article content into vectors, storing them in a knowledge_articles table, and using whereVectorSimilarTo for semantic search that ranks results by meaning rather than keywords. The video covers creating a KnowledgeArticle model with an embedding cast, a migration that seeds a 1536-dimension vector, and a seed command to populate eight example articles. Haris also shows how to generate embeddings with Laravel AI embeddings and how to query with a custom route that returns a concise excerpt from the matching articles. Finally, he ties everything together by wiring the knowledge base into a support agent’s similarity search tool, ensuring the agent consults the knowledge base instead of inventing policies. Viewers will see practical code snippets and see the end-to-end flow from content to embeddings to search results to agent usage, all natively in Laravel 13 without extra packages beyond the built-in features.

Key Takeaways

  • Embedding vectors convert text to numeric representations that preserve meaning, enabling semantic search across a knowledge base.
  • KnowledgeArticle uses a 1536-dimension embedding aligned with OpenAI models, stored in a vector column with an index for fast similarity lookups.
  • Laravel 13 supports vector similarity queries via whereVectorSimilarTo, which embeds a query and returns results ordered by semantic similarity without loading everything into memory.
  • Embeddings are generated with Laravel AI embeddings, then stored in a casted array field on the model for easy manipulation.
  • A custom Artisan seed command populates eight articles and computes embeddings for each, supplying realistic FAQ content to test the flow.
  • The ADK’s similarity search tool ties the model, the embedding column, and a descriptive prompt into a single, reusable search flow for agents.
  • The full flow demonstrates a production-ready loop: content → embeddings → database → semantic search → agent response, all without hard-coding policies.

Who Is This For?

Laravel developers who want an end-to-end semantic search solution using Laravel 13, pgvector, and embeddings, plus anyone building a searchable knowledge base or intelligent support agent.

Notable Quotes

"Our support agent can look up orders and hold conversations, but when a customer asks, 'What is your return policy?' It has to make something up, right?"
Sets up the motivation for why a searchable knowledge base matters.
"Embeddings turn text into arrays of numbers called vectors that capture meaning."
Defines the core concept behind semantic search.
"We use where vector similar to to embed the query and compare it against our article embeddings."
Shows the key Laravel 13 feature enabling semantic similarity search.
"This is built in Laravel 13 without any need for extra packages."
Emphasizes the native capability and simplicity of the approach.
"Always base policy answers on the knowledge base. Never make up policies so it doesn't hallucinate, of course."
Highlights the governance rule for the intelligent agent.

Questions This Video Answers

  • How do I implement semantic search with pgvector in Laravel 13?
  • What is the correct embedding size for OpenAI models and why 1536?
  • How does Laravel's whereVectorSimilarTo work under the hood for ranking results?
  • How can I seed a knowledge base with embeddings in Laravel without external packages?
  • How can I integrate a knowledge base with a support agent in Laravel?
Laravel 13pgvectorPostgreSQL vector extensionembeddingsOpenAI embeddingssemantic searchwhereVectorSimilarToKnowledgeArticleLaravel AIArtisan seed command
Full Transcript
Our support agent can look up orders and hold conversations, but when a customer asks, "What is your return policy?" It has to make something up, right? He has no access to our actual documentation. I'm Haris from Laravel News and today we're building a searchable knowledge base using embeddings and postsql native vector support just like you can see here. Before we start building, let's talk about this quick concept. So embeddings turn text into arrays of numbers called vectors that capture meaning. Similar concepts end up with similar vectors even if the words are completely different. For example, let's say we have this question, how do I get a refund? And this translates to a specific array of numbers. Same for what's your return policy, which is very very similar to how do I get a refund, right? But it's very different from something like what are your store hours. As you can see the numbers are very very different but those two arrays are very very close. And this is how the vectors know which results are very similar and just return them. So when a customer asks a question convert it to a vector then find the articles with the closest vectors and this is called semantic search. It understands meaning not just keywords. So let's go ahead and build this now. First, let's add a model and a migration for our knowledge base. Let's go back to our terminal and type PHP artisan make model. We're going to call this one knowledge article. Let's add the migration as well. Let's go back to our editor and open up the knowledgebased migration. So, let's go ahead and add this. So, we need a title. It's going to be a string. The next thing we need is content. We also need a category. And last but not least, we also need the vector in this case. And the vector will be called a bedding. And we do set up dimensions. And let's add 1536. And I'm going to explain now what this actually does. So let's make this nullable. Let's give this an index. And we are done. So we also need to add this thing called ensure vector extension exists because we need to make sure that your database has this vector extension enabled already and it's up and running. So this vector size dimensions down here is the standard size for open AI's embedding models. You can find that in the documentation. The index at the end make sure that we create this index for fast similarity lookups. So all this is built in Lar level 13 without any need for extra packages. Now let's go to our model. The model again is called knowledge articles. Now let's go up here and we're going to add the fillables again. So that protected fillable and let's add title content category and of course embedding. Save that. We also need to add another function called casts. This is a well-known function for Laravel. It's nothing new, but we need to make sure that we cast everything in our embeddings into an array. So, we return embedding and we say that this is going to be an array in this case. Save it and we're done. Next thing, we need to generate the embeddings. So, add another function down here called generate embedding. And now this is going to get the text from the articles. So let's do this title of course. Let's leave some new lines down here. And then we have this content the content of the article of course. Next thing is we need to get the response. And in order to get the response we use embeddings from Laravel AI embeddings as you see up here. Let's import that. And for the text which needs to be an array and for the dimensions that we already mentioned before cuz it's the standard for open AI we generate those embeddings. And now let's update the embedding and let's add the response and from the array we get only the first index index zero in this case. So the key method here in this model is generate embedding. We combine again the title and the content like we said. We pass it to the SDK's embedding class down here and we store the vector in the end. The model casts the embedding columns to an array automatically. Now we need some content, right? Let's create an add some command to seed support articles. Go back to our terminal. Let's add PHP artisan make command. Let's call this seed knowledge base. We'll fill it in with real FAQ content that the support team would actually have. So I'm going to copy and paste implementation and we can discuss this together. You can see we have many articles here. Now let's import everything we need. And for each article we are going to update or create title and the data. We have a progress bar. We generate the embeddings for each article. We advance the bar and we just have a simple info message in the end. So the brokers bar is nice since its API call takes a moment, right? So let's go ahead and run the command in terminal. So PHP keyb seed. Let's run this. Got a parser somewhere. It's line 33. Let's add our migrations before we run that because I don't think we run the migration. Now we have the migration. Let's go ahead and run the seed command. We're now seeding the loaded space. As you can see, progresses the bar. knowledge base seed with eight articles. If we go to our table plus and refresh, go to the knowledge articles and you can see here we don't only have titles and content categories. We also have the embeddings. Pretty neat, right? Let's go to our routes file now. So, web.php. So, now the important part searching by meaning. So Lar 13 gives us this thing called where vector similar to it's this thing here where vector similar to right on the query builder. So it embeds the query calculates similarity and at the end it filters the result in one method call. Let's go ahead and add a new route on here. Going to call this SL KB/ search. Let's open up function here. Let's close this. And now we have the query. It's going to be the Q property from the request. So how do I return item? And now we need to get results. So we use the knowledgeless article query. And now let's use this nice function we mentioned where vector similar to. So we now have two things to pass now. The column and the vector. The column is the embedding like we have in our database, but the vector is the query, right? Because we want to search for this specific query. How do I return a damas item? Then let's limit that down to three. So we can see some faster results in this case in our example and then return result. Let's map this. So we so we can have a map result. So fn we have all the articles. So for each article in this result we're going to get three things title category and last but not least excerpt. So from the content we just get first 100 characters as an excerpt. It's fine. Save that. You'll notice that we only have this method call where vector similar to and this takes the column name and the search query as a plain string. The laral generates an embedding for the query. It calculates similarity against every article using the index and returns results ordered by relevance and without loading everything in memory. How cool is this? Let's go back to our browser now and let's run this. So, KB search and then what we're going to search for is how do I return a dumbest item? Let's run this. You can see that it went in our database and found that we have this damaged item claims with a category of returns and it says if you receive a damaged item take photos of the damage and packaging contact support with 48 hours. This is this is the excerpt. It's not the full thing, right? But we did find a result. So damaged items claims comes up first even though the query didn't use the exact same words. We have semantic search which understands that return a damaged item and receive a damaged item take photos are about the same thing, right? So keyword search would struggle with that. Think about it for a second. Let's try another one. Let's say how long does express shipping take? And you can see we have some shipping information category shipping. Standard shipping takes 5 to seven business days and it's free on orders over $50. That's pretty pretty cool. So something sipping information comes up in this case and the embeddings matched on the meaning not just the exact words. Let's go back to our editor. Let's go and open up support agent now again. Now let's make this searchable by our support agent. The ADK has a built-in similarity search tool that wraps everything we just built. We point it to our model. So let's go ahead and do that. Let's go down to our tools and down here we say similarity searcherts using model and our model is knowledge article and the second thing is our column and the column is again embedding like we have it in our database but we don't stop here do we with description and then we add I'm going to copy and paste this description so we don't have to write it ourselves and we're going to discuss this so search the company knowledge pays for policies, procedures, and FAQs. Use this when a customer asks about returns, shipping, billing, account issues, or any company policies. And that's it in this case. So easy. So this is one line, right? We have similarity sets using model that takes this model class and the embeddings column. Then we use the width description in this case tells the agent when to reach for this tool. So under the hood it calls where vector similar to just like our test route but agent decides when to use it based on the customer's question. Let's update the instructions so the agent knows about the knowledge base. So we added this here when a customer asks about policies, shipping returns or procedures. Use the knowledgebased search tool to find accurate information. Always base policy answers on the knowledge base. Never make up policies so it doesn't hallucinate, of course. So that last line matters. We are telling the agent to always check the knowledge base instead of guessing. So let's test the full flow now. Let's go to our route file. Let's go down here and we have a new route and we're going to call this route support KB test. So we want the response equals new support agent of course and then let's prompt that. Let's say what is your return policy for damas items. Let's close this and let's return the text from the response support KB test. Let's go back. Support KB test. Oops, we didn't import that. So undefined constant n article. Let's go back in our support agents. Forgot to import this down here. Let's go back. Let's refresh. And now we're getting the actual result. If your item arrived damage, please contact support within 24 48 hours of delivery, etc., etc., etc. And this is all in our FAQ system. The agent hit the similarity search tool, found the damage item claims, and return policy articles, and gave a specific answer. So 48 hours to report photo required, free return label, choice of replacement or refund, 5 to seven business days for processing. All from our knowledge base without anything invented. We built a full symb system, a model with PC vector embeddings, an artisan command to populate the knowledge base and the SDK similarity search tool wiring it into our agent. Lavas 13 native vector support and vector similar to did the heavy lifting for us. So in the next episode we were adding provider host and vector stores and the file search tool. The agent gets the access to entire PDFs policy documents without us writing any search logic. See you in the next episode.

Get daily recaps from
Laravel News

AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.