LangGraph Tutorial - How to Build Advanced AI Agent Systems
Key Takeaways
This video tutorial by Tech With Tim covers building advanced AI agent systems using LangGraph, a professional and in-depth framework for creating scalable and complicated AI agents. The tutorial includes setting up the environment, getting an LLM API token, and building simple and complex chatbots using LangGraph.
Full Transcript
In this video, you're going to learn how to build AI agents using Langraphph. Langraph is a much more professional and in-depth framework compared to something like Langchain or Llama Index, which allows you to build a really complicated and wellthoughtout AI agent. If you're looking to push something into production, you want to have scalability features, and overall you just want more control, then Langraph is what you should be using. But it can be difficult to learn. So that's why I'm making this video. I'm going to break it down for you as simple as possible. And by the end of this, you'll know how to build AI agents and you'll have a more complex one that you can adapt and change to your use case. Now, what we're going to do here is just quickly discuss the key differences between Langraph and something like Langchain. Then, we're going to hop onto the computer. So, let's go ahead and do that. All right. So, let's scroll down here and just look at some stuff that they have on their website. So, Langraph really is meant for when you want to have a more complex application. It really is an orchestration framework. That means that it allows you to control the flow and kind of how your AI agent uses various state or passes through various stages. If you're not familiar, there are modules like Langchain. Langchain is kind of a simpler, higher level framework that makes it easy to build simple AI agents, but when you have a lot of state or you have a lot of steps, it can be difficult to orchestrate that agent because it doesn't have those lower level features. So lang chain really just gives you much more control. It also is much better at persisting things like the context. So as you can see here, persisted context for long-term interactions. So it knows kind of the information that you've given to it. And you can update and modify the state as you move through these various different steps. Now, as it says, lang graph uses a graph to represent data and to represent kind of the state of an agent. I'm going to show you that in just one second, but those are the main kind of key features. Now, of course, there are also advantages here when it comes to things like scalability and fault tolerance. We're not really going to get into that in this video, but Langraph also has kind of this cloud platform that you can pay for that would allow you to deploy your Langraph applications. Again, we're not doing that in this video, but it is worth noting because that's kind of a huge selling point of using something like Langraph. Okay, so those are the main features. Now, what I want to do is I want to show you an example of a graph that you could generate with Langraph. So have a look at these graphs here. On the right side, we have a very simple one. On the left side, we have one that's a little bit more complicated. Now, we're actually going to build both of these graphs. And these graphs will represent an agentic system or an AI agent. So, if you look at the right hand side here where we have start, chatbot, and then end. This is a super simple agent flow and something that you've probably built before without using something like Langraph. Now, all this means is we start at this particular node. Maybe we collect something like some user input. We then throw that to a chatbot and maybe the chatbot gives us some output and then we end. Okay, very very simple graph. Now on the left side we start to get a little bit more complicated. Still simple but you can see where Lang graph starts to have an advantage here. We now have some orchestration and we kind of have a flow between our application. So we have some start node. Maybe we collect some user input. In this case the user input can be maybe a problem that a user is having. We then classify that input. We pass that to a router based on that classification whether it's something that maybe a therapist should handle or something that like a more logical thinker should handle. We then route that request to one of these two nodes. So this logical node or this therapist node and then we end from there. Okay. So in langraph we have nodes which are all of these things you're seeing. So like start classifier router these are all nodes. And then we have edges those are the connections between those nodes. And we can have things like conditional edges which you can see here in our router where we can either go to the therapist or to the logical. Okay, so that's kind of how Langraph works. That's how we orchestrate the flow of the agent and allows us to build these really small components that we can combine together to make these large agentic systems and that allows us to have multiple agents that are interacting with each other and to do some really cool stuff. Obviously, in this video, we can't cover everything, but you're going to see how we make a super simple one and then how we get a little bit more complex and really take advantage of the graph component of Langflow. Okay, so now let's hop over to our IDE. Let's start coding and let's actually get into it cuz I know this is going to make a lot more sense to you guys once we really jump into the code. Now, right now I am using PyCharm. Okay, a lot of people ask me why I use this. Well, PyCharm really just is the best IDE when it comes to professional Python development. PyCharm does have a free subscription, but I also have a link in the description where you can get a threemonth extended free trial of their Pro subscription because I have a long-term partnership with them. So, make sure to check that out from the link below. And you'll see in this video why I do choose to use PyCharm because the autocomplete is just better, the environment management, all of that kind of stuff. It's really just a go-to IDE if you're doing a lot of heavy Python coding. Anyways, with that in mind, let's start creating a few things and getting our uh project set up. So, what we're going to do is open up our terminal and we're going to start dealing with our dependencies. Now, since we're in PyCharm, we can use something like uh virtual environment and we can just create it manually. But recently, I've been using UV a lot. So, I'm going to use UV and show you how that works in terms of kind of enabling the dependencies for this project. Now, if you're unfamiliar with UV, this is a new package manager for Python. I'm just going to look it up right here so you guys can see it. So, go UV right here. Okay, I'll leave a link to this in the description. You can install it very easily. You actually install it using pip, which is kind of funny. Once you have it installed, you should be able to just follow along with me here and type in the relevant UV commands. I also have a video I'll leave on screen that shows you how to use UV. Okay, so let's assume you have UV installed on your system. What we're going to do is we're going to open up a new folder. So I've done that inside of my IDE here and we're going to initialize a new UV project. To do that, I'm going to type UV init and then dot. This just means initialize in the current directory. So you can see it's now initialized a new project. And if we open this up here, you see that we have our Python version, pi project.toml, main.py file, all of that kind of stuff. From here, we're going to install the various dependencies that we need. So in order to do that, we can just type uv add. And then the first one we're going to bring in is python and then env. This is for loading environment variables. After that, we're going to type a few more that we need. We are going to bring in lang. Okay, graph like that. We should spell lang graph correctly. Of course, we're also going to bring in lang chain and then in square brackets. This is going to be anthropic. Okay, so anthropic like that. And I believe we do need to put this in quotation marks because we're using the square brackets. Okay, so we're going to have python.nv langraph and then lang chainropic. Did I spell anthropic correctly? Let's make sure that we are good there. And after that we are going to bring in last one here which is I pi kernel which we'll use later on for actually creating something like a Jupyter notebook. So we're going to go ahead and press enter here. It's going to create the environment for us and add all of those dependencies. And we should pretty much be good to go. And if we look at our pi projectl file we can see that we have the dependencies showing up here. Okay. So that's all we need for now. After this what I'm going to do is open up my main.py file. I'm going to delete everything inside of here. Now, after the main.py file has been created, we're going to go ahead and make one more new file. This file is going to be aenv file. Okay, just go ahead and press add there. That's fine. The env file is going to store an environment variable that will allow us to kind of store the key for whatever LLM it is that we're going to use. Now, we can use any LLM that we want here. In this case, I'm going to use Claude or I'm going to use entropic. Again, kind of pick whatever you want. You could use OpenAI. You could use a llama if you wanted to do this locally, but I find that claude works pretty well here. So that's the one that I'm going to go with. So inside of this file, all I'm going to do is just write an environment variable. So to do that, we're going to say, actually, let me just copy it in here so that I don't mess it up. We're going to have entropic API_key is equal to and then we're going to paste in our API key. Now, in order to get our API key, we're going to have to go to the entropic console. So we're going to go to console.entropic.com/ ontropic.com/dashboard. Okay, we're then going to go to API keys here. You will need an account on this and I believe you will need a credit card, although it should only cost you like a few cents. You can see here like one of these cost me 43 cents. These I don't think have cost me anything so far. And then I'm going to make a new API key. I am just going to call this lang graph like that. I'm going to go add and then I'm going to copy this key and delete it later so that you guys don't see it. Obviously, don't leak this with anyone. And then I'm going to paste it right here. Okay, so we have our API key now inside of this env file. Again, you're going to need to copy this step for whatever LLM provider you use. And if you just want to follow along with this video, then of course the easiest will be to use Entropic. And that's the one that I installed. Okay, so now that we have the key, we have everything installed, we can actually start writing some code. So from our main.py file here, the first thing we're going to do is we're going to say from.env import load.env. We're then going to call the load.env function. And what this is going to do for us is load in this environment variable so it can then be used when we initialize our model. So again just to be clear here we need an LLM and the LLM will kind of control the agent or be the brain of the agent. But around that LLM we can wrap a bunch of functionality. We can build this graph. We can have these multi- aent systems which is what Lang graph allows us to do. Okay. So now that we've done that uh what we're going to do is bring in a few things. So we're going to say from typing import annotated and literal. Okay, we're going to say from lang graph dot and this is going to be graph and we are going to import the state graph. Okay. And we're going to import start in all capitals and end in all capitals. Sorry for the cut there, but I just fixed my interpreter settings. So now we're not getting any of those autocomplete issues. I did that in PyCharm just by pressing this button and selecting the existing interpreter that's inside of this. Venv folder. Okay. So now that we've done that, we have a few more imports that we need here. So we're going to say from langraph and then this is going to begraph message. We are going to import this function called add messages. We're then going to say from this is going to be lang chain this time. Okay, not langraph. So we're going to say from langchain chat_models and we're going to import the init chat model. Then we're going to say from paidantic we're going to import the base model and we're also going to import the field. We'll use this later on. And then lastly we're going to say from typing extensions we are going to import the typed dictionary. Okay. So that's all of the imports that we need. Now that we've done that, we're going to load in our LLM. Okay, so we're going to say llm is equal to init chat model. And then inside of here, we're going to specify the model we want to load. So I'm just going to copy this in so that I don't make a mistake. And keep in mind all of this code will be available from the link in the description. So you will be able to just copy this if you need to. So you can see here that I'm just loading in the clawed 3.5 sonnet latest. Okay, you can put any model name you want here, but in this case, we're loading the entropic one. And because we have this environment variable in our enenv file and we've loaded that in with loadenv. Oops, that's not what I meant to do. Uh, this is going to load properly and allow us to access claude and use our API key. Okay. And there's other models you can use here. Again, you can use GPT, you can use DeepSeek. There's all kinds of ones. You will have to look that up or maybe ask an AI tool to assist you. But it's relatively easy to swap the LLM in the example that I'm showing you. Okay. Okay, so now that we have the LLM, the next thing that we want to do is we want to start setting up this state for our graph. Now, I know some of this will seem confusing right now. Just bear with me and I promise I'm going to break it down, but there is a bit of code that we need before we can really get going here. So, we're going to make a class and we're going to call this state. Now, inside of here, we're going to have a typed dictionary. Okay, that's going to be the type or the inheritance for our class. And this is where we're going to specify the state that we want our model and our agent system to have access to. And this is going to kind of control the flow of our application. So for right now, we're going to keep it nice and simple. And we're going to say messages. And then this is going to be annotated. And then we're going to have list and then add underscore messages. Okay. Okay. Now, what this is doing is we're saying that messages is going to be of type list. And whenever we want to change the messages, we're going to use this function called add messages which is provided by langraph to essentially add a new message to this list. I know that this seems a little bit weird, but this is just how you do this for storing messages. And in our state, what we're going to be doing is just keeping track of all of the messages that have been said. So the message that we say, for example, like a user message, and then the message that the LLM gives us back. So something like the assistant message. Okay, so this is like the most simple state that you can set up. And again, when we use annotated here, I mean, you can read this if you want. It kind of explains first we're putting the type and then second we're putting how we want to modify this type. Okay, so that's our state. All right, so we have the state and later on I'm going to show you an example where we put some other things in the state, but for now it's just going to store the messages. Now that we have this state, what we're going to do is we're going to kind of define a graph builder that will work using this state because again, if we go back here, this is essentially what we're going to be creating in these next few lines of code. We're going to create these graphs and then we can run through the graph and that represents our AI agent or our agentic system. Okay, so on line 18 here, we're going to say the graph_builder is equal to a state graph. Okay. And then for the state graph, we're going to pass our state. There's other types of graphs you can have, but the state graph is kind of the most basic. I don't know why this keeps popping up. I guess I'm highlighting something. Okay, so graph builder is equal to state graph. And the reason why we're getting these lines here is because we haven't yet used these objects. We'll use them later. So, don't worry. And let me just add some spacing here between our class. Okay. So, now we have our graph builder. And the next thing that we need to do is we need to start figuring out these nodes. We're building the nodes that are going to be in our graph. So for right now we're going to have a single node which is going to be our chatbot. But later on we'll have multiple nodes. So for now let me show you how you make a simple node. So to make a node you simply write a function. So I'm going to say define chatbot. This node is always going to be taking in the state. Okay? So, it's going to take in the state and then it's going to return essentially a modification to the state or the next state that we'll have in our graph. Again, I know it seems weird. Just bear with me here as we write this out. So, what I'm going to do is I'm going to say return and I'm going to return something that looks exactly like this state right here. So, I'm going to say messages. Okay? And then inside of a list, I'm going to say llm.invoke. Okay? And for this we're going to take in the state and then messages. Okay. So what I'm doing is I'm saying all right for this node I want to take in the current state. The state is going to be a bunch of messages. So what I'm going to do now is I'm going to say okay I want to return now some new messages and these messages are going to be a list. And what I'm going to do is I'm going to say llm.invoke and then whatever the current messages were. So I take all the messages in my state. I pass that to my llm. When you invoke the LM, it just means you're calling the LLM just as if you were using like claw desktop or something. We're just wrapping that in a list and then we're returning that. Now, the way that this works is that it's going to take this list or whatever is inside of here. It's simply going to add that into our state because we have this add messages function. So when we return something that kind of matches this state dictionary, since we've defined how it is we want to modify this state, this new message, whatever the LLM returns to us will simply get added into the state. Okay, so that's our first node. Now, in order to use this node, we need to register it in our graph. So to do that, we're going to say graph builder, and we're going to say add node, and we're going to add a node called chatbot. And this is going to point to the chatbot function. So whenever you want to add a node, let me just do a little bit of spacing here. The way that this works is you say graph builder. Okay, so our graph builder right here for our state graph. Add node. You give the node some string name. In this case, we called it chatbot. And then you point it to some particular function. All right. So now we have our single node. But the thing is in order for our graph to work, we always have to have a start node and an end node. So again if we go back here you can see we have start and we have end. We always need this in our graph. So we need to connect this node to the start and to the end. So in order to do that we can say graph_builder add edge and then when we add the edge we can use the name of our nodes and connect them. So I want to connect my start to my chatbot. So that's what I'm going to do. And start again is a variable that we imported here. It's kind of a special value that represents the start of our graph. Okay, so we have an edge and we say all right, we're going to have an edge between start and chatbot. This is a directional edge, which means we go from start to chatbot. And then we can just copy the same thing here. And now rather than going from start to chatbot, we're going to go from chatbot to the end because after we get a response from our chatbot node, the next step is we just want to end. we want to end this system. Okay, that's it. So, we've now just built a really simple graph. We added a single node. We added edges between the start node and the chatbot and the chatbot in the end. And now what's left is to simply run this graph. So, let me show you how we do that. So, what we're going to do here is say graph is equal to the graph builder.compile. Okay. So, after you construct the graph here by adding the edges, you're going to compile the graph, which just means you're actually going to convert it into something that's runnable. and then we'll be able to run it. Now, in order to run the graph, we're just going to grab some user input. So, we're going to say user input is equal to let's go input here and let's go like, you know, enter a message. Okay? And then we're going to say our state is equal to graph dot invoke. Okay? And let's spell this correctly. Now, when we invoke the graph, we can do this by passing the state that we want the graph to start with. I know again this seems a little bit weird but essentially what we're going to do is we're going to pass some state here. This is like the initial state that we want to start with which is going to match this type. Okay. So here this is really just the type of our state. So now what we're going to do is we're going to pass some messages. So we're going to have essentially this dictionary. We're going to say messages colon. We're going to have a list and then inside of this list we're going to have a ro. This role is going to be the user and then we're going to have content and the content is going to be the user input. Now, let me just make this a little bit smaller so that you guys can see this. Okay, so we have state is equal to graph.invoke and then what we're doing is we're passing messages because again we need to kind of match this state right here which is a typed dictionary and then again let me get out of this thing. Sorry. We have the role is user and then the content is user input. So now because we're invoking the graph at the end of this we're going to be able to get the state at the end of the graph run. So we can simply look at that state we can grab the last message which should be coming from our LLM and we can print that out. Again I'm going to run through this slowly so don't worry but for now we're going to say print state messages and then we're just going to say1content. Okay because all of the messages are going to have this ro and this content field. They actually have some other fields as well, but in our case, we just care about the content. That's what we want to print out. So, what I want to do now is I want to run this code. I just want to make sure it works. And then I'm again I'm going to walk through it step by step so that you fully understand it. So, let's press run here. It's going to open up our terminal. It asks us to enter a message. Let's go with something simple like hello world. Let's wait a second. And you can see it says hi, how can I help you today? Okay, let's run this again. Let's say you know what is the square root of you know 128 or something and let's see what it gives us and give this a second and it says so the square root is 8 <unk>2 which is approximately 11.137 and it kind of gives us the response. Okay so let's walk through what's happening here because I fully understand this is a bit confusing especially if it's your first time seeing it. So of course we start with our imports. All these ones that we're missing we're going to use in one second when we make the example a little bit more advanced. We load in our environment variables. We initialize our LLM and then we create this state. Now the state is really just defining the type of information that we want to have as we run through this graph. Right now it's quite simple because the graph is just this right start chatbot end. But later on you can have some more advanced state which will kind of allow you to control what edge you go down or what path you go down in the state. Then we have our graph builder. So we say okay we want to eventually build a graph using this state. We're going to use a state graph. So we take in the state that we defined and then we have our nodes. Now in these nodes you can do anything that you want but typically what these nodes do is they modify the state or they check the state. So in this case all we're doing is we're invoking the LLM using all of the messages that are currently in our state. So that will come from here when we start with this message. Okay. Okay, we then take whatever the next message is and we add that into messages. Okay, then we construct a graph. So we say, all right, we want to have this node chatbot connected to this node, this function right here. We add our edge. So start edge and the end. And then we compile the graph and we run it. Now at this point when we run it, we start it with a single message. The reason for that is we're immediately going to go to this node. This node is going to check the state. It's going to take our starting message and then it's going to run this. Okay. And that's how it works. Now, if you want to see something, we can print out all of the messages that we have. So, let's just print the kind of uh what do you call this here? State messages just so you can see what it looks like. And you can see that we are tracking all of the messages. So, if we run this again, let's just go hello. Okay. And I just want to show you the kind of output here. And you can see we have a human message that says hello. And then if we keep scrolling here, we have an AI message and it says, "Hi, how can I help you?" And you can see there's some other fields in here like this is the content that we're printing out. But we also get, for example, the model that we use, the stop reason, all of this kind of stuff. Okay? So that's why I'm just printing out the uh the content. So we have two messages, right? Because we're tracking all of the messages in our state. And then what I did is I grabbed the last message and I just printed the content. Okay? So quick pause here. this graph that you see here, you can actually generate this for any of the um what do you call it? The graphs that you make in Langraph. Now, in order to do that, I'm just going to show you a code snippet. So, if you go to this website right here, it's actually the getting started guide for Langraph. They have this right here, this code from ipython.dis, import image, etc. If you run this at the bottom of your script, if you're inside of a Jupiter notebook, then it will allow you to actually save this image or to view the image. Now, I'm not going to do all of this right now, but essentially what you would do is you would make a new Jupyter notebook. You would just paste this at the bottom. So, you take all of this code, paste it in a Jupyter note Jupyter notebook, simply run the cell, and then it's going to generate the image for you. Okay? If you're unfamiliar with Jupyter notebooks, that's not really the tutorial that I'm aiming to do. So, I'm not going to walk through those steps, but if you are, then you can generate the graph and you can see it. Now, I already generated them obviously, so I don't need to do that. But if you want to test it out and kind of make sure the graph looks as you expect it to, then that's what you can do. Okay. So now that we've created this simple example, I want to move to a more complex one where we build out this graph right here where we have a classifier, a router, and then we can go between multiple AI agents. Now, my idea is that sometimes you want maybe a more emotional response or sometimes you want a very logical response. For example, if you were to talk to me, I'm probably going to give you a logical response. If you were to talk to my mom, she's probably going to give you an emotional response. So, what I want to do is I want to create an AI system where based on what the user is saying, we can kind of adapt how we're responding to them using two different AI agents. So, the concept is we're going to start here. The user is going to give us some input. We're going to classify that input whether we go logical or or uh therapist. Sorry, that's what I'm calling this here, but really it's emotional. We're then going to have a router. The router is going to look at the classification. If the classification is logical, it's going to ask the logical agent to give us a reply. If it's emotional or therapist, it's going to ask the therapist agent to give us a response. So, that's what I want to generate. So, let's move over now and see how we do that. It does require a few more steps. Let's remove the bottom four lines here. Let me get out of this bottom four lines. Okay. And let's go back up to the top and let's start by modifying our state. So in our state like before I do want to keep track of all of the messages that we had but I also want to have another piece of state that specifies the message type that we're going to be using. Okay, because we are either going to have like the emotional message type or the logical message type and we need to know that in the state of our graph. So we know which AI agent should kind of handle the next task. So for this I'm going to say this is string or none as the type uh because we may not have any message type but if we do then it will be a string. Okay. So when we start it's nothing and then later we can add some string to it. So now that we have the state I'm also going to make another class above this which is going to be a type that we're going to use for something called a structured output parser. Okay, you'll see how this works in one second but it's pretty cool. So we're going to say class and this is going to be message classifier. Okay. And this is going to be a type. It's going to inherit from the base model of paidantic. Pyantic is a typing system in Python. Okay. And inside of here, what we're going to do is the following. We're going to say our message. And then this is going to be underscore type is of type literal. Okay. And then for the literal, we're going to have emotional as one of the types and logical as the other. Okay. Now, why is this not giving us the correct highlighting? Okay, there we go. It's fine. now and we're going to say this is equal to field and inside of here we're going to have dot dot dot comma and then we're going to have a description okay which is going to define how we kind of fill in this value again give me a second to type this out it's kind of hard to type and explain at the same time and then I will break down kind of what this is so we're going to say classify if the message requires an emotional or logical response. Okay, so we can say emotional and maybe we'll just go like therapist here to be a bit more clear. And then we're going to save that. So what I'm doing, let me just space this out here, is I'm making this pideantic type and I'm saying that in the type I want to have this field which is of message type. Now this is going to be a literal. Literal just means it's like an exact value and the value is either going to be emotional or logical. Okay, that's kind of what I mean by literal value, like a literal string. And we're saying this is equal to a pyantic field. The three dots, don't worry about that. We just put that here in order to now add the description. And then we specify kind of what this field represents. So we're saying, okay, the message type is going to be a classification. If the message requires an emotional therapist, let's spell this correctly. Okay, so you'll see how we use this in a second, but essentially what we're going to do is we're going to have a stage within our kind of agentic system here where we ask an LLM to give us an output that matches this paidantic type. So that's why I'm defining it here. And you can make these types anything that you want. You can have as many fields as you want, but what's important is that you specify the type of the field, which we did here, and then you give the field a description so the model knows how to fill this in. So we're using this as a classification. But for example, if you wanted to collect someone's personal details, you can make another class like you know person and then inside of here you have all the fields like name, string is equal to a field. You give this a description etc. And all of the things that you want the model to kind of extract from the text you would put inside of this model and you then tell the LLM, hey use this particular model and give me a response in this format. It's called a structured output format. You're going to see this in just one second. Okay, so now we have our state, we have our message classifier type, and we want to start building out our various nodes. Now, I'm going to remove this whole graph because right now we don't need any of that, and we will leave the compile because we'll use that in one second. All right, so after this, we're going to start uh defining our various functions. Okay, so we're going to say define, and the first thing we're going to have is classify message. Okay, now this is going to take in our state. And for now I'm just going to say pass and we'll write that in just one second. Now after classify message we're going to have define therapist and this is going to be agent. Okay, this again is going to take in our state and for now we're going to pass. Now why can I not spell therapist correctly or is that correct? I think therapist. There you go. Is now correct. Okay. Okay, then we're going to have another one and we're going to say this is going to be logical agent and we're going to take in state and state and then pass. Okay, so what we're doing so far is we're saying all right, we want to have this classify message node. We're going to have a therapist agent node and a logical agent node. And then what are we missing? Well, we need one more which is going to be our router. So we're going to say define router. Same thing here for the router. We're going to take in the state like we do for all of our nodes. we are going to pass and then we're going to space this out. So we can start writing these one by one but I like to just define the nodes that we're going to have up front so that we know what it is that we're about to be doing. And again if we look here we have a classifier, a router, logical and therapist. Okay, so we've kind of written the function to represent all four of these. So let's start with classify message. Now for classify message we're going to start by getting the last message. So we're going to say last message is equal to state messages and then negative one. So, whatever the user last type, well, we're going to get that and then we're going to use that to well classify it. We're then going to say our classifier LLM is equal to our LLM dot and this is going to be with_structured output. We then are going to pass our message classifier. So, what we're doing now is we're creating essentially a version of our LLM that will give us only output that matches this pyantic model. So that's how we use this kind of structured output class. Okay. Now that we have that, what we can do is we can invoke the classifier LLM. So we're going to say result is equal to the classifier LLM do.invoke and then inside of here we can put a list of messages that we want to invoke. Now the first thing we need to do is we need to tell the classifier what it should be doing. So, we're going to specify a message and we're going to say roll is system. Okay, this means this is not a user message. This is coming from the system like instructions on what this should do. And then we're going to say content. And inside of here, we're going to write kind of what the instructions are for this model. So, I'm just going to paste them in here. Again, you can copy this from the link in the description, but essentially this is what we want. So we're going to say that we want to classify the user message as either emotional or logical. Now it's emotional if it asks for emotional support, therapy, deals with feelings or personal problems and logical if it asks for facts, information, logical analysis or practical solutions. So this system prompt in combination with the description of our message classifier classifier pideantic model will allow the LLM to take the user message which we're going to put here in one second and then classify it into this structured output. So after we have the system message, we're also going to specify the user message. So we're going to say roll user and then we're going to say the content is simply the last message dot content. Okay. And we're going to pass all of this to the classifier llm. And then what we can do is we can return whatever this result is. So, we're going to say return, and then we're going to say message type, and this is going to be result dot message type. Uh, oops. So, let's go back here. Message underscore type. Now, again, the way that this kind of works is because we're returning something that matches something in our state, we're automatically going to update the message type in this state to be equal to whatever this is. So when you're returning something from these nodes, as long as you match one of the types with the state, which is what we're supposed to do, then it's going to update that state for us, which means now in the next steps of our graph, we'll be able to access this state and know what it is that we should do next. Okay, so that's our classify message. Now that we've classified the message, we need to look at our router, sorry, so that we know what to do next essentially. Should we route to the therapist or should we route to the logical agent? So inside of our router, we're going to say the message type is equal to the state.get and then we're going to get the message underscore type or we're going to default to logical. Okay, so if for some reason the message type didn't get classified correctly, we're just going to go default to the logical route. Okay. Then what we can do is we can say if the message type is emotional then we can return and we can return next and then therapist. I'm going to show you how this looks in one second because this isn't currently in our state. And what's the issue here? We're missing one of our quotations. Okay. And then otherwise we can just return. And this is going to be next and then logical. So all we're saying is we want to look at our message type in the state. Now if the message type is logical then well we can return logical. Otherwise we're going to return therapist. I'm doing this intentionally. We could have just used the me message type which you'll see in a second. But because the message type is different than the next node that we want to go to. Um that's kind of what I'm doing here. I I hope that makes a bit a bit of sense. Sorry. But I'm just adding an additional node just to add a little bit complexity so you can kind of see how this works with different situations. Okay. So now let's build out the therapist agent and the logical agent which will be very straightforward and all we're going to do really is just change kind of the system prompt that we pass to them. So same thing we're going to say last message is equal to state messages negative one. Okay we're then going to say the messages that we want to send are going to be the following. We're going to have a ro which is system. Okay. And then we're going to have content. And for the content I'm just going to again paste this in. You can copy this from the link in the description. I just don't want to waste the time writing all of it. Okay, so there we go. This is our system message. It says, "You are a compassionate therapist. Focus on em emotional aspects of the user's message. Show empathy, validate their feelings, etc., etc." Okay, you can do anything that you want here. Um, but this is just the message that I'm using for this to make sense. Now, we're going to have another message. This is going to be rule of user. And then the content of this message is going to be the last message. Okay. Then what we are going to do is we're going to say the reply is equal to llm.invoke on the messages and then we are going to return the following. We're going to say messages like this with a list. We're going to say the role is the is this uh assistant sorry and then the content is going to be reply.content. Okay. Now we can literally copy the exact same thing here and we can put this in our logical agent. The only difference is we are going to change the uh system message here. Okay. And why is this giving us an issue? It says duplicated code fragment. Okay. That's fine. Don't worry about that. And we are just going to take this new system message. Give me one second here for the logical agent and paste this in. So let's go here and paste. And it says you are purely logical assistant. Focus on only facts and information. and provide clear, concise answers based on logic and evidence, etc., etc. So, again, we can make this a reusable function, but same thing, just changing the system message. And obviously here, you could make like two entirely different agents. We're just making them, you know, kind of simple chat bots with different system prompts. All right. So, there we go. We have our messages now. We have our logical agent. We have our therapist agent. We have our router. We have our classify message. And now, it is time to actually build out the graph. So, as we build out the graph, we're just going to add the nodes and edges, which I think is the easy part. So, now we're going to say graph builder add node. I like to start by adding all of the nodes. So, first we're going to say classifier, and this is going to go to the classify message function. Okay. Next, we can add the therapist. That's fine. We're just going with autocomplete here. We can add logical. That goes to the logical agent. And before that, we can add the router. Just let me just copy this and change this to say router and the router function. Okay. So we have classifier router therapist logical. Nice. Now we need to add our edges. So the first edge we can add is with the start. So we can say graph builder.add edge. We're going to go start and the first one we're going to go to is our classifier. Okay. So classifier like that. Next, we're going to say the graph builder add edge. And then we're going to add the edge from the classifier, okay, to the router. Very good. Next, rather than just adding a standard edge now, because the router could go to one of two different places, we're going to add a conditional edge. So, we're going to say graph, okay, underscorebuilder.add add underscore conditional edges. Okay, multiple edges here and we're going to say that we want to go from the router. Okay, we're going to have a function here which is going to be our condition. Okay, so we're going to say lambda and this is going to be state and then we're going to say state.get and then next and then just bear with me here. We're gonna say therapist, okay, is going to go to the therapist and the logical is going to go to the logical. Now, I know this is a little bit weird, but essentially what this does or the way this works is we start by defining the source. Then we can write a function that we will call to get a value that we will then match against this path map. So what I'm doing is I'm looking at the state and I'm getting next. Okay. Now the reason we can do that is because from our router we return this next value. Now notice next is not defined in our state. It's okay if it's not defined here. It doesn't need to be defined here. We can still access it afterwards. We just haven't typed it correctly. So if we wanted to, we could go like next and then we could say string or none in our state. But I'm just trying to show you that if you don't have that in the state and you return something, you can still access this returned value in the next node. Okay? So that's why I did it this way just to kind of show you that you don't need to map it in the state, but it's a good idea to do that. So you can define exactly how it should work, the type it should be, etc. So we're returning next. Okay. So here now in our conditional edges, we're able to look at the state. So we say lambda state, this is a function, right? State.get next. We then get whatever this value is and we say okay if the value is therapist we go to therapist. If it's logical we go to logical. But we could change this right if it was one go to therapist. If it's two go to logical or we could have different node names which is why we have this kind of path mapping as defined here. Okay. So that's our conditional edges. So now we're either going to go to therapist or logical from router. Next what we need to do is we need to add the edges. Let me get out of this. uh between our therapist and logical and the end. So we're going to say graphuer add edge and we're going to go from the therapist not to logical but to the end. Okay. And then we're going to do the same thing here and we're going to go from logical to the end. Okay. So we're adding edge between therapist and end and logical and end so that we will be able to end the graph. All right. All right. So at this point the graph is finished. We can compile the graph and this will all be working. But the next step is to actually allow us to run through the graph and well to utilize this tool. So let me show you how we do that. We're going to write a simple function here called run chatbot. Okay. Inside of run chatbot we're going to get some initial state. So we're going to say state is equal to and we're going to define our initial state. So we're going to have messages which is an empty list and we're going to have the message underscore type which is going to be none to begin. All right. Then what we're going to do is we're going to have a while loop. So we're going to say while true and inside of here we're going to get some user input. So we're going to say user input is equal to input or we're just going to say message like that. All right. Now if the user input so if user input is exit then we're just going to print by and we are going to break so we can get out of the wall while loop uh so that we have a way to kind of exit this right okay good so we have our break now after that we're going to say state messages and then this is going to be equal to state get okay messages and then we're going to have an empty list and then we're going to say plus a list and then we're going append the user's message. So we're going to say roll and then user and then we're going to say content and user input. So what we're doing is we're saying okay let's look at the current state. Let's try to get the messages if messages does not exist to get an empty list. And then what we're going to do is we're just going to add this new message with the ro and the content to our state messages. Okay? So that we can kind of keep doing this continually. Then we're going to say state is equal to graph do.invoke invoke with the current state. So what's going to end up happening here is that we're going to get the new state after the graph is invoked and then we're going to keep using that variable within here. So we can kind of keep track of the messages that have been said previously and we can keep invoking the llm. Okay. So then what we're going to do down here is we're going to say if state.get get messages. Okay. And the len of state here messages is greater than zero. So we're just going to make sure that we do actually have a message otherwise this code would fail. We're going to say last message is equal to state messages negative 1 to get the last message. And then we're simply going to say print and we're going to print an fstring. and we're going to say assistant colon and then this is going to be the last message content. Okay. And then down here we can simply say if_ame is equal to main then run the chatbot function. Okay. So let's quickly look at this. We have this run chatbot function. Let me just space it out. We start with some initial state. We go into a while while loop sorry. We grab the user input. If the user input says exit, we have a way to quit. So we, you know, print by and we get out of there. Otherwise, we take this message, we add it to the current state. We then invoke the graph using the current state and then we look at the state after the invocation and if there's any messages, we print them out. That's how this works. Okay, so let's run this uh and see if it functions. If we have any errors or not, I'll be amazed if this runs the first time, but let's give this a shot. Okay, so I think uh yeah, it says message. So, let's say, hey, I'm really sad right now. and let's see if it goes to the correct agent here and gives us the emotional response. Okay, so I hear you're feeling really sad right now. That must be really difficult to experience. Would you like to tell me more about what's going on? I'm here to listen. So that definitely seems like it went to the emotional agent. Let's do something like I need some advice. You know, my father would give or something. And let's see if it goes to the logical agent. Okay, I hear you're missing your father's guidance right now. Okay, so actually this time it went to the emotional agent. I guess it doesn't have the same father that I had, but let's go. I need some hard solid advice about buying a house or something. And let's see if it g goes to our uh logical agent this time. Okay, give it a second to run.
Original Description
Download PyCharm and use it for free forever with one month of Pro included: https://www.jetbrains.com/pycharm/
In this video, you're going to learn how to build AI agents using LangGraph. LangGraph is a much more professional and in-depth framework compared to something like LangChain or LlamaIndex, which allows you to build a really complicated and well thought out AI agents. If you're looking to push something into production, you want to have scalability features, and overall you just want more control, then LangGraph is what you should be using.
Want to make real money with coding? I share high-signal insights on careers, monetization, and leverage in my free newsletter. Join here and get my guide How to Make Money With Coding instantly: https://techwithtim.net/newsletter
🎞 Video Resources 🎞
Code In This Video: https://github.com/techwithtim/LangGraph-Tutorial
UV Website: https://docs.astral.sh/uv/
UV Video: https://www.youtube.com/watch?v=6pttmsBSi8M&ab_channel=TechWithTim
Anthropic Console: https://console.anthropic.com/settings/keys
LangGraph Getting Started Guide: https://langchain-ai.github.io/langgraph/tutorials/introduction/#part-1-build-a-basic-chatbot
⏳ Timestamps ⏳
00:00 | Overview
00:44 | LangGraph Core Features
02:31 | LangGraph Examples
04:20 | IDE Choice
05:00 | Environment Setup/Install
07:45 | Getting LLM API Token
08:59 | Simple LangGraph Chatbot
23:20 | Generating The Visual Graph
24:25 | Complex LangGraph Chatbot
Hashtags
#LangGraph #LangChain #AiAgents
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Tech With Tim · Tech With Tim · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
A* Path Finding Algorithm(Visualization)
Tech With Tim
Python Programming Tutorial #1 - Variables and Data Types
Tech With Tim
Python Programming Tutorial #2 - Basic Operators and Input
Tech With Tim
Python Programming Tutorial #3 - Conditions
Tech With Tim
Python Programming Tutorial #4 - IF/ELIF/ELSE
Tech With Tim
Python Programming Tutorial #5 - Chained Conditionals and Nested Statements
Tech With Tim
Python Programming Tutorial #6 - For Loops
Tech With Tim
Python Programming Tutorial #7 - While Loops
Tech With Tim
Python Programming Tutorial #8 - Lists and Tuples
Tech With Tim
Python Programming Tutorial #9 - Iteration by Item (For Loops Continued...)
Tech With Tim
Python Programming Tutorial #10 - String Methods
Tech With Tim
How to Overclock a NVIDIA GPU
Tech With Tim
Python Programming Tutorial #11 - Slice Operator
Tech With Tim
Python Programming Tutorial #12 - Functions
Tech With Tim
Python Programming Tutorial #13 - How to Read a Text File
Tech With Tim
Python Programming Tutorial #14 - Writing to a Text File
Tech With Tim
Python Programming Tutorial #15 - Using .count() and .find()
Tech With Tim
Python Programming Tutorial #16 - Introduction to Modular Programming
Tech With Tim
Python Programming Tutorial #17 - Optional Parameters
Tech With Tim
Python Programming Tutorial #18 - Try and Except (Python Error Handling)
Tech With Tim
Python Programming Tutorial #19 - Global vs Local Variables
Tech With Tim
Python Programming Tutorial #20 - Classes and Objects
Tech With Tim
Cool VBS Script to Prank Your Friends!
Tech With Tim
How to Overclock an AMD GPU
Tech With Tim
Best GPU'S For Mining Ethereum (2018)
Tech With Tim
Recursion and Memoization Tutorial Python
Tech With Tim
Ethereum Mining Rig - Hardware Guide
Tech With Tim
Pygame Tutorial #1 - Basic Movement and Key Presses
Tech With Tim
How to Install Pygame (Windows 8/10)
Tech With Tim
How to Trade Your Cryptocurrency (Bitcoin, Ethereum etc.) For Cash!
Tech With Tim
How to Mine Ethereum 2018 - WORKING (Super-Easy)
Tech With Tim
Microphone Comparison - $10 Mic vs $150 Mic (Blue Yeti USB)
Tech With Tim
Pygame Tutorial #2 - Jumping and Boundaries
Tech With Tim
Pygame Tutorial #3 - Character Animation & Sprites
Tech With Tim
Pygame Tutorial #4 - Optimization & OOP
Tech With Tim
OBS Studio Tutorial - Best OBS Settings
Tech With Tim
Linear Search Algorithm - Python Example and Code
Tech With Tim
Make Any Mic Sound AMAZING! (WITH OBS)
Tech With Tim
Binary Search Algorithm - Python Example & Code
Tech With Tim
Pygame Tutorial #5 - Projectiles
Tech With Tim
Pygame Game - Mini Golf
Tech With Tim
Pygame Tutorial - Projectile Motion (Part 1)
Tech With Tim
Pygame Tutorial - Projectile Motion (Part 2)
Tech With Tim
Pygame Tutorial #6 - Enemies
Tech With Tim
Pygame Tutorial #7 - Collision and Hit Boxes
Tech With Tim
Pygame Tutorial #8 - Scoring and Health Bars
Tech With Tim
Cloud Mining vs. Hardware Mining - 2018
Tech With Tim
How to Install Pygame on Mac OSX (Fast-Simple)
Tech With Tim
Pygame Tutorial #9 - Sound Effects, Music & More Collision
Tech With Tim
Pygame Tutorial #10 - Finishing Touches & Next Steps
Tech With Tim
How to Fade Your Screen in Pygame [CODE IN DESCRIPTION]
Tech With Tim
How to Create a Button in Pygame [CODE IN DESCRIPTION]
Tech With Tim
Pygame Side-Scroller Tutorial #1 - Scrolling Background/Character Movement
Tech With Tim
Pygame Side-Scroller Tutorial #2 - Random Object Generation
Tech With Tim
Pygame Side-Scroller Tutorial #3 - Collision
Tech With Tim
Pygame Side-Scroller Tutorial #4 - Scoring and End Screen
Tech With Tim
How to Create A Message Box in Python - Tkinter
Tech With Tim
Is Ethereum Mining Still Profitable - Is It Worth It (April 2018)
Tech With Tim
How to Run MAC OSX on a WINDOWS PC (Clover Boot-loader)
Tech With Tim
Programming Problem #1 - Alphabet Soup (Beginner/Novice)
Tech With Tim
More on: LLM Engineering
View skill →Related Reads
Chapters (9)
| Overview
0:44
| LangGraph Core Features
2:31
| LangGraph Examples
4:20
| IDE Choice
5:00
| Environment Setup/Install
7:45
| Getting LLM API Token
8:59
| Simple LangGraph Chatbot
23:20
| Generating The Visual Graph
24:25
| Complex LangGraph Chatbot
🎓
Tutor Explanation
DeepCamp AI