I Built the Agentic Loop in Laravel from Scratch
Chapters8
Introduce how an AI agent differs from a simple chatbot and set up the goal of building the agentic loop from scratch.
A hands-on look at building an agentic loop in Laravel from scratch, showing how tools and function calls empower an AI to act like a real agent, not just a chatbot.
Summary
The Laravel channel walks through building an agentic loop from the ground up, using the OpenAI PHP client and Laravel’s Level SDK as the backbone. Brandon explains why an agent differs from a simple chatbot and demonstrates how to wire in tools and prompts so the AI can decide when and how to act. The video starts with a minimal setup in PHPStorm, loading an OpenAI key, and making a basic GPT-4.5 call to show the baseline capabilities. Then it expands into a looped interaction, adding a thinking state for better UX and introducing a simple tool system that includes a web search and a custom calendar-availability tool. A key step is parsing the AI’s function calls and feeding the results back into the model to keep the conversation going. Brandon also demonstrates fetching the latest Laravel Level release from GitHub and building a custom tool to surface that information, illustrating how the agent can orchestrate multiple tools within one session. The takeaway is that tools, when defined clearly, let the AI supply much more precise, actionable answers. The video also references Level prompts and hints at a broader SDK workflow that handles the loop for you, advocating for hands-on experimentation to understand how coding agents operate in practice.
Key Takeaways
- Using the OpenAI PHP client with GPT-4.5, you can build a basic AI call flow inside a Laravel console command.
- Implementing a thinking state improves UX by showing a spinner while the AI processes data within a loop.
- Adding a simple tool (web search) helps the model fetch up-to-date information beyond its training data.
- Creating a custom function tool (get calendar availability) lets the AI surface personal scheduling information from your side.
- Introducing a second tool (get latest Laravel Level release via GitHub API) enables the agent to fetch external data and respond with structured outputs.
- The agent loops back with tool outputs as function-call results, then re-prompts the AI to refine its answer until a satisfactory conclusion is reached.
- Level prompts and the Laravel Level SDK simplify loop management, prompting the AI to decide when to call tools and how to use their outputs.
Who Is This For?
Essential viewing for Laravel developers experimenting with AI agents and the Level SDK. It’s especially valuable for those who want to extend AI capabilities with custom tools and real-time data sources.
Notable Quotes
"What’s actually happening under the hood? Today, we're going to build the agentic loop from scratch in PP and level so you truly understand how AI agents work."
—Intro framing about building the agentic loop from the ground up.
"We keep this very simple here. And now we’re creating here a new client from the new open AI library which we're using."
—Setting up the OpenAI client in the Laravel project.
"The point here is we have this AI model. We can lots of things but um yeah this is now very limited."
—Describing the baseline limitations of a plain AI model without tools.
"We can create our own tools here. So I’m going to paste here in one because it’s a little bit lot to write."
—Introducing the idea of custom tools (functions) for the agent to call.
"This is the agentic loop where the AI is triggering some tools here, being run, some functions being called and then going back and forth with the AI model until it is satisfied."
—Core concept demonstration of the looping agent and tool calls.
Questions This Video Answers
- How do I build an AI agent loop in Laravel using the OpenAI PHP client?
- What are function calls in OpenAI and how can I use them with Laravel Level SDK?
- How can I implement a calendar availability tool for an AI agent in PHP?
- What is the difference between a chatbot and an AI agent in practical terms?
- How can I fetch latest GitHub releases for Laravel Level in an AI-assisted workflow?
LaravelOpenAI PHP clientGPT-4.5Level SDKLevel promptsAI agentsweb search toolfunction callscalendar availability toolGitHub API releases
Full Transcript
What makes an AI agent different from a simple chatbot? One thing, the agentic loop level makes working with the AI SDK incredibly easy. You define tools, h your prompts, and the agent just figures it out. But what's actually happening under the hood? Today, we're going to build the agentic loop from scratch in PP and level so you truly understand how AI agents work. We are going to start here from scratch with a new level application. I just installed this new application. Nothing in here yet. And we're going to use Open AI here as our AI model provider.
And I'm going to work with the OpenAI PHP client, which is really great for our use case today. Okay, that's installed. And now inside this application, inside PHP Storm, the only thing that I have already added here is inside services, we have our open AI key settings here defined. And my key I have already added to my environment file. Okay. And we're going to trigger now a new AI call through a console command. I'm just calling this chat command. And what we're doing here is chat chat with AI. We keep this very simple here. And now we're creating here a new client from the new open AI library which we're using.
And we're going to load now our key which we have here services open AI key. All right. So this gives us a new client and we're now getting new response by calling on responses. We're going to create a new one. And here we're going to need to define the model which in our case is GPT 4.5. And the second argument here is our input. And we're going with a static string here of just hello. And now we're going to print out the response. And we should have the output text. All right. So, PHP artist on chat.
Let's trigger this command. Okay. Something is working. Hello. How can I help you today? Okay, perfect. So, we've made a very basic API call to the open AI um model which we're using here and we got a response back. Okay, pretty straightforward so far. So, let's update this a little bit. And now for the input, we are using a lava prompt here. And we're calling this u which is the label placeholder is hello. And now we are using this input here. So we don't have here a static value. And let's try this now again. Um I have art is my shortcut for PHP Addison chat.
Now we have this input here. Hey, what's going on? And this should still be working. And it's now a little bit nicer. Not much. Just here and ready to help. What's up with you? Okay, perfect. So, we have now this amazing AI model which is capable of so many things. Um, let's give me a short song. That is funny. And as you can see, it just can do lots of Yeah. Funny thing. Sure. Here's one level blues. I woke up late. My app was down. And PHP artisan turned it all around. Routes were crying. Cash was mad.
But composer update made things worse. How bad. Blade was slicing. Eloquent was slick. Then one small typo made the whole thing sick. All value. Elegant queen. What's my buck always on line 70? I mean um yeah that's funny. The point here is we have this eye model. We can lots of things but um yeah this is now very limited. So if I would ask it what was the latest Laravel release, what do you think we will get back? So we can already tell you if you mean Laravel. Oh yeah, I misspelled that. The latest they were releas 12.
Here you can see those AI models are pretty outdated because they were trained on a lot of data from the internet from a couple of years ago. So yeah, we don't get here the latest information when we ask it things like what's the latest level of release. So the idea is now today in this video we're trying to here help our AI by creating some tools that our AI model can use trigger and then use this information from these tools to provide us better feedback here and better responses. But before we're going to do this, we're going to make this a little bit better to use because currently we just have um one input and then it stops immediately.
So we're making a loop here. So this ends down here. All right. So now we're inside a loop. And then what we're going to do here is we are we're changing the response to be a task here. And we're going to give this a label called thinking. So this is also level prompt feature which you can see is very handy. And the second argument is a call back which is a closure. And then we just need to close this off here like this. And we need to import the function. Okay. So what we're doing here, we're wrapping now our API call inside this task which will give us a nice spinner.
And we're also now inside this loop. So as long as we have here some feedback, we are still staying inside this loop. So let's give this a try. Hey, now we get this nice sper thinking. How can I help you? Nothing. All good. And you can see this is still working. Okay, so this is now a little better for us for testing. And we also have some nicer output. And as always, yeah, check out level prompts. All those features here are just amazing. They look so cool in your terminal. Okay, but the point here is now we want to add a tool here.
And the most simple tools that we can add. First we're going to provide tools here through through our API call and every tool is an array item with a specific type search preview which we can use with open AIS. So many models have some specific web search tools that you can just provide here and then they have something where they are going to trigger the web searches something that we don't have to do on our side and this should be it. Let's give this a try. What is the latest Laravel release? Again, a typo here, but it's a good thing about AI.
They don't matter about my typos. They don't complain. So, let me see what we get back here. Now, the latest major LAR release was level 13, which is already good. Um, if you mean the latest framework package version on GitHub, the result I found was 1244. Okay. So, um you can see it's already way better, but um yeah, it's still missing some exact details about so it's just getting this by searching searching and googling for the right answer. And yeah, it can't really tell me here about what's the latest minor release. So that's um yeah, if you want to get to know the specific information, a web search is just not enough.
So what can we do about this? We can create our own tools here. So I'm going to paste here in one because it's a little bit lot to write. So the new type is now called function. So this is something that's being called here on our site and then we provide information. The name get calendar availability. So this will be about if the AI so that the AI can tell if I have time on a specific day to record a video. The description get available recording dates. And then for the parameters we don't have one.
We just need to provide here some boiler plate. So that's an object. Here we have the properties. We keep it empty. But for example, you could provide a from or to date in order to look for something through a specific um through some specific parameters parameters here. But in our case, we don't need that. We're we're just going to provide the I some days here where I have or have not time and then the eye can figure out the rest. So that's that way it is a little bit easier for us to handle. Okay. And in order to let the I know if I have time or not, get calendar availability which just gives an array of some dates here and tells if I'm available at this day or not.
So very simple for now, but you could al think that this could maybe connect you to your Google calendar and you provide some dates from there or yeah, there's a lot you can do. In this case, we're just keeping it simple with an array of these dates where I'm available and where I'm not for the next couple of days. Okay. So, let's go back here. So, what do we have to do here now? So, after this first response here, let's go back down here before we type something out. We're now creating a new loop here.
And this loop is about the tool calls. And in order to check if we need to make a to call, what we're going to do is we're going to make a collection of the response and the output. So in the output of the response, typically there's just a message here with the response. But if the AI feels like, hey, I need I would like I would love to use one of your tools because this sounds like it can help me to provide a better response, then we have some function calls here as well. And we can find them.
Let's do this by first where the type is called function call. Okay. And if we don't have a tool call then we're just creating a new line and a new info. Basically just this here. Okay, now it's fixed. So if um we're going to make a loop here. We're going to check if we have some two calls here by using a collection. And then if we don't have a two call, we're just providing the response back similar to what we had before. And I think we also yeah, we also got to break out here of the loop.
But if we have a tool call, let's make this very simple for now. Let's call this tool tool result equals this get calendar availability. So we're going to assume here that if there is a tool call from the AI, it must be only the one that we have here and then we're calling. We're going to call this here immediately. And then let's also make a new line here. And let's just info out that our tool was called. So very similar to coding agents uh chatgpt or other tools here where you would also see if the model is doing a web search or using other tools here.
You would also see this in the UI. And now let's we're going to copy this here. We're going to make another call now to the AI. But now we don't need to provide the tools anymore. And what we also need to do, we now need to response to a specific call from the AI from before. And we're going to find this with previous response ID. and we're going to grab the response ID from the response from before. So what's different is now we don't have a text input like before. Now we're providing the information from our tool.
So there's a new array item. It has a type of function called output and the call ID is which we have inside our tool inside our tool call and it's called call ID I believe. And then the only thing missing here is the output which is our tool result just JSON encoded. Okay, let's go through this again. So up here we're creating a new client in order to make call to openi. Then we have this loop to keep the conversation going. If I ask something we get a response back. I can ask something again and so on.
This is the first input we are providing by typing something. Then we are providing this into the input of this openi call. And inside this call we are telling openi in this case hey here's the input here's what the user wants but I also want you to let you know that we are providing some tools here. First one this is of openi a web search tool but this other one is a function tool which we are providing. And here we have the information and the description here. and the description helps the AI model to yeah think if this cool tool could help us to provide a better response to the user.
We don't have any properties here. So this means after that we're creating another loop. We need to create the loop because you have to think about maybe there are multiple tool calls um that could be triggered before we send something back to the user. Okay. So we are collecting from the response output. This is where the I would respond to us that it wants to provide it want to run a two call and with the type function call. Okay, if we don't have a two call, we just provide the info back. But if we have one, we are telling out we're here getting the result of our function.
We're providing my availability and then we're making another call to open AAI where we're going to respond to the previous response from open AAI and in the input here we are providing specific input which is a function call input for a specific tool call with a specific output. Okay. Um yeah this was a lot. Let's see if this is working. Okay let's try with something where we wouldn't trigger a tool called just hey do we get something back? Yeah we do. But now let's try something different. When do I have time this week to record a new video?
Okay, now the AI model should see it has already um has already called our tool. Let's get this input here. And then you have time to record a new video on those two days where I have provided in the array items that I'm available for this. And I really hope you could see how useful this now is that the AMI model can use specific tools running on our hand to provide specific information on our side like some specific dates where I have time to record a new video. And now this conversation becomes more personal in the AI model or this AI conversation can help us a lot more than before.
And it's not just a response and uh question here from my side. It now can in between run this loop to call some tools and then the AI at some point decides okay now I got enough information now I don't need any other tools to be called now I can respond back to the user okay but back to application here where we were first using the builtin web search tool then we were creating our own tool in order to find out my calendar availability and when I think about an example from before getting the latest release which is something that I do um almost weekly videos about.
So how can we yeah give the AI some information about this and this is also actually pretty simple. So here in Tinko we can make just an HTTP request to the GitHub API and we just go to level frameworks releases and check out the latest and if we're going to run this we should see yeah the latest one is 13.4 4 which was released I believe yesterday and inside I think there's also a body somewhere yeah here inside the body we see all those new features which could be something very useful to me when I ask the AI about the latest release okay so since this is just an HTTP call here we can also make a tool in order to yeah give this information to the AI model so we're going to create here a new tool or new tool definition.
So I'm going to copy the code in here. This again is a function. Get latest level release is a name. Description get the latest level framework release from GitHub. Again, we don't have any properties here because we don't need to provide something. That's why this is almost empty here. Okay. Then we also need another function here in this application. Of course, later we're going to clean this a little bit up. And here we have it. We're going to import the HTTP facade here. All right. And we don't have any headers. So, let's get rid of that.
Okay. Like this. And now we're just returning here release tag name, HTML, URL, and body, which is enough for the AI to yeah to do something with this and provide this in a format that I can work with this. Okay. So, what do we need to change here? A few things. So currently we have hardcoded that we are just getting if we needed to we're going to get this from the calendar. So and we're starting by changing this here. We're going to call this tool calls. And now we're getting rid of the first because now we grab multiple ones if there are multiple ones.
And then we're just grabbing here the values. And then we're checking here if let's make this tool call. now is empty. This stays the same. And now here we're going to change this. And I've already prepared this again because this would be a lot of time. Okay. So what we're doing here for all of our tool calls which we got right here by checking what we got from the output back from the AI. So these are all the things that the all the tool calls that the AI wants us to do. So we're mapping this.
We're providing here again the type the call the output similar to what we have before. And now we're changing this the the input now is just our tool outputs. I think we still need to close this. Yeah, like this one. Okay. So now again we have multiple outputs here and we're providing those inside the input key here for the client call here to the AI model. I think that's it. Let's give this a try now. Let's create a new chat. Hey, what is the latest level release and when do I have time to make a video about it?
And please also tell me about the three most important features of this release to cover in my video. Okay. So now this should make two calls here to our HTTP or it's failing because All right. Let's take a look. Yeah. Is empty. Why wasn't PHP telling me about this? Okay, let's give this another try. I'm going to paste in here the same prompt. Record this week. Okay, the prompt was very similar to before. So, let's see if this is working now. It looks like we forgot now the info about the tool that our tool was being called.
But this looks already good. Latest release. Yeah, 13.4. Okay, so was using the tool. These are the top three features. Form request, strict mode. Boom. I need to check this out. Okay. And best time to record. We have now two two days here where I have time to record this. And this is now really cool because we asked AI something. It didn't have the answer but it knew about the two features the two tools here that we are providing here and it saw okay I think those tools can help us. So it triggered that we are going to call both of those tools.
Then it got back the response. Then it made the response from the IM model and then we saw the message. So this is the aentic loop where the AI is triggering some tools here being run, some functions being called and then going back and forth with the AI model until it is satisfied and it can provide us a good answer like we do here. And as you know, yeah, this wasn't possible before, but yeah, this is now possible like this through what we've done here. And the cool thing here, you can just implement here anything you want.
So I could even further enhance this and provide some new tools in order to save some stuff into a notion page which I normally use in order to have some information about level releases before I record the video. Or maybe you're using Trello, you can create a to-do there and so on. So everything that you can think of, everything that maybe some of the tools, AI tools that you're using have some specific integrations already, you can do this as well. And yeah, as you've seen, it's not that complicated. And we did this everything here in this video.
And yeah, basically this is also how a coding agent is working. Of course, here I would clean this up quite a bit. I would probably create a custom PHP class for every of our tools here where we have the definitions here and also the function calls here that we don't have those inside this here. But even better would be to check out the Laval AI SDK where all of this is already integrated for you to use in a much nicer and cleaner and easier way. But yeah, I think it's good to understand how do how such tools are working.
And I hope that this helped you as much as it did for me. And that's the agentic loop. The AI decided needs a tool. We execute it. We feed back the result and the eye tries again over and over until we have a final answer. And this is the core mechanical behind every AI agent out there. And the beautiful thing is the level AI SDK does it all for you automatically. You define your tools, call the prompt, and it handles the entire loop. Now that you know what's happening behind the scenes, please go out and build something really cool.
Post it in the comments and let me know about it. Thanks for watching. If you like the video, please like the subscribe uh click the subscribe and like the video. You know what to do. And we'll see you in the next one. Bye.
More from Laravel
Get daily recaps from
Laravel
AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.









