back to indexLangChain Agents in 2025 | Full Tutorial for v0.3

Chapters
0:0 LangChain Agents 101
1:27 Introduction to Tools
7:5 Creating an Agent
11:27 Agent Executor
18:2 Web Search Agent
00:00:00.000 |
In this chapter we are going to introduce agents. Now agents I think are one of the most important 00:00:07.860 |
components in the world of AI and I don't see that going away anytime soon. I think 00:00:14.880 |
the majority of AI applications, the intelligent part of those will be almost always an implementation 00:00:23.920 |
of an AI agent or most of all AI agents. So in this chapter we are just going to introduce 00:00:30.220 |
agents within the context of linechain. We're going to keep it relatively simple. We're going 00:00:36.760 |
to go into much more depth in agents in the next chapter where we'll do a bit of a deep dive but 00:00:44.040 |
we'll focus on just introducing the core concepts and of course agents within linechain here. So 00:00:52.120 |
jumping straight into our notebook, let's run our prerequisites. You'll see that we do have an 00:00:59.880 |
additional prerequisite here which is Google search results. That's because we're going to be using the 00:01:04.600 |
SERP API to allow our LLM as an agent to search the web which is one of the great things about agents 00:01:13.980 |
that they can do all of these additional things and LLM by itself obviously cannot. So we'll come down to 00:01:20.300 |
here we have our Linesmith parameters again of course so you enter your linechain API key if you have one and 00:01:27.260 |
now we're going to take a look at tools which is a very essential part of agents. So tools are a way for 00:01:35.980 |
us to augment our LLMs with essentially anything that we can write in code. So we mentioned that we're going to 00:01:44.060 |
Google search tool, that Google search tool is some code that gets executed by our LLM in order to search 00:01:50.940 |
Google and get some results. So a tool can be thought of as any code logic or any function indicate in the 00:01:59.900 |
case of Python and a function that has been formatted in a way so that our LLM can understand how to use it 00:02:08.060 |
and then actually use it although the LLM itself is not using the tool it's more our agent execution logic 00:02:17.020 |
which uses the tool for the LLM. So we're going to go ahead and actually create a few simple tools we're 00:02:24.060 |
going to be using what is called the tool decorator from Langchain and there are a few things to keep in 00:02:31.020 |
when we're building tools. So for optimal performance our tool needs to be just very readable and what I 00:02:37.500 |
mean by readable is we need three main things. One is a dot string that is written in natural language and 00:02:44.700 |
it is going to be used to explain to the LLM when and why and how it should use this tool. We should also 00:02:52.860 |
have clear parameter names. Those parameter names should tell the LLM okay what each one of these parameters 00:03:00.940 |
are they should be self-explanatory. If they are not self-explanatory we should be including an 00:03:08.140 |
explanation for those parameters within the dot string. Then finally we should have type annotations 00:03:13.900 |
for both our parameters and also what we're returning from the tool. So let's jump in and see how we would 00:03:21.100 |
implement all of that. So come down to here and we have linechain core tools import tools okay so these are 00:03:28.540 |
just four incredibly simple tools. We have the addition or add tool, multiply, the exponentiate and the subtract tools. 00:03:37.340 |
Okay so a few calculator s tools. Now when we add this tool decorator it is turning each of these tools 00:03:47.820 |
into what we call a structured tool object. So you can see that here we can see we have this 00:03:55.900 |
structured tool we have a name description okay and then we have this arg schema we'll see this in a 00:04:01.980 |
moment and a function right so this function is literally just the original function it's a mapping 00:04:08.060 |
to the original function so in this case it's the add function. Now the description we can see is coming 00:04:14.140 |
from our dot string and of course the name as well is just coming from the function name. 00:04:19.900 |
okay and then we can also see let's just print the name and description but then we can also see the 00:04:26.860 |
args schema right we can so this thing here that we can't read at the moment to read it we're just going 00:04:33.820 |
to look at the model.json schema method and then we can see what that contains which is all of this 00:04:40.380 |
information. So this actually contains everything includes properties so we have the x it creates a little 00:04:46.700 |
title for that and it also specifies the type okay so the type that we define is float float for openai 00:04:55.340 |
gets mapped to number rather than just being float and then we also see that we have this required 00:05:01.420 |
field so this is telling our lm which parameters are required which ones are optional so we you know in 00:05:08.460 |
some cases you would we can even do that here let's do z that is going to be float or none okay and we're 00:05:19.500 |
just going to say it is 0.3 all right wait i'm going to remove this in a minute because it's kind of weird but 00:05:26.700 |
let's just see what that looks like so you see that we now have x y and z but then in z we have some 00:05:36.380 |
additional information okay so it can be any of it can be a number or it can just be nothing 00:05:41.820 |
the default value for that is 0.3 okay and then if we look here we can see that the required 00:05:48.780 |
field does not include z so it's just x and y so it's describing the full function schema for us but let's 00:05:56.940 |
remove that okay and we can see that again with our exponentiate tool 00:06:02.380 |
similar thing okay so how how are we going to invoke our tool so the lm the underlying lm is actually 00:06:13.180 |
going to generate a string okay so we'll look something like this this is going to be our lm output so it is 00:06:21.340 |
is a string that is some json and of course to load a string into a dictionary format we just use json 00:06:30.860 |
loads okay so let's see that so this could be the output from our lm we load it into a dictionary and 00:06:38.220 |
then we get an actual dictionary and then what we would do is we can take our exponentiate tool we access the 00:06:46.540 |
underlying function and then we pass it the keyword arguments from our dictionary here 00:06:52.780 |
okay and that will execute our tool that is the tool execution logic that line chain implements and 00:07:01.500 |
then later on in the next chapter we'll be implementing ourselves cool so let's move on to 00:07:07.580 |
creating an agent now we're going to be constructing a simple tool calling agent we're going to be using line 00:07:13.660 |
chain expression language to do this now we will be covering line chain expression language or else 00:07:20.620 |
more in a upcoming chapter but for now all we need to know is that our agent will be constructed using 00:07:29.340 |
syntax and components like this so we would start with our input parameters that is going to include our 00:07:36.300 |
user query and of course the chat history because we need our agent to be conversational and remember 00:07:41.660 |
previous interactions within the conversation these input parameters will also include a placeholder for 00:07:47.660 |
what we call the agent scratch pad now the agent stretch pad is essentially where we are storing the 00:07:53.420 |
internal thoughts or the internal dialogue of the agent as it is using tools getting observations from those 00:07:59.420 |
tools and working through those multiple internal steps so in the case that we will see it will be using for 00:08:07.420 |
example the addition tool getting the result using the multiply tool getting the result and then providing 00:08:13.100 |
a final answer towards as a user so let's jump in and see what it looks like okay so we'll just start 00:08:19.580 |
with defining our prompt so our prompt is going to include the system message that's nothing we're not 00:08:25.340 |
putting anything special in there we're going to include the chat history which is a messages placeholder then we 00:08:33.340 |
include our human message and then that we include a placeholder for the agent scratchpad now the way 00:08:39.900 |
that we implement this later is going to be slightly different for the scratchpad we would actually use 00:08:44.620 |
this message's placeholder but this is how we use it with the built-in create tool agent from blank train 00:08:51.180 |
next we'll define our lm we do need our open API key for that so we'll enter that here like so 00:08:58.380 |
okay so come down okay so we're being going to be creating this agent we need conversation memory and 00:09:04.940 |
we are going to use the older conversation buffer memory class rather than the newer runnable with 00:09:09.660 |
message history class that's just because we're you also using this older create tool calling agent and 00:09:16.460 |
this is this is the older way of doing things in the next chapter we are going to be using the more 00:09:23.740 |
recent basically what we already learned on chat history we're going to be using all of that to 00:09:29.100 |
implement our chat history but for now we're going to be using the older method which is deprecated just 00:09:34.780 |
as a pre-warning but again as i mentioned at the very solid of course we're starting abstract and then we're 00:09:42.140 |
getting into the details so we're going to initialize our agent for that we need these four things lm as 00:09:49.500 |
we defined tools as we have defined prompt as we have defined and then the memory which is our 00:09:56.780 |
old conversation buffer memory so with all of that we are going to go ahead and we create a tool calling 00:10:03.500 |
agent and then we just provide it with everything okay there we go now you'll see here i didn't pass in 00:10:11.580 |
the memory i'm passing it in down here instead so we're going to start with this question which is 00:10:17.900 |
what is 10.7 multiplied by 7.68 okay so given the precision of these numbers our normal lm would 00:10:29.260 |
not be able to answer that or almost definitely would not be able to answer that correctly we need 00:10:35.740 |
a external tool to answer that accurately and we'll see that that is exactly what it's going to do 00:10:41.340 |
so we can see that the tool agent action message here we can see that i decided okay i'm going to use 00:10:50.220 |
the multiply tool and here are the parameters i want to use for that tool okay we see x is 10.7 and y is 00:10:57.100 |
7.68 you can see here that this is already a dictionary and that is because lang chain has 00:11:04.460 |
taken the string from our lm call and already converted it into a dictionary for us okay so that's just 00:11:11.420 |
it's happening behind the scenes there and you can actually see if we go into the details a little bit we 00:11:17.180 |
can see that we have these arguments and this is the original string that was coming from our lm okay which 00:11:22.300 |
has already been of course processed by lang chain so we have that now the one thing missing here 00:11:30.140 |
is that okay we've got that the lm wants us to use multiply and we've got what the lm wants us to put 00:11:38.060 |
into multiply but where's the answer all right there is no answer because the tool itself has not been 00:11:45.340 |
executed because it can't be executed by the lm but then okay didn't we already define our agent 00:11:52.620 |
here yes we defined the part of our agent that is how lm has our tools and it is going to generate which 00:12:01.340 |
tool to use but it actually doesn't include the agent execution part which is okay the agent executor 00:12:10.380 |
is a broader thing it's it's broader logic like just code logic which acts as a scaffolding within 00:12:18.380 |
which we have the iteration through multiple steps of our lm calls followed by the lm outputting what 00:12:26.620 |
tool to use followed by us actually executing that for the lm and then providing the output back into the 00:12:33.900 |
lm for another decision or another step so the agent itself here is not the full agentic flow that we 00:12:43.980 |
might expect instead for that we need to implement this agent executor class this agent executor includes 00:12:51.580 |
our agent from before then it also includes the tools and one thing here is okay we we already passed 00:12:58.140 |
the tools to our agent why do we need to pass them again well the tools being passed to our agent up 00:13:03.340 |
here that is being used so that is essentially extracting out those function schemas and passing 00:13:10.700 |
it to our lm so that our lm knows how to use the tools then we're down here we're passing the tools again 00:13:15.980 |
to our agent executor and this is rather than looking at how to use those tools this is just looking at 00:13:22.460 |
okay i want the functions for those tools so that i can actually execute them for the lm or for the agent 00:13:28.380 |
okay so that's why it's happening there now we can also pass in our memory directly so you see if we 00:13:35.740 |
scroll up a little bit here i actually had to pass in the memory like this with our agent that's just 00:13:43.260 |
because we weren't using the agent executor now we have the agent executor it's going to handle that for us 00:13:49.020 |
and another thing that's going to handle for us is intermediate steps so you'll see in a moment that 00:13:54.620 |
when we invoke the agent executor we don't include the intermediate steps and that's because it that 00:13:59.660 |
is already handled by the agent executor now so we'll come down we'll set verbose equal to true so 00:14:06.220 |
we can see what is happening and then we can see here there's no intermediate steps anymore and we we do 00:14:14.540 |
still pass in the chat history like this but then the addition of those new interactions 00:14:20.940 |
to our memory is going to be handled by the executor so in fact let me actually share that very quickly 00:14:27.580 |
before we jump in okay so that's currently empty we're going to execute this 00:14:32.460 |
okay we entered that new agent execute chain and let's just have a quick look at our messages again 00:14:41.420 |
and now you can see that agent executor automatically handled the addition of our human message and then 00:14:47.580 |
the responding ai message for us okay which is useful now what happened so we see that the multiply tool 00:14:55.980 |
was in vote with these parameters and then this pink text here that we got that is the observation from 00:15:02.940 |
from the tool so they spot the tool output back to us okay then this final message here is not formatted 00:15:08.860 |
very nicely but this final message here is coming from our lm so the green is our lm output the pink is our 00:15:16.940 |
tool output okay so the lm after seeing this output says 10.7 multiplied by 7.68 is approximately 82.18 00:15:31.420 |
okay cool you saw and then we can also see the the chat history which we we already just saw great 00:15:38.300 |
so that has been used correctly we can just also confirm that that is correct okay 82.1759 recurring 00:15:47.980 |
which is exactly what we get here okay and we the reason for that is obviously how multiply tool is just 00:15:53.820 |
doing this exact operation cool so let's try this with a bit of memory so i'm going to ask or i'm going to 00:16:03.180 |
state to the agent hello my name is james we'll leave that as the it's not actually the first interaction 00:16:11.260 |
because we already have these but it's an early interaction with my name in there then we're going to 00:16:19.980 |
try and perform multiple tool calls within a single execution loop and what you'll see with when it is 00:16:25.340 |
calling these tools is that you can actually use multiple tools in parallel so for sure i think 00:16:29.980 |
two or three of these were used in parallel and then the final subtract had to wait for those previous 00:16:35.340 |
results so it would have been executed afterwards and we should actually be able to see this in 00:16:41.500 |
langsmith so if we go here yeah we can see that we have this initial call and then we have add a 00:16:49.020 |
multiply and exponentially or use in parallel then we have another call which you subtract and then we 00:16:54.220 |
get the response okay which is pretty cool and then the final result there is negative 11. 00:17:01.660 |
now when you look at whether the answer is accurate i think 00:17:06.460 |
the order here of calculations is not quite correct so if we put the actual computation here it gets it 00:17:15.180 |
right but otherwise if i use natural language it's like i'm doing maybe i'm phrasing it in a in a poor way 00:17:21.180 |
okay so i suppose that is pretty important so okay if we put the computation in here we get the negative 13. 00:17:31.900 |
so something to be careful with and probably requires a little bit of prompting to prompting 00:17:37.820 |
and maybe examples in order to get that smooth so that it does do things in the way that we might expect 00:17:44.620 |
or maybe we as humans are just bad and misuse the systems one or the other okay so now we've gone 00:17:52.540 |
through that a few times let's go and see if our agent can still recall our name okay and it remembers 00:17:58.060 |
my name is james good so it still has that memory in there as well that's good let's move on to another 00:18:05.180 |
quick example where we're just going to use google search so we're going to be using the serp api you 00:18:11.580 |
can okay you can get the api key that you need from here so serpapi.com slash user slash sign in and 00:18:19.900 |
just enter that in here so you will get it's up to 100 searches per month for free so just be aware of 00:18:29.100 |
that if you overuse it i don't think they charge you because i don't think you enter your card details 00:18:34.860 |
straight away but yeah just be aware of that limit now there are certain tools that linechain have already 00:18:42.860 |
built for us so they're pre-built tools and we can just load them using the load tools function so we do 00:18:48.860 |
that like so we have our load tools i'm just passing the serp api tool only we can pass in more there if 00:18:54.780 |
we wanted to and then we also pass in our lm now i'm going to one use that tool but i'm also going to 00:19:02.460 |
define my own tool which is to get the current location based on the ip address now this is we're 00:19:08.140 |
in collab at the moment so it's actually going to get the ip address for the collab instance i'm currently on 00:19:13.420 |
and we'll find out where that is so that is going to get the ip address and then it's going to provide 00:19:19.820 |
the data back to our lm in this format here so we're going to latitude longitude city and country 00:19:24.940 |
okay we're also going to get the current day and time so now we're going to redefine our prompt i'm not 00:19:33.820 |
going to include chat history here i just want this to be like a one-shot thing i'm going to redefine our 00:19:40.140 |
agent and agent executor using our new tools which is our serp api plus the get current date time and 00:19:46.540 |
get location from ip then i'm going to invoke our agent executor with i have a few questions what is the 00:19:53.420 |
date and time right now how is the weather where i am and please give me degrees in celsius so when it 00:20:00.300 |
gives me that weather okay and let's see what we get okay so apparently we're in council bluffs in the us 00:20:10.300 |
it is 13 degrees fahrenheit which i think is absolutely freezing oh my gosh it is yes minus 10. 00:20:18.300 |
so it's super cold over there and you can see that okay did give us fahrenheit so that's that is because 00:20:25.740 |
the tool that we're using provided us with fahrenheit which is fine but it did translate that over into 00:20:33.180 |
a estimate of celsius force which is pretty cool so let's actually output that so we get this which i 00:20:40.780 |
is correct for the us approximately this and we also get a description of the conditions as well as partly 00:20:48.780 |
cloudy with zero percent precipitation lucky for them and humidity of 66 okay all pretty cool so that is 00:20:58.780 |
it for this introduction to line chain agents as i mentioned next chapter we're going to dive much 00:21:03.740 |
deeper into agents and also implement that for line chain version 0.3 so we'll leave this chapter here