AI Agents for Business: Build Multi-Agent Systems with LLMs | Jeiwin Bhamangol | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

AI Agents for Business: Build Multi-Agent Systems with LLMs

teacher avatar Jeiwin Bhamangol, Creative Artist

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Getting Started with AI Agents

      1:25

    • 2.

      What is AI Model?

      8:22

    • 3.

      What is Generative AI Model

      5:56

    • 4.

      Setup Environment & LLM Keys

      4:20

    • 5.

      Building First Agent

      6:01

    • 6.

      Multi-Agent Orchestration

      7:57

    • 7.

      Sequential Agents

      7:40

    • 8.

      Parallel Agents

      7:52

    • 9.

      Loop Agents

      6:43

    • 10.

      Agent Patterns Overview

      3:39

    • 11.

      Advance Tools for Agents

      12:00

    • 12.

      Building Reliable Agents

      8:48

    • 13.

      Agent Tools vs Sub Agents

      6:14

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

16

Students

--

Projects

About This Class

Welcome to AI Agents for Business: Build Multi-Agent Systems with LLMs — a hands-on course designed to help you build powerful AI agents from scratch.

If you’ve been using prompts and want to go beyond that, this course will teach you how to create AI agents that can think, act, and collaborate to solve real-world problems.

You’ll learn how to design and build AI agents using LLMs, and take it further by creating multi-agent systems using patterns like sequential workflows, parallel execution, and loop-based reasoning.

Whether you’re aiming to create a simple AI Agent or a real-world AI Agent, this course provides all the necessary code and templates to get you started!

Throughout the course, you will:

  • Build your first AI agent from prompt to execution
  • Understand how agents plan, reason, and take actions
  • Create multi-agent systems for real-world workflows
  • Apply these concepts to business automation use cases

This course focuses on practical, hands-on learning, so you won’t just learn concepts—you’ll build working systems step-by-step.

By the End of This Class

You’ll be able to build AI agents and multi-agent systems from scratch and apply them to real-world business problems.

Meet Your Teacher

Teacher Profile Image

Jeiwin Bhamangol

Creative Artist

Teacher

Hello, I'm Jeiwin.

See full profile

Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Getting Started with AI Agents: Welcome everyone to this class, which is AA agents for Business process. Before we jump into the first session, I brief about myself. My name is Javin and I have been working with Fortune 500 companies, specifically in the technology and the media space. Now, with that experience, I have curated course which can help you to build agents for your own business to solve the problems or to increase the efficiency. Now, what are the skills that you'll be learning in this session? So you'll be learning right from the fundamentals of what is an lem, what is an agent, how do you build a single agent, and then going towards the intermediate of how do you build multiple agents together? Coming to the advanced part, which is, how do you build multiple agents and make them communicate with each other to solve a business problem? Also, how do you delegate your task to different agents and solve the business problem? Now, having said that, we'll also see how do you actually build an enterprise grade agentic system using different architectural patterns. So you'll be able to walk away with the ability to design and build production grade A agents that are practical, skiable and industry ready. So let's go and I'll see you in the first class. 2. What is AI Model?: All right, welcome back. Now, let's start by understanding what is an AI model. Now, here is a question for you. What do you think is an AI model? Do you think it is an algorithm wherein we have written multiple conditional statements in the files? If your answer to that is yes, most probably your understanding about an AI model is inaccurate. Now, let me ask you another question. Now, I am on Chat GPT, and if I ask this question, what is the capital of USA, what do you think? The answer is, which is the correct one, that the capital of USA is Washington, do you think this answer is being retrieved from any database? Do you think this is coming from any database is Open EI or GPT storing the answer to each question that you might ask? No, right? Then how would this answer generated? Now, let's go back and understand what is an AI model. So think of AI model as a newborn child. So as a newborn child, he's unaware about all the things that are happening in his environment. So what do we do? We teach our child different things. For example, if your child knows what a dog looks like, but he's unaware about the characteristics of a cat or how a cat would look like. And if you try to ask your child by showing him an image of a cat and asking him, What is this. Most probably you'll get an answer that I don't know. Or he might also say that this is a funny looking dog. Right? So what do we do? We show multiple images to him, multiple images of cat so that his brain will be trained. The weights and the biases that he have will be trained, and then it will be stored. Now, what would happen is, again, if you show an image of a cat, this time you show a different image of a cat, this time the child will be able to answer the question straightforward. The reason being, you have showed him you have trained the mind. You have helped him in understanding what are the characteristics, what are the dimensions of a cat would look like? And if you even show a different colored cat, he will be still able to understand what a cat would look like and identify it, right? So similar to that, in the space of computer science, we have something known as machine learning model or a deep learning model. So predominantly, those are artificial neural networks, ANN or CNN. So similar to a child, here we have a model, which is a computer model which ANN or a CNN. And if you try to show him a picture of a cat, most probably he would throw an error. Why? Because the weights and the biases that he have does not recognize the image as a cat, right? So what do we do? We again feed in multiple amounts of data and we retrain the model. Retraining means changing the weights and the biases. Now let me do one thing. Let me actually show you what a neural network looks. Okay. So this is a neural network. The neural network, think of it as a similar to what our brain would have. So a neural network would have multiple neurons. So all these circles that you can see is a neuron. So in a neural network, we have an input layer which takes the input given by us. Then we have multiple hidden layers. Now, hidden layers, the purpose of it is to understand the input and also predict what it might be and then give the output, right? So these lines that you say or as these neurons are connected to each other neuron in each layers, there are weights and there are biases. When you try to train the model by feeding in multiple images, what we are essentially doing is we are using a mathematical equation to change the weights and the biases of the each neuron. Now, once that is completed, we freeze the neuron, and then we can say that now the model has the capability to understand the difference between a cat and a dog. So this is on a high level, but a few things to note are the neurons, the weights, and the biases. Now, you would ask me a question. If chat repeat when I ask a chat repeat, what is the capital of USA, it is not retrieving from any database, then where is the data stored? Now the data is stored as a weights. So when we say we are training, predominantly we are computing the weights and the biases. So all the data that is being stored is the weights. So each neuron has small amount of weights. Now, you might ask me another question if it is storing, Is it storing in a question and answer format? Do you think that would be the case? The answer is no. And we will see how it is storing in what format and how this computation takes place in the future sessions. But let's now understand that this is an artificial neuron network which has weights and biases. We feed in the input data. We have multiple hidden layers which will compute the thing using the weights and the biases, and it will give us an output. Now, let's go back to the slide. Similar to this is how it would be. Once you train the model with enough information about the thing, then it would be able to answer or predict the question with the right answer correctly. Right? So model is nothing but a composition of huge mathematical equation whose parameters or weights change as we train in, right? So if I show a picture if I show the data of lion, then again, the weights and the biases has to be pre trained, right? If I show a different data, again, the model has to be trained upon that. Now, there are multiple different neural networks. And each neural network has its own advantage and disadvantages, and what it is able to solve. For example, anything that has to be taken care similar to image classification. For example, whether it is a cat or a dog, whether it is a fraud or not a fraud, right? So CNN takes care of those things. For example, the object detection, image classification. In COVID, you can see that if you don't wear a mask, it would red flag you, right? That was done using CNN. Then we have RNN, which is most probably used for language models, speech recognition and time series predictions, right? Now, out of these all different things, there are a few architecture which are predominantly used, and those are auto encoder, transformer, but and diffusion models. Now, the architecture that is powering the GPT models is that transformer architecture. The architecture that is powering the image modeling. So you might have seen that people are showcasing AI generated videos, AI generated images, right? The diffusion model is the architecture that is being used to create those kind of AI models. And also, transformer is also predominantly used, but we will be seeing in depth of what this each architecture is about. We'll be going in depth of it. So I think you have got a gist of what an AI model is. AI model is nothing but a huge amount of neural networks. Which have weights and biases, and based on the input data, it will compute what it is about. For example, if you give in multiple images of cat, it might be able to understand, okay, you have multiple images of cat and then it might answer whether it is a cat or a dog. That is an EI model. 3. What is Generative AI Model: Come back. Now, we are going to learn about what generative AI. In the previous session, we have seen what an AA model is, and based on the image that we pass on that the model is able to predict whether it is the given images of a cat or a dog, right? Now, if you think in terms of outcomes, the model is only able to predict whether it is a cat or not. So the answer is binary, yes or or no, right? So that is an AI model. But when we come to a generative AI, generative AI models, based on the input that we give, the model will actually go and generate new content. It can be text, it can be image, and it can be audio. Now, let me demonstrate. I'm using hat GPT, and let me ask this question. Explain generative AI in a single line. Okay. So it gives me an answer that generative VA is a type of artificial intelligence that creates new content like text, images or music based on patterns learned from existing data. Now one thing to understand from this is the patterns learned from existing data. Remember in the previous session, we actually have shown multiple images of a cat, like 1,000 images of cat in order for that model to understand the difference between a cat and a dog, right? So let's broaden our horizon and now let's train the entire model on the entire data that is available on the Internet. Just think of. If you're able to predict whether it is a cat or a dog based on just showing you training the model on, let's say, 5,000 images, what would be the capability of that model if you train it on the entire data that is available on the Internet? Think of it, right? So let me try to give the same question again. Can you see the difference? I'm giving the same input, but it is giving me a different answer, even though the intent of that answer is one and the same. So generative A is an A that produces new content by learning patterns from existing data. Now, let me try to do it once more. Right? So it's an Adi intelligence that creates original content from the wn patterns. So did you see a pattern? Every time I give the same input, the model is giving me answer in a different format, but the intent of that answer is same. So this is what happens under the hood, as what we have seen, right, the weights and the biases. Now, every time I give the input, the weights and biases and the mathematical equation that performs the entire computation is probabilistic. Now, when I say probabilistic, it would change. Not necessarily all neurons would be triggered for the same question, right? So hence, we get a different variety of answer back altogether. So similar to this, Generative AI is a model wherein based on the input given, it will go and generate a new answer. It won't go and fetch the data from any database or a thing. Now, think of it. If it was fetching from a database, for the same input that I give, I should get the same output, right? The reason why it is not happening is because it is generating it by itself. It is not fetching anything from the database. Now, what are the different generative AI applications that are available out there? I'm sure most of you would have used so generative A models create new content like text, images, or code based on the learned patterns from existing data. Now, popular A application that we use day to day. And let's see what is the underlying model that they are using. And what is the category of that is it? So Gemini, GPT, we are all familiar with CloudA as well. So it uses transformer architecture and GPT 4.1 GPT 40, 3.5 Gemini 2.5 P flash Gemini three, right? And so on it has their own models. But they are all in terms of text generation and multimodel, right? Multimodel as in the model has the ability to understand images, text, audio, and language. Similar to that, we also have diffusion, stable diffusion, which says an application which uses diffusion model. So remember the architecture that we saw right? So transformers and the diffusion models, so diffusion models predominantly used for, you know, generating new images and videos. So similar to that, we have a diffusion, stable diffusion as in company who has f trained their model on multiple images so that they are able to generate images. Similar to that is Bit Journey, runway three. And there are a few more which are able to generate video as well. For example, they're using diffusion plus transformer architecture in order to generate video. We have popular website, which is Snot TI, which is pretty cool altogether. You should try it, which generates music based on input given in natural language. We have whisper speech to text. So whatever I'm talking right now, it will take that as an input as an audio file and it will convert it into a text. Then we have multiple other things which are into scientific generation. So scientific here, Deep Mind is from Google, and they're using. They have created an arc model which is able to help scientists in the development of new proteins, right? And similar to that, we have others. So that's it for this session, and we will see what is under the hood of an LLM and how it is 4. Setup Environment & LLM Keys: Welcome back, everyone. Let's go ahead and create an environment that we are going to use in order to understand or explore the components of ADK and its features. Going forward, we are also going to use VS code in order to develop an enterprise grade, multi agent a. Now, the most important part once you open your Google Colab is to make sure that you click on this reconnect button, which will connect instance running in the Google server. Second part is to get an environment where you can store Gemini APAKys, right? Similar to how we have in a development area which we do in VS code as dot ENV. If you have your APIKey created, you can directly click on Add New Secret and you can page those. If you don't have it, you can also go ahead and create new APAKes. You can go ahead and create APAKys with the help of Google AS studio. Now, let's go ahead and create an APIKey. Let's name the key as agent. Let's select any project, or you can go with the default project settings. Which will create the API key for us. Now, let's go ahead and copy this APAkey and add it to our environment variables, which is nothing but secrets in Google Colab. Now you can give a key which is Gemini and its value is the key that we have copied. Now, make sure that you can enable this so that your code can access this key. Now let's close this. Now, once we have the LLM API set, the second part is to install the libraries. Now the most important library is the Google ADK. Let's go ahead and run that. Now, it will go ahead and install all the libraries required. Now, you can see that as the ADK is developed by Google and the Colab is also from the Google itself, it already has the installed ADK into it. Now, let's go ahead and check the version of which AD Google ADK library we are using. So it is 1.20. So make sure that anytime that you go ahead and input any library, make sure that the version that you're using is 1.2 0.0 in order to follow along with me. In future, if I go and change any version of any library, I will mention those changes in the requirement dot TxD. Now, let's go ahead and add a few more configurations. Now, let me explain why we are adding this. So we are going to add Cloudfare tunnel, and the reason is that we will be required in order to access the ADK web. And I will explain why we are required to do this only in Google Colab. If we are going to do this setup in the VS code, we are not required to install these libraries. Now, that's it for the installation step. The main things were creating an API key and installing the library. Now, you have set up your APA keys in the secret. But how do you actually go ahead and use those keys inside your code? So this is the piece of code, which will actually go ahead and fetch the keys from the Google Colab. And remember we have set up a key which named Gemini. So it will go ahead and check if the user data has anything related to a name such as Gemini, that is a Google API key. And then we are going to go ahead and set up it in the environment. All right, so we have the Gemini API key setup done. So that's it for the setup that we are going to use in order to explore the Google ADK feature. 5. Building First Agent: All right, welcome back. So once you open your Google Colab, make sure that you first go ahead and reconnect and you have the LLM key setup. All right, we have connected to the server. Now, let's go ahead and execute these cells. So I'll collapse this. Once that is done, we execute the remaining cells as well. Now what we can see is to understand how we are going to build our first agent. Now to do so, we have to import few components from the ADK. Now, I'm importing agent. I'm importing Gemini as we are going to use Gemini keys. I'm going to import in memory runner, Googled search as a tool and types for the validation part. Now, as we are working with LLMs, right, we might encounter rate limit errors or a temporary service on availability error. Now, in order to automatically handle these failures by retrying the request, we are going to set up this configuration, which is the retry configuration, where we set the number of atoms we want to retry again, the delay and the ATTP status code. Now, these are the codes. If we get any of this code, we will go ahead and retry for the maximum retry atoms set, which is five. Let's go ahead and run this. Let's go ahead and see what is the difference between a normal API call and an agent. What makes it different? So you might have used Gemini or any chatbots like GPT, right? When you give a prompt, it will go to an LLM, and then it will give the text back. But when it comes to an A agent, it will take it one step further wherein when the user gives a prompt, it will go to an agent. The agent will think about the input. What is the output that the user is expecting? Based on that, it will create a detailed execution plan and perform actions in order to reach the goal. Now the output from these actions is again fed to the LLM, where it will understand and observe whether the output is according to what the user's expectations. If it is, then it will be sent back to the user as a final answer. Now let's understand how we are going to leverage the Google ADK library and build agent. Now, to build any agent, there are few main properties that are required initialize any agent. Now these main properties are name, description, instruction, and a tool. Now let's see how we do it in the code. So we have imported agent, which is the component from ATK, and we provide these main properties inside it, which is the name. So we are going to build helpful assistant. We are going to provide this agent access to a model, which is nothing but will act as a brain with a retry option which we have set over here. So, in case if it fails to connect to this API due to a rate limit or temporary service unavailability, it will go ahead and retry. It will not break the entire code. And then we have a description. Now, this description is important in order to understand what is this agent about. Then we have an instruction, which is the guidelines of how this agent should process the user input and what is the expected output from this agent. Then we have given access to Google Search, which is tool to this agent so that this agent can go ahead and use this Google search tool in order to fulfill the task. Now that we have built this agent, it's important to understand that how we're going to interact with this agent, right? We might have a single agent, we might have multiple agents altogether, right? Now there is another component which is central to the ADK that will act like orchestrator. Now that is known as a in memory runner. Now, this will go ahead and manage the conversation between what the user is going to send to the agent and the response from the agent back to the user. Now we have imported this from the Google ADK, which is known as runners. Now let's go ahead and call this runner and interact with our agent. So we'll call this runner and we will use a run debug. Now, this method is used to send out prompt and get an answer. Now, this method will abstract the process of creating a session and maintaining it throughout this life cycle of an agent. Now, this is mostly used in testing your agents at an atomic level. So for example, you have an agent, and you want to test by invoking it whether the tools are being implemented correctly, whether it is able to follow the guidelines or the instruction that you have given. Now let's go ahead and give a prompt, which is what is Agent development Get from Google and which language is the SDK available in. So it will go ahead and call the agent and we'll give the output to us. And congratulations that you have built your first agent using Google ADK. Now, this is the most simplest agent that we can build using Google ADK. Now, let's go ahead and see what are the different types of agents, different types of patterns used in order to build multi agent system. 6. Multi-Agent Orchestration: Alright, welcome back. So I have re connected to the system, and I have installed these all libraries. Now in the previous class, you have learned about how you can build a single agent that could take action. Now let's see how we can build agent teams. Now, think of agent teams similar to a team of people. Now, you can create specialized agents that can collaborate to solve complex problem, right? And this is called multi agent system, and it's one of the most powerful concepts in AI agent development. Let's first start by installing few libraries again. So over here, we are going to import those components which are sequential agent, parallel agent, loop agent. Apart from that, we also have additional agent tool, function tool, Google search as tools. Now understand this why multi agent system. Now let me bring image, which will make it much more clear on why it is important to build a multi agent system and where it is important to build a multi agent system. Now the problem is that it is do it all agent. Now, the agent that we have built previously was do it all agent, where a single agent can do a lot. But think about it. What will happen when the task gets complex? A single monolithic agent tries to do the research, writing, and then editing, and then also fact checking all at once, and it can become a problem, right? Think of the instruction prompt, how long it will take. And it can also become confusing. Apart from that, it will become difficult in order to debug which part has failed. For example, fact checking age might have failed, but in the monolithic agent, as it is a task within those multiple input or the prompt the user has given, it is difficult to maintain and often it can produce unreliable results, right? So the solution is to build a team of specialist, where we have multiple agents, a team of simple specialized agent that can collaborate just like a real world team would do. So let's see how we can build a research summarization system. So we have two agents in that. First is the research agent. And then second agent is the summarizer agent. And these both agents will be orchestrated with the help of a root agent. We also have a shared state. Now remember, I talked about a runner, which is in memory runner, which acts like an orchestrator between multiple agents. Now, when I say orchestrator, it is not an actual orchestrator, but it is a message queue between these agents. So it will help in order to pass the output of one agent to another agent. And any agent can access the output of any agent with the help of the shared state, which is available inside this in memory runner. Now, first, let's go ahead and build a research agent. Is the output key. Now, the output key is used in order to make sure that the Output that is being produced by this agent can be dumped into the shared state with a key. For example, once the research agent has completed its task, it will write the answer to the shared memory with a key as research finding, right? So the result of this agent will be stored in this session with the key. So it will be easier for the agent to understand what is the output of the particular agent. Alright, now that we have built these two agents, let's build a root coordinator. Now root coordinator is nothing but another agent with a different set of instructions. Now, let's go through what is the instruction for the research agent. So you are a specialized agent and the job is to use Google search tool to find articles relevant to the given topic. And the summarizer agent instruction is to create a concise summary with three to five key points, right? Now that we have the root agent, which will take care of the orchestration part between the two agents, right? So you are a research coordinator, where the goal is to orchestrate the query. First, we must call the research agent, which will get the relevant information. Next, we are going to provide the output of the research agent to the summarizer agent to create a concise summary. Now, once we have the output, present the final summary clearly to the user as your response, right? So that is what the root agent will actually go ahead and do. Here we are using Agent tool. Now, as a tool, this agent is only using Google Search, right? Summariz agent is not using any tool because it is just summarizing the output of the research agent. But root agent is going to use tools as the agent. So think of this. Here we are using Agent tool to wrap the sub agents, which is the research agent and the summarizer agent. To make them callable tools for the root agent. Now we will explore more on the agent tool in detail in the upcoming session. But for now, just think of this. You're giving root agent access to the sub agent, which are the research agent and the summarizer agent. And this root agent can call these agents like a tool calling. Now that we have this set, similar to how we will go ahead and interact with any agent we will call the in memory runner and then we will also run it in the Run Debug mode and send in our input, which is what are the latest advancement in the quantum computing and what do they mean for AI? It will go ahead and use delegate between the research agent and the summarizer agent and give us the output back. Now, let's see what is the output. Now, in this output, you can see that it is using a function call, right? The function call is done because this research agent has access to a tool known as Google Age search, which is nothing but a function calling or a tool calling to this agent. Now we have just built a first multi agent system with a root agent as the coordinator. Now, this coordination is happening with the help of the instructions that we have given as a guideline. That's it for this. This is our first multi agent system using a single coordinator agent to manage the workflow, which is powerful and a flexible pattern. All right. Now we will see there are multiple patterns in the upcoming session. 7. Sequential Agents: All right. Welcome back. And congratulations on building your first multi agent system. Where you have used a single coordinator agent to manage the workflow, but relying on an LLMs instruction to control the order can sometimes become unpredictable. Now, here we are going to explore what are the different patterns that will help us to build a system which will give us a guarantee on the step by step execution of those agents. Now, we call those thing as a sequential workflow. Now we have imported the component which is sequential agent. Now, why multiagent why we have to build a sequential workflow where it is important. Now, we have to use sequential workflows when the order matters, or you need a linear pipeline where each step would build on top of the previous one. So think of a scenario or before that, let's think about the problems. The previous multi agent system worked, but it relied on the detailed instruction prompt to force the LLM to run the steps in order. Now, this can be unreliable, right? A complex LLM might decide to skip a step or run them in the wrong order. Now, the solution is to build a fixed pipeline or a sequential workflow. Now, when we need the task to happen in a guaranteed or a specific order, we can use a sequential agent. Now the agent acts like a assembly line. Now, think of this as a block post creation agent system. Over here, the order in which I want the agent to be executed is fixed. I want the outline agent for to be invoked. Its output should be given to the writer agent. Once the writer agent completes its output, it should be given to the editor agent, which will go ahead and edit a blog post or draft for a clarity and a structure, and then it will give the final output. So the entire flow is deterministic and fixed. And hence we can leverage something known as sequential. But before that, let's first go ahead and build these agents. We have three specialized agents, an outline agent, which will create a block outline for the given topic then we have a writer agent, which will write a blog post, and then we have an editor agent, which will edit a blog post for clarity and the structure. Now that we have the outline agent over here with the instruction of create a blog post for the given topic, and it should have a catch headline, an introduction hook, three to five main sections, and a concluding thought. So that is the instruction given to it. There are no access to any tools given to it. Along with the model, and they mean properties are required to define any agent. Similarly, we have the writer agent with the instruction like follow this outline strictly and we can specify the outline that we want. Now, one more important thing to notice is Outline agent has an output key which is blog outline. So the output of this agent would be traced with the help of this key in the shared state. This writer agent will actually consume the output from this agent. So remember, the shared state has a key which is blog underscore outline. So in the instruction, it will go ahead and take that as an input with the key which is present in the shared state and then go ahead and process the information. Similar to that, the output of this writer agent will be written to the shared state with the key blog under scope draft. So the editor agent will go ahead and use the output of the writer agent in order to curate blog by fixing grammatical errors and the instruction given to this. Now, let's go ahead and initialize the three agents. Now that we have three agents created, we need to call those agents in a sequential manner, and the way we do it is with the help of a sequential agent component. Now we define a root agent, and instead of a agent, we will go ahead with a sequential agent, and the name of that sequential agent will be a blog pipeline. Now, the subagents are those agents which we have defined earlier and we will call them in the order that we want to call. Now that we have defined a root agent, where it is able to call those agents in the order which we want. Now, remember, the order in which you specify the sub agents in the sequential agent is the order in which those agents will be executed. Now, again, in order to interact with these agentic system, let's go ahead and call the runner and again, run the in memory runner using a run debug method and with an input of write a blog post about the benefits of multi agent system for software developers. It will again go first, write a blog. It will first go to an outline agent once the outline agent will give its output. So this is the entire output with the instruction that we have given like have a catchy headline and introductory hooked three to five main sections. So it is adhering to all the instructions that we have given. Once that is done, it will go ahead and give that output to the next agent. That is the writer agent. Writer agent will get the output, it synthesize that and go ahead and give it to the editor agent. Now let's see what is the final output that it will give. As there are three agents, it will take some time in order to execute everything, right? This is how we can use sequential agents where each step runs in a predictable order, right? Now, this is perfect for task that builds on each other. Now, as you can see, this is slow. If the task are independent, we can solve it via different agentic pattern. Now, the editor agent has given us the output, which is this entire one. All right. That's in this and we are going to see multiple different patterns. And when we should use which pattern, what are the pros and cons of it? 8. Parallel Agents: I'm back. So I have connected to the server, and I have installed all the libraries and the code which is required to fetch the APA key. And congratulations on building an assembly line using a sequential agent where each step runs in a predictable order, right? Now, this is perfect for task that builds on each other, but it will be slow if the tasks are independent. Now let's look into a different pattern where we can run multiple agents at the same time to speed up the workflow. All right? Now, the major pitfall with the sequential agent is that it's an assembly line, right? Each step must wait for the previous step to finish. But what if you have different tasks which are not dependent on each other. So we can execute all those tasks independently, and execute those agents parallel, which will dramatically increase up the speed of the workflow. And then at the end, we can just combine all the output and then give it as a final output to the user. Now we can use perl agent when the tasks are independent. Think of this multi topic research agents. Over here, we have four agents, which is that tech researcher, health researcher, finance researcher, and an aggregator agent. Now, these all four agents are atomic and have a specific task to follow. Now, let's go ahead and build a system with these four agents and execute them parallel as the tasks for each agents are not dependent on each other, right? So let's first go ahead and build the tech researcher. Now, again, similar to how we build agent with the main properties which are name, model, instruction, tool, and an output key as we have multiple agents. The output of this tech researcher would be dumped into a shared state with a key tech research. Similar to a tech researcher, we also have to build another agent which will go and do a research about all the topics or the breakthroughs in the health research. And similar to that, you also have to do it in the finance domain. Let's go ahead and build these three atomic agents and initialize those. Now, once the output of these all agents are dumped into the shared state, we need an aggregator agent which will take the output of these agents and create a combined report for the user to go through. So this will be done with the help of a root agent or an aggregator agent. Now. Each agent will be dumping their output in the output key with the respective key, which is tech research for tech researcher, health research and finance research. All three agents will use Google search as a tool in order to find the relevant topics. Now coming to the aggregator agent, it will take the output of these three agents with the help of the key, which is tech research, health research, and finance research. And then with an instruction that your summary should highlight common themes, surprising connections. The most important key takeaways from all the three reports. Now, let's go now that we have created these agents, let me initialize this aggregator agent. We have to somehow call these three agents parallel. Now, in order to bring these agents together, let's go to the architecture and do a brainstorming. Can we divide these agents into multiple patterns, pause this video, and then give it a thought? I hope you have given a thought. No. Let's divide it into two parts. We have to execute tech research agent, health research agent, and finance research agent parallel. Let's run this paralle and then output of the three agents will be an input to the aggregator. So can we think in this way, running these parallel and then running these sequentially as well? Let me tell you how we are going to do it with the help of a code so that it will be more clear. So this is how we will do it. So first, we will execute all the three agents in the parallel manner with the help of parallel agent. We will give a name to the parallel agent and the sub agents that it should execute parallel. Now, as the name says parle agent, it does not matter the order in which we give the agents in this list, as each agent will be executed parallel. Once we have the output generated in the parallel research team, it will be used as an input to the aggregator agent. Now once we have this parallel agent, we'll build a sequential agent which will take the output of all these agents and give it to the aggregator agent. Now, as this is sequential agent, the order in which we define these agents is important. The reason being, we have to execute this first, and the output of that should be used in order to give it as an input to the aggregator agent. Now let's go ahead and initialize these agents as well. Now let's go ahead and interact with our agent team with the help of in memory runner in the debug mode. Now that we have the root agent defined, which is a sequential agent, which indirectly is calling the parallel research team, which contains all these three agents, and then output of that will be passed to the aggregator agent. So we have all the four agents, and this is the root agent which will take the user input. Let's go ahead and ask run the daily execution briefings on tech, health and finance. Now, as you can see, the health, technology, and finance, all these three agents are running parallel, thus reducing the execution time drastically. Now, having said that, it will go ahead and give us the report with the help of an aggregator agent, and you can see how dramatically the speed of the workflow has increased by running independent task concurrently or parallel. So far, all our workflow run from start to finish, right? So we have a start step and then we have a stop step. But what if you need to review and improve and output multiple times? For example, I want to review the health researcher output, and if there are any corrections, I would like to make it there and there itself. How would we do it? Think of this as a loop, right? So we will see that pattern in the next session. 9. Loop Agents: All right, welcome back. I have connected to the server, and I do have the credentials with me as well for the Gemini LLM keys. I have executed these cells, which will install all the ADK components, and today we are going to understand about loop pageants. So far, all our workflows have run from start to finish, and then it will stop, right? But what if we need to review and improve an output multiple times? Now, let me tell you the problem that we face with traditional workflows, like the sequential workflows that we have built. Eight. So these workforce will produce their final output, and then they will stop. So it's a one shot approach. Now the solution is to build an iterative refinement loop into the agents, and we will do it with the help of a loop agent, which will run a set of subagents repeatedly until a specific condition is met or a maximum number of iterations is achieved. Let's think of a scenario where we are building a story writing and a critic loop where we will have an initial prompt, which will go to a writer agent, where predominantly the writer agent will write a draft of a short story. Then it that story will go to a critique agent where it will review and give a short critique on the story and suggest any improvements if required. Based on the condition, we have another agent which will decide whether I should approve or whether I should send it back again to the writer agent to enhance or to improve the story, right? Now, the most important part over here is how do we add a loop into agents, and that we can do with the help of a loop agent. Now, let's go ahead and build our agents, which is the writer agent, and we will do it with the help of agent component. Which will have a name, model, instruction, and output. The output key is required in order to dump the output of this initial writer agent into a shared state. Now, shared state is where all agents can see what other agents have produced as an output. We have the initial writer agent. Let's go ahead and execute it. Now let's go ahead and build a critique agent. Now critic agent is something we will also build using a normal agent component, which will have a name, model, instruction, and output key. Now in the instruction, we have specified a prompt wherein it will take the input as a story written by the writer agent. Then it will evaluate the stories, plot, character, and the pacing. If the story is well written and complete, it will only respond with the phrase which is approved, and nothing more than that. If the agent thinks that the story is not well written, it will provide two to three specific actionable improvements for that story, and then the output of this agent will also be stored in the shared state with the key as critique. Now that we have built two agents. Now let's see how we are going to incorporate the looping mechanism. How do we build it in place, right? Before that, the way we can implement the loop is in two parts. First, we have to write a Python function. Now I will explain why we need a Python function altogether. Now, this is a simple Python function with the name as exit loop, which does not take input. So if I execute this tool by default, it will return a predetermined output, which is a dictionary which contains the status as approved message as story approved exiting the refinement loop. So this is just a simple Python function written which does not take any input. Now that we have this function written, somehow we need the agent, the refiner agent to use this tool in order to stop the loop. The reason being the agent will not be able to understand what an approve means, right? So the critic agent, if the story is well written, it will give the output as an approved. But how will an agent know that when I get a word as an approved or a phrase as an aprud, I have to stop the loop and give the final output to the user. And in order to incorporate that, we need to write a Python function. Which will be consumed by the agent. Now, let's understand how we are going to do that. Now that I have a refine the agent with a name, model, instruction. Now, the instruction is that it will take the current story. It will take the critics output, which can be either improvements or either a simple phrase as approved. Now the task is to analyze the critique. If the critique is exactly approved, you must call the exit loop. Now, remember, we have written this exit loop as a Python function. So it will call the exit loop function and nothing else. So it will stop if it has called the exit loop. Otherwise, rewrite the entire story and fully incorporate the feedback from the critic given. Remember, if the critique will not approve it, then it will add in the actionable suggestions for the improvement in the stories. Now the way we have incorporated this Python function and created a tool out of that is with the help of a function tool. Now, till now, we have seen multiple ways of incorporating tools. If you want to give any agent access to an agent as a tool, you're going to use an agent tool. Now let me show you how we are doing it. Now, you can see from the tools we have imported agent tool. 10. Agent Patterns Overview: All right. Welcome back. Now that you have a complete understanding of workflow patterns, let's put it all together and review. How do we choose the right one for the uses that you are building? Let me build a small tigra which will help us in order to take decisions or understand which kind of a workflow should we use and why, right? Now, if the pipeline or the agents needs to be or the task that we are working on needs to be executed in a in a sequence, then we use a sequential agent. If the tasks are not dependent on each other and we can run them concurntly, then we can go ahead with the parl agents. In terms of building a refinement loop in any agents, for example, we have to go and validate the output of a few agents with the help of guiding prompts. Then we can go and use loop agents. Now, this loop agent is somewhat different of R. It is not similar to a human in the loop. Now, human in the loop is also a kind of a loop, but this loop agent is something which will leverage the LLM and the guiding prompts that we have given in order to implement the loop. So we will be going in depth of human in the loop as well. But for now, this is how a loop is implemented using an agent. Then the last part is where we let the LLM orchestrate the task to the agent based on the capabilities that the agents have on quick reference diagram related to which pattern, when should we use it? An example, what are the key features? So if you are going with LLM based orchestrator, when to use it when the dynamic orchestrator is needed, where we are not sure of what kind of a task should be delegated to what kind of an agent. It is not something which we are sure of. That we can go with an LLM based orchestrator. Examples are research process summarization. The key feature is that the LLM will go ahead and decide which agent should be called, which tool should be used. In sequential agent, the order matters. We have a linear pipeline where the output of one agent is an input for another agent, so it is a deterministic or workflow. The pattern parallel should be used when we have independent task and the speed matters. So conquer day execution is something which should be used when we have tasks which are independent to each other. Looping should be used in order to incorporate the iterative refinement within the agents. And if we require repeated cycles for agents to improve upon, then we can go with loop. Now, all these patterns altogether used within a multi agent system will make more sense. In an enterprise grade solution, all these patterns should be used in the right appropriate manner. You won't find an enterprise system which will only have sequential agents or parallel agents. These all kind of patterns would be used in hybrid mechanism in order to build an enterprise grid, multi agent system. 11. Advance Tools for Agents: All right. Welcome back. Now I have connected through to the server, and I have imported all the libraries and the components. Now that we have a fair understanding of what are the different kind of workflows and agent patterns and when we should use which type of agent pattern to solve the business problem. Now, one thing which you might have observed is the most important part of an agent is a tool. Right? Now, without tool, the agent is just a simple API called to the LLM. So let's go ahead and actually understand how we can build custom tools and it can help us in order to solve business problems which are unique, right, which traditional gently tools can't handle. So we are going to build a custom tool using ADK and we will understand how we can incorporate it with the hell along with an agent. Now let's take it with an example. Now before going to an example, I will require a helper function written in a Python. And we will come to this and explain what is this function all about and where it is being used. Now let's start by understanding how we can build a tool with the help of an example. Let's think of a solution where we're building a currency converter agent, where we have a single agent, and we will build two custom tools. One is to get fee for payment method and then exchange rate. Now, these tools are nothing but helping this agent in order to perform a task in a deterministic manner. Now let's go ahead and understand how do we define a custom tool altogether? Now, we can define a custom tool with the help of a Python function, a simple Python function. But there are few frameworks or guidelines that needs to be implemented in order to create a custom function. Now, what are these best practices in action that we should remember in order to create a custom function? The first point is a dictionary. The function should written in a dictionary which should have status and the data. It should have a clear dox ting. Docting as in an explanation of the agent, what the Python function is about. What is the input, what is the output, and what that function is capable of. Type is to implement validation for the input and the output. And again, error handling as we have to handle the failures gracefully. Now, taking into this consideration, let's go ahead and build our first custom tool using Python. And this is how an function is written, which is absolutely simple. Let me walk you through what we have done in this function. Now, we are going to build a currency agent, which will have access to get free for payment method as a function. Now this is the function named as get fee for payment method. It will take input as a method, which will be in string. Now, this is the third point type hens. Now type hens will help us in order to validate the right type of input and the right type of an output is being given or received back. Now, it helps LLM understand or an agent understand. In order for me to use this custom tool, the method should be passed in as a string, and the output of this tire function would be in the form of a dictionary. And hence, these are the type hens. What you can see in this triple codes is the docstring. Now, this docting explains what is this function all about. Arguments is what input this function will accept, and return is what is the final output of this function along with when it is successful and when it fails. Then we have a simple dictionary named as fee database where based on the type of method, we have the method as key and the appropriate conversion rate as the value. Now, this is just a mocking data that we are going to use. After that, we are going to take the input, and we are going to check it against this dictionary. What is the method, and what is the appropriate value for that? And that will be written. If we find the method to be present in the existing fee database, it will be returned with a dictionary as status success and the fee percentage as the fee retreat. If we do not find anything, then we will return it as an error with a doc string as payment method not found. This is just a simple function. It will take method as an input in a string. It will check in this database whether what is the percentage fee for that payment method, and it will return it as it is. Now, let's execute this Alright. Now that we have this first function written. Let's go ahead and see how we are going to build a second function. Now, this is the second function which is get exchange rate, which will take two inputs, which is the base currency of what is the base currency that you are going to give as an input, and what is the conversion currency or the target currency? The base currency has to be converted into. So these are the two inputs which are in string, and this entire function will return the data in the form of a dictionary. And hence, we have this type hens. Going forward, we have a doc string, which explains what is this function all about? What is the input that it will accept? What is the output that it will return? For success, what is the type of data it will return and for error, what is the type of data it will return with an error message of unsupported currency pair. Then it will go and check in the mob database, which is the ad database, it is a dictionary, where it will check against each, what is the currency conversion? For example, if I'm trying to convert USD to any one of these currency, this is the corresponding conversion rate. For example, USD to Europe, conversion rate is 0.93. So again, it will take the input base currency and the target currency. It will go and check against the database, retrieve the appropriate conversion factor, and it will return. If the rate is available in this conversion factor, it will written as dictionary, which is with status as success and rate as the retrieved read from this database. If the convergent factor is not available within this database, then it will simply return as status error with the error message to unsupported currency pair given. Now, these are the two simple functions that we have created. One is to understand what is the convergence rate or the payment method, and the second one is to find out the conversion fact. Now let's go back and see what is this about. Now, this agent can convert the currency from one denomination to another. Also calculate the fees to do the conversion, right? So converging the denomination from one to another and the fees required for that. That is what we are trying to build. Now that we have these two methods built, which are custom tools defined in the Python, let's build a currency agent and give access to these tools now let's go ahead and create the agent using a LLM agent with a name model with Jeremi 2.5 Flash, with the retry options. And then we have an instruction. You are a smart currency conversion assistant. For conversion request, this is the method in which you should follow in order to give the answer back. So first, you have to go and execute this tool, which is get fee for payment method to find the transaction fees. Once you have the transaction fees, you should go ahead and fetch the exchange rate for that currency conversion. Once you have both of these details, go ahead. Check for the status, fill in each tools response. Remember, we have defined this return status of each function as a dictionary with a status and the rate so it helps in order to identify whether the tool has been executed properly or it is throwing any errors. Even if it throws an error, we are gracefully handling it, and we are returning the proper response back to the allem in order to understand whether the tool has worked or whether the input is wrong. Now, once we have those things, calculate the final amount after the fees based on the output from these two tools and then provide the final converted amount back to the user, right? So this is what we have done using the prompt. If any of the tool returns error, explain the issue to the user clearly. So we will have the tools and inside the function, we will gain access to both the functions. Now, these are the function names which we have provided back to the user. Now let's go ahead and initialize this agent. Now, how do we interact with an agent? The main thing is to use the in memory runner. Now we are going to dig deep into different types of runners as well. But for now, as we are doing this at an atomic level for testing purposes, it is always a better to use in memory runner as this takes care of all the session management in this runtime. Now let's go ahead and initialize in memory runner and give this agent as currency agent as we have a single agent. And then run the runner in the debug mode, and let's give it an input, which is, I want to convert $500 to Euro using the platinum credit card. So this is the payment type, and this is the base currency and the target currency. Now, based on the prompt, it has used the tools, and it found that the fee for the payment, which is platinum credit card was 2% ten USD is the amount. And then after the fee, the remaining amount would be $490 with an exchange rate about 0.93 for the conversion. The total amount would be 490 USD converted to 455 euros. So this is how you can build a custom function and give the custom function in order to solve the day to day task or any complex visitance problem. So that is a quick glance on how we can build a custom function in Python and give this function to the agent to solve or create multiple integrations in the enterprise as well. 12. Building Reliable Agents: Alright, welcome back. Now that we have built an agent, which now uses our custom built logic and is able to give us the structured response, right? Now, think of a way on how we can improve the agent's reliability with code. The reason being the agent's instruction says, calculate the final amount after the feeds. But think of this way. LLMs aren't always reliable at solving mathematical equations. They might make calculation errors or are inconsistent in solving mathematical formulas. So the solution for this is to ask our agent to generate a Python code. And do the maths and run it to give us the final result. So code execution is much more reliable than having LN try math at its own. So let's understand how we can do that with the help of enhanced agent. Now, we have built currency agent. We have the custom functions, which is get fee for payment method and get exchange rate. Let's add an addition to this system by adding a calculation agent with a built in executed code tool. The reason is that we will ask the LLM to generate a Python function to solve that problem, and then we will execute the code in order to retrieve the answer pack. So ADK has a built in code executor capability of running code in a sandbox, which is one of the tools. Now, let's create a calculation agent which takes in a Python code and uses the built in code executor to run it. Now this is another agent. With a name as calculation agent model instruction. Now, let's specify what is the purpose of this agent, right? So the task is to take a request for a calculation, as we can see clearly that this calculation agent is a part as a sub agent to the main currency agent, or enhanced currency agent. So the specific task of this agent is to take the request for a calculation and translate it into into a single block of Python code. For now, the built in code executed tour only executes Python language. And we have also defined few guidelines or rules for it to generate the code. Similar to how we have as a guideline for designing custom tools in Python, we also asking the agent or an LLM to write the Python code with few rules. So the output must only be a Python code block and not an explanation of what it will do or the doc string. So do not write any text before or after the code block. The Python code must calculate the result. The Python code must print the final result to STD out. Now the reason we have added this line is as the Python code would be executed inside this built in code executed tool, it is required to write the final output to this SDD out. And you are also prohibited for performing the calculations yourself. So you should not use the LLM to calculate the final answer, but you should use the M to write a code which will solve the problem for me, which will calculate the result for me. Right? So let's go ahead and initialize this agent, which is the calculator agent. And then let's update the instruction and the toolset for the main enhanced currency agent. And we will see what enhancements we need to do in order to bring in the code execution as a sub agent for that main agent. Now, update the currency agent's instruction to generate the Python code. Which we have done, right? So originally, calculate the final amount after fees, which was taken care by the LLM itself. Now, in enhanced agent, what we are doing is generate a Python code to calculate the final amount and use the calculator agent to run the code and compute the final amount. So we are specifying in this prompt to the enhanced currency agent that we have another agent, which is the calculator agent, which is capable of generating a code, executing the code, and giving the final answer back to us or this enhanced currency agent. The second part is the calculation agent. Now the EDC will let you use any agent as a tool, using the agent tool, right? So what we have done is inside this tool, we have given this agent as a sub agent or a tool calling to this main agent, using the agent tool. So agent tool lists down all the agents which we have to provide it as a tool calling, so that this agent will be a callable tool to the rote agent. Now let's go ahead and run this. Again, we need to define a runner for this. Which will take care of all the session management, memory management, maintaining the state between the multiple agents, tools, and the user. Now, let's go ahead and convert 12 50 USD to ANR using a Bank transfer and show me the precise calculation. Now let's see how it is going to solve this problem using the code execution tool that we have. And remember, in the last session, I have written a utility function. We are going to use that utility function in order to see what is the code that is being generated by the calculator agent and how it is being executed. So that utility function is nothing but written in order to understand what is the code generated and how it is executed by the agent under the hood. So let's give this some time for it to run. Okay, I think I need to stop this. The reason being I have exhausted flashlight for today. Let's go with flash. Yeah, I will give me an error. The reason being I have paused it in between. Now let's go ahead and run it again. That's important. The reason why I did have not got an error is because I was using this retry mechanism. Even though if I would have not used this retry mechanism, this would have failed the first time. As I have this retry option in place, it will go ahead and retry for the set iterations in the retry configuration. Now let's debug and see how is the output looking at. So original amount is 12 50 USD. The method is bank transfer, calculation breakdown. The fee is 1%. So fee amount would be $12.50. And then the final amount comes to around this much NR. The most important part is about how the calculator agent has used the tool in order to generate the Python code and then execute it. All right. Now, generated Python code, I have exuded provided Python code block. Fee amount is 12 50, which is correct amount after fee is this much and the final amount is this much, right? 13430. So that is how it is done with the help of a code executor, which brings in some deterministic level of understanding so that we can inspect the generated output using the helper function. And that's how we can build agents with custom tools. Also use the inbuilt tool, which is the built in code executed tool in order to make these workflows much more reliable with the help of code. 13. Agent Tools vs Sub Agents: Alright, welcome back. Now I'm pretty sure that you might be confused about sometimes we are calling sub agent sats tool. Sometimes we are calling tools at the root agent. What is this going on, right? Now, let me break it down and explain what is the difference between Agent tool versus the subagent. So this is a common thing, both involve using multiple agents, but they work very differently. Now, Agent tools is what we were using. So this is used when agent calls agent B as a tool. Agent B's response goes back to the agent A. And then agent A stays in control and continues the conversation, right? So agent E is always at the center of everything. This is something as an orchestrator or or the main root agent, which is deciding based on the task, whether I should call any other agent which will solve the small problem and then use the output of that agent to proceed further with the main task. Hence, we use Agent tools. Now, agent tools as I will explain that in depth now this is used for delegation for specific tasks like calculation, which we have done, right? Now, when do we use subagents? No, it is a different pattern altogether. The agent A will transfer the control completely to the agent B. Wherein agent A will not understand what is the output of agent B or it will not care about the output from the agent B because the complete control has been transferred from the agent B to the agent B. Now, the agent B takes over and handles all the future user input. So it is like a workflow where once the agent A has completed its task, it's no longer required to solve the user question. Whereas in the initial phase where we have the agent tools, agent A is the main orchestrator where it will solve the problem till the end. Now over here, AgenD is out of the loop. In Agent tools, agent A always stays in the control and continues the conversation, and it might call another tools if required. But the main center at the stage is the agent A. Now, the use case for subagents is to hand off to specialists like custom support tiers. Now, in our currency example, we want the currency agent to get calculations, result and continue working with them. The reason being, let me show you. Now we have this enhanced currency agent. Over here, we have the calculation agent. Where this root agent will give the input to this calculation agent, it will go ahead and calculate with the help of its tool and then again, give back the output to the main root agent. Hence, it is an agent tool and not a sub agent Now, now that we have a fair understanding of what is Agent tool and sub agents, although we are going to see this in depth on when we should use what type of tool. Now let's go ahead with some inbuilt components or the tools that we have from the agents or the ADK framework. Let me bring up that slide so that it will be far more clear. Let me zoom in. So inside ADK, we have multiple tools. Now we have custom tools. In which we have function tools where we will define the Python function according to the business problem that we are trying to solve. Now, we also have long running function tools, which we have not touch based yet, which we'll be covering in detail in the upcoming sessions. But these are used where human in the loop is required, and these tasks can take a longer duration to complete, such as few hours or few days. Then we have agent tools, and we have used these where other agents are used as a tool. Similar to what we have done in the currency conversion agent. Then we have MCP, which is model context protocol. These are servers where these can be file systems, Github MCP, Google Map MCP, or any database connector. So we can connect to these services without writing a lot of custom to code in order to incorporate their EPs. And then we have open tools. These are tools automated generated from the APS specifications. Now, these are all about the custom tools that we have. But what about in build tools that we are from the ADK as well? We have used few tools, but let's go in depths of it. Now we have used Gemini tools, which is the Google search and the built in code executive, right? Are there are multiple more tools in total, till now there are 32 tools available, which are Gemini tools. We will be covering in the upcoming sessions in the Capston projects that we are going to build and the future learning that we are going through. Then we have Google Cloud tools, which are specifically tools designed in order to integrate with the GCP services, which is the BigQuery, Spanner tool set, and much more, right? And then we have third party tools like Github, Hing face, Cagle, and multiple More now, I think you have a fair understanding of what are the different types of tools that are provided by the ADK, how we can define custom tools. What is the difference between calling an agent tool versus a sub agent?