📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Master Google's Agents Development Kit (ADK) in 60 mins– Build Production Agentic Workflows today!

The AI Lifestyle1:00:58

Transcription

Google just released their agent development kit, and it's a game-changer for anybody looking to develop agents. With it, you can build, test, evaluate, and deploy agents right from your IDE. In this video, we'll take a look at all the components that make up the agent development kit, and we'll get cracking with some awesome examples and even take one and deploy it all the way to production on Google Cloud.

[Music]

The agent development kit has multiple components to help develop, run, evaluate, and deploy agents. Let's take a look at some of the components involved in developing agents. First, we have the agents themselves. Agents can be divided into non-deterministic, deterministic, and custom agents. Non-deterministic agents use LLMs to do the coordination, and deterministic agents use workflows to do deterministic coordinations like sequential, parallel, and loop. Custom agents are a mix of both deterministic and non-deterministic components, LLMs, and code that helps them do activities.

Then we have tools. Tools are what agents use to accomplish certain tasks. We have different kinds of tools available in the agent development kit. Function tools are those that are defined as functions which have agents as tools. Built-in tools include Google search, code execution, and RAG. Third-party tools like LangChain and Crew AI are supported. Tools like Apogee and other GCP components are supported, in addition to MCP and security, which is tool-based.

The next component we take a look at is callbacks or guardrails. We have guardrails across the board in different components. Agents have their own guardrails, tools have their own guardrails, and models have their own guardrails. These protect the system from unwanted queries. And the guardrails are also set up as before and after, which means a guardrail can be applied before or after the execution from that component.

That we've looked at how to use components to build it. Let's look at what it takes to run an agent. We have session services and memory services. Session services contain session state and session parameters. Memory services contain short-term memory and long-term memory. Short-term memory associates itself with the session. And long-term memory is what you look back at for the agent run itself. Both short-term and long-term memory have persistent and non-persistent options. Persistent options are where you would use databases, etc., and non-persistent options are ones that are in memory and during the session itself.

Let's now take a look at the other components like deployment and evaluation. Evaluation allows you to evaluate the quality of an agent, and deployment allows you to deploy the agent in either a cloud environment or in your own self-managed environment. Deployment components can use the new Vertex AI agent engine, which we will take a look at in our forthcoming examples. All these components make the agent development kit a must-have tool for any developers looking to build, test, evaluate, and deploy agents in any environment.

Let's take a look at our first component for how we build our workflows: tools. Tools are an integral part of building any agentic workflow. Tools allow an agent to accomplish certain tasks depending on how those tools are set up. Now let's take a look at what tools are available in the agent development kit. The first set of tools are defined as function tools, and these tools are nothing but tools that are functions that you can call from your agent. These function tools have specific configuration for ADK. You essentially need to have what's called a docstring, which explains what the name of the tool is, what the purpose of the tool is, what parameters the tool has, and what return type it's using. The docstring kind of gives the LLMs and agents that are calling these tools an idea of what the tool is capable of. We also have agents that can function as tools and also long-running functions that are going to be set up because ADK works asynchronously as well.

In addition to the function tools, we also have built-in tools. Built-in tools are similar to how you would have capabilities within an agent itself. Examples of built-in tools include Google search, code interpreter, and RAG functionality. These tools are specifically designed to be built into the agents themselves. It is something that Google's models are using. Some caveats here: You cannot have multiple built-in tools in one agent. You cannot have built-in tools in sub-agents. And we'll talk about sub-agents a little bit later, but that's a limitation for now. They may be changing that in the future.

In addition to built-in tools, we have ADK, which also integrates with LangChain tools and Crew AI tools. LangChain does it through its Tavi tool, and Crew AI does it through Serp. The best part of Google's ADK and why it is very good for the enterprise crowd is that it allows for good integration with GCP's connectors and also it allows you to connect to all of the databases in GC through its MCP toolbox. In addition to Google Cloud's MCP toolbox, it also supports the MCP protocol in general. So you can connect it to a multitude of MCP servers out there.

A lot of these tools that we've seen carry with them a possibility that there could be authentication and authorization involved when using these tools. So ADK supports authentication for tools through multiple scenarios. It allows for API key, OpenID Connect, OAuth 2, and other components. Now, if you want to take a look at the flow of how this would work, think about ADK as some sort of a middle layer that is sending the right response of key and credential to each of these tools. We'll take a look at runtime and how ADK runs these workflows so that it gives us a better idea of why it's able to make these authentication calls better.

The next thing we're going to be talking about in the building blocks for an agentic workflow are agents. Agents, by definition, are self-contained execution blocks that can act on their own to accomplish a specific task. This specific task is given to it in the instructions, and the tools that it uses are established for it to use to accomplish that task. Now, an agent in its own framework does not do much, but an agent along with other agents builds a very powerful agentic workflow. In ADK, we have support for different kinds of agents. Agents, by definition, are split into non-deterministic, deterministic, and custom agents. What this basically means is that non-deterministic agents use an LLM to drive the engine and the logic for how they perform and do the actions to accomplish a task. LLM-based non-deterministic agents are very flexible and allow us to do a lot of different activities. Now, if, when it comes to certain use cases, you'd want there to be some sort of logic and a flow of steps that are more definite. In these cases, you would use deterministic agents. And in ADK, you have support for three kinds of deterministic agents. They are sequential agents, loop agents, and parallel agents. All these are nothing but different kinds of ways you can run a workflow. A sequential agent is a workflow agent that executes sub-agents in the order of how they are specified in the list. For example, you may require a use case where you want step one, step two, step three to be done in exactly that fashion, and if any deviation of that order will mess up the output. In these cases, you want a deterministic workflow, and in that case, you use a sequential agent. In our example section and demo section, we'll take a look at a sequential agent that does exactly that. The loop agent is a workflow agent that is set up to run a set of sub-agents in a loop for a specified number of iterations to accomplish a task. Again, this, the number of iterations for a use case can be determined by a fixed number, or you can also build an agent to provide a condition that will satisfy if the iterations can stop. A parallel agent is a workflow agent that executes a set of sub-agents all at the same time. This is very important when you want to do tasks that are simultaneously run and you want to just provide a final output, which is a collection of all the outputs from the sub-agents. This is especially important if you want speed and you want to hit different sources where each agent doesn't need to depend on the other for its previous input or output.

Finally, custom agents. In real-world scenarios, in production workflows, you don't typically see a scenario where a non-deterministic and deterministic agent can happen explicitly to each other. Most of the time, most agents are always a combination of logic steps that you want to involve and also allowing the LLM to do its own coordination. These kinds of scenarios call for building custom agents. And as you can see in a custom agent workflow, you can inject a certain amount of determination by including decision points, etc., with code, and as most of these ADKs I've mentioned, the best production scenario which yields the best output is always a custom agent that has a mix of deterministic and non-deterministic workflows for our next building blocks to building the agentic workflow.

We're going to take a look at one of the most important things you need to keep in mind in order to do a production workload or any workload for that matter. These are callbacks or guardrails, in simpler terms. Callbacks and guardrails are nothing but conditions that you can set before and after any component usage that will determine whether the process can go forward or not. Now, it's very important to understand the role of callbacks. Callbacks are determined to inject a level of quality and also to kick out unexpected behavior. Now, unexpected behavior in an agentic workflow can happen at every single stage. Sometimes the agent itself can produce a bad output. Sometimes the model that's running the agent can produce a bad output. Sometimes the tool that's running it can produce a bad output. So, in this case, because you need guardrails at every level, ADK does a good job of allowing us to use a callback or a guardrail at every single step. You can have agent callbacks, you can have tool callbacks, you can have model callbacks. This, I think, sets ADK apart from the rest of the frameworks out there because this allows you to have a level of control that's not seen in any of the other frameworks. In our example that we will see going further, we will see how we can use these callbacks both from an agent level and also from a tool level.

Now that we have seen what the agent building blocks are, it's time for us to understand how an agentic workflow is run in ADK. What are the steps that allow these agents to interact with each other and how it's run? To understand that, we have to now call back on all of our knowledge that we built with our building blocks and understand how it is set up in ADK. A runtime for ADK involves tools at the most granular level, agents using these tools. These agents are controlled and run by a runtime that has different components like session service, memory service, and a runner that runs the whole process. Now, this is a very simple concept; it's a single-agent format. But in real-life use cases, we don't have single-agent formats. We have multi-agent networks. In a multi-agent system, you will have the same concept, but it's expanded upon by the inclusion of a couple of other agents. Now, I want to call a little bit, I want to take a little moment to explain coordination agents, sub-agents, etc. Right? So, in a multi-agent system, you always need to have an agent that is coordinating other agents. You can either do it as a parent agent or base agent and sub-agents, or you could do it as these sub-agents being tools to the parent agent. The biggest differentiator is a base agent does not need to return output back to the parent agent. It can operate on its own. But a tool has to always return output back to the base agent that's calling it. That's the biggest difference of a multi-agent system. Remember that. And we, in our example, we will see both these use cases, and we will see how one doesn't work well for our use case, and in converting it to a tool, it works well for us.

Now, in this runtime, we're going to dive into it a little bit and understand how this whole entire runtime is run in an ADK framework in ADK. So, just to recap before we further look into how this entire process is run, you have the runtime, you have session service, memory service. Memory service uses either databases or in-memory sessions. Session contains state, and agents use tools, and agents can coordinate with other agents and provide output. That's the nutshell view of this workflow. Let's look at a deeper dive into how this is run. This is by far the most important diagram in this entire set of discussion. This talks through every single detail on how an ADK framework runs agents and responses and interacts with the user. What you want to see are the building blocks plus pillars of this agent workflow. The first part is you have a user. Second, you have a runner, which I mentioned runs the entire workflow. Then you have a session service, agent, tools, and maybe memory. In this scenario, a user asks a question, a simple question. What the runner then does is it establishes a session. It takes the session ID, puts it in the runner so that the runner knows what's the session that's going on. It then takes the user's question, sends it to the agent. The agent then goes ahead and uses the LLM model that it's part of to determine what it's going to do with the logic. The LLM will determine, okay, I may need to use a tool to accomplish this task. And that call to use a tool is then sent back to the runner, and the runner registers this. So this back-and-forth process is registered with what's called events. I didn't talk about events in the very beginning, but events are nothing but registries of the activities or history steps of the activities that take place across the board in this agentic workflow. Let's go ahead and look at the rest of the steps in this diagram. Once the function call is registered, it is sent back to the runner. The runner then takes the function call. It records it, sends it to the session state. Session state needs to know that it's going to call a function. The event is recorded, sends it back to the runner. The runner then says, "Yes, you're good." Sends the call back to the agent. Agent then makes the call to the tool. The tool then returns the result back to the agent. And the tool result is sent back to the runner. The runner records the function's result, sends it to the session state because you need the session state to hold these values so that it can manage the process, and then the LLM receives the tool answer. The LLM then goes ahead and returns a value for the tool answer, which is, in this case, "What is the capital of France?" is "Paris," and then it's sent over back to the runner. It registers back in the session agent with what the LLM has returned, and then it's sent to the runner and then sent to the user, finally mentioning that the capital of France is Paris.

For our first example, we will take a look at the quick start example that Google provides. With it, we will kind of see what comes out of the box to quickly test your agents. And this is the fastest way to test an agent that I've seen in any framework. To start off with, we want to set up our folder structure, set up a virtual environment. In this case, it's Python, and install `pip install Google ADK`. Once you've installed that, you want to set up three folders here. You'd want to set up your main folder for your agent folder. And then you'd want to set up two folders in there for your Py files. You'd want to set up your `__init__.py` and set up your environment file for your Google key. And then, finally, the `agent.py` file. The `agent.py` file is a very simple file; you're all, you're doing is you're importing `agent`, and this is just a quick start way to test out an agent. In this example, we have two tools that we are setting up and one agent that is going to use two tools. Same thing with tools; you have to have a docstring which explains your tool and what it does. We're not actually using any LLMs for our tool; we're just hard-coding some values. And for the agent itself, you'd want to give your model, description of the agent, instruction of the agent, and the tools it has access to. After you do this, you can test out your agent in one button. All you have to do is go `adk web`, and it will generate you a web interface for you to test your agent. This is what gets served, and you can test out your agent. You can select your agent that you just selected right now. You can ask it, and that will give you a response. You can do streaming, audio, video. But the most important thing here, what you're trying to do is you're trying to look at the different agents, what it does, right? "New York" should give me the weather in New York. Goes and gets weather. Get weather. Okay. So now if you look at your events, it goes to the get weather tool. It ran, and it gives you the output. Now this is good; this is all awesome. Let's now take this concept and blow it out and create some Streamlit agents that can do really cool stuff. Not just one agent, multi-agents.

To set up our Streamlit app, we do the same thing. Set up our virtual environment. Set up an environment variable. The environment variable will have your Google API for your Gemini models. What we are going to do is we're actually going to use OpenAI and Google AI. So I'm going to set up both my keys, OpenAI key and my Google. I set them up in my environment variable. So, and I'm actually going to use both of these to build agents. The first agent we're going to look at is looking at how to develop a multi-agent system in Streamlit. The concepts remain the same. You have to go initialize your Streamlit application, initialize your variables, build the tools first, then build the agents, then set up the runner, establish session state, and finally run your Streamlit. For this example, we're going to do a simple Streamlit application. This Streamlit application takes the user's details; it sends it to a triage agent or a base agent, and it determines whether it is a homework-related question, and if it is, it will either send it to a math agent which runs simple math problems or to a Spanish agent which runs Spanish translations. The important part is each of these, the Spanish agent and the math agent, are set up as both of these are set up with tools. The math is set up with a simple tool that just does addition. The Spanish is set up with a translation tool that does translation to Spanish. I've added callbacks to all of this process. I've added one callback to the model itself in the very beginning stage that is if there is any blocked word that I'm giving explicitly, the functioning needs to stop; then I'm adding a callback at the Spanish agent's level where the Spanish agent shouldn't run if I ask it to convert any French words to Spanish. So let's take a look at how to build these agents. This example, we're doing them as sub-agents; base agents didn't work as well, and I'll collect and I'll contact and I'll let you know why, and then in the next example, we do the exact same Streamlit and we do it as tool agents, agents as tools.

So, first things to start off with, we're doing our Streamlit setups. We're adding all of our ADK imports that we're doing in this situation. We are having `agent`. We're having Google search, which I'm also adding an additional. In this example, we're also adding multi-model, and we're adding built-in agents to the mix. So Google search will be the built-in agent; it will ask it to do some search. The base agent will give it some search capabilities, and the sub-agents are both going to be running in OpenAI. So we are actually running an agent network, which is multi-model, not just multi-model at the same vendor, multi-vendor multi-model, right, and then we are establishing LightLLM. LightLLM is the tool that's used. LightLLM is a package that's used to allow you to talk to OpenAI-like models. So LightLLM is the one that's used to be model-agnostic in your code. We're adding runners. We're adding tool context, callback context, LLM request, LLM response, base tool, function tool, and agent tool. All these three are important for us because we're using the three different categories. All right. First things first, we have to set up is we have to set up our instructions for our agents. So the default agent, you're giving it certain instructions. You're asking it to think about the discussion, and if it is a tutor question, math goes to math, Spanish goes to Spanish, etc., or if it's a current events-related thing, use Google search to return results. Then you're having your math agent, Spanish agent, and your default search agent. You have some instructions there. Then what we are setting up is our session state. Remember, session state is a session service that has state management of what is being returned by these different agents. So, in session state, we have all of our agent configs. Then we have our guardrails. So two guardrails: one is a blocked word, and the other one is blocked language. And we'll set that up in our guardrail. We'll set that up in our callbacks. Then we load our API keys. It'll respond back if it doesn't have the API key. You have to, if you're using Google, if you're using a Google key from Google AI Studio, make sure you set up `genai_use_vertex` as false. Set up your models that you want to use. And then we go into our tool definitions. Tool definitions. Let's start with, remember I told you that we'll set up a simple math tool for our math agent. A math tool is basically adding two numbers. So we're giving that as the tool ability, and then translate to Spanish. We're going to hardcode that with the ability to translate some basic phrases. Then we have agent call, tool callback. In the agent's tool of convert to Spanish, we're adding "do not convert to Spanish if the word is French." So we're adding those details, and then you have to give some indicator of what words are French. In this example, I'm going to take any of these words; when I use them, it should kick out and call back. After you do that, you should then establish your agents. You're creating your search agent, which is basically your search, Google search. Next, we're creating our agents. We're creating our math agent, which is basically giving all the descriptions. You're adding the tool, which is the solve math problem. Then we are adding our Spanish agent. Spanish agent. We're giving the tool, which is translate to Spanish. Then we are adding our tutor agent. This is the main base agent. So this is the base agent which will have sub-agents, as you can see here, and in addition to that, it will also have tools which are going to be tools. In this example, we're adding the search agent as a tool, and the search agent has a built-in tool, right? So once we have all of this defined, an important point is you need to establish a runner service and then initiate the runner service. So I'm creating a runner service for my root agent. My root agent is the root agent over here, the tutor agent. I'm creating a runner service that looks at my root agent, and it has some session states that I define. Essentially, this is all that's required to set up your agents, agent workflow setup. Now you have to set up the runner and initiate the runner. Everything else is sidebar and Streamlit app. When you ask a question, it will then trigger the runner to run the agent, and the root agent will take care of non-deterministically coordinating all the things it needs to do to use the tools and answer the query. In this case, it's going to answer the query, and it's going to return some results. Let's take a look at this in action and see how this works.

As you can see, for this Streamlit app, we have used multiple models, and we can look at all the agent instructions that are available. You can modify them if you want and save them. You can update your guardrails with like any forbidden word that you want to apply on your model input guardrail, or you could add a French word and affect the tool guardrail. You have a good amount of debugging requirements, just like how the agent development kit had the ADK web; this interface actually gives you all the events as well. So let's look at a simple question. First

question? We'll just hit the base agent. We'll just ask it a "hi," right? So, it goes to the base agent, uh, which is our tutor agent, and it tells you it can handle these things. Let's ask it a math question. At this point, it should use the math agent.

And remember what I told you about the base agent and the sub agents. The sub agents should return the result, not as a tool back to the coordinating agent, but they should return the result. As you can see here, the math agent returned the answers. If you look at our debugging code, you can see all the events that happened.

Now what I want to do is I want to now ask the base agent its questions on any current affairs. Now this is where the base agent is now going to return. It's going to use a tool that we've identified—the Google search tool—and give you the results. Again, it uses the particular tool, and it assumes it uses a particular tool. It's the search agent gets the results and then returns the results.

Now, here's an important thing. Let's see if our guardrails work. Our first guardrail that we're going to test out is a forbidden word. So, we'll just use that as the word, right? Same question that we have asked before, but I've included the forbidden word, and it's kicked me out.

Now, we are going to take a look at the exact same Streamlit, but we're going to use the agents not as sub agents, but as tools. So, the only difference here is it's almost the same concept, uh, where you have your instructions, you have your different tools, you have your guardrails, you have your models, you have your agents, and in this situation for the coordination agent, you're going to add these two agents as tools. So total, we'll have three tools in there. So let's take a look at how that looks, and then let's take a look at how the Streamlit will perform. The advantage of doing this tool method is it controls what the user can see. If you don't want the user to know that this other agent replied back to the user, you want to use the tool method.

So you can see here for the tutor agent that we are calling, we're adding tools. We're adding all the search agent, Spanish agent, and math agent as tools. This will manifest differently. I'm going to have exactly the same one. Everything on the left is the same. Going to ask for it first. Um, "hi." Tells me what it can do. I'm going to ask it a math question. Now, the good thing here is the tool is being triggered. It goes to the math agent, but what is being returned is the tutor agent router itself. If you look at the events, you will see what's happening—that it's calling the agent, returning the value, and then the tutor router is returning the value.

Now a very important point here is that if you then make any sort of extra next questions, it will stay within the same router agents mechanism and it'll answer those questions. So let's ask for uh a simple thing: if if you want the math agent to—to use its tool. So it's basically a tool using a tool. So let's see how that looks. Remember the math agent has a tool for simple additions.

All right. So what is happening here? It's going to the math agent. The math agent is then calling for a simple answer that is in itself using a tool, and then it's being returned. This is how this agent will respond.

Let's take a look at how if we were using deterministic workflow agents how this would look. So we'll have three Streamlit examples: one for sequential, one for parallel, and one for looped.

So for the sequential, what we're going to do is we're going to do a code interpreter. We're going to ask it to generate a piece of snippet of Python code. We're going to pass through different agents that we've set up to evaluate the code, make some suggestions, then make some updates, and in the final agent, we're actually going to use the built-in code interpreter to actually run the code. So, we're going to try that now. Okay, let's take a look at the code first.

Um, we start off with the same importing the different Google ADK libraries. We establish a session for app name, user ID, etc., so that we can set up the session state. We first write the code writer agent. So this is the agent that will develop the code itself. Then we would add the code reviewer agent, code reviewer agent, code refactor agent, and the code interpreter agent. These are agents that you're going to run sequentially. So all of these steps are going to be run sequentially. It's a deterministic way of running agents. And let's take a look at how that is structured. So now it's a simple way of establishing an in-memory session service. So this is what you would set up to set up an in-memory session. Uh, then you would set up a runner. The runner is going to start with the code pipeline agent. The code pipeline agent is one that is going to have all these in sequence. So base agent is code pipeline; code writer, code reviewer, refactor, code interpreter are the sequential steps. So now let's take a look at how we're setting up the base agent. The code pipeline agent is essentially having these steps as sub agents. And if you can see, it's a sequential agent workflow. And these sub agents are these sub agents. Let's run the Streamlit and take a look at how it works.

All right, let's take a look at running this sequential agent Streamlit with an example in Python. So, I want it to give me a Python function. I want to return the amount for an original price and a discount percentage. Return me the amount. So, this should trigger a series of steps. The agent pipeline results should display on the right. This is very crucial in use cases where you have to do a bunch of code scans for a code or if a code needs to refactor in a particular way to a code base. Right? So you can set this up so that there's sequential steps before the code is run on an end product. So in this case, we're actually figuring out and building the code well before we run it in the code interpreter. There you go. That's the code interpreter output; that actually is a run that happened in the back end in code interpreter.

For the loop agents, the concept is pretty straightforward. You have a bunch of sub agents, and you want all of them to run in a loop. And you want them to run in a loop with some condition for how many times you want to run the loop for. In this scenario, we're going to build a pitch enhancer. For example, I love pitching ideas. I want to actually build a tool that when I give my pitch, the agent critiques that pitch and gives me ways to update my pitch. And I want another agent to refine my pitch once it's critiqued based on the critiques and give me a better version of the pitch. So excited to run this, and I've been kind of wanting to build this for a while. Um, so let's build our pitch refinement agent. The steps again are simple. It's the same steps. We are establishing uh Streamlit um dependencies. Then we adding some constants. Um, and in here we are going to establish our agents. First we're going to create a critique agent. A critique agent will take the current pitch. It takes the audience for which the pitch is created, and it gives feedback. That feedback is saved in what's called an output key. Output key is nothing but think of it as a return object for your agent itself. So the output key is going to be saved with state feedback. Now every time an event is run or a call is made to an agent or a group of agents, the output key is like the final return value. So in this case, we've seen the critic agent. Then we'll see the write agent. Writer agent uses the critic provided by the critic agent and enhances our pitch. Both of these will then need to be included in a loop agent, and it's as simple as putting in as loop agent and including the sub agents. Again, the order of the sub agent determines which one runs first. So everything else is the rest of setup for Streamlit. And uh let's get cracking. Let's say this is my starter script. We're building an app to analyze financial data and predict market trends. Um, let's give it something goofy. We're building an app that uses tea leaves to read people's fortunes. Right? I mean, that's sounds like it's a great idea. Let's say the investors are our target audience. So, we're trying to get money. And let's refine our pitch. The first the critic looks at our pitch that we have. Um, it gives us a critic score. These are like just fixed values. But in the first cycle, it basically gave me the critic of like you're not doing any highlighting any unique intellectual properties. So the result draft writer said I'm going to use AI-powered tea leaves to targeting like a billion dollar market, etc. And then the critic said "billion dollar" is like kind of vague; just get specific on it. Show, don't tell; provide data supporting the 90% claim. So the algorithm says 90%. So AI-powered tea leaf fortune-telling app targeting the $50 billion global divination market. Our proprietary algorithm boasts 90% accuracy validated by independent studies. Obviously, it's fudging, but it's a good way to put a pitch. Generating recurring revenue stream via premium subscription and partnerships with brands like Brand A, Brand B. LOI secured. Strong IP protection ensures competitive advantage. Honestly, that's a pretty reasonable pitch, and I—if I—someone came to me with that pitch with all the numbers lining up, I would definitely invest. So, this is an example of how a loop agent works.

For the parallel agent, we're going to do something sort of like what Deep Research and other tools do. We're going to take a topic. We're going to generate three subtopics from that topic. We're going to send each of these subtopics to get data back from different search agents. And once it sends me back the data, I'm going to collect it and generate the report out of it. It's actually a typical researcher—kind of a research assistant. So in this scenario also, it's the same concept. You establish your agents, you set them up, you give them instructions, and then you set up a deterministic parallel agent run with all these three agents. Here the order doesn't matter because everything is running at the same time. So let's take a look at the code. Uh, we are setting up our constants and we're setting up our states. Again, state mechanisms are important because it then gives us an understanding of like what state values it needs to use so that the same session and stuff is used. Then we are setting up our agents. Um, in this—in this app, we're actually going to have one additional non-agent workflow where you're reaching out to—where you're generating subtopics for a topic. So, this is like you don't really need an agent because you are actually using—reg—you are just using LLMs to generate subtopics. You want the user to then select the subtopic, either change it and stuff, and then click "go research," and then it does the research. So for the first one is just a function. Then you're setting up your parallel research assistants and your uh parallel research subtopics. Once you get them, you are establishing your agents. You are setting up your LLM agent here as a researcher agent. And then finally, you have a report synthesizer. What you're doing here is you are running parallel agents. So in the runner parallel, this is a good topic: Healthcare and artificial intelligence in healthcare is a good topic. So I want to generate some subtopics for this. Um, it's giving me some examples. Um, and I want to run parallel research agents. All of these are running at the same time. It's getting those values, and then it's synthesizing this report. Again, very powerful, very cool, very deterministic in its approach, but very powerful in the sense that it's able to collect the data and give it in a very speedy manner.

Now, let's take a look at—once we've finished building our agent, we've tested it, we want to now deploy it. Um, ADK, Google's Agent Development Kit, allows you a multitude of ways for you to distribute your agent or deploy your agent. Um, there's—you can either pick a custom infrastructure where you can build your Docker host and GKE and on-prem way of deploying your agent or you could pick a cloud-based deployment model. In a cloud-based deployment model, you can either pick a Vertex AI's new agent engine or you can run it as a Cloud Run. What is Vertex AI's agent engine? Agent engine is a new fully managed Google Cloud service that developers can deploy agents to. They are used to scale AI agents in production. So essentially if you deploy it there, it's like a Cloud Run or a Cloud Function, but it does a much better job with agents. It's built with agent memory and all that stuff. Um, now to install or deploy your agent in Google's Vertex AI agent engine, you have to go through and run a bunch of steps. And deployment is as easy as running one set of commands on your VS Code. Let's take a look at all of those examples when we get to it. The agent engine is a good way for users to keep a fully managed agent instance without doing much upkeep or without doing much setup. Agent engine supports multiple frameworks. It supports the Google ADK, which is the one we are looking at. It also supports LangChain and other frameworks as well. Um, deploying agents in agent engine is as simple as dockerizing them and deploying them there. The pricing for agent engine—the availability of agent engine right now—general availability is limited in scope. Um, from the US side, only US Central 1 and West 1 have it available. And from a pricing perspective, you're paying for CPU and memory usage. And both of those are covered in this slide here. Um, what we want to do next is take our examples that we've deployed or take an example that we want to construct, go through the full life cycle of that agent—like building it, testing it locally, and then deploying it. And then we're going to actually look at the deployment and use that deployment in a Streamlit just to give that full flavor of what's available.

Now that we have taken a look at what deploying an agent means and where we are deploying it to, let's take a look at the code to deploy it. First of all, before we set up this code, we have to set up our GCP login and authentication and download the Google Cloud SDK. The first thing you'd need to do is go to this link, which I'll put it in the description. You'll install the Vertex AI SDK onto your Mac system. Once you've—in—once you've downloaded the zip file, you will then go to the directory where you've downloaded the zip and then move it to your home directory. Once you've moved it to your home directory, you would then go and do a Google Cloud SDK initiate. And once you do the initiation, it'll install the Google Cloud SDK on your system. Once it's installed, it'll ask you to pick some—it'll ask you to pick some default projects and default regions. Once you do all of that, it'll get you set up. And once you're done with that, you can go ahead and do a Google Cloud auth. And Google Cloud auth will sign you in into the Google Cloud system. So now you're all set up to use Google Cloud Shell on your VS Code and deploy your agent right from your VS Code to Google Cloud. Let's take a look at how you build that code. Again, a lot of this—there's documentation out there, but it's very tough. They've not released Google Cloud Agent Engine in the Google console, so you may not be able to see it. But I have built and included a handy-dandy CLI management tool for coordinating and checking your Google Cloud engines, Google Cloud agent engines. Uh, let's first run that, and I will walk you through that, and I'll run that so you see how the CLI works and how you can manage your own Google Cloud agents on your VS Code. So first things first, um, the command to run to check out or list the agent engines is this: You go to Google Cloud; import from Vertex AI; import agent engines; and list agent engines, and that'll list you all the agent engines. Then I've included in this um codebase ways to delete and update engines. Uh, let's go ahead and run this and uh check it out. So I've set—I've set up a virtual environment. I've installed my Vertex AI. Um, and then I will run my CLI. I'm going to ask for it um to list out any available agents. "No agents found." So, let's deploy our first agent and then come back to CLI and see our agent and delete it from here. Right.

All right. So, deploying an agent, and I will link the code in the description, the GitHub link in the description. And uh let's walk through what the code looks like. So for the first things first, you have to initialize your Vertex AI. Uh, you are then going and importing from the Vertex AI agent engine. You're importing agent engines. Uh, in addition to agent engines, you're also importing agent and agent tool, etc. And so on so forth. um, you are establishing an initialization for your project, your location—right now just US Central 1 is what's supported in the quota—and then you're also establishing a Google Cloud Storage bucket. Uh, then you're initiating your Vertex AI—again, this is different from Google AI Studio; this is Vertex AI, so you have to have a Google Cloud account, you have to have a project there, and so on so forth—then you are—then you are going to go ahead and establish your agent definitions. Here for this example, I'm going to keep it very simple. I'm going to have three translators: Spanish translator, French translator, and an Old English translator. And I'm going to use my coordination agent. Based on my ask, it should probably route it to the right agent and give the result. We are then actually going to deploy this engine. And once we deploy, we're going to build a Streamlit app that uses the engine from the Google Cloud. So just to paraphrase what we're doing in the deployment, we are going to deploy an engine from VS Code. We're going to test it locally and then deploy it. And then once we deploy it, we're going to build a Streamlit app that uses the engine that's set up on the Google Cloud itself.

All right. Now once we set up these agents, um, you will then have to create the tools for these agents. So these agents are now going to be used as tools in our main translator agent. As you can see, we're passing them as tools, and we're adding these ones. We're adding what's called a skip summarization part because we don't want these tools to do any summarizations. We wanted to give exactly the result so that the base agent can run it. We then need to wrap this root agent in an ADK app. So remember how in our web ADK that we did where we showed the thing—similar thing—what we're doing here—the concept for deployment is that once you hit deploy, it dockerizes it, it bundles it, and deploys it into an agent engine. So here you're wrapping it up in this thing called an ADK app, and essentially you're enabling tracing for any tracing—the val—for tracing the logs, etc. So once you do that, you can then do local test first before you deploy. Um, in this scenario, I've commented out the local test. You can do that if you want to. So you can definitely run the local test. In the instance of you running the local test, make sure you comment out the deployment, and that will make sure you're just testing the agents locally. So once you're done—take this—and we are going to run. So then once you're actually done with the local testing, you'd then deploy this agent. The Google Cloud deploy command is essentially this: You go—said agent engines.create. That's the thing that will give the instruction for Google to create an agent engine using your wrapped agent app that you just created. So it will now create that, and then once it finishes creating, we're going to test out the remote app. So we're going to just basically—once it finishes creating—we're going to create a session, and we're going to give it some responses and see if it's resulting back. So let's go ahead and test this out. So I am going to run this whole thing in here. So what it's going to do now is it's going to go ahead and create an app. And as you can see, it's initiated all my agents. It's initiated my app, and then it's taking my app and deploying it to the bucket as a Docker, and then from there deploying it to the agent engines. You can also deploy it to your Kubernetes engines or Cloud Runs. Uh, so this process is going to take at least two to three minutes.

All right. So let's now see how this looks deployed. You can see here that I've run the tests post-deployment that were included in the script. They are now showing up in the deployment logs, and it now has a detail around what it can return, and we should be able to now take this and test it with our CLI. The CLI will be able to tell us what agent was created, what was the details of the agent, etc.

All right. So, if you can see the CLI when I list my agents, I see my agent. That's the agent that was deployed. You can see the name of the description, etc. This will tell us exactly when the agent was deployed, what are its details. You can use the CLI to do other things like update and delete, etc., but at this point, we should just keep it to uh active so that we can test this agent in a Streamlit app.

All right. So let's take a look at the Streamlit app. This is the Streamlit app that is going to connect to the GCP's agent engine and use our agent to return values. Um, the concept is same—like you establish your Streamlit connections. Uh, you will need to like give the details of the resource ID. The resource ID that this agent is set up in. You will have to get the resource agent ID, and you will have to like establish the resource with its full resource name, which includes your project ID, uh location, etc. Now for getting your resource ID, you can use the CLI; that's a great tool. Um, that is how I've kind of structured this. I've also given it in a way that the Streamlit itself—you can enter those details so that it reads any agent that you want. So you can actually use this for any agent. Then you have to—in this example, we're setting up a simple translation example, right—so you have to build your Streamlit UI, you have to develop it, you have to—agent ID—and we are going to be invoking this and running this, so the remote app is the app that we've—we have established on our street—on our agent engine, and we are going to invoke the remote app with the invocation there, and—and this way our Streamlit should be able to connect to GCP and get the details. As you can see, I have some older engine IDs there. So the Streamlit is failing. I'm going to convert and add the engine ID that we just deployed. And I can use that by going into my CLI commands that I ran and gave me the engine ID. So I'm going to grab that, put it in my Streamlit. And once I put it in there, it should validate, and it should show me the agent that I'm going to be connecting to. So this is the agent that I'm connecting to. And then let's test it out with some translate text. You can see that this call is actually going to the Vertex AI engine, and it is returning all the results.

Now that we have finished our test, let's go ahead and find our agent and delete it so that we don't incur any extra cost. We go back to our CLI. We enter our agent list, and then we go ahead and pick the agent that we want to delete. We want to give a "d," and then pick the agent number and then double confirm just because it's going to delete all parent and child entries. Uh, and this is a good way for you to actually manage your agents. And like I said, the CLI will be included in my code uh that you can take and fork and use it on your own. In this way, users can use Google's new Agent Development Kit to build multi-agent,

Multi-vendor agents, and all kinds of agents. Build them easily, test them, evaluate them, and even deploy them in Google's own architecture. Users can then take these tools to build and augment their existing applications or drive some exciting applications in the future.

Uh, all of the code that you've seen today is available in my GitHub. Follow along for all the cool stuff that we're building.

I'm still in the process of developing the master fitness/health companion app that will change everybody's purview on how one can manage their own health. Uh, that has a lot of agent stuff coming along. So that's looking good. [Music]