Now it's time to write our react agent.
So let's define a variable called agent.
And it's going to take our prompt.
And it's going to plug it in into our LM.
Now you might be wondering what are those pipe thingies.
So this is me using the Lang chain expression language or LCL.
So the Lang chain expression language is a way for us to define declaratively and compose our chains
together.
So there are lots of benefits of using the LCL.
It makes our code more readable, more composable, and it really helps us understand what's happening
under the hood when we dive into internals.
And it has a lot more benefits like parallel processing, batch and streaming support fallbacks, and
we'll dive into it later in this course.
By the way, one of the reason it was created was because people complained that all the chains and
agents were too abstract, and they didn't understand what was going on under the hood.
But with the help of the LKL, we can understand exactly what's happening in each step.
And what's the chronological order of those executions.
Okay, let's go back to our agent and let's now describe what are we doing here.
The pipe operator takes the output of its left side and plugs it in into the input of its right side.
So here it's going to run the prompt step, which is going to output us a prompt value.
And it's going to input it into the LM because LMS receives a prompt value.
So intuitively you can think about it that we're taking our prompt and plugging it into the LM and then
running it.
You can see in this description the building blocks of length chain and what would they output and what
input do they need to receive.
Here we can see that prompt outputs us a prompt value.
And this is something that the LM can receive.
It receives strings and it can receive a prompt value.
But this prompt is not complete yet because we haven't supplied it with our question that we want to
ask our agent.
To do so, we need to plug it in its input.
And what does it input?
It comes in the form of a dictionary with the keyword, which is going to replace the placeholders,
and the value is going to be what's going to replace those placeholders.
So because we partially initialize this prompt with the tools and the tool names, we only need to populate
the input placeholder.
So we're going to input our prompt with a dictionary that's going to contain the key of input.
And its value is going to hold eventually the question that we're going to be asking our agent.
So because we want everything to be dynamic, we won't be passing right here.
The prompt that we're going to send to the agent, we're going to pass it when we invoke all of this
chain.
And when we invoke the chain, we need to supply it with a dictionary of the keywords that we're going
to replace the placeholders.
So because of that, instead of putting here the input, we're going to write a lambda function that
is receiving a dictionary and is accessing the input key of that dictionary.
So this is how we're going to be tailoring everything together.
Eventually we're going to have in our agent an LLM, which is going to receive our prompt filled with
all the arguments.
And when we'll use the invoke function, we'll populate the input keys with the value that we're going
to be giving in the invoke.
And this will propagate until the LLM call.
So let's now use the invoke method of this agent.
And we want to pass it a dictionary where the input is going to be what we're going to be asking for
the agent.
And here we're asking what is the length of dog in characters?
Now notice the way that we write here.
The prompt is super important because our agent is going to receive it, and it's going from that determined
which tool to use and what input will it receive.
And even it will affect the output parsing later when we parse the results of the LLM.
So let's run it and see what we get.
And we can see that the LM responded.
I can use the Get text Links tool to determine the length of the text dog.
I will parse the text dog as an input to the get text length function, and after that we can see we
have a backslash n action colon.
It's going to be the name of the function get text length.
Then we're going to have a backslash n action input which is going to be dog.
So this is what the LM responded.
And this is actually the reasoning engine.
The LM got our prompt and it responded us with exactly what needs to be run, what tool needs to be
selected.
And this covers in the react algorithm, the query part which we plug into the agent.
And how does the agent comprise an elaborate prompt which is sent to the LM.
Then the LM functions as a reasoning agent to select the correct tool, and returns us a response containing
all the information about which tool is selected and need to be run.
And now we'll need to go and parse this output that we just saw.
And now we're going to see how we can take this response.
And we can actually invoke this function.
So to do that we'll need to parse this text and to retrieve from it the action and action input and
translate it to it, to the function that we need to call and to the arguments that we need to supply
it.
So we're going to be implementing that.
And we're going to do that by using regular expressions.
So I hope you're ready to writing some regex.
Just kidding.
Linkchain is going to do all the work for us because they already implemented the output parser, which
take the output of the LLM in the react agent and simply parse it into the components that we need.
So this output we want to pass into something which is called the react single input output parser.
And we're going to import it from link chain.
And we want to invoke it.
So let's run it.
And we can see that when we run it we'll get an error.
And we have the error of could not pass the LM output.
And this is probably the most common error when it comes to agent.
It's an output parsing error.
So remember I told you that we have a lot of weight and a lot of impact on the text that we input our
agent.
So this is what I meant.
And this error basically means that the LM responded to us, not something in the format that the output
parser expects.
So the output parser expects something to be in the format of backslash n action backslash n action
input.
So let's go to our input.
And let's go to refine it a bit and remove text from it.
So hopefully this would now work correctly.
So we can see that we get a response back.
And we can see now that the output parser gave us something in the format of tool, each get length
and the tool input is doc.
So this is exactly what we need.
We can also see that in the log property we have a what the LLM responded.
And we can indeed see that it's in indeed in the correct backslash in action and backslash in action
input format that the output parser expects.
So I've been mumbling about this output parser.
So let's check out how does it look and what does it do.
So according to the description it parses the react style LLM call that have a single tool input.
So it expects the output of the LLM to be in one of two formats.
And we'll be focusing on this video in the first format.
And the second format will be focused on in the next video.
So the first format is the format of action and action input.
And this basically the case where the LLM tells us that we need to perform some kind of action, aka
select a tool and then invoke it so it will come in the format of action, which is going to be the
tool name and the action input, which is going to be the input that we're going to supply our tool.
So in our example the action was get text length which is the name of the function.
And the action input was dog.
So now let's go and show you the logic of what length chain is doing with all that output parsing.
It has a function called parse which is going to be executed, and it's going to return us something
which is called an agent action.
And this is simply a link chain object, which is going to hold the tool name and the tool input that
we want to supply it after we passed it.
And that is going to help us invoke the tool that the LM selected from the reasoning engine.
And let's have a look at the parsing using regular expressions.
So we can see we have a regular expressions that is supposed to extract the action and the action input.
And you can see in the bottom lines over here that we take what we matched.
If it was in that format and we place it in the action and action input variables.
And the last thing I want to show you is that we return an agent action object, which is built from
the action and the tool input and the text, which was the original answer from the LM.
So by taking this we can select the tool that we want to run and run it.
So right now we finished with the parsing part.
And now we want to go to the tool execution.
So we have now all the information about which tool we want to execute.
So now we just need to execute this tool.
Now let's change the name of the variable res to agent step.
And it's going to be of the type of agent action or agent finish.
So let's import those two long chain classes.
We discussed a bit about Agent Action and Agent Finish.
We're going to discuss soon.
Let's add a print.
And now if the agent step is the type of agent action, it will hold all the information of the tool
we want to run and execute and get our observation which is the result of this tool.
So we want to write this logic.
So if we get back from the output parser, the agent step, which is going to be an instance of the
class agent action, we want to extrapolate the tool to use.
So we'll get the tool name.
And from the tool name we're going to find from the list of tools the tools to run.
So let's extrapolate the tool name.
And it's going to be the agent stepped dot tool.
We'll define a variable called tool to use.
And this is going to be the function that will run.
And now we need to take the tool name.
And we need to find the tool from it.
So we'll need to define a new function which is called find tool by name.
It's going to receive the tools list that we defined earlier.
And it's going to receive the tool name.
So let's go and copy that.
And let's define this function.
And this function arguments is going to be tools which is going to be a list of tools.
And the second argument is going to be a tool name that we're going to find which is going to be a string.
This function is going to return us a tool.
And the implementation is going to be very straightforward.
We're going to be iterating through the tools.
And if the tool dot name is equal to the tool name that we're searching for, then we want to return
the tool.
And if we finished iterating and we didn't find the tool, let's raise a value error and write that
we couldn't find the tool with the tool name.
So now that we finished implementing the fan tool by name function, we want now to run the tool.
And for that we'll be needing the tool input.
So we're going to get it from the agent step dot tool input.
And now let's define a new variable and we'll call it observation.
And it's going to be the results of us running the tool.
So it's going to be the tool to use.
And the tool has the attribute of function.
And this is the function that we defined the tool on.
And here we're simply going to plug in the tool input.
Just to be safe.
I converted it into a string because I know that the function is expecting to get a string.
However, of course the length chain implementation is much more robust and can handle much more cases
where we need special attributes and special types for our inputs.
And now let's go and print our observation which is the result of running the tool.
Now let's run it and let's see what we get.
We can see we got a value error that it couldn't find the tool.
And this is because I passed the wrong argument to this function I passed instead of tool name the list
of tools.
So I'm simply going to change the second argument to be the tool name.
So let's rerun it.
And we can see now that we get observation equal to five because we passed to our tool the argument
of dog with quotes.
And it also counted the quotes.
And just to make it a bit more explicit, I'm going to add to our tool a print where we're printing
the tool name, and we're also mentioning the argument that we entered with.
So now let's rerun it.
And indeed we can see we entered the function gettext length with the dog word and wrapped with the
quotes.
So if we just want to make it a bit more nicer, let's remove the quotes from the word dog.
And I'm just want to refine a bit more the prompt.
So I'm going to simply write the final prompt, which is going to be what is the length in characters
of the text dog.
And when we run the agent, we can see that we indeed chose the correct tool, ran it, and we got that
the observation was three, So it counted the number of letters in the word dog.
So in this video we reviewed a massive part of the react implementation of Lang Chain.
We saw how we can start from a user query to count the number of letters in the word dog, how we plugged
it into the agent.
Then the agent wrapped it up in a special call of the react algorithm.
Sent this LM call to GPT 3.5.
We got back a response from the LM, which had the thought and all the information of the tool selection,
and this was actually the reasoning engine of the LM.
We then saw how link chain parses all of this information and all of this response, and we saw then
how link chain transforms it into a tool to run and to execute that tool.