00:02Hello guys
00:04So, welcome to this amazing crash course on building agentic AI applications with the help of LangGraph
00:07This entire crash course has been divided into three important parts, and each part will be around 2 to 3 hours of videos
00:13Right
00:19And here you can basically see how we are going to cover all the topics and where we aim to reach by the time we get to part three
00:23Okay
00:28So, in part one, you will see that we will be covering various fundamental techniques which are really, really important for building agentic AI applications
00:33Some of the important topics include how to build a chatbot, how to integrate tools, and how to combine multiple tools in a chatbot
00:42I will cover how to add memory, how to incorporate human-in-the-loop feedback when executing the entire graph state, how to use different streaming techniques, how to probably go ahead and use MCP, and how to build MCP completely from scratch
00:56So, this part will also include discussions on various topics like states, what are graphs, nodes, edges, and how to use this with the help of the Graph API
01:08All these concepts will be covered in part one
01:12Part one will be approximately around 2 hours and 50 minutes, maybe
01:18Okay, but that's just an approximate estimate
01:21Once we complete this, we'll move on to part two, which covers advanced LangGraph concepts
01:28We are going to focus on various kinds of workflows and agents
01:34Here is the topic where we will be developing applications where agents will be communicating with other agents, right? And why they will be communicating is to solve a complex workflow
01:41Okay, solve a complex workflow
01:49Right? Along with this, we will try to see how we'll be handling multi-state management even in multi-agents
01:57Then we'll also introduce you to how to directly use the functional API instead of just going through the graph APIs themselves
02:05And then I will also show you how you can debug and monitor them in the LangGraph Studio
02:10Okay, LangGraph Studio
02:13And for this, we will also be using Lang
02:18So, all these fundamentals are presented in the advanced..
02:20Part because, uh, this will be like one step towards developing some amazing production-grade applications, and finally, this part two will also be around 2 hours of video
02:33Then we have in part three, where we'll focus on building completely end-to-end projects, focusing on the LLM pipeline, deployment techniques, and recently, I have also explored all the evaluation techniques and metrics, specifically in large language models, and how you can use them along with LangGraph and some open-source tools like MLflow
02:55You can also use AWS to track all those metrics, and how you can use Grafana to display all those reports
03:02That is where we will be moving in part three
03:04We'll also be..
03:06Using Hugging Face Spaces to do the deployment, so this is just a tentative plan in order to cover the LangGraph crash course
03:13And these are all long recorded videos, so I definitely require your entire support
03:18Yes, now part one is ready
03:20You can go ahead and watch this entire video, make sure that you also download the material from the description, keep practicing, and definitely share it on various platforms like LinkedIn and others
03:29I want to see how your learning progresses
03:33Definitely tag me on LinkedIn, Twitter, or wherever you can
03:35So, yes, let's go ahead and enjoy this particular session
03:39Now, let's build a basic chatbot using LangGraph
03:44This is my entire empty
03:45Folder
03:47So this will be my project workspace
03:48From this, I will go ahead and open my command prompt
03:51So let's go ahead and open my command prompt
03:52As I said, that is my working directory with respect to my project workspace
03:59I will just go ahead and open my VS Code because I'm going to use VS Code for my coding purposes
04:06Once I open my VS Code, this is how my VS Code looks
04:08You know, whenever we start any kind of project or build any applications, it is necessary to create an environment
04:19Most of my videos have actually shown how to create environments, but in this particular video, we are going to use something called the venv package manager
04:24Okay
04:29Yes, you can
04:34Also use Conda, uh, but if you don't know about the Python package manager, it is a really fast, extremely fast Python package and project manager, and it is completely written in Rust
04:40Since it is written in Rust, it is very, very fast
04:42So you can probably compare it here—from Conda to Poetry to PDM and Pipsync
04:46This has the least time
04:48Uh, that means that whenever you're trying to create an environment or do any kind of installation of the packages, that happens really, really fast
04:57Okay, some of the highlights that you can see here: it is 10 to 100 times faster than pip
05:02Uh, it is a single tool to replace pip, pip-tools, pipx, Poetry, Pyenv, Twine, and virtually Env
05:10Uh, it provides comprehensive project management and a universal lock
05:12It installs and manages different kinds of Python versions as well
05:16You can do it within the same project itself, right? And to start with the installation, if you are on macOS or Linux, from the terminal, you just need to copy this particular command and execute it
05:27If you are on Windows, open your PowerShell, copy this command, and paste it there
05:31And if you're using Raspberry Pi, just go ahead and write `pip install uv`
05:35Okay
05:40Once that is done, your entire project repository will be initialized
05:44So first of all, what I'm going to do is open my terminal
05:47Now, inside this terminal, I will open my Command Prompt
05:49I've already done the..
05:52Installation of the UV package manager
05:54So I will just go ahead and quickly initialize my project workspace
06:00In order to initialize, all I have to do is write `uv init`
06:02Okay
06:05As soon as I write `uv init`, it will happen in the project workspace
06:07Okay
06:09So here you can see, in the project workspace, there are some files that have been created, like `.gitignore`, `python-version`, `main.py`, `pyproject.toml`, and others
06:12If you go ahead and check the Python version you have actually created, it is 3.13
06:22Then you also have this `main.py`, so you can start the program execution directly from here
06:27Then you have this `pyproject.toml`, which contains the project brief information
06:32You can change the version
06:34You can add your own description and all
06:36Here, you can see that it requires Python version 3.13 or higher
06:38Currently, this dependency is empty because we haven't installed any packages yet
06:45What I am going to do now is create a `requirements.txt` file
06:51Inside this `requirements.txt`, I will list some libraries to install, such as LangGraph and LangChain
06:55Along with this, I will also include my custom code
06:59All of these libraries will be particularly useful, and I will explain as we proceed
07:04We will be using various functionalities of LangChain and LangGraph to build generative AI applications, chatbots, and agent AI applications
07:17It is basically used for tracking and evaluation of your applications, you know, directly in the Langgraph cloud
07:23So, these are the basic libraries that we're going to use
07:26Now, since I have already initialized this workspace, the next thing is that I need to go ahead and create my virtual environment
07:34So, quickly, I will go ahead and write `venv`
07:36With the help of this command, you'll be able to create a virtual environment
07:41This `venv` is nothing but your virtual environment name
07:45Okay
07:50So, once I go ahead and write `venv`, you can see that it has been created with the help of this particular version, which is 3.13.2
07:53The virtual environment is located at this position
07:56Now, in order to activate the environment..
07:59I'll just go ahead and copy this quickly
08:01I will paste it over here
08:05Okay
08:08So once I activate this, you can clearly see that, hey, my environment has been activated
08:10Okay
08:12So here, Agentic LangGraph has been activated
08:14Now, this is perfect; everything looks good so far
08:19The next step is to install all the necessary libraries
08:22So, in order to do that, if you're using pip, the command is like `pip install -r requirements.txt`
08:26But here, we are going to write `pip install -r requirements.txt`
08:31Okay
08:35Once you run this installation, you will see that the process completes successfully
08:40And now, if you open this particular file, all the libraries that have been installed will be visible
08:42Over here
08:44Okay
08:46Now, as I said, uh, this is my first tutorial
08:48I'll go ahead and just write one folder named 'one,' and I'll say, hey, uh, basic chatbot
08:53Okay
08:57And we'll just learn some of the basic stuff over here
08:59Okay
09:02Now, with respect to this particular basic chatbot, uh, we are going to go ahead and create our, uh, you know, applications
09:04So we'll go ahead and create our basic chatbot itself
09:09Um, we'll just go ahead and open my one file
09:12Let's say I'll go ahead and name it 'basic_chatbot.ipynb.' Okay
09:15So, as soon as I open this 'basic_chatbot.ipynb,' it will prompt me to select a kernel
09:23I will go ahead and select a kernel
09:25And since I'm using Jupyter Notebook for the initial stages, um, I also have to go ahead and add one more library: UVicorn, ipy
09:31Kernel
09:37Okay, so follow the steps step by step, like you have to just follow these steps as we go ahead, because an IPython kernel will be required in order to run anything in the Jupyter Notebook
09:40Okay
09:43Now, once this is done, I will start writing my code over here
09:46Okay
09:48Now, with respect to the code, let's check whether this is working or not
09:51Okay
09:53It should give an error because one plus exclamation is something happening over here
09:56Here, you can see it is connecting to the kernel Agentic
09:58Okay
10:00So, yeah, invalid syntax
10:02Now, if I go ahead and write 1 + 1, it is working fine
10:06Perfect
10:10Now, as I said, let me just quickly go ahead and write here— we are going to build a basic chatbot
10:12Okay
10:15Now, building a basic chatbot, you know, this..
10:17This chatbot is like a basic chatbot, which essentially means, uh, and here, whenever I'm talking with respect to LangGraph, okay? With LangGraph, I'll go ahead and write that here
10:30We are going to use the Graph API functionality
10:33Okay, there is one more API called the Functional API, and as we go ahead, we'll also try to learn about it
10:39But what I felt is that the most efficient way of learning LangGraph is specifically using this Graph API
10:45Okay
10:51So, let's start with this, and let me go ahead and write some information about how you should actually start and all the other details, and what we are basically going to develop
10:55Okay
10:58So, guys, now let's go ahead and build a basic chatbot with the help of LangGraph
11:02Now
11:06Before we go ahead, we need to understand some of the important components of LangGraph so that you will be able to understand how to build a basic chatbot
11:10So, let's go ahead and talk about the components of LangGraph
11:17There are three important components of LangGraph: number one, edges; number two, nodes; and number three, which is called the state
11:29Right now, what are these, right? What are these components? So, in order to explain, I would like to probably take a use case
11:37Okay, let's say that I have, I had this use case a long time ago and I solved it
11:42You know, as you all know, I also upload a lot of YouTube videos
11:46Right? YouTube videos
11:51Now, what I wanted was that, as soon as I upload a YouTube video, I should be able to convert or create a..
11:55Let's break it down
11:57Okay
11:58So, this is a kind of task that I really wanted to do
12:00Now, considering this particular task and this workflow, how this workflow needs to be executed, let's understand this
12:08If I want to solve this task, the first step is that from my YouTube videos, I have to extract the transcript
12:22Okay? So, from these YouTube videos, I want to first of all extract the transcript
12:26Then, I will use this transcript
12:33And with the help of this transcript, since I need to start writing my blog, I will go ahead and create the title of the blog
12:39Okay? And in the third step, I want to take both the title and the transcript, and we will go ahead and create the content of the blog
12:56Right? So if I want to solve this use case, you know, this will be my workflow to solve this use case
13:04First of all, I need to go ahead and take out the transcript from the YouTube video
13:07Then I need to generate a title based on the transcript, and afterwards, based on the title and transcript, I need to generate content
13:15Right now, I am alone uploading the videos, and it is not possible for me to also create the blog from it because it would take more time
13:23But since, you know, LLMs are the buzzword right now, we definitely have LLMs
13:32Now, with respect to LLMs, you know that these are really, really good at content generation
13:39They are very, very good at content generation
13:41Right? Now
13:43Whenever we talk about content generation, that basically means LLMs
13:50It can take an input
13:58Let's say I ask, "Hey, what is machine learning?" It will be able to generate the explanation of what exactly machine learning is, right? Now, can we use LLMs to solve this particular workflow with the help of LangGraph? To solve this problem, I will follow some kind of graph structure
14:02Okay
14:07And yes, in LangGraph, if you want to solve these kinds of workflows, there are two ways
14:11Okay
14:15One is directly using the Graph API, and the second one is directly using the Functional API
14:26But according to my experience, I feel the Graph API is the easiest and best way, especially if you have a lot of expertise with it
14:37Respect to the Graph API, you can directly go ahead and use the functional API
14:40The difference between them will become clear as we go ahead
14:44Okay, so first of all, in order to solve this complex workflow, I will create some kind of graphs
14:50Okay, and this graph will show how my flow of execution will happen
14:53Okay
14:57So let's say that I have this node, and I have one more node
14:59Okay
15:01So these are my two nodes
15:03As I said, the components of LangGraph are edges, nodes, and state
15:07Okay
15:12So initially, let's say we are going to go ahead and start over here
15:15Okay
15:18So here, I will have my start node
15:20Okay
15:23In this start node, we give our input
15:26Right
15:28Let's say, in this particular case, in my use case, obviously, I need to give some..
15:31Kind of input
15:33Now, what input will I give? I will give my YouTube URL
15:36Okay, let's say this is my input YouTube URL
15:39Then it goes to this phase, from start, it goes to this node
15:43This node should be responsible for taking out the transcript from my YouTube video
15:48So here, I can go ahead and write, "Hey, this is my transcript." Okay, this is my transcript generator
16:01Now, how do I go ahead and generate the transcript in LangChain? In LangChain, we have some third-party libraries
16:08No, I think there is something like YT loader, or what it does is that we give it our YouTube videos as input, and the output will be that we are able to get the transcript
16:24So here, the output of this particular node should be that we should be able to get a transcript
16:26Okay
16:27Understand one thing here
16:29So, what is this? This is nothing but my node
16:35What is this? This is nothing but my edge
16:39Right? So, this is an edge
16:41The fundamental concept of an edge is that the flow of information should go from one node to another, or node to node
16:47Right? So, this is also an edge
16:52Now, whenever we talk about nodes, as soon as you create a node, we also need to create a node implementation, which defines some functionality for this particular node
17:08For example, what does this node actually do? In this case, the node's functionality should be to take a YouTube URL and generate a transcript
17:15Okay? And the output of this node should be this transcript
17:18Okay? Now, in My workflow: I have completed this YouTube video transcript using this node
17:24Now, based on this transcript, I should be generating the title
17:29So, what this node will do is simply act as a title generator
17:36The input will be the transcript, and this will be my next node
17:41The functionality of this node should be to take the transcript and generate the title
17:48This is my main functionality
17:55Very simple
18:03After that, the output I will get should be the title
18:10Along with the title, I also want to include the transcript so we can move to the next step
18:18What is the next step here? It is nothing but content creation
18:23Generation
18:29So, my third node that you'll be able to see over here is nothing but a content generator
18:35Content generator, right? So, this will again be an edge, and this node will have a functionality which will take this information—title and transcript—and it will generate content
18:53Right? And finally, you go to the next step, which is end
18:56In the end, you get the output
18:59Right? Now, you may be thinking, how do we generate a transcript to title? Now, if you have a fundamental idea of large language models, or LLMs
19:10So, here in my title generator, I will have an LLM along with one prompt, and then when we give this input of transcript, it should be able to generate the output
19:27Right? Similarly, for this content generator, which is the node, if I give the title and..
19:31Transcript here again, I will be having some kind of LLM plus some prompt which will be able to generate the content
19:40Here, we give the input as transcript and we get the output over here, right? And finally, all this output is combined and we display it over here
19:51Right? So, this is an example of a workflow, and this is entirely with the help of the Graph API
19:56We will be able to see the graph, we'll be able to see the execution, and we'll be able to see the output
20:02Okay
20:09Now, coming to this — I have told you already about edges and nodes, right? Now, where does the state come into existence? Okay
20:15Now, see, based on this particular use case, state, we can define something, right? So, here, this state will have some values or some variables we can..
20:27Define some variables, and those variables can be accessed by any of these nodes in this particular graph
20:36Okay, so let's say, for this particular use case, you know that I require a transcript
20:41So I will go ahead and create a transcript variable
20:45As soon as this node is executed, the output will be saved in this variable
20:50Okay, so let me just go ahead and write it down here
20:52So, what does "state" mean? Whenever we define any kind of state, our main aim is that whatever variables we define here will be accessible later
21:02So, let's say one of the variables I want to define is "transcript," because as soon as I execute this node, my transcript will get generated, and this transcript will also be required in my third node
21:17What I can do when I create this state, right? This state will have one variable which will contain the information about the transcript
21:23Okay? Similarly, the title is my third output, which I really want because here in this node I want to go ahead and save the title, right? So here, the title information will be saved
21:35And then here you have content
21:37So, let's say that if I go ahead and create these three variables, as soon as we generate them, we can save them in this
21:43And the advantage of saving those values inside this state will be that, throughout the entire graph, every node or any of these nodes will be able to access this variable
21:53Okay? So that is the importance of the state
21:56Okay? And we basically refer to this entire graph as a state
22:03So, that is the reason we call it a state graph because it is able to maintain the context of the state at every node
22:10Yes, don't get confused with external memory or memory
22:17Right? So, memory can also be used here, and that part we'll discuss in later stages
22:22But here, we want to focus more on the state graph
22:25It is able to maintain the state within specific nodes
22:29Now, I hope you have a clear idea about the components of LangGraph
22:34Now, what we'll do is build a basic chatbot
22:38In this basic chatbot, what we'll do is, I will have a start node
22:42From this start, I will create one node
22:46Let's say this particular node is nothing but the chatbot
22:48And from this, we will go ahead and end it
22:51Now, this chatbot will be integrated
22:53With some kind of large language model (LLM), the press prompt, and the work is to take the input and give the output
23:02Right? So this is the basic chatbot we are going to build, and as we go ahead, you know, we will add external tools
23:10We will see how we can integrate these external tools along with the chatbot
23:18Then, as we proceed, we'll again discuss the React agent
23:20Okay
23:23So, React agent is something more amazing with respect to the tools
23:25I know there are many topics we have discussed, but let's now focus on understanding how to build this basic chatbot
23:33For this, I will again go back to my code, and now you have understood what a state graph is
23:38You have understood what exactly nodes and edges are
23:40Okay
23:43Now, step by step, we will go ahead and do this
23:45As usual, what we are going to do is that first of all, before starting to build a chatbot using the StateGraph or Graph APIs, you know, first of all, we will go ahead and import some important libraries
23:53Okay
24:01So, one important library is something called 'from typing import Annotated.' I'll talk about Annotated—what exactly Annotated is
24:09It is just to add context-specific metadata to a type
24:13Okay
24:16I will show you an example to make you understand
24:20One more important library that I’m going to use is 'from typing_extensions import Type.' Okay
24:24Now, along with this, since you know that every graph starts with a start node and ends with an end node, okay, so for..
24:32I will go ahead and write from langgraph.graph import StateGraph, since we need to go ahead and also create a StateGraph
24:42StateGraph will represent the entire graph, the entire graph that you have seen over here
24:50If I want to represent this entire graph, we can represent it with the help of StateGraph
24:52Okay? And then, we will also have start and end
24:58Okay? Start and end are just like my start node and end node
25:00Along with this, we will also go ahead and add from langraph.graph.message import add_messages
25:14Okay, then let's go ahead and execute this
25:20Okay, now we have imported all the libraries
25:22Now you may be thinking, Krishna, what exactly is this add_messages? These are called reducers
25:30Okay
25:38Now, what is the What is the importance of reducers? Okay, I will talk about it
25:45Let's say I want to create this chatbot, right? If I want to create this chatbot, you know that we also have a state, right? Now, in this state, what kind of variable do I really need to create so that any output generated by the chatbot will be saved in one variable itself? So, let's say that I go ahead and create a variable called 'messages'
25:58Inside this, can I make 'messages' a list type, and inside this list, as soon as I keep asking for any input, it should automatically keep getting appended? So again, let me repeat what I am trying to say here
26:15Let's say I am creating this basic chatbot
26:16As soon as I give an input, this should be able to..
26:21Generate an output
26:26But again, in that session, if I give another input, this graph will again get executed and it'll give me the output, right? So we can execute this graph as many times as needed
26:31Right? So when we are creating this state graph, okay, state graph, every conversation can be saved inside my state, which will be available to this particular node at any point in time
26:38Yes
26:44So for that, what we'll do, we'll create one variable
26:51We'll make it a list type, and inside this list, we should keep adding these messages
26:57When I say adding, it should be appending these messages; it should not replace the previous message
27:00Okay
27:04When I say replacing the previous message, let's say in the first instance I had one
27:08Message: I said hi, how are you? Then the chatbot replied, I am good
27:14Then my next question is, hey, uh, tell me, what is your name? Then the chatbot replies, hey, I do not have any name
27:18I'm just a basic chatbot
27:20So, this message should not get replaced; instead, it should get appended, you know, as every conversation goes ahead so that we will be able to maintain this information
27:29And that is the reason we say it as a state graph
27:33Okay, so in order to probably append it, we can use something called reducers
27:39Okay, one of the examples of reducers—there are different types of reducers that we can specifically use
27:45One of the reducers is nothing but add messages
27:50Now, this add messages, what it is going to do is, its work is only to add the messages
27:56Instead of replacing in any kind of variable that we define
27:59Okay, so now let me just go ahead and execute this
28:04And now I will go ahead and start creating my state
28:06So here I will write `class State =` and here we are going to use this type, `dictionary`
28:11That basically means the State class is going to return a type of a dictionary, right? So here, let me just go ahead and provide you with some basic docstring so that you should be able to understand it as we go ahead
28:26So here you can see messages have the type `list`
28:29The `add_message` function in the annotation defines how the state key should be updated
28:34In this case, it appends messages to the list rather than overwriting them
28:39I hope everybody has understood why we are inheriting
28:44Type is deck because this state is going to return, right? This class is basically going to return of this type, which is nothing but a dictionary type
28:50So, if you see what is type Dict, it is a simple type name space at runtime; it is equivalent to a plain dictionary
28:55Right? If I'm going and writing class Point2D, type Dict, right? So, x is int, y is int, label is str
29:03So, what we can do, we can provide values in the form of dictionaries, right? Key-value pairs
29:08It's like x is equal to 1, y is equal to 2, label is equal to "good", right? Something like this
29:14Now, in the next step, what we are going to do is that we create one variable
29:16Let's say 'messages'
29:19Inside this 'messages', we will go ahead and use 'Annotated'
29:21Now, 'Annotated' is just like a kind of label, okay? This annotated class that we have inherited or are basically writing is nothing but it indicates the hypothetical runtime check model
29:34This type is an unsigned integer
29:36Every other consumer of this type can ignore this metadata and treat this type as an integer
29:40So, if you see some of the examples over here, you should definitely be able to understand that these are something like in Python, what exactly this basically means
29:48Right now inside this, I will say, hey, you have to go ahead and add the messages inside a list type with the help of the add_message
29:59So, this add_message is called a reducer
30:02Please remember this information
30:04When we say reducer, that basically means it is not going to replace this list with respect to..
30:09Every conversation we have, instead, it is going to append
30:12Append right
30:16So here, you can see how this state key should be updated
30:19In this case, it appends messages to the list rather than overwriting them
30:24So this is the basic information, but I will show you how this looks as we go ahead because we will proceed and just display this with respect to the state
30:33Now, I will go ahead and build my graph
30:35So, in order to build my graph, I'll say graph builder
30:39I'll use the state graph, and I'll give this class
30:42I'll give this class, which essentially means that when I assign this specific class here, this state graph — when we are creating the entire graph — at any point, we can provide this specific information to
30:54Our different, different nodes
30:56Okay, so this basically becomes my graph builder
30:58Here, I'm just going to go ahead and show my graph builder
31:02It is nothing but a type of state graph
31:04Okay, so my state information has been completed
31:10Now, in the next step, what we are going to do is build our entire graph itself
31:13Right, we are going to go ahead and build our entire graph
31:17Okay
31:21Now, for this, first of all, we are going to add one more library
31:25So for this, I will use Python's virtual environment, since we are going to use, you know, GPT models
31:28You can use OpenAI models
31:32You can use any kind of model
31:36So here, what I'm actually going to do, I'll go ahead and write `pip install`
31:38uh -r requirements.txt
31:44So, once I go ahead and install this, the installation has been done
31:46Now, once I go over here, right? So here, you can see that now we can go ahead and quickly import all the libraries that we want
31:56So I will go ahead and write import os, then I will go ahead and write from env import load_env
32:05Right? And then we're going to go ahead and initialize this load_env
32:10Right? So, the reason why we are doing this is that whatever keys we specifically write in our .env file, it should be able to load them
32:18So, here I am going to go ahead and create my .env file right now
32:22With respect to the env, the next step that we are specifically going to do is that whatever keys we specifically want with respect to the GPT API, we'll..
32:31Paste it over here
32:33So, this is my environment
32:35I hope everybody knows how to create a Grok API key
32:37In order to do that, just go to console.grok.com
32:40Okay? So, here you go to console.grok.com, right? And here, you just go ahead and create your API keys
32:49You can go ahead and create your API key, write the API key name, and start using it
32:53Okay? So, this API key we'll be using, and we can use different models, LLM models, in order to develop your generative AI applications
33:04Okay? So, once this is done, I will quickly go ahead and, again, execute this since my environment
33:20So, first of all, I will show you one very easy way
33:21So, I will go ahead and write from LangChain, or sorry, from LangChain Grok
33:32Okay? So, for this, we need to install this library
33:34It's called a Langgrok
33:37So, I will go ahead and write Langchain Gro
33:41Okay
33:44I will open my terminal, requirements.txt
33:48Now, here you can see Langchain Grok has been installed, and I will go ahead and minimize this
33:52So, from Langchain Grok, I will be importing ChatGROK
33:55Okay
33:57So, this is one way you can directly initialize the GPT model
34:00The other way is more common and generic, where you can just give the model name, and it should be able to load it automatically
34:06For that, you will be using from langchain, langchain dot chat models, import init_chat_model
34:14Right
34:22So, here, if you want to directly go ahead and use your language model with ChatGROK, you can just write it like this, and with respect to this, you can just provide your model name
34:30Okay, so models, it is up to you whatever models you specifically want to use or want to go ahead with, you know, you can definitely go ahead and just use that
34:36Okay
34:42See, at the end of the day, it's all about how you are using some specific models and which model you really want to use
34:47Okay
34:52So here, let's say that I want to go ahead with some other model, right? Uh, for this, I will again open my—let's see—my playground is over here
34:57So let's say I will be using some models like Llama 3, 8 billion, 8192
35:04So here, all you have to do is give your model as equal to, uh, Llama 3
35:11Llama 3 is the correct name
35:148B 8192
35:17Right? So you can basically give this particular model, and if you execute it, this is nothing but this
35:21becomes your LLM, right? This becomes your LLM, right? You can either initialize it in this way or you can also directly go ahead and write something like this
35:30So here, I'll be using the Llama LLM, initiate chat model
35:34Here, we are going to give the model name
35:36The model name will start with something like this: "grok: llama-3 8 billion" or "8192"
35:43Okay? So here, you can also use this, and it'll also give you the same LLM
35:49So these are both ways how you can initialize this
35:53And again, if you are using OpenAI, then you can use LangChain OpenAI, and here you can just mention "OpenAI:" followed by the specific OpenAI model name you are going to use
36:04Okay? Now, this is my LLM
36:06So here, if I go back to my graph, we have created..
36:09Our LLM is ready
36:11Now we will go ahead and create this chatbot
36:14The chatbot is nothing but, it is just like a node
36:17Right now, for every node, you need to create a node definition
36:22So, in order to create a node definition, I will go ahead and write 'definition chatbot.' Let's say this is my node
36:25And here, uh, here I'm going to go ahead and define my state, colon state
36:31Okay
36:37And here, what I'm actually going to do is that I'll go ahead and write 'return messages:'
36:43Now, see, this is why I'm returning this in this particular variable—because whenever I define this chatbot, right, it should be inheriting this state, because at the end of the day, I need to keep on appending inside this particular variable
37:00Right, and you..
37:02The return type of the state is a dictionary, so that is the reason we are inheriting over here: `state: State`
37:07When we write `return message:`, here we are going to invoke it with our LLM
37:11So here, I'm going to go ahead and write `llm.invoke`, and with respect to the invoke, we're going to use the state of messages, okay? State of messages
37:22So we are basically going to go ahead and return this
37:25To give you a very brief understanding, this is what my node functionality is
37:33Okay, this is what my node functionality is
37:35Here, we have defined a node called 'Chatbot'
37:37This `llm.invoke` is basically returning output based on this input message
37:43See, the state of messages is what will be my input message, right? As soon as we..
37:47Get an input message we are giving to our chatbot node, and that chatbot node is going to provide the response from this, from my LLM, and it will append inside this messages variable
37:58This messages variable is nothing but the same variable that we defined in the class state
38:01Okay
38:03Now this is done
38:06Now, in my next step, what we are basically going to do is that we are going to go ahead and quickly start building our graph
38:09So, for this, we will be using our graph builder
38:14If you remember, what is a graph builder? So, the graph builder is nothing but my state graph
38:18So, I will just remove this quickly here, and I'll just paste it over here itself
38:22Okay
38:25So, this is my graph builder, and with respect to the graph builder, how we need… To build it
38:28Right
38:31In my graph builder, I have to have one chatbot node, one start, and one end
38:33Right? And there should be edges connected to both of them
38:37As I told you, we are going to use the Graph API, right? So, uh, for this, what I'm actually going to do is that I'm quickly going to write `graphBuilder.addNode`
38:44Okay
38:46So, this will basically be my first node
38:51My first node's name will be "Chatbot." You can mention anything
38:55Let's say I will go ahead and write `LLMChatbot`
39:00Okay
39:06But the second parameter that I'm going to write is about my node definition, which is nothing but "Chatbot," right? So, this way, every node will have some node implementation that you should be specifying here
39:11Okay
39:15Then..
39:18Uh, coming to the next option is that in my graph, right? I definitely have only one node, right? This is the node that is there
39:22But along with this, I will go ahead and create start and end as my starting and end points, right? So, in order to create that, we need to go ahead and create edges, right? So, first of all, what we are basically going to do is that I'll go ahead and write `graphBuilder.addEdge`
39:36So, this was my adding node; this is my adding edges
39:52Now, with respect to add edges and add node, here is my start
39:54So, from the start, I have to go to my LLM chatbot, right? So, from my start, I am going to the LLM chatbot, and from the LLM chatbot, I should basically go where? To the end, right? So, I will go ahead and add one more edge
40:11This edge is going from the LLM chatbot, and remember here you need to specify the node name instead of a node functionality, right? And this will basically go to my end node
40:25Okay, perfect
40:28Now, see, that is what it is matching
40:31Right from the start, I have created an edge to the chatbot, then again it is going to the end
40:34So this is my entire graph
40:38Finally, what we do is that we compile the graph
40:40These are some of the steps when we define the graph
40:45The compilation is necessary so that we can execute the graph
40:47Right? Unless and until the graph is not compiled, you will not be able to execute it
40:50Right? So for this, I will go ahead and use `GraphBuilder.compile()`
40:55And here, we are basically just going to go ahead and execute it
40:58Okay
41:02Now the question arises, can we go ahead and see how this graph looks? Okay
41:06Yes, obviously you can see it
41:09For this, we will be using a visualization graph
41:11So, I will just go ahead and write code to visualize the graph
41:15Okay
41:20From the visualization graph, I will write from IPython.display import Image, display
41:24So, we are going to use this
41:33Again, we're going to go ahead and use a try-except block where we'll use the display method, which is responsible for displaying the graph with respect to any image object you provide
41:40If I go ahead and write graph.get_graph(), I should be able to get the graph itself, and we will try to draw it as a Mermaid PNG
41:50Okay, these are some of the
41:53Functions that were provided in the documentation
41:55So I'll go ahead and write an except block for exception handling
42:01Okay, and here I can just go ahead and write pass
42:03So, as you can see, this is how my chatbot looks
42:05Here I have a start, which is my LLM chatbot, and this is my end, right? So, when I give my input here, my LLM, my start, will send this, and I should be able to get a response
42:16Okay
42:26Now, the question is, how do we run this? You know, we really need to run this at any point, and if you are running it, what does it basically look like? So, for this, I can directly use `graph.invoke()`, okay? And I will say, "Hey, u, hi." So, let's say this is the message that I'm sending
42:37So, what will happen? Hi will go from here
42:39It'll go to the LLM chatbot
42:41It'll give you the output, and it'll end
42:43That's it, right? So when I say hi, uh, got hi
42:48Okay
42:53So one problem over here that you'll be able to see is that, uh, when it is trying to retrieve the details, we are facing some kind of problem
42:56Okay
43:00Now, what is the exact problem that we are facing? I will just try to, uh, resolve this as we go ahead, you know
43:04So let's go ahead and do this
43:06So here, one very important thing is that, in the state, you remember what is the variable that we created, right? Messages
43:12So what I will do, I will go ahead and create a dictionary called messages
43:16And now, inside this, I will give my message saying, "Hi." Before, I had not given this, so it is not able to pick it up, right? Because here
43:24If you see, inside the functionality of the LLM chatbot, it is invoking from this particular variable, right from the state of messages where it is basically saved
43:34So, now let's go ahead and execute this
43:39Now it should execute, let's see
43:42Invalid API key during the task
43:46Okay, so my environment is ready
43:50Okay, no worries
43:55The problem here is that we need to restart the kernel because I added my API key in the later stages, right? So that is the reason
44:00I will quickly execute all these things
44:02Sorry, the Graph Builder is not required here now
44:07It should execute because I just needed to reload this, you know, by restarting my kernel
44:11Then only it will get reloaded
44:14Okay, no worries
44:17Now it should work
44:19So, my visualization graph is there, and now— I'm invoking the messages of high
44:23Now here, you can see that I have called `graph.invoke` for messages of high human message
44:28Now you see this "high" that is going right
44:30It is being treated as a human message
44:32And now your response is with respect to the AI message
44:34Hi, it's nice to meet you
44:36So let's go ahead and save this as my response
44:40Okay
44:45Now, in order to check the response, right? What was the final response here? You can see that I can go ahead and read inside my messages variable
44:49Now, this is what is really important
44:51See, inside my class state, right? I told you that we are going to create a variable right over here
44:58This is my messages variable, annotated with a list, and an add_message method
45:03This add_messages is acting as a..
45:07The reducer's work is to append inside this list
45:11See, initially, the human gave "high," then the AI message gave "high," right? And this has been added inside this list
45:17Understand one very, very important thing: this is in the messages variable
45:22Right? Now you may be thinking, what is this "annotated"? Annotated basically means what? As soon as I gave "hi," see over here, automatically this message got converted to a human message
45:34Right? A human message is just like one kind of annotation
45:38The graph is making sure that it is annotating and appending it to this specific list
45:45And the reason it is getting appended is because, here, you can see that my messages are directly being appended with the help of those
45:54The reducers themselves add messages, right? Now I hope you are able to understand why we have specifically defined it
46:00Now, the question arises: how do I go ahead and retrieve the last message? It is nothing but the response of the message minus one
46:05Okay, so here you can see that I have got this, and if you just go ahead and write `.content`, you should be able to get "Hi, it's nice to meet you
46:13Is there something I can help you with?" Okay, so this is the easiest way of probably reading all the stuff
46:20Okay, now there are two more ways of streaming it, right? Streaming your specific data or running your entire graph and, you know, displaying the information
46:31So, that is what we will discuss now, and understand one thing
46:37Guys, if you are able to understand this, trust me, as you go ahead, any kind of graph or complex workflow that you have in your mind, you should be able to execute it
46:46Okay? Now, what I will do is I will go ahead and write a for loop for an event in graph.stream
46:52Okay? So this time, instead of directly using graph.invoke, I am using something called graph.stream
47:02We will understand this as we go ahead, but I just want to give you some information on how things work in this
47:08So, now here I will give messages
47:12Okay? And colon
47:16Let's say I go ahead and give "Hi, how are you?" Okay? So, this is what my message is
47:20Let's see whether everything looks fine
47:22Uh, yeah, this is my for loop
47:24Yeah
47:25Now, what I'm actually going to do is I will just go ahead
47:27and write print event
47:34Okay, now let's execute this
47:40So here, you can see that inside this, I have got an output which looks something like this: AI messages, messages, AI message, all this information, and I'm getting this right now when I am doing graph stream with this particular input
47:47So here, I'm getting this with LangChain chat models
47:50The LangChain chat model is nothing but my node, which you can see here
47:54Okay, now let's say that I will go ahead and write one more for loop
47:58I'll write a for event, or so, for value in event dot values
48:06Event dot values
48:09Now, what will happen if I just go ahead and print this? Okay, see, I will print my value
48:17Now, if I execute this, you can see that I'm getting this AI message
48:21So, that basically means now, whenever we try to— Stream from this graph stream, and whenever we try to see the event values, only AI messages will be getting displayed
48:30Right now, in order to display this, what I can basically do is that I can also go ahead and write the value of messages, which will be my last message minus one, and here I'll just use .content
48:44This will basically display the same thing as what was displayed over here, right? Hi, I'm just a language model, so I don't have feelings or like humans do
48:52And all this is just one specific example I've told about streaming
48:54But don't worry, because this streaming, we will discuss more about it
48:58There are multiple types of streaming
49:00With respect to streaming, you can also provide different parameters
49:04Exactly, it means, you know
49:09So, we will discuss it as we go ahead, but here this was just an example of how you can go ahead and build a basic chatbot
49:14Okay
49:18Now, it's time that we start thinking—can we go ahead and integrate some kind of external tools? Okay
49:22So, for this, let me go ahead and talk about a use case
49:24Let's say I have a chatbot
49:32Okay
49:41Now, this chatbot, I have a question—I can basically go ahead and ask a question to this chatbot, saying that, "Hey, let's say this is my chatbot," and this chatbot, you know, contains an LLM with some kind of prompt, and it is taking an input from the user and then providing a response
49:49So, here, start and end
49:55Now, if I ask a question—"Provide me the recent AI news." Do..
50:07You think the chatbot with the help of this LLM will be able to provide the output? The answer is simple
50:16No, it is not able to provide it
50:19Why? Because the LLM will not have any information related to live data, right? Any live information, it will not have
50:25It may not have been trained with the recent data, right? So, here the dependency on external tools comes in
50:32External tools come into play
50:35So, what we can basically do is that for this chatbot, as soon as we give an input, this chatbot should understand, "Hey, we are not able to answer this." So, I definitely have to make a tool call
50:48I definitely have to make a tool call
50:51And when I'm making this specific tool call, this tool call—let's say this can be any third-party API, it can be a Google search engine
50:58It can be, let's say, one of the search engines that we are going to use is Tavi
51:02Tavi is nothing but a web search engine that provides a web search API
51:07Okay, and with respect to this Tavi, we will be able to get some kind of response over here
51:12Okay, so as soon as I make a tool call, or in order to define it like this, I will just make this graph a little bit longer now
51:22Okay, so what happens is that as soon as I get an input, the next thing is that the chatbot understands it is a tool call
51:28So it goes and makes a tool call, and here we will define another node, which will be called a tool node
51:33Okay, and then, based on this tool call, I should be able to get the response in the end
51:44Okay, so instead of the chatbot not being able to give you the output, let's say if I give any
51:49Input, provide me with the recent AI news
51:51This request will go to the chatbot
51:53The chatbot will understand, "Hey, we do not have that information," so it definitely has to make a tool call
51:59So, what it will do is make a tool call, and then it will go to the end
52:04Okay, it will go to the end
52:07Right
52:10In this tool node, I may have multiple tools
52:14I may have tools like TabNine
52:19I may also go ahead and define some custom tools, like add, subtract, or some custom implementation
52:23Also, you can go ahead and write
52:25Right now, the question arises: how does this chatbot know about the tool node? See, there is something called LLM
52:34Okay, inside this chatbot, we use an LLM, right? The LLM is actually the brain behind taking this decision
52:41Why this LLM? It can be binded with these tools
52:47When an LLM is binding with these tools, what does this basically mean? It means that, let's say I go ahead and create a custom function
52:53This custom function is called "Addition." Let's say this is my addition function
52:59This can be added as a tool to the LLM
53:05It can be binded with the LLM itself
53:11Then, whenever you define any custom tool, you also need to provide the docstring
53:16You need to provide the docstring
53:18Now, with the help of this docstring, the LLM will know what the inputs and the arguments required are
53:31So, if these inputs and arguments match the input that we are giving in this chatbot, then automatically this will trigger a call to that particular tool
53:43Right, so this same thing I will try to show you in a practical way
53:47We will go ahead and create some tools, and we’ll also go ahead and create some of the custom tools
53:54Once we do that, what we are basically going to do is that we will also create a tool node, and there is one more additional condition called a tool condition
54:04So, we will discuss all these things with respect to this particular implementation
54:08But our main point here is that chatbots can also be integrated with a separate tool node, and it can make a tool call based on a specific input that we receive
54:21Okay? How that can be implemented is by binding tools with the LLM and also defining your custom functions if needed
54:30required, and this LLM will be able to understand whether it has any tools or not through these dockstrings
54:36Okay, so now let's go ahead and implement those functionalities
54:42So, guys, now let's start building a chatbot with tools, using the help of LangGraph
54:46First of all, I'll just show you what we are trying to build here
54:49Okay, so here is one graph, you know, which we will try to create
54:54Now, just observe this graph
54:57Okay, this graph is quite amazing because we have a separate set of tools
55:02Here we have a tool called Calling LLM
55:04Okay, so from here, we are definitely going to provide our input
55:10Now, from this input, as you know, these are my edges
55:13This tool called Calling LLM is my first node, and this node has an LLM
55:22LLM with binding tools
55:27Okay, when I say binding tools, what does this basically mean? So, this means that I have LLMs and tools integrated with themselves
55:34We will use a couple of tools
55:36One of the most famous tools that we will try to use is the Tably API, or Tably Search
55:43This is just like an internet search
55:45Along with this, we'll also create some of our custom functions
55:51Okay, we will create some of the custom functions or custom tools
55:58And remember, here I can also combine multiple tools into one tool node
56:03So, what we're doing here is that we're going to combine this into one tool node
56:10Okay, so this is nothing but a tool node, and here you can observe one more very amazing thing
56:17From this particular tool, from this specific node here, we have two paths: either we can go there or we can go over here
56:24So, let's say my question is, "Hey, what is the recent AI news?" The input will go over here
56:33Then this tool calling the LLM will decide whether it can give the answer or whether it depends on some tools
56:41Since we have bound these tools and remember how the LLM will be able to understand from the docstring, right? So, in every tool, there is some kind of docstring
56:50Docstring is nothing but a brief description of what that tool actually does
56:55Okay, I will also define one custom tool and show it to you
56:59Then this tool calling the LLM, since it has that tool information, will take a decision
57:03Whether it has to make a tool call or whether it can just answer and go to the end, let's say if it makes a tool call, the tool will then provide some kind of output message and it will end
57:13If it is not a tool call, it is just going to give you the output and go to the end state
57:17Okay, so this is fundamentally a simple problem—things that we are going to solve right now
57:26Okay, and we'll solve it step by step
57:28Okay, how do we go ahead and solve it? That I will discuss as we go along
57:31Okay, so now let me go back to my code
57:34So, first of all, in my `requirements.txt`, I will go ahead and import one library called `langchain_tavly`
57:45Okay, now `langchain_tavly` is nothing but, if you see in my API, we need a Tavly API
57:53Okay, and in my..
57:56requirements.txt, we need to first install this
57:58So, quickly, let's go ahead and open my terminal and here I will go ahead and write `pip install -r requirements.txt`
58:04Okay, so once we do the installation, it will complete, and we are good
58:10We have this LangTabi
58:12The next step will be that I will just go ahead and open this website called Tabii
58:17Okay, so here you can just go ahead and search for tabi.com
58:24It empowers your AI applications with real-time accurate search results tailored for LLM and RAG
58:27It's just like an internet search
58:29Okay, so I will just go ahead and log in
58:34Once I log in, you can see that it will give you an API key
58:35I will copy this key, and it is free
58:37You can probably hit many
58:41Number of requests with the help of this, so I think you don't have to be dependent on my API key
58:47Right? So, I will go ahead and write my API key and paste it over here
58:52Right now, the next thing is that, since I'm working over here with the help of this, I will just go ahead and restart my kernel
59:00Okay? You have to restart your kernel; otherwise, things will not work
59:05The reason is very simple because we need to import this again
59:09So, I will first go ahead and execute this
59:10This will basically be my language model
59:12Okay? This—or this can be your language model—no worries
59:14Okay, now I'll go back over here
59:19Now, let me go ahead and import some of the libraries
59:21Right
59:23So, first of all, I will go ahead and import this tool
59:25So, I'll..
59:27Write from LangChain TAVLY
59:29Okay
59:32Uh, I'm going to go ahead and import TAVLY Search
59:36Okay
59:40I will go ahead and create this tool wherein I initialize the TAVLY Search, and here my max results are equal to two
59:42Okay
59:44And then I will define my tools
59:47Let's say this will be my list of tools
59:48Okay
59:50I can still define many numbers of tools I like
59:51Okay
59:53But I'll use this tool
59:54Let's say I will go ahead and just invoke it with one message
59:56Let's say I will write, "What is LangGraph?" Okay
01:00:03So this will basically be my question
01:00:05Now, once I execute this, you should be able to see some kind of response
01:00:10So here you can see "What is LangGraph?" results
01:00:12You are able to see all these values: title from different sources, and URL
01:00:17Able to see this, right? LangGraph is a Python library, and all this information is specifically coming up
01:00:22So once we have created this SavTavly search tool, our next step will be to go ahead and try to create our custom method, okay? A custom function, so that gives you an idea of how you can also integrate a custom function and how LM is able to understand, because I spoke about something called a docstring, right? So, how do we write this docstring? Everything we'll discuss, right? So, let's take a basic function
01:00:50Here, I will define one custom function, and this custom function, we're going to go ahead and write the definition, multiply, and let's say here, I will go ahead and write "def multiply" and then, let's say, "a: int, b: int"
01:01:02And let's say this is going to return a type of int, right? So now the question rises: how do we go ahead and write our docstring? So, this basically gives you a docstring example
01:01:14Okay, here in the summary, let's say I will go ahead and write "multiply a and b." And then, here, let's say a will be my first int, b will be my second int, and it returns an output int
01:01:37Right? So it is something like this
01:01:40I’ve just written some information
01:01:41Now, this is what is called a docstring
01:01:45Okay? Now, this docstring will be very important because once we bind any functions, right, with our LLM, or these functions can also be converted into tools and bound to it, then the LLM will be able to understand what this tool will be able to do
01:01:59Now, what..
01:02:02I will go ahead and create my variable tools here
01:02:03I'm going to use the first tool, multiply, and let me just go ahead and execute it right now
01:02:12As I told you, I need to bind this entire list of tools with my LLM, so I will go ahead and write `llm.bind_tools`, and here we're going to basically go ahead and write tools
01:02:27This will be nothing but LLM with tools
01:02:33So once I go ahead and write it, now if you see, this is nothing but LLM with tool
01:02:36So this is a runnable binding—ChatGPT has all the information over here and what functions it is connected to, like it is connected to Tability Search, it is connected to Multiply, and you can find out all those specific details
01:02:48Information over here itself, right? And this is how, uh, things work in this
01:02:53Now, once we have defined this LLM with the tool, this tool we are going to use inside our chatbot node
01:02:57Okay
01:03:01So, now let's go ahead and create the entire state graph
01:03:04Remember the structure of the state graph—how it will be
01:03:10I have start, I have tool calling LLM, this is connected to tools, and this is end
01:03:15Okay? Now, our question is, how do we basically create these tool nodes also? And for this, we also have some predefined, uh, packages available in LangGraph
01:03:25Okay, so I will quickly go ahead and write from LangGraph, from langgraph.graph import Graph, as usual
01:03:35I'm going to go ahead and import StateGraph
01:03:37See? Again, I'm importing all these things so that you get to know
01:03:39Like, I know in the top already we have imported it, but you should know what all things are there
01:03:45So, from langraph.py, pre-built, I'm going to go ahead and import the ToolNode
01:03:49See, we have anyhow binded this LLM with all the specific tools, right? So, binding will play a very important role
01:03:59See, there are two important things: one is binding
01:04:06When we are binding the LLM with tools, this actually helps the LLM to understand which all tools it has, which all tools it has, right? So, whenever an input comes, it's just like—just imagine the LLM has some kind of weapons to solve your input
01:04:30Right? If I ask, "Hey, provide me the recent AI news," obviously, the LLM will not be able to do it
01:04:35It will do an internet search and try to provide you with the response
01:04:38When we do this binding, it is just trying to give you information that the LLM has all the specific tools, but further, when an LLM makes a tool call, it has to make a call to this tool
01:04:51That is what we really need to understand—how that tool call will be happening
01:04:56Okay, so I'll go back over here
01:05:01We have imported something called a tool node
01:05:03Now, all the tools that we have created—these all tools—have some kind of functionality, right? These need to get converted into a tool node because each tool node will have some kind of implementation
01:05:17Along with this, we will also go ahead and import one more library from langraph.prebuilt: import tools_condition
01:05:22Okay
01:05:27Now, first of all, we will go ahead and start with the node
01:05:29Definition
01:05:32Okay
01:05:34Here we are going to create a, uh, definition
01:05:37Okay
01:05:41And before creating a node definition, also, first, let's start creating the graph
01:05:43Okay
01:05:44So, first of all, we are going to use a builder
01:05:46This will be of type StateGraph
01:05:49StateGraph
01:05:52And inside the StateGraph, we will be using something called a State
01:05:54Okay
01:05:56This will be our class, specifically the State class
01:05:58Then, in the next step, we are going to go ahead and create our builder, add node
01:06:03So, two, one node—uh, two nodes—we definitely require
01:06:09If you see in this graph, one is a tool calling LLM and the other is the tool, right? So, first, we will go ahead and create this node
01:06:15Inside this node, we will give the name as Tool Calling LLM
01:06:23Okay, and then I have something called..
01:06:24As a tool, or I have to define the functionality of this node, right? So, in the later stages, it will be defined
01:06:34Still, I'm not defined because I will be defining it over here
01:06:38The other edge that we really need to create, or the other node that we need to create, is nothing but the add node, which is nothing but a tool
01:06:45And remember, this tool will be of node type "tool," and here we are going to give all our tools themselves
01:06:53So, this node is nothing but this specific node, and inside this node, if I want to go ahead and write a definition, it will be of tool nodes
01:07:03If you go ahead and see the definition of these tool nodes, it is how all the list of tools that we specify will be implemented as a tool node itself
01:07:12Okay, so this is my node name
01:07:14And this is the definition
01:07:16This is my node name, and this is the definition
01:07:18Now, let's go ahead and create the definition
01:07:19So, for creating the definition, I'll go ahead and write `tool_calling_lm`
01:07:26And here, we are going to define `state: state`
01:07:29And here, we are going to go ahead and write `return messages:`
01:07:38Again, what we are going to go ahead and write here is that we are not directly going to call the language model, but instead we are going to call `Lmit` tool, right? So, here, `llm_tool.invoke`, and where do we get the input from? From the `state` of `messages`
01:07:56Right? So, here, we are going to go ahead and define `state of messages`
01:07:59Perfect
01:08:02So, here you can see very clearly
01:08:05Now, in the next step, we are going to go ahead and add the edges
01:08:06Now, adding the edges is really..
01:08:09Important
01:08:12If you understand this, any kind of complex use cases you'll be able to understand it
01:08:13Okay
01:08:15So, the first edge is from start to tool calling LLM
01:08:17Okay
01:08:18So, first of all, let's create that
01:08:20In order to create it, uh, we will just go ahead and write something like this: builder.addEdge start to tool calling LLM
01:08:27Now, from tool calling LLM, there are two nodes that are going on, right? Sorry, two edges
01:08:33One edge is going to the end, and one edge is going to the tools
01:08:35Right
01:08:38Now, these kinds of edges are called conditional edges
01:08:41Okay
01:08:43So, in order to add conditional edges, it will be like builder.addConditionalEdges
01:08:46And inside this, we are going to call our tool calling LLM
01:08:54From tool calling LLM, this will happen, right? From..
01:08:56This specific node, it is going to happen
01:08:57So, tool calling LLM, and in the next — this is really important — okay, in the next, we are going to import something called a tools condition
01:09:07Now, the question arises: Kish, what is this tools condition? The tools condition applies to two different kinds of conditions
01:09:15Let me go ahead and write it over here
01:09:20If the latest message, right in the input message, when we are giving it from the assistant, if the latest message from the assistant is a tool call, then the tools condition routes to the tool node
01:09:30So, the tool node is basically created here, right? If you create it with this other name, this will not happen then
01:09:38Okay, so that is the reason we have created this tools node
01:09:39Okay? If the assistant is..
01:09:42Saying it is not a tool call, then it will go to the end
01:09:44That basically means this will serve, and it'll go to the end
01:09:47So, this tool condition basically applies two different conditions
01:09:51If the latest message from the assistant is a tool call, the tool condition routes to the tool
01:09:59If the latest message from the assistant is not a tool call, the tool condition routes to the end
01:10:01And that is where you are actually doing this with the help of the tool condition
01:10:05Okay, very simple
01:10:10Here, if this tool-collecting LLM is making a tool call, it will go to the tool node; otherwise, it will go to the end node
01:10:13That is what the tool condition does
01:10:15Okay
01:10:18And that is a kind of—see, whenever there are two edges coming from a node, it has to go inside this additional conditional
01:10:20Edges
01:10:23Add conditional edges
01:10:26Okay
01:10:28Now finally, I will go ahead and add the final edge: builder.addEdge
01:10:31Then, you know where this addEdge should go, right? The final edge will be nothing but—it'll be from tools to end
01:10:37Sorry, this is a keyword
01:10:46So, the other part is that, by default, if it is not a tool called, it is anyway going to go to the end
01:10:54Okay, so this is actually managing the other condition
01:10:56Now finally, we will go ahead and compile the graph
01:10:59Compile the graph
01:11:02After compiling it, let's go ahead and write it out
01:11:06Graph is equal to builder.compile, right? And then, we are going to go ahead and view the graph
01:11:12Okay, so, to view the graph, it will be nothing but using that same function called as
01:11:17Display
01:11:18And here we go
01:11:20Uh, state is not defined
01:11:23Okay, state is not defined
01:11:25Let me go ahead, and again I think I restarted the kernel, right? So that is the reason we got that issue
01:11:28So I will just go ahead and execute this
01:11:30Okay, these two things I’ll execute
01:11:32Perfect
01:11:34Now this should definitely work
01:11:36So here you can see that I’m getting one error: node already present
01:11:41The thing is that I did not define the node definition over here
01:11:44Okay, so let’s go ahead and define this and execute it
01:11:46Okay, uh, image is not defined because I need to import the image library
01:11:52It’s okay, no worries
01:11:55I will do that
01:11:59Okay, now here you can see I’ve got the same image start, then calling LLM tools, and end
01:12:02Okay, now it’s time we see how we can
01:12:06Probably call this okay, quickly
01:12:10So I'll go ahead and write messages as equal to or I'll just go ahead and use the same graph, graph invoke
01:12:14So we know there is an invoke method, and here we will go ahead and give our messages parameter, and I will give my message
01:12:21Hey, uh, I'll say, hey, what is the recent AI news right now? With respect to this, you know, if I'm executing this, it definitely needs to make a tool call to my, um, you know, to the, uh, third-party API with respect to Tavi
01:12:43Now, here you can see this is lovely, see clearly, you are able to see what the recent AI news is
01:12:49So here is the human message that has been appended in the AI message
01:12:54It did not respond with anything; the content is empty
01:12:58But it is saying that the LLM has made a
01:13:00Tool call, right? Tool call
01:13:02The ID is this
01:13:05The function name is this
01:13:08And this is the query, right? With this particular topic, news, right? And here you are able to see this
01:13:11And finally, the tool message that you are getting—recent AI news, follow-up questions, all this information that you're able to see
01:13:19Okay? Now we need to see what information is available to us
01:13:22So now I will just quickly save this in some kind of response
01:13:29Okay, response
01:13:31I'll execute this
01:13:34Let's go ahead and write this response
01:13:38So this response is basically coming like this
01:13:40I will go ahead and check my messages
01:13:42Messages
01:13:45I will take the last message
01:13:47It should definitely be a tool call
01:13:49So, tool message, and if I just go ahead and write .content, I..
01:13:51Should be able to do this
01:13:53Recent AI news was the query
01:13:56The follow-up question is null, and this is all the information
01:13:58Nvidia's self-driving software platform— all this news information—is specifically coming
01:14:02If you want to display it in a much better way, I can also go ahead and write something like this for, let's say, whatever response I'm getting, response of messages—okay, response of messages from on this
01:14:11I'm just going to go ahead and write m.prettyPrint
01:14:21PrettyPrint, I know
01:14:30So, here you can see what the recent AI news is
01:14:33It made a tool called Tably Search, and here is my query with respect to all the responses that I'm able to get right now
01:14:39The question arises: Kish, did we go ahead and test some other things? So, let's test
01:14:44One more thing, one more tool we added, right? What is 2 * 3, or the multiply function
01:14:51What is 2 * 3, right? And we will try to display the same response here
01:14:56This time, it will make another tool call, okay? And that tool call will be nothing but a multiply tool call
01:15:03See, multiply tool call
01:15:10Now, how is it able to do it? Because the LLM has that binding information already, right? And it is able to make this specific tool call in a much easier way
01:15:16But still, there is one very important thing
01:15:19See, a tool message is coming up, but the operation is not happening, right? Why is it not happening? See, over here you can see that, what is 2 multiplied by 3, or I'll just go ahead and ask, what is 5 * 2? If I'm executing this, okay? Here, you will be able to see that 5 multiplied by 2 is not probably producing the right kind of output
01:15:41So, one interesting thing you can see here is when I'm multiplying, the output is null
01:15:46Then I realized that there was some mistake we made—we did not go ahead and write the definition, so return a multiplied by b
01:15:51Okay, so now I'll execute this
01:15:56This will basically be my Tools, or LM binding tools
01:16:00So, this will be my LLM tool
01:16:04Now, let's see—I think now it should get executed
01:16:07So, 5 multiplied by 2
01:16:11Okay, I still need to recompile my graph
01:16:13Okay, so I'll go ahead and recompile my graph
01:16:15Now, if I just execute it, let's see what happens
01:16:17So, now you can see, Tool Call has made 5, 2
01:17:08The argument, it is able to find out, and tool message is nothing but name multiply, and the answer is 10
01:17:09So, this kind of issue, smaller issues may come, but you need to go ahead and fix them
01:17:11Okay
01:17:13But now, one more important thing is that what if I just go ahead and write something like this? Okay, see this
01:17:15Okay, what is 5 * 2, and then add 10? Okay, or let's say I'll go ahead and say multiply by 10
01:17:15Okay, if I go ahead and execute this here, you'll be able to see some kind of messages
01:17:15Let's see
01:17:16So, here you can see first, what is 2 multiplied by 2, and then multiplied by 10
01:17:16So, multiply 2 * 2, 10, 2
01:17:17Okay, it is able to capture the argument
01:17:17It is able to find out this multiply, and here also, we are able to get it right
01:17:17So, what is 5 * 2, and then multiply by 10? It is..
01:17:18Able to find it out
01:17:19Okay
01:17:20Now see, I will again change this
01:17:27This is also working
01:17:34Give me the recent AI news and then multiply 5 by 10
01:17:40Now, if I execute this with this kind of query, now just think over it
01:17:43You know what is going to happen
01:17:46So here, one very important thing happened, right? Give me the recent AI news
01:17:50In this particular sentence, there are two important sentences themselves
01:17:55One is "Give me the recent AI news," and the other is "Multiply 5 by 10." With respect to "Give me the recent AI news" and "multiply," here you can see tally search is done, but after that, it gave the output and it came out
01:18:07But what about this particular query right now? What has actually happened? See, if this is my LLM, okay, this is my LLM or this..
01:18:17This is my chatbot
01:18:28Let's say here I asked a question: what is the recent AI news? And I asked to multiply 5 by 2
01:18:39Let's say I asked these two questions
01:18:50So, in a sentence, there are two questions, right? When the LLM receives the input, it makes a tool call
01:19:01The tool call was in a tool node
01:19:11Why does it make a tool call? Because here you can see that it is asking for the recent AI news, and it knows that in the tool call it has Tavly API
01:19:22Okay, Tavly, and then from here it went to the end node
01:19:33This was the start, and this was the end
01:19:44But what about this particular question: multiply 5 by 2? And this is how my entire graph looks
01:19:54Don't you think if we made some changes, this answer would also be generated? And what were the changes? Here, instead of once the tool node gives you the output, can't we give that output back to an LLM instead of sending this output to the end state? Now, once we make this response back to the LLM, then the LLM will be the main decision maker, and this decision maker will help them to probably take up the next query — multiply 5x2 — and then it can again make a tool call because here I have my multiply function also
01:20:05Then, once it gets the response, it'll give it back to the LLM, and it will combine both the outputs and provide it till the end of the output
01:20:16Give it at the end of the output
01:20:19So, this way of interaction of LLM with tools, right? It specifically uses a very important kind of, um, you know, there is a very good communication that..
01:20:34Happens between LLM and tools, and we use a kind of agent called a react agent
01:20:43Okay? And this react agent plays a very important role altogether
01:20:47Right? Now, first of all, what exactly is this react agent? You need to understand
01:20:52Okay? Let me just go ahead and explain this with a better, simpler example
01:20:58Here, I definitely have an LLM
01:21:01Okay? Let's say this is my LLM
01:21:06I ask a question
01:21:10Okay? And you know that this LLM is nothing but the brain
01:21:13Right? So, here it is the brain
01:21:16When I say brain, this will be responsible for making the decision about which tools to call
01:21:19And in the LLM, I have some kind of binding tools
01:21:27So, here we go ahead and start
01:21:30Here we go ahead and end
01:21:34And here is my tools node
01:21:40This is my another node
01:21:43Okay, so let's say here I give my natural input
01:21:48The natural input is "Provide me the recent AI news," and along with this sentence, I say, "Hey, multiply 5 by 5." Now, when the large language model (LLM) takes this specific input, it breaks it into two sentences
01:22:00First, it will try to serve the AI news, as I said, this is the brain, right? So what it does is it knows it has to make a call to the tool node
01:22:10Now, with respect to the tool node, it will get an output, and instead of giving it directly to the end, it will send the response back to the LLM
01:22:19The LLM will still have the context of the second sentence
01:22:21Then, what will it do? It will again make a call to the tool node
01:22:26Why? Because this is "5 multiplied by 5," right? So "multiply" is again there
01:22:31It will again go ahead and execute
01:22:32This particular tool node and again get the response
01:22:34Then it will go ahead and see, hey, is there anything left in this particular sentence? Nothing is there
01:22:40So, what is it going to do? It is going to summarize and give you the output at the end
01:22:43So, this way of communication, right, this agent architecture is basically called React agent architecture
01:22:54In React, there are three main key terms
01:22:57One is act, the second one is observe, and the third one is something called reason
01:23:07Act basically means whenever an input comes, the LLM will be able to make a tool call
01:23:11Right? Then, when the output of the tool comes, the LLM will observe, okay? The LLM will observe, do I again need to make the tool call, or should I directly go to the end? Let's say, if this..
01:23:25A question is asked again after that, then again it makes a tool call, okay, and then it is going to get the output
01:23:30Essentially, it means that after it gets the output, what the Large Language Model (LLM) should do—that decision is made by the LLM
01:23:38This is where your agent architecture comes into existence
01:23:44That is where your agent behavior comes into existence
01:23:46And this rise in architecture is why your agentic AI has become very popular
01:23:52Okay, that is the reason why it has become really, really popular
01:23:56So, in order to just implement this, see, I will just give you an example
01:24:00Here, if I want to go ahead and use this React agent architecture, okay? How we are basically going to do this, okay? I will just go ahead and use the..
01:24:08Same thing
01:24:15See, I will use the same state graph for this agent
01:24:23Now you should tell me where the changes should happen
01:24:27Okay, I will copy this over here from the tools
01:24:32Instead of going back to the end, it should go back to tool calling LLM
01:24:41Yes or no? Just think: instead of going from tools to the end, it is now going to the tool calling LLM
01:24:47Now, how will my diagram look? This is how it looks: from start, tool calling LLM goes to the tool and then again goes back to tool calling LLM
01:24:55And this can keep on repeating unless and until the answer is completely satisfied, and the LLM is basically making the decision
01:25:03Now, if I go ahead and ask this question, now see the magic
01:25:06Okay, see the magic of how good the output will be
01:25:10Okay, so here
01:25:14If I go ahead and probably just show you the output, give me the recent AI news and then multiply 5 by 10
01:25:17Now, see how the LLM is going to behave
01:25:21So, give me the recent AI news, multiply by this query, and tabular search is happening
01:25:23Perfect
01:25:25Here's the recent AI news
01:25:27After this, what has happened? The response has gone back to the LLM, and then now multiply 5 by 10, which is nothing but 5 * 10, which equals 50
01:25:38And this is how your entire React agent works, right? I hope you're able to understand this with the beautiful example I have provided here
01:25:49And this is with respect to the React agent
01:25:51So, I hope you are able to understand this
01:25:54Now, you can keep on adding any number of tools; the LLM will be the deciding factor in choosing which tool to use
01:25:57Specifically, let's call it
01:26:00So, guys, now we are going to go ahead and implement adding memory in the Agentic Graph
01:26:04Uh, so whenever you create a Graph, you know, LangGraph has a feature where you can go ahead and add memory, and this memory actually solves a major problem, which is nothing but persistent checkpointing
01:26:20Now, why do we specifically use this memory? Okay, so let me just give you some examples
01:26:24So, already, if you know, we were able to invoke it from the previous Graph that we have actually created
01:26:32Now, let's say I go ahead and ask a question
01:26:35Hello, my name is Kush
01:26:38Okay, so let's say this is what I'm communicating with my chatbot
01:26:41So, my chatbot should be able to give me a good answer, right? It I'm going through this entire graph
01:26:49The tool call is not required here, so it directly goes to the end after giving the answer
01:26:52So, let's say that I just asked, "Hello, my name is Kish," and it is able to provide a nice response, saying, "Nice to meet you
01:27:00How are you today?" Now, what I will do is ask another question: "What is my name?" Okay, "What is my name?" So now, what is actually going to happen is that you will see what kind of response we are able to get here
01:27:17Now, "What is my name?" It is making this tool call
01:27:22I apologize for the earlier mistake since the tool ID yielded
01:27:24I will assume you're asking about your name again
01:27:27Unfortunately, I don't have any information
01:27:29About your name and it's not provided in the conversation
01:27:30Can you provide more context or clarity about what you mean by name and all? So, see, I just now told my name, and it also told me, "Hey, nice to meet you
01:27:41How are you today?" And now, when I'm asking the same question, "What is my name?" it does not know
01:27:46So, it is not persisting that entire information with respect to the previous conversation or previous interaction that we had
01:27:53Now, LangGraph has a very special property to overcome this limitation, which is called memory
01:27:59Now, for memory, what we will do is, let's say that I'm going to use the same graph
01:28:04Okay, so I will copy this, and let's say I go ahead and paste it over here
01:28:09Okay, now once I paste it over
01:28:12Here, LangGraph has a feature wherein you can create a memory saver checkpoint
01:28:18Okay, now how do I go ahead and create it? So here, what I will do, I will just go ahead and write `from langchain import` uh, sorry, `langgraph.checkpointer.memory`
01:28:23Okay
01:28:28And here, uh, we are importing `langgraph.checkpointer.memory`
01:28:34We’re going to go ahead and import this
01:28:37So, let's see whether the spelling is correct: `checkpointer` `do` `memory`
01:28:41So let me just go ahead and use this
01:28:44And here, you can see from `langgraph.checkpointer` import `checkpoint.memory_saver`
01:28:49And we go ahead and initialize this memory saver
01:28:53Now, what exactly is this memory saver? It is nothing but an in-memory checkpoint saver
01:28:57This checkpoint saver stores checkpoints in memory using a..
01:29:04Default dictionary
01:29:10Okay, so here, if you go ahead and see, what it is going to do is that with respect to every node that it executes, it is just going to go ahead and save all the information so that you can recall this particular memory again and again whenever it is required, based on the previous interaction
01:29:17Okay, now, where do we add the specific memory? This is really important
01:29:21So here, we have created a memory object
01:29:22Where do we add it? While we are compiling, there is a parameter called checkpoint
01:29:27We have to add this memory over here, right? So, once I go ahead and execute this, now you can see that I have this exact, uh, right thing
01:29:34Now, what I'll do, I will just go ahead and give some input
01:29:40Okay
01:29:45Now, see, if I want to use this specific memory, right, for a previous interaction or probably I want the context of the previous interaction, first of all, we need to go ahead and create a thread ID
01:29:51This thread ID will be important because it will be related to one specific session
01:29:56So, we will go ahead and create a variable
01:29:58Let's say I will just go ahead and create a list
01:30:00So, this is memory, obviously
01:30:02Okay
01:30:04And now I will just go ahead and create one config
01:30:07Okay
01:30:09Inside this config, we will be using a key which will be called 'as configurable'
01:30:12And inside this configurable, we are going to create one thread
01:30:16And this thread ID or any number that I give it should be unique
01:30:21Let's say I'm going to, probably, a user has joined a..
01:30:24I will go ahead and create a thread for that particular user
01:30:28Okay
01:30:31And this here is the configuration that we need to provide, a configurable key, and there should be a thread with this specific key-value pair
01:30:35And this should be unique
01:30:37So, once I have provided my unique thread ID, I will use this graph and call the invoke method
01:30:42Okay
01:30:46Now, once I call the invoke method, I will basically pass it in the form of key, value pairs, that is, as a dictionary
01:30:51So here, I am going to go ahead and write messages
01:30:57And now, if I give the message saying, "Hi, my name is Krishna," see what magic will happen
01:31:02Okay
01:31:06So here, apart from this, right, the..
01:31:11Messages that we are sending, we also have to make sure that for which thread ID I am providing the configuration
01:31:15So here, there will be one more additional parameter, which is called 'config,' and we will provide this particular config
01:31:20Right
01:31:25So once we get the response, I will just go ahead and print this response
01:31:29So this will be the graph; let's go ahead and print it
01:31:33Okay, response
01:31:36Perfect
01:31:39Now I should be able to get my output
01:31:41So here, you can see that output is nothing but all this information is there
01:31:46Hi, my name is Kish, and it says, "Nice to meet you." All this information is there
01:31:51Right now, what I will do, I will quickly go ahead and write the response, or let me do one thing because I think it got appended two times
01:31:54Okay
01:31:57I'll execute this once again, and let's just execute it one time
01:32:00Okay, so with this particular thread ID, we will just run it for one time
01:32:03Um, and now here you can see that I'm getting one human message, one AI message
01:32:07Nice to meet you
01:32:09Now, if I just go ahead and see the last messages, so it'll be messages minus one
01:32:16So, here you can see that if I go ahead and see this particular content, I should be able to see the output
01:32:18Okay
01:32:21Hi, nice to meet you, Crush
01:32:23Is there something I can help you with? Okay
01:32:24Now, let's go ahead and again use the same config, and let me now ask, "Hey, what is my name?" Okay
01:32:31Now, let's see whether it'll be able to remember or not, because we have already used memory saver, and it is putting everything in that
01:32:40Uh, memory saver itself, right? So the previous interaction context, it'll be able to remember it
01:32:44Hey, what is my name? Okay, so I'm just going to go ahead and do this, and we are going to print this particular output
01:32:50Okay, so we are going to print this output and remember, we're giving the same config
01:32:58Okay, see, when you create an end-to-end application, this dynamic ID, thread ID, will be maintained in the session itself
01:33:06So, that way, we'll be able to maintain this entirely in the memory saver
01:33:10Right? So, here now it is able to understand that, hey, your name is Crash
01:33:12Okay
01:33:15Uh, so this is really nice, right? Now it is able to remember
01:33:17Do you know what my name is? Uh, hey, do you remember me? I'll just go ahead and write it like this
01:33:24Remember me? Right
01:33:28This is the beginning, so I don't have previous memory of you
01:33:29I have my large language model and all
01:33:32Okay
01:33:34Do you remember my name? Let's go ahead and ask this question
01:33:36Do you remember my name? So it will be able to remember me, my name at least
01:33:39Yes, your name is Kush, right? So it is able to answer that, right? So guys, now we are going to discuss about streaming and LangGraph
01:33:46See, most of the time, whenever we want to probably invoke or chat with our chatbot, we are basically using this graph.invoke method, right? And somewhere we also use stream
01:33:59Now, let's go ahead and try to see what are the different streaming techniques to probably get the response from the chatbot itself when we..
01:34:08Executing a graph
01:34:09So first of all, what I'm actually going to do is that I will go ahead and implement some of the things, like, let's say, I will go ahead and initialize my memory saver
01:34:13Okay
01:34:18Now, inside this memory saver, we are basically just creating a memory object
01:34:22I will go ahead and create one node definition, and this node is nothing but the name is SuperBot, and here we are going to use LLM with tool.invoke
01:34:31Okay, or I can just go ahead and use LLM, right? I'll just create a simple graph to probably show you what are the different types of streaming that are available over here
01:34:42Right now, let's go ahead and execute this
01:34:45Now, here is my entire chatbot node that is available over here
01:34:49Right now, I will just go ahead and create my..
01:34:52Entire graph
01:34:54So, let's say this is a very simple graph wherein I am trying to create a node called a Superbot
01:34:59The functionality is nothing but Superbot here from start to Superbot, Superbot to end, and then we are compiling it with a Checkpointer memory
01:35:07And this is how my graph looks—very simple graph
01:35:11I think, uh, we are learning a lot right out here, uh, from that much time
01:35:15Like, in this entire session, we have understood how to create different types of graphs
01:35:19Now, what I will do, I will go ahead and create a thread
01:35:22Let's say the thread is one
01:35:24I'll say, "Hey, my name is Krishna," and "I like cricket," and I will give this particular config
01:35:27I'm just going to go ahead and invoke it
01:35:29Okay
01:35:31Now, when we are invoking it, you can..
01:35:33See, there are some pieces of information that you are seeing, right? One is the human message, and the other is the AI message
01:35:38The AI message is basically the response
01:35:40Now, with respect to this, we are going to learn about three streaming techniques
01:35:48Okay? And this will be very, very handy when you try to develop some kind of chatbot
01:35:53Okay? So, inside streaming, you have the `.stream()` method and the `stream()` method
01:35:57The methods are sync and async, used for returning results
01:36:01And inside the `.stream()` and `stream()` methods, you have these two parameters: one is `value`, okay, and the other is `nothing but` updates
01:36:11Now, the question arises: what exactly is the difference between `value` and `updates`? So, in order to make you understand, let me go back over
01:36:19Here
01:36:26Okay, let's say I have a node and this is related to streaming, right? To help you understand the differences between values and updates, that is what we are going to discuss
01:36:34Okay, so let's say this is my streaming topic
01:36:36First of all, let's say I have this graph
01:36:41Inside this graph, I have various nodes
01:36:43Let's say I have Node 1, Node 2 that gets executed, and then finally I have Node 3
01:36:53The flow of execution is in this direction, right? And we are discussing about stream and Earth stream methods
01:37:03There is a stream method, and then there is an Earth stream method
01:37:08In order to understand the difference between stream and Earth stream, this is specifically used for asynchronous operations
01:37:14Okay, now if you know Python, I think you should get an idea about what is sync and async
01:37:19Basically, it means, right? But the main important point that I'm really interested in is understanding about modes
01:37:27So, inside this method, you have two modes: one is update mode and one is value mode
01:37:32Okay? Where is value mode? Okay
01:37:37Now, what is the difference between update mode and value mode? And we will play with this parameter
01:37:39Okay
01:37:41This is an additional parameter we give
01:37:44Let's say, over here, in node one, as soon as node one gets executed, my messages variable will be equal to, let's say, "Hi." Let's say, my LLM gives a "Hi" message when node one is executed
01:37:59When node two is executed, the messages will probably have another piece of information
01:38:07Like, my name is okay
01:38:10So this will be my another information, and when node three executes, my current message—that is being updated—is okay
01:38:18This is a very simple concept
01:38:23When node one gets executed, my current output response is "Hi." Then, when node two gets executed, my current response is "My name is." And when node three is executed, it becomes "Kish." Okay
01:38:37Now, if I use mode equal to update, only the message that is currently being updated will be displayed as output
01:38:43Okay
01:38:49Let's say if node one is getting executed, I just go ahead and print or do the streaming with respect to mode equal to update; only this message will get updated
01:38:54Right? Let's say after executing
01:38:56All these three nodes, this is the message that is getting executed
01:38:58Again, I go ahead and give my another input, then this message will get generated
01:39:02Then, this message will get generated
01:39:04Whereas, in the case of values, you know, in the first case I will get a message that says "Hi." Okay, but when I give the message again, this message "Hi" will also get appended, and it will come as "My name is" in the form of a list
01:39:19Right, so this is basically getting appended over here
01:39:25Right, when I try to stream with the help of mode set to "value." Similarly, when I give another input and execute all the specific nodes, then here you'll be able to see that I'll get another message which will say "Hi, my name is Kish." Right, so this is how it works
01:39:44Executed right here in a specific execution, what is one of the messages that gets appended or displayed, that only I will be able to see it
01:39:54Okay, so that is a basic difference between mode equals update and value
01:39:58But if you still have confusion, we'll try to understand this with an example over here
01:40:02Okay, so now what I'm actually going to do is that, now, you can see over here that I have this, okay, my name is this and all
01:40:12Okay, now what I will do is I will use the stream or stream method, whichever method you specifically want, we can use this
01:40:17Okay, so let's say that I go ahead and create a thread, and this particular thread has a for chunk and GraphBuilder.stream, and I'm giving this message: my name is
01:40:25Krishna, I like cricket
01:40:27I've given this particular configuration, which is nothing but with-thread, and this time I've used stream mode equal to updates
01:40:32Okay, so there are two stream modes: one is updates and one is values
01:40:36Now, with respect to updates, if I just go ahead and print it, okay, see what will be the output that I get
01:40:43Okay, so it shows the current execution AI message, that is what I'm actually getting
01:40:47I did not get the human message
01:40:49See, focus on this: whichever was the last message that came from the AI only—that's the one getting displayed
01:40:55But if I go ahead and execute the same thing, instead of writing mode equals updates, I will write mode equals values
01:41:02If I execute it here, you can see, human..
01:41:04Message
01:41:06Here, you can also see that the human message has been appended twice
01:41:08And if you go forward, your AI message will also be appended here
01:41:12See the AI message, right? So, all the conversation is basically getting updated whatever input you give and whatever output you receive here, specifically the output you're getting, okay? Here, specifically, you're actually getting the output
01:41:25Again, let me repeat this: you'll be able to see that whatever output you get after any node, and if you try to stream it, only that is basically being displayed
01:41:33This is the AI message over here, whereas in the case of mode equals "value," everything is getting displayed—your human message, your AI message, everything
01:41:42Getting displayed, so that is the basic difference between these modes and values
01:41:45Okay
01:41:47So now I hope you get this clear understanding
01:41:49Okay
01:41:51And let's say that I go ahead and add one more message
01:41:56Okay
01:42:01I'll say, hey, um, see, I executed this two times, right? This is the first time, this is my human message, and here also I got the AI message, and everything is basically getting updated
01:42:06Let's say I go ahead and add one more method, or I just go ahead and create one new key
01:42:08Okay
01:42:11So, let's create this
01:42:13Okay
01:42:15And you'll be able to understand this very clearly
01:42:18So here, I will just go ahead and use thread is equal to 4
01:42:19Okay
01:42:21I'll say, hi, hi, my name is Krishna
01:42:22I like cricket
01:42:23Okay
01:42:24Let's start from fresh
01:42:25So here now, mode is..
01:42:26The update is that it is an update
01:42:28Now I will be getting the AI message over here
01:42:30Obviously, since I've used this
01:42:33So, I've got the AI message
01:42:37Now again, I will go ahead and use another message over here and I'll say, "I also like football." Okay
01:42:41Now see what will happen if I make this update to the value
01:42:45Okay
01:42:49Now, if I go ahead and print the chat, I'm getting the human message
01:42:52"My name is Kish
01:42:55I like cricket." So, this is saved in the memory
01:42:58My next prompt will be something related to "I also like football." You can see this
01:43:00Okay
01:43:03So, let this get printed
01:43:06It is still executing
01:43:08So, right now, I got this human message
01:43:10In the next sentence, the previous conversation has also been attached
01:43:14Right? Previous conversation has also been retained
01:43:17Attached
01:43:21And then probably after some time, when this gets executed, you'll be able to see that one more message will get appended, and that is related to the human message
01:43:23See, my name is Kish
01:43:25I like cricket
01:43:26The previous one, along with that, hi Kish, nice to meet you
01:43:32So, you also like cricket? Which team do you support? He's asked the question, and if you go forward here, you can see an AI message, a sports fan, with a diverse effect
01:43:40Now, see, here somewhere, a human message, "I also like football," has been added, and here you got the response
01:43:44So, what it is doing is that it keeps on adding all the conversation inside this, and you're able to stream through that entire information
01:43:53Sometimes, this becomes very useful in use cases where you are
01:43:58Focused on understanding about things and all, right? And if you want some more detailed information and all, now there is one more method which is called the stream method
01:44:08Okay, and for this, you just need to probably go ahead and use it like this
01:44:12See, I'm using another thread ID; let's say the thread ID will be five here
01:44:17We are using the Graph Builder stream events, and here you can use the config version and other information
01:44:24If you just print this particular event, you'll get more detailed information on different things and various events
01:44:29So, there are multiple events present over there
01:44:32Right? So, if you want much more detailed information just for debugging and all, you can do it with respect to every
01:44:39Sentences, you can specifically use this streaming technique, right? So now, guys, we are going to discuss a new topic in LangGraph, which is called Human in the Loop
01:44:50Now, Human in the Loop can also be referred to as human feedback
01:44:54To explain this, let's make sure to take an example
01:44:57Okay, so let's say I have a specific example
01:45:02I'll just go ahead and draw something similar to what we are doing
01:45:09Let's consider that I have a start node, then one more node
01:45:14Let's say this is my LMZip tool, which is my tool node, and finally, this is my end node
01:45:20Okay? Now, here we know that this is the start
01:45:29So, this is the start, and let's continue from there
01:45:33This is my chatbot
01:45:37This chatbot has been bound with multiple tools
01:45:39This is my tool node
01:45:43When I am creating various tools, we have created one tool called Tavi, right? We use Tavi, and let's say, along with Tavi, we will go ahead and create one more custom tool
01:45:53This tool is related to human assistance
01:45:55Human assistance means that whenever I try to give an input, let's say this is my input, when it goes to this chatbot, which is bound with multiple tools—where we have LLMs (Large Language Models) bound with multiple tools—here we have an LLM with tools
01:46:18Based on this input, if it triggers a specific tool call, instead of making a call to the table, it makes a call to human assistance, okay? In response, the human assistance should provide some kind of feedback, and then the chatbot should continue the execution
01:46:42Okay, so this is what we will try to execute, and this feedback can be very much necessary
01:46:47You know, we will take a very good example—let's say if there is some complex workflow, and in that particular workflow, unless and until a human approves, the workflow should not be completed
01:47:02Right? Let's say there are two nodes; one node is executing here
01:47:05We can interrupt with human feedback
01:47:10If the human gives positive feedback, saying yes or continue, it should go ahead with the execution
01:47:18Okay, so let's take this example and show it to you
01:47:20That you get a clear understanding
01:47:22So first of all, I've created a new file
01:47:24Okay
01:47:25Here you can see that this is very simple
01:47:26We are just loading the model, which we have already discussed
01:47:30Here you can see we are using the TAVLY search tool, type Deck Memory Saver, State Graph, Start, Add Messages—these are all about your reducers, tool condition, tool node
01:47:40These are the two new libraries that we are going to specifically use
01:47:45Okay, one is Command and one is Interrupt
01:47:47Interrupt basically means we are interrupting a workflow
01:47:51It is forcefully interrupting so that a human can provide feedback
01:47:54Okay
01:47:57So here is my state
01:47:59Here I have used annotations with List and Add Messages
01:48:02We have initialized the state graph
01:48:04Here we also imported..
01:48:06This is one tool library
01:48:08This tool library is useful because here we will define a function, and that function gets converted to a tool, and this tool can be bound with the LLM
01:48:17So here, we are defining a tool, uh, which is called Human Assistance
01:48:22It takes a string and returns a string
01:48:24Here, you can see the docstring is given: "Request assistance from a human." Human response interrupt query with this
01:48:29So here, we are interrupting with the query
01:48:32Query is equal to query
01:48:36So whatever query we pass over here, that query will get interrupted, and then we are returning human response data
01:48:39So, human response data here, we are returning that information
01:48:44Then, this is my another tool
01:48:46So we are combining those tools in the list
01:48:49We are binding..
01:48:51Then, here is my entire chatbot
01:48:53This chatbot is nothing but an LLM with tools.invoke, and it is returning messages
01:48:57We are creating this chatbot by adding additional conditions along with the tool conditions and all
01:49:02Right? So, if I go ahead and execute it, here we are applying the memory saver, and finally, this is what the graph looks like
01:49:08So, start the chatbot inside the tools; there are two tools: one is TAVLY, and the other is the Human Assistance
01:49:14Okay, interrupt one, right? So, interrupt one—you can also see over here, uh, if you see right, this interrupt will happen in the tool node, because the tools are having that Human Assistance
01:49:28Now, let's go ahead with the first..
01:49:30Question, so the first question over here is that user input says it is giving an input
01:49:34I need some expert guidance for building AI agents
01:49:38Could you request assistance for me? Now, this assistance will play a very important role, right? Because here we are providing a message, and this message is matching to this particular dock string
01:49:51So, when the LLM gets that message, it is going to call this specific tool instead of calling ChatGPT
01:49:55Okay? So, now let's go ahead and see
01:49:58Here, we are creating a thread ID
01:49:59We are giving a user input, which stream mode is equal to values, and everything, and we are executing this
01:50:04Okay? So, here you can see a tool call is made
01:50:06Initially, it went to ChatGPT search, okay, but it is not able to provide you the
01:50:10Answer: Taleby search says that expert guidance for building AI agents
01:50:14Now, based on the result of the tool, I can see that it provides two relevant results, a blog post and a YouTube post
01:50:19So, what it has done is that, for the first time, when we call this particular function, it is calling the Taleby search API
01:50:26So let's call this again
01:50:29Okay, I need some expert guidance and assistance
01:50:31I will change the message now to see what will happen for building AI agents
01:50:38Could you please provide assistance to me? Okay
01:50:41So now we are again executing
01:50:43I need some expert guidance and assistance
01:50:44You can see that the tool call for human assistance has actually been made
01:50:49So this time, when I just change the message over here in the..
01:50:54I need some expert guidance and assistance for building an AI agent
01:50:57You can see that a tool call is basically made
01:51:02Okay
01:51:08Now, with respect to the human, because now it has stopped over there, it is expecting the human to provide some kind of input back, right? So, with respect to this, you can see over here, now, in the human response, we have provided this
01:51:14We, the experts, are here to help you out
01:51:16We recommend you check out LangGraph to build your agent
01:51:18It's much more reliable and extensible than a simple autonomous agent
01:51:23So, this is the message the human is basically giving
01:51:26Now, how do we go ahead and execute this message? We basically use this command
01:51:30You remember, in the top, we used this command, and we are going to put this
01:51:36Rume is equal to the data of human response
01:51:38So, whatever human response we are creating, we are putting in this particular value and telling it to resume the flow of execution
01:51:43Now, when we go ahead and resume it here in graph.stream, we give this particular human command, and automatically you'll see that the execution will happen
01:51:54Now, the human—us, the experts—we get the response, and then here you get the AI message
01:51:58Thank you for the recommendation
01:52:00LangGraph seems like a great tool for building AI agents
01:52:02I'll make sure to keep that in mind to further assist
01:52:05I'd like to ask a follow-up question
01:52:07What specific these things and all
01:52:08Now, what you can do again—now it has again interrupted, right? Uh, sorry, it is not interrupted now
01:52:15It is basically giving you an AI message
01:52:16Please let me know, and I'll do my best to provide your tailored guidance and assistance
01:52:20Now, what you can do is that again, you can go ahead and insert an interruption, and then provide a response
01:52:27So, when you are probably creating an end-to-end chatbot, any number of times, you can provide this kind of human feedback in the lower right
01:52:32I hope you have understood this topic very clearly
01:52:35Hello, guys
01:52:38So, in this video, we are going to discuss how you can build your own MCP servers
01:52:43Along with that, you'll also be seeing how you can integrate any kind of MCP servers that you build with your app
01:52:50Here is a basic diagram; you can see there are three main..
01:52:54Components
01:52:57One is MCP servers, MCP client, and app
01:53:01Whenever I talk about MCP servers, here you can have multiple tools
01:53:03Just imagine that there is another company or third-party companies which are developing this kind of service
01:53:10It can be simple mathematical, you know, calculations; it can be third-party APIs, integrations, or anything
01:53:18It can be specifically written over here
01:53:20Here, with respect to this MCP server, it provides you with context tools and prompts to the client, and similarly, you have something called an MCP client
01:53:30The client maintains a one-to-one connection with the server inside the host app, and finally, you also have an app
01:53:37It can be a cloud desktop or any kind of app that you are specifically..
01:53:42Developing
01:53:48So, uh, in this video, what I am actually going to show you is how we can go ahead and develop this entirely, and how we can also build the MCP server from basics or from scratch
01:53:52Okay
01:53:57So, first of all, what we are basically going to do is that we will be having this, uh, this application
01:54:01Let's say that this is the application that I am currently building
01:54:03Okay
01:54:05Inside this application, we are going to use LangChain or LangGraph
01:54:09Okay
01:54:12The application, uh, we will be having some kind of chatbot application in short
01:54:15Okay
01:54:18Now, this chatbot application may have different, different LLMs integrated
01:54:21So, whenever a user provides any input, okay, so let's say a user provides any input
01:54:28So, based on this particular input, the LLM should be able to make a decision whether it has to make any kind of call from an MCP server
01:54:34Okay
01:54:40And let's say that this MCP server has some of the important tools
01:54:45Let's say we have tools like addition, multiplication—I'm just showing this as an example—and let's say that we also go ahead and create one more tool here, which is just like a weather call API
01:55:01Okay, weather call API
01:55:06Now here you'll be able to see that this is my MCP server itself, and this MCP server is connected to these tools, which are like add, multiply, weather call APIs—anything of that sort
01:55:19So, let's say if I go ahead and ask a question, "Hey, what is the weather in New York or Bangalore?" you know, so the LLM obviously will not be able to answer because..
01:55:28Obviously, LLMs do not have live information, so what this will do is make a tool call, and this time the tool call will be with the help of the MCP protocol
01:55:41Here, internally, there will be a client developed called the MCP client
01:55:44Then, once this communication is made, that specific API or tool—whichever is based on the input—will be called, and you will finally get a response
01:55:57 So, if I talk about how this entire communication basically happens, first of all, when we get the input, the call will go directly to the MCP server
01:56:05The MCP server will provide all the necessary tools along with the information it has regarding that particular tool
01:56:09Then, the LLM will make a..
01:56:13Decision
01:56:16Uh, then the LLM takes this particular input and passes it to the MCP server to get the response
01:56:21So, this is a basic kind of communication that actually happens, and I have already covered it in depth, already in my MCP module itself, right, uh, in my previous videos
01:56:31So, this is how the basic communication basically happens
01:56:37Now, here, what we are going to focus on is that I will show you how you can go ahead and create your MCP server from scratch
01:56:43Okay, here we are going to use one of the most popular libraries, which is called LangChain, and in LangChain, there is a library called LangChain Adapters
01:56:55Okay, so we will be using that
01:56:57Second, I will show you how you can go ahead and create your MCP client
01:57:00And whenever we talk about the MCP protocol or when we discuss communication with the MCP servers, there are different transport protocols that we use
01:57:10Okay, transport protocols that we use
01:57:13Now, some of the transport protocols, um, there are some kinds of arguments which actually help you communicate with any kind of tools itself
01:57:23So, one of the tools that we are going to use is something called HTTP, and the other tool that we are basically going to use is related to the HTTP protocol
01:57:28Okay
01:57:33So, we'll try to understand what the differences between them are, and we'll also try to use them
01:57:38Again, from a coding perspective, I'll show you how this also works
01:57:42Okay, we will be developing our MCP server
01:57:44We'll also be developing our MCP client in this MCP server
01:57:48When I talk with respect to the tools, this tool—one of the tools—we will try to run it with the help of the transport protocol that is HTTP/2, and the other one we will try to use is HTTP
01:57:59Okay? And we'll also talk about the differences—what exactly these both transport mechanisms are, and how they differ, you know
01:58:05So, now let me quickly go ahead and open it, and we are going to start completely from scratch
01:58:12First of all, I am inside my drive
01:58:15Okay? So, this is the MCP demo language chain
01:58:17Here, you can see—I will open my Visual Studio Code
01:58:20I hope everybody has Visual Studio Code now
01:58:22Okay? Now, from this Visual Studio Code, what I am actually going to do is open this particular..
01:58:28Folder location as my project
01:58:33Okay, so here I will go ahead and give this particular path and I will select the folder
01:58:38Okay
01:58:43Now, the first step, when you are specifically using a cursor or whenever you work on any kind of project, it is good to try to create an environment
01:58:48Right now, before creating an environment, I need to initialize this particular workspace as a Virtual Environment, or venv, with the help of the venv package
01:58:55Okay
01:58:58So, if you know about venv, it is quite faster
01:59:01You’ll be able to do the development very quickly with respect to the package management of the entire project itself
01:59:07Right? Any Python project
01:59:09So, let’s say that I am going to go ahead and initialize this workspace with the help of the venv package
01:59:12So, I'll write 'uv' in it
01:59:15This is the first step
01:59:17Now, here you can see, based on this, there are some files that have already been created
01:59:21Okay, and if I talk about all the specific files that we have created over here, one very important thing is that you have to go ahead and see which Python version this entire basic package was created with
01:59:36So, here you can see the Python version is 3.13
01:59:40Here you have this 'pyproject.toml'
01:59:43Right now, the dependencies are empty because we have not installed any dependencies yet
01:59:47But we will go ahead and install them
01:59:49And this is the basic project information
01:59:51Now, to start with any project, I will go ahead and create my virtual environment
01:59:54In order to..
01:59:57Create the virtual environment with the help of venv; it is very simple
02:00:00So I'll go ahead and write `venv venv`
02:00:03Okay
02:00:07Now, here it shows that my venv environment has been created
02:00:10Now, any packages that I install I have to install inside this environment
02:00:12So, first of all, I will go ahead and activate my environment
02:00:15To activate, I will just copy this command and paste it here
02:00:17Okay
02:00:20So now we have activated the environment itself
02:00:22Okay
02:00:24Now, this is done
02:00:26The next step is to go ahead and install some packages
02:00:29Okay
02:00:32Now we will see how to install the packages, but before that, I will just go ahead and create my `requirements.txt`
02:00:33Requirements.txt
02:00:35Okay
02:00:37Now, with respect to `requirements.txt`, I will just go ahead
02:00:41and write which all libraries I will be requiring
02:00:44Okay
02:00:46So two libraries that I specifically want to use, one is LangChain Grok and then you also have something like LangChain adapters, right? So as I said, we are going to go ahead and use some of the libraries that are available with respect to this, that is LangChain adapters, and with the help of LangChain adapters, you will definitely be able to use this MCP properties even in LangChain
02:01:11So here you can see, I’ll write LangChain MCP adapters—sorry, it is MCP adapters—along with this, I’m also going to use one library which is called Fast MCP
02:01:24Fast MCP
02:01:28Okay
02:01:31So here, with respect to Fast MCP, you can actually see what exactly this is
02:01:33Okay
02:01:35So let me just go ahead and search
02:01:38For the Fast MCP again
02:01:41So, if I talk about Fast MCP here, you can see it is the Fast Pythonic
02:01:44It is written in a Pythonic way to build MCP server and client
02:01:46Okay
02:01:49So, we are going to specifically use this
02:01:51This is a very, very easy way of creating MCP tools and all
02:01:56So, I will definitely show you step by step how you can basically use this Fast MCP library and develop your entire MCP server from scratch
02:02:00Okay
02:02:04Step by step, we will go ahead and implement it
02:02:08Now, quickly, here we are going to create three more important files
02:02:12Okay
02:02:14Now, what all files need to be created based on this—that is what I am going to discuss and understand based on the use cases, right? I have already told you that I am going to use one MCP server
02:02:27which has this, add multiplication, and we'll use the transport as Studio
02:02:31We will create another MCP server that will communicate with this tool, called the Weather Call API, and it will use this HTTP tool, right? Transport mechanism
02:02:40Okay, transport mechanical mechanism
02:02:43Basically, it means the communication between the client and the MCP server and how it is going to happen
02:02:48Okay
02:02:53So, what we are basically going to do is that over here, I will just go ahead and write all my packages that are specifically required
02:02:57Okay
02:03:00And along with this, I will also go ahead and import MCP
02:03:03Okay
02:03:06So, this MCP will actually help us to use the package Fast MCP itself
02:03:08Okay
02:03:10Now, here is my requirements.txt
02:03:12The next step..
02:03:14Is that how I go ahead and install all these particular libraries? It is very simple
02:03:16I will go ahead and write `uvicorn --reload --requirement requirements.txt`, like how we used to write `pip install -r requirements.txt`
02:03:24Similarly, we'll go ahead and do this
02:03:27Okay
02:03:30So now I'm going to go ahead and clear the screen and just confirm whether all the installations have happened or not
02:03:34So here, you can basically go ahead and check all the installations in respect to this
02:03:36Okay
02:03:38Uh, till here, everything looks good
02:03:40Our installation has happened perfectly, and we have already installed all the packages that are required
02:03:47Okay
02:03:48Now, let me just go ahead and create some important tools with respect to the MCP server
02:03:55So first..
02:04:01The tool that I'm actually going to create is nothing but a math server
02:04:04Okay, so math_server.py
02:04:06So this is just like my MCP server, and here we are going to define some of the tools that we are basically going to use
02:04:09Okay
02:04:11So quickly, in order to use this, as I said, I'm going to use FastAPI with MCP
02:04:14So I'll write from MCP.server.fastapi, I'm going to go ahead and import FastAPI
02:04:20Okay
02:04:26And once we do this, the next step is that we need to initialize this MCP, right? So I'll go ahead and write MCP is equal to FastAPI()
02:04:32And I will give my tool name, which is nothing but math
02:04:35Okay
02:04:37So I'll give my tool name, which is nothing but math
02:04:41Okay
02:04:45Now, inside this tool, uh, sorry, inside the server, uh, this is just a server name, okay, not a tool name, because Math is just a basic server name over here
02:04:49Then the next step is that I will just go ahead and write, add the rate MCP
02:04:53And this is how we go ahead and create our first tool, which is present inside this MCP server
02:05:00So I'll create a definition, I'll write add
02:05:01I'm just starting with a basic example so that, as we say, right? You want to go ahead and write, create any kind of tool, but it is important that you understand the basic stuff, right? So then, my second parameter will be equal to int, and this I'm going to give a return in the form of an integer here
02:05:19I'm going to probably provide some docstring, and based on this docstring, the LLM will be able to understand which tool to specifically call
02:05:29So here I will write add
02:05:31Two numbers, okay, and then we're going to go ahead and return a + b
02:05:35Okay
02:05:38The next tool is nothing but an MCP tool
02:05:41And here, we're going to go ahead and define multiply as a colon int, b colon int
02:05:50Again, you can go ahead and define any number of tools as you want
02:05:55So this will return an int type
02:06:00And here, I'll just go ahead and write "Multiply two numbers." Okay
02:06:04Some information that I'm specifically giving, and I'll go ahead and write "Return a multiplied by b." Okay
02:06:13Now, the thing is that I am planning to create this MCP server with respect to addition, multiplication, or any kind of tool on the Transport Hddio
02:06:24Now, we need to understand what this Hddio transport basically means
02:06:31Okay
02:06:38And what you will be Able to do from it, uh, and it is important that we get a clear understanding about that because, uh, many people have seen that they try to write this particular code but they fail to explain this
02:06:43Okay
02:06:47Um, what does mcp.tr run mean? So, let's say that I want to run this particular file
02:06:52How do I go ahead and run this? First of all, I'll go ahead and write the code
02:06:55So, quickly, I will write mcp.run
02:06:57So, here what I'm actually going to do, I'll just say if __name__ == "__main__" and here I will just go ahead and write mcp.trun, and we're going to run this entire application of MCP using the transport
02:07:16Transport double equal to stdin IO
02:07:20Okay
02:07:24Now, here we have used a transport called stdin IO
02:07:28Now, we need to understand what this transport
02:07:31And for this, I will just go ahead and put some basic information so that you should be able to read it within the material itself
02:07:35Okay
02:07:39So here I will write two important comments
02:07:43The transport is equal to H stdio
02:07:47And here, one more sentence
02:07:50Okay, it tells the server to use standard input and output to receive and respond to the tool functional calls
02:07:57Now, see what this is—right—when we say input and output, right, the standard input and output
02:08:02Now, standard input and output are like, let's say, if this is a server, if it is running, this will specifically run in some kind of command prompt
02:08:10Let's say, in one of the scenarios, what we can do is that if I have a client and I want that client to interact with this particular server, then what we'll If we have written this, and the transport is equal to stdio, we will run this particular file directly in the command prompt and get the input and output there itself
02:08:29Let's say I want to give an input; that input should go with respect to the command line itself
02:08:35Hit any function and get the response out there, and the client should be able to read the information directly from the HTTP I/O, which basically means from the command prompt itself
02:08:46Right? So this kind of setup is very helpful if you really want to test things locally
02:08:52You have your server executed locally, and you want to go ahead and test it with the client
02:08:58Right? So at that point, you can use HTTP I/O
02:09:00Okay
02:09:01So this is..
02:09:03The basic functionality with respect to this
02:09:04So, this is one of the servers that we have basically created
02:09:07The other server that I am really interested in creating is about, let's say, there may be a third-party API call
02:09:15You know, that API call can be with respect to weather or anything else, just to show it to you
02:09:21I will quickly go ahead and create a weather.py file
02:09:23Okay? Now, weather.py file, see? Now, at the end of the day, I will also talk about how you probably take it to production and what exactly goes into production
02:09:36So, I will not show you directly by executing this in the cloud, but I will give you a brief idea of how things work over here
02:09:43Right? So, here I will go ahead and write `from MCP.Server import MCP`
02:09:47import fastapi
02:09:49Okay
02:09:52And then I'm going to go ahead and write MCP = fastapi
02:09:54Okay
02:09:56And this time, this particular server name will be my weather
02:09:58Okay
02:10:00Now here, I'm going to go ahead and create my MCP tool
02:10:04Okay
02:10:09Now, in a real-world scenario, if I talk about that, this is my MCP server and I want to probably take an input and give the weather of a specific location
02:10:13That is the code that I'm going to write over here
02:10:15Okay
02:10:17But for right now, I'll just go ahead and define something
02:10:19So I'll go ahead and write, "Hey, this is my get weather functionality," and let's say this is my location
02:10:22Okay
02:10:25This is my location
02:10:27This is my str, and this will basically return a str
02:10:30Okay
02:10:33And then what I will do, I will go ahead and write my docstring
02:10:35Get Let's get the weather location
02:10:39Okay, weather location
02:10:43Now, this can be any code
02:10:47This can be code that interacts with some third-party API to get the weather
02:10:52Right? For now, I'll just return a constant value
02:10:55So, let's say here I'll write that it's always rainy
02:11:01It's always raining in California
02:11:04Let's go ahead and write this message
02:11:09Okay, it may not be true weather, but I just want to give you an idea
02:11:13Let's say that this is the output of my API that I'm getting here
02:11:17You can write any code related to interacting with APIs
02:11:19Then I will go ahead and write 'if __name__ == "__main__":'
02:11:23So, here, my program execution will basically start
02:11:32This should be Okay, now what I will do is quickly write `mcbp.tr run`, and this time I'm going to use another transport
02:11:39See, whenever I want something, the previous transport mechanism that we specifically used was nothing but HDIO
02:11:47I've told you the importance of it
02:11:52In this case, we are going to use Streaming HTTP, right? HTTP
02:11:57Now you need to understand what this exactly means
02:12:00Okay, so guys, now let's understand what this Streaming HTTP transport will do
02:12:04Now, in order to make you understand what exactly the function is, I will just go ahead and open my terminal
02:12:16Now, inside my terminal, what I will do? I will just go ahead and run this: `python weather.py`
02:12:19Let's run this
02:12:22Okay
02:12:24Now, here you can see that this entire application, this entire server, is running on this particular URL
02:12:28Okay
02:12:32When we use streamable HTTP transport, what it is going to do is that it will run as an API service itself
02:12:35Okay
02:12:39Similarly, if I go ahead and run this Math server right in HDDIO, it will not run like that
02:12:42See here, it will not run like that
02:12:44Instead, it will not run using any HTTP protocol, but instead, it uses standard input and output
02:12:51Okay
02:12:57So, if I just go ahead and execute this Python Math server.py here, you can see that nothing is happening, right? So, that basically means internally, as in the command prompt, it is getting executed
02:13:03Okay? But if I see in this particular use..
02:13:05When we are using weather.py with the help of Transport, it is equal to Streamable HTTP
02:13:12Here, you can see that it is working; it is running in the form of an API with this particular URL
02:13:16So, after setting up this Transport, you can also go ahead and set up your URL and all
02:13:20And with respect to that, you can also set up the port
02:13:22Okay
02:13:25But right now, we are not running this; we are running this as an HTTP
02:13:27Right
02:13:29So, by default, you'll be able to see it is using my localhost, and the default port is 8000
02:13:32Now, the question arises: Chris, fine, you told me the differences between Streamable HTTP and, obviously, HTTP where my Transport was HTTP
02:13:42Right? So, here I have used HTTP, right? So, you have told the differences between this, but how do we..
02:13:47Go ahead and integrate it from the client
02:13:49So, here what I will do, I'll go ahead and write client.py
02:13:52See, I have created two servers, one is the math server and one is the weather server
02:13:57Now it's time to go ahead and write our client.py file, so let this get everything running
02:14:02Now, I'm going to focus on understanding how to write the client.py
02:14:08At the end of the day, this client.py should be able to interact with math_server.py and weather.py
02:14:12For this, I'll be using from langchain_mcp.adapters import client
02:14:19So, we first need to go ahead and create a client, and this client should conform to the documentation provided by LangGraph
02:14:26It should be a multi-server MCP client
02:14:28Okay, that basically means it supports multiserver itself
02:14:33Then, in LangGraph, whenever I want to call any of this particular client, we need to create an agent
02:14:41That agent will be responsible for integrating all these models, including LLM models or tools
02:14:45Tools basically mean all these MCP tools and so on
02:14:49For this, we will be using pre-built components from LangGraph
02:14:53So, from LangGraph.prebuilt
02:14:56First of all, I will go ahead and quickly add LangGraph because I require it
02:15:00Okay, so here I'll open my command prompt, another command prompt, and I'll type `pip install -r requirements.txt`
02:15:08Okay, this is perfect
02:15:15After that, you'll be able to see that if I just go back to my client.py, I will be able to import..
02:15:22It, so from langchain.prebuilt, create react agent
02:15:26So, for creating an agent—uh, so that based on the input, the agent and the LLM will be able to act as an agent itself
02:15:32And, uh, you know, in my previous videos, I have all discussed about this
02:15:37If you're following the series of videos that we have developed, then from langchain.chat_models, import ChatOpenAI
02:15:44So, I'm going to go ahead and use ChatOpenAI as well
02:15:48And then, from langchain.openai, we will not be using that
02:15:55So, from langchain.core, I'm also going to go ahead and use, or let's say, for now, I will just go ahead and use this: from env import load_dot_env
02:16:06Then, I'll go ahead and initialize this by calling load_dot_env()
02:16:13And I will also import asyncio right now
02:16:16The next thing is that I definitely..
02:16:20Require my env file, so quickly let me go ahead and create my .env file
02:16:25This is just for my LLM model, right? So I'll write the GROB API key since I'm going to use the GROB API key
02:16:29Now, I hope everybody, if you're following all the tutorials that I have created till now, you should know how to create a GROB API key, right? So here is my GROB API key
02:16:40I'll go back to my client, and inside this particular client, I'll start going and writing my content, sorry, my code
02:16:47Now, what I'm going to do is go ahead and write a sync definition main
02:16:51And here, we are basically going to go ahead and create our client
02:16:56This client that we are going to create will be my multi-server HTTP client, sorry, MCP client
02:17:00And here, I will give the client key-value pairs
02:17:05The first client that I want to create is the server that I want to set up
02:17:10This client will be able to interact with this MCP server
02:17:14So, it will be my math server
02:17:16In the math server, let's say the command that I want to use to execute my math server will be nothing but Python, because you can use Python or UV
02:17:21It is up to you
02:17:25Okay, Python
02:17:29And then the next parameter that we give is 'argument'
02:17:33Okay, let's see
02:17:36There are a lot of suggestions that come in here
02:17:40So, 'arguments'
02:17:45So, inside 'arguments', I will give another parameter, and that parameter will be nothing but my filename
02:17:50So, here I'm going to go ahead and write 'maths_server.py'
02:17:52Please make sure to give the correct location
02:17:54So, here, since..
02:17:56This is my current working directory
02:17:57I'm directly giving the name of the file
02:17:59If it is inside any folder, I have to give the entire absolute path
02:18:03Okay
02:18:08So once this is done—sorry, not the relative path, the absolute path—here, I'll go ahead and write the comment to ensure the correct absolute path
02:18:13Okay
02:18:17Then, my next parameter here is nothing but my transport protocol, sorry, my transport metrics that we really want to specify
02:18:22So, here, based on the transport we have used, which transport will be used? It is nothing but stdio
02:18:25Okay
02:18:28So, here, I will go ahead and write stdio
02:18:32Okay
02:18:35So, this actually completes all our parameters with respect to the maths
02:18:39Now, similarly, I will go ahead and add my another tool
02:18:41So, this is my maths tool
02:18:43Over here
02:18:45Okay, I'll go ahead and write it like this
02:18:48Now, coming to the next tool, it is nothing but my weather tool
02:18:49So, if you see my weather tool, it'll be something like this: Weather localhost 8000 / MCP — ensure the server is running here
02:18:57So, if you see over here, my server is running where it is running on this localhost
02:19:02And when I do /mcp, that basically means it will be able to get all the MCP servers that it is running — all, sorry, this particular weather server is specifically running on this URL
02:19:14So, here obviously, my localhost is there, but if you see /mcp, this is where we will be able to find the entire MCP server running
02:19:22Okay, so this will be my URL over here
02:19:24Right, so now, till here, it is really, really good and easy
02:19:27Here we have just created our multiserver client
02:19:31Now, remember, this client is what will be interacting with these particular servers
02:19:35Right? So now I will go ahead and quickly write `import os`, and then I will set up my environment
02:19:42So, for the OS environment, it will be nothing but `os.getenv` for my API key
02:19:52Okay, then I’ll go ahead and write my tools
02:19:59It will be `await`, first of all, in order to get the tools, I can use `client.get_tools`
02:20:04Okay, now see, this client is nothing but this client here, and when I write `.get_tools`, I will be getting the information of both these tools, like math and weather
02:20:15Right? Then I will go ahead and initialize my model
02:20:17My model is equal to..
02:20:19ChatGPT, and I'm going to go ahead and use a model name, which is nothing but GPT-3.2 billion parameters
02:20:28Okay, then, I will go ahead and create my agent, and this agent will be a Create React App
02:20:33And here, I'm going to go ahead and write model, tools, right? So, these are the two important parameters that we need to give in order to make the agent
02:20:44Now, I can use this agent and directly call invoke with respect to any messages that we specifically give
02:20:52So, let's say I just go ahead and execute this math response
02:20:57So, here you can see I'm just executing this
02:21:01Just a second
02:21:04So, import OS
02:21:06This is done
02:21:08Uh, okay
02:21:10Now, math_response = await agent.invoke
02:21:13I'm giving the messages equal to the user content
02:21:18I've just written, "What is 3 * 5 * 2?" Okay, 3 + 5 * 2, and here I should be able to print my response
02:21:25Print my response
02:21:27So here, in order to print my response, I will write, "hey, maths response:" colon
02:21:33Okay, math response is equal to, I'll just go ahead and give this, and then I'll write, "math_response." I will take the messages key, take the last message that is available out there, and I will go ahead and read the content
02:21:52Okay, "dot content" will give the output of the math response
02:21:55Okay, now since this main function is async, in order to run this, we are basically going to use "asyncio.run." Okay, and here we are going to call the main function
02:22:09Okay, so whenever we use "asyncio," or whenever we define any method that is async, we have to go ahead and run this with this particular method
02:22:18We have imported the library here
02:22:20Okay, so now we're just trying to get the math response
02:22:23Okay, now let's go ahead and execute this
02:22:26I will open my command prompt
02:22:28Now, very important to understand: when I'm calling this agent, right, it is invoking which tool? Based on this particular message, it will invoke that tool
02:22:37And you know, in this tool, the transport is H stdio, which basically means this tool is going to run in the normal standard input/output device, that is, the command line
02:22:48So, the input will go directly over there and get the output from there
02:22:51Okay, so here, in order to execute this, if I go ahead and write `python client.py`, now you should be able to..
02:22:55See, I'll cancel this
02:22:59You should be able to see what the output will be for this
02:23:01What's 3 + 5 * 12? Okay
02:23:04So this is my input
02:23:06Now you should be able to see what the result will be
02:23:08Here's a step-by-step breakdown: addition, 3 + 5 is equal to 8; multiplication, 8 * 12 is equal to 96
02:23:13The math response is nothing but the result of 3 + 5 * 12, which is 96
02:23:18So, 8 * 12, it is nothing but 96
02:23:20This is absolutely perfect
02:23:23Okay
02:23:25So here, you can quickly see how we are able to call our MCP, which is our Math Computing Protocol, server, and that is nothing but our math server, which is running in this environment right now
02:23:39The other thing is, if I also want to check the weather, for the weather server, again, I will go ahead and write something like this
02:23:41See, I'll give a question
02:23:44Quickly, and it will be the same thing
02:23:47See, weather response, await agent.invoke, invoke content
02:23:53What is the weather in NYC or California? Right now, in California, this will take this particular message, but right now I have hardcoded the output
02:24:03It always rains in California
02:24:10We have written it like this, so my weather response should probably be the same as what we are getting directly from weather.py
02:24:16Okay, so I will go ahead and run this once
02:24:18And before running this, I will also go ahead and print the output
02:24:25Okay, so this is my weather response
02:24:27Yeah, it is printed
02:24:29So now, if I just go ahead and execute this again, python client.py
02:24:33First of all, I should be getting my math
02:24:35Response
02:24:37And the second thing is that I should be getting my weather response
02:24:39Okay, so quickly let's see this
02:24:41And this is how you are basically communicating from one client to multiple servers itself
02:24:46Right? So it is taking some amount of time
02:24:48Okay
02:24:51See, sometimes this kind of error will come
02:24:54You just need to go ahead and restart it
02:24:56Okay
02:24:58But now it will not, this kind of error will not come
02:25:00Okay
02:25:02So now you'll be able to see that it will do the execution
02:25:05So here you can see the result of 3 + 5, weather response
02:25:07The tool indicated it is always raining in California, but in reality, California has a diverse climate
02:25:13So, LLM is also able to add some information, which is good
02:25:17But here now the The tool is basically returning this
02:25:19Okay, so that is the reason
02:25:22Again, it depends on what kind of API functionality you're implementing
02:25:25The best part is that this is running in a streamable HTTP, so it's running in the form of a URL
02:25:31You can just see that, and we are integrating that into client.py
02:25:33This is the URL we are getting with /mcb, and all these things are with the help of the LangChain adapter
02:25:42Right? So I hope you are able to understand this particular example
02:25:45Now, what you can do is close all the servers where you're running your applications, but these are some servers that are independently running, and you're integrating them into a single client
02:25:51Okay
02:25:57These were two ways of calling: one is HDIO transport and streamable HTTP transport
02:26:03So here, we have created a client
02:26:06In short, what all did we do? We created a client, and this client was able to communicate with two MCP servers
02:26:10Okay
02:26:13So, this communication was basically happening with these MCP servers
02:26:17These MCP servers are essentially communicating with your transport layer, which is either HDIO or HTTP transport
02:26:24And here, see, this entire setup is based on the MCP protocol itself
02:26:39So, we had that MCP server-client setup
02:26:42In this, you had some tools like addition, subtraction, and whatever other tools you want to create
02:26:48And this was like a weather API, right? The main thing is that when you're running this tool, you are basically communicating with respect to the response from the HTTPIo itself
02:26:59That basically means from the command prompt here, we were using some kind of URL, right? So, that is the reason we use HTTP
02:27:05I hope you understood this particular video
02:27:10I hope you understood the coding mechanism that we specifically did, how we implemented each and every step
02:27:16That was it from my side
02:27:17I hope you liked this particular video
02:27:19I'll see you in the next video
02:27:20Thank you.