تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Introducing Safe Agent Tools0:00

Large language models are great at words, but they are terrible at facts. So, we are going to give our agent some safe tools so that it can fetch real data from our application. In the previous episode, we streamed data. It was really fast streaming, but it streamed. But now we need to give our agent a safe bounded access to our application. And the key idea is that, you know, we're going to give it tools with strict schemas plus authorization inside of each tool. And that way, the model can look things up, but only what we explicitly allow. So, the first thing that we need to do is create some tool classes.

Creating Tool Classes0:42

And that way, the model can look things up, but only what we explicitly allow. So, the first thing that we need to do is create some tool classes. And we will do that with Artisan. We want to make a tool called tickets fact tool or ticket facts tool. Let's also make another tool called ticket messages tool. Basically, these are tools that we will give our agent access to so that if it needs to access, you know, certain facts about a ticket or if it needs to access the messages, then these tools are there available for it to use. Like, for example, let's open up the tickets facts tool.

Building Ticket Facts Tool1:21

then these tools are there available for it to use. Like, for example, let's open up the tickets facts tool. We can see that it implements tool and we want to scope this tool to two things to the ticket as well as the user. So, we're going to have public int ticket ID, then public user user, which we will default to no. We, of course, need a use statement for the user model. And the first thing we need to do is set the description for this tool. Now, the purpose of this is to fetch the key facts, not keys, key facts about the current ticket.

Now, the purpose of this is to fetch the key facts, not keys, key facts about the current ticket. You know, things like status, priority, department, sentiment, that's a lot to say, but that's, that's a good description because we are telling it exactly what this particular tool is for. And so then we need to implement the handle method, the comment here is very telling this executes the tool. So if we were going to get facts about a ticket, what would we do? We would get the ticket and then, you know, get the facts, get those things that we mentioned, status, department, things like that.

We would get the ticket and then, you know, get the facts, get those things that we mentioned, status, department, things like that. First of all, though, we want to check if we have a user and if not, then we want to get to the currently signed in user. And if we don't have a user, then we are going to return unauthorized. So then we need to fetch our ticket. We can do that, of course, with our ticket model. We want to include the tags and we will find based upon this ticket ID. Now, if we don't have a ticket, then let's just say unauthorized too. Ideally, we would do more checking here. We would be sure that the user could

Now, if we don't have a ticket, then let's just say unauthorized too. Ideally, we would do more checking here. We would be sure that the user could view this particular ticket. You know, maybe we had some gates set up or used a policy, something along those lines. We would check for that here as well. And, you know, maybe let's just do this to do check if user can view this ticket. Just so that we would have a reminder to implement that at a later time, which we probably won't do. But then we want to build our payload. This is going to contain all of the

we probably won't do. But then we want to build our payload. This is going to contain all of the facts about our ticket. So we're going to have an ID, which will come from our ID, but then we will have our subjects. And basically, we're just going to build an array that has all of these attributes of a ticket. So I'm just going to paste those in because we don't need to type all of that out. So we will have our payload and then we will return a JSON structure of that

out. So we will have our payload and then we will return a JSON structure of that payload, and we can do JSON pretty print. So we need to return JSON here. We also need a use statement for our ticket model. We need to return JSON because that is what we need to provide the model because we also need to define the schema. Now, this isn't an output schema. This is an input schema. So this particular tool doesn't need any kind of information except the ticket ID and the user.

So this particular tool doesn't need any kind of information except the ticket ID and the user. So we don't need to supply anything for the schema here. It's just going to be an empty array. And that's our ticket facts tool. We are just getting the facts of a ticket and we are supplying the facts of that ticket. We don't have the actual description or the message of that ticket here. But all of that is going to be very different than the ticket messages tool. For example, schema. So the schema is what the model is needing to provide to the tool in order for the tool to do what it needs to do.

Building Ticket Messages Tool5:00

For example, schema. So the schema is what the model is needing to provide to the tool in order for the tool to do what it needs to do. So in order for the ticket messages tool to work, it's going to need to know how many messages to retrieve. So we could say that there will be a count that will be an integer that will have a min of one and a max of, I don't know, let's do five. And we can provide a description that can say how many recent messages to retrieve. And we could also say that that is required. So in order for the model to use this tool, it will need to supply the count, which will be an integer, which

And we could also say that that is required. So in order for the model to use this tool, it will need to supply the count, which will be an integer, which will be between one and five. But this too needs to have a constructor. So we will define that and we will need the ticket ID. We will also need the user, which we will default to null. So just like before, and you'll see whenever we incorporate these tools into our agents, we'll see how we supply that information. The constructor, obviously, the description is going to be a little bit different here, because we aren't dealing with facts or returning, you know,

The constructor, obviously, the description is going to be a little bit different here, because we aren't dealing with facts or returning, you know, description, not description, but department status, things like that. We return the most recent tickets, not tickets, ticket messages, so that when it comes to handle this, you know, we're going to start off pretty much exactly the same way to where we will check if we have a user, if not, then we will get the user. And if we don't have a user, then we will just simply say unauthorized, but then just like before we will get the ticket, I should have left the other file open so that we could copy and paste, but we will find the ticket based upon

then just like before we will get the ticket, I should have left the other file open so that we could copy and paste, but we will find the ticket based upon the ticket ID. Then once again, we will check if there is not a ticket, then we will return unauthorized as well. But just like before, we could add a to do to be sure user can view ticket. So then we need our count, and our count is going to come from the request as an integer, because that's how we defined it in the schema, and we can say that we would have a default of three. Now, we need to be sure that our count is within our defined range, so we want

we would have a default of three. Now, we need to be sure that our count is within our defined range, so we want the max of one, and then the min of five and count, so that then we can get the messages so that we will get ticket messages, but we want the latest messages. We are going to limit by our count, we will get them, then we will reverse them , we'll flip it and reverse, sorry, then we will map, because we want both the role, which we will get from our message role. Then we want the body that we will get message body, and then we will call values, so that then we will return messages, we'll call to Jason, and Jason, pretty print.

Wiring Tools into Agent8:13

values, so that then we will return messages, we'll call to Jason, and Jason, pretty print. So we define a schema, the schema is what the model needs to provide the tool in order for the tool to do its thing, we call it count, so that whenever we handle that request, we will get the count so that we can filter the messages, or rather limit the messages, and there we go. So we have our tools, we now just need to use them inside of our ticket assistant. So if you'll remember, whenever we created these agents, they implemented several things, agents, conversational, and then there was the has tools, and

So if you'll remember, whenever we created these agents, they implemented several things, agents, conversational, and then there was the has tools, and in order to implement has tools, we need the tools method, which I deleted. We can easily add it back, simply called tools, it needs to return an iterable, and the first thing we need to do is get the user. So if we have a user ID, then we want to get the user based upon that user ID, otherwise it's known, except do we have a user ID? We do, don't we, instruct? No, we only have the ticket ID, we also need the user ID now, because our tools depend upon that. So public read only int user ID defaults to no.

user ID now, because our tools depend upon that. So public read only int user ID defaults to no. Okay, so now that we have that user ID, we will try to find the user with that ID, otherwise it's no, but you know, we don't have to worry too much about that because the tools are going to take that into account. So we are going to return a new ticket facts tool, we will pass in the ticket ID and the user. We also want to provide our other tool, tickets message tool, where we once again pass in the ticket ID and the user. So now our agent is aware that it has some tools that it can use, and so if the

again pass in the ticket ID and the user. So now our agent is aware that it has some tools that it can use, and so if the model ever decides that, hey, I need something from one of these tools, it's going to use one of those tools. Now, by introducing tools here, we need to add another attribute, and I'm going to bump the max tokens up to 5000, because if we are going to be dealing with multiple messages, then we're going to need something with enough tokens. But let's include this max steps attribute, this is going to set a limit so that the model can't essentially loop forever with these tools. So we cap it at three or whatever we need to cap it as so that the model doesn

that the model can't essentially loop forever with these tools. So we cap it at three or whatever we need to cap it as so that the model doesn 't endlessly try to use these tools. Alright, so now that we have this ticket assistance, we need to open up our controllers, so we need the chat controller, we also need the draft controller, because in both of those we used the ticket assistant, because now we have a user that we need to pass to it. So here we'll just say request, user, and ID, we will do the same thing inside of the ticket chat controller. So where is that, where we create our agent there, we pass in the ticket ID,

of the ticket chat controller. So where is that, where we create our agent there, we pass in the ticket ID, then we pass in the user ID, but it doesn't like that, why doesn't it like that ? Oh, because, yeah, der, it's positional, let's just use positional. Okay, so now we have implemented two tools, these are tools that the model will decide if it needs to use based upon the prompt that we supply. The tools are going to be scoped to the ticket and the user, so there's not going to be any bleeding through or leaking between everything is just going to work as it should.

Testing Tool Calls11:56

going to be any bleeding through or leaking between everything is just going to work as it should. So we can test this by, you know, getting the last couple of messages, so what for the last two messages, and we will send that. Of course, we need to hope that it's going to use our tool, but there's actually a way that we can check and see if our tool is used. But here we can see the response, here are the last two messages, user, what is the priority of this ticket, agent, the ticket priority is for. Now we can hope that our tool was used, but at least in the case of open AI, I can view the log everything that comes through their API using my API key is

Now we can hope that our tool was used, but at least in the case of open AI, I can view the log everything that comes through their API using my API key is logged. And we can see the inputs here, you are a support assistant, stay strictly within the current ticket. This is all part of the instructions for our agent, but here we can see recent messages, user, I reset my password, but I still can't log in. Blah, blah, blah, blah, blah, blah. And then here, here's the user message. What were the last two messages? So this was what we just sent, but notice the output.

What were the last two messages? So this was what we just sent, but notice the output. There is a function call to ticket message tool. The schema definition has account of two, because we asked it to get the last two messages. So it indeed used our ticket messages tool to get those messages and respond with them. Now we can create these tools, we can attach them to our agents, but it's up to the model to determine if it wants to use those tools. And really it comes down to the prompt.

the model to determine if it wants to use those tools. And really it comes down to the prompt. I provided a pretty specific prompt, get me messages, get me two messages. So since the model knew that those tools were available, one of them specifically has messages that allows a count, then yeah, the model definitely was going to use that tool. But these particular tools are, well, they're scoped to an individual ticket and an individual user. In the next episode, we are going to talk about real domain tools, things that have lookups and orders and cross ticket intelligence.

In the next episode, we are going to talk about real domain tools, things that have lookups and orders and cross ticket intelligence.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟