{"id":458115,"date":"2025-04-29T15:01:26","date_gmt":"2025-04-29T15:01:26","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=458115"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=458115","title":{"rendered":"<span>Google ADK: Easiest Way to Build an AI Agent<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>In this tutorial, I\u2019ll explain in simple terms what AI, AI agents, and workflows are, and then I\u2019ll walk you through building your very first AI agent in Python using Google\u2019s Agent Development Kit (ADK). By the end, you\u2019ll understand the differences between these concepts and have a working content-assistant agent you can run from your terminal or a web interface.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d27\/161\/d35\/d27161d35715ad45f1019b8c54abcfe5.png\" alt=\"Google ADK: Easiest Way to Build an AI Agent \" title=\"Google ADK: Easiest Way to Build an AI Agent \" width=\"1317\" height=\"749\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/d27\/161\/d35\/d27161d35715ad45f1019b8c54abcfe5.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d27\/161\/d35\/d27161d35715ad45f1019b8c54abcfe5.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Google ADK: Easiest Way to Build an AI Agent <\/figcaption><\/div>\n<\/figure>\n<h3>Key Concepts<\/h3>\n<p>In the world of modern automation and smart systems, it is helpful to consider three key building blocks: AI, AI agents, and workflows.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/584\/057\/cf4\/584057cf4544794f6aade49182f17653.png\" alt=\"Key Concepts\" title=\"Key Concepts\" width=\"1536\" height=\"1024\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/584\/057\/cf4\/584057cf4544794f6aade49182f17653.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/584\/057\/cf4\/584057cf4544794f6aade49182f17653.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Key Concepts<\/figcaption><\/div>\n<\/figure>\n<h4>AI (Artificial Intelligence)<\/h4>\n<p>Think of AI as the \u201cbrain\u201d of technology. It learns patterns from data\u2014text, images, or numbers\u2014and uses them to translate sentences, recognize pictures, or predict the weather. On its own, AI only provides a narrow ability to think or understand; it doesn\u2019t decide when or how to use that ability.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a8b\/49c\/5a1\/a8b49c5a1968edc372dec4ad59df848d.png\" alt=\"AI (Artificial Intelligence)\" title=\"AI (Artificial Intelligence)\" width=\"1024\" height=\"1024\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/a8b\/49c\/5a1\/a8b49c5a1968edc372dec4ad59df848d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a8b\/49c\/5a1\/a8b49c5a1968edc372dec4ad59df848d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>AI (Artificial Intelligence)<\/figcaption><\/div>\n<\/figure>\n<p><strong>For instance:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>Spam filter<\/strong> in your email: it \u201cknows\u201d patterns of junk mail and flags them for you.<\/p>\n<\/li>\n<li>\n<p><strong>Language translator<\/strong> on your phone: type a sentence in English and it instantly translates it into French.<\/p>\n<\/li>\n<li>\n<p><strong>A photo app<\/strong> that tags \u201cbeach,\u201d \u201cdog,\u201d or \u201csunset\u201d in your pictures automatically.<\/p>\n<\/li>\n<\/ul>\n<h4>Workflows<\/h4>\n<p>Workflows enable you to map out a flowchart of steps that connect various apps and services. You select a trigger, such as a new entry appearing in a spreadsheet, and then define a sequence of actions like sending an email, posting to a chat channel, or invoking an AI process to analyze the data. Once activated, the workflow follows those rules precisely\u2014each step always leads to the next, with no decision-making beyond what you\u2019ve laid out.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a47\/824\/048\/a47824048d6f62d1124e22a54528d36e.png\" alt=\"Workflows\" title=\"Workflows\" width=\"1024\" height=\"1024\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/a47\/824\/048\/a47824048d6f62d1124e22a54528d36e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a47\/824\/048\/a47824048d6f62d1124e22a54528d36e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Workflows<\/figcaption><\/div>\n<\/figure>\n<p><strong>For instance:<\/strong><\/p>\n<ul>\n<li>\n<p>Whenever someone fills out your Google Sheet, automatically send a summary email to you (or your team).<\/p>\n<\/li>\n<li>\n<p>As soon as your favorite blog publishes a post, post the headline and link in your Slack channel.<\/p>\n<\/li>\n<li>\n<p>When a customer submits your web form, add their info to Salesforce and tag them \u201cnew lead.\u201dPutting It All Together<\/p>\n<\/li>\n<\/ul>\n<h4>AI Agent<\/h4>\n<p>An AI agent is like giving that \u201cbrain\u201d a body and a job. It can take in new information, such as your questions or the contents of a web page, use an AI model to decide what to do, and then run code, call APIs, send an email, or update a spreadsheet. In other words, an AI agent wraps an AI model in rules and tools so it can work for you automatically, planning multiple steps, adjusting if something goes wrong, and even choosing which tool to use next.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/462\/308\/947\/4623089475be8296c8ad28b460b92487.png\" alt=\"AI Agent\" title=\"AI Agent\" width=\"1024\" height=\"1024\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/462\/308\/947\/4623089475be8296c8ad28b460b92487.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/462\/308\/947\/4623089475be8296c8ad28b460b92487.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>AI Agent<\/figcaption><\/div>\n<\/figure>\n<p><strong>For instance:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>Smart inbox assistant<\/strong>: it reads new emails, summarizes them, drafts replies, and even sends follow-ups if no one responds.<\/p>\n<\/li>\n<li>\n<p><strong>Travel planner bot<\/strong>: you say \u201cbook me a weekend in Chiang Mai,\u201d it searches flights, picks the best price, reserves a hotel, and emails you the itinerary.<\/p>\n<\/li>\n<li>\n<p><strong>Social-media manager<\/strong>: it watches for brand mentions, analyzes sentiment, then posts thank-you replies or escalates complaints to the support team.<\/p>\n<\/li>\n<\/ul>\n<h4>Putting It All Together<\/h4>\n<ul>\n<li>\n<p><strong>AI alone<\/strong> is the smart engine (like a chess computer that knows how to play).<\/p>\n<\/li>\n<li>\n<p><strong>An AI agent<\/strong> is that engine plus instructions and tools (like a chess-playing robot that can decide which tournament to enter, book its own travel, and adjust its strategy if the Wi-Fi drops).<\/p>\n<\/li>\n<li>\n<p><strong>A workflow<\/strong> is a fixed recipe you build by hand (like a conveyor belt in a factory: if one widget arrives, do steps 1\u21922\u21923 every time, no surprises).<\/p>\n<\/li>\n<\/ul>\n<p>Okay, now that we have more clarity on these, let&#8217;s dive into Google&#8217;s ADK.<\/p>\n<h3>What Is Google\u2019s Agent Development Kit?<\/h3>\n<p><a href=\"https:\/\/google.github.io\/adk-docs\/tutorials\/\" rel=\"noopener noreferrer nofollow\"><strong>Google\u2019s Agent Development Kit (ADK)<\/strong>\u00a0<\/a>is an open-source Python toolkit that makes it easier to create AI agents. Think of ADK as a collection of libraries and tools that handle a lot of the heavy lifting so that we can focus on an agent\u2019s logic and abilities instead of low-level details.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1e6\/4c8\/ffa\/1e64c8ffa058637f2e9d539fa2ac5686.png\" alt=\"Google\u2019s Agent Development Kit\" title=\"Google\u2019s Agent Development Kit\" width=\"1556\" height=\"1056\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/1e6\/4c8\/ffa\/1e64c8ffa058637f2e9d539fa2ac5686.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1e6\/4c8\/ffa\/1e64c8ffa058637f2e9d539fa2ac5686.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Google\u2019s Agent Development Kit<\/figcaption><\/div>\n<\/figure>\n<p><strong>Key features of ADK:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>Flexible &amp; Modular:<\/strong> Start simple or scale to multi-agent workflows without rewriting core code.<\/p>\n<\/li>\n<li>\n<p><strong>Code-First:<\/strong> Define your agent\u2019s logic, tools, and tests entirely in Python.<\/p>\n<\/li>\n<li>\n<p><strong>Tool Integration:<\/strong> Plug in any Python function (API call, data fetch, computation) as an agent capability.<\/p>\n<\/li>\n<li>\n<p><strong>Model-Agnostic:<\/strong> Use Google\u2019s Gemini models or any LLM (OpenAI, Anthropic, Meta) via LiteLLM.<\/p>\n<\/li>\n<li>\n<p><strong>Orchestration &amp; Memory:<\/strong> Built-in context tracking, multi-turn conversation handling, and session memory.<\/p>\n<\/li>\n<\/ul>\n<p>In summary, ADK provides a robust foundation for building an AI agent\u00a0quickly and reliably. Now, let\u2019s prepare our environment and develop our first agent.<\/p>\n<h3>Build a Content Assistant AI Agent<\/h3>\n<p>We are going to build an AI Agent that will help us brainstorm topic ideas, then draft the article content, and then create a formatted draft in markdown. This agent has multiple sub-agents that work together.<\/p>\n<p>Here\u2019s how it works:<\/p>\n<ul>\n<li>\n<p><strong>Idea Agent<\/strong> \u2013 comes up with topic ideas.<\/p>\n<\/li>\n<li>\n<p><strong>Writer Agent<\/strong> \u2013 turns ideas into a draft.<\/p>\n<\/li>\n<li>\n<p><strong>Formatter Agent<\/strong> \u2013 turns the draft into something ready to publish.<\/p>\n<\/li>\n<\/ul>\n<p>Each sub-agent does its part. The main agent runs them all in order.<\/p>\n<h4>Setup and Prerequisites<\/h4>\n<ul>\n<li>\n<p>Download VS Code or another IDE.<\/p>\n<\/li>\n<li>\n<p><strong>Install Python and PIP<\/strong> if you don\u2019t have it.<\/p>\n<\/li>\n<li>\n<p><strong>Create and activate a virtual environment<\/strong> in your project folder:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"bash\">python3 -m venv venv source venv\/bin\/activate   # macOS\/Linux .\\venv\\Scripts\\activate    # Windows<\/code><\/pre>\n<ul>\n<li>\n<p>Install Google\u2019s ADK and Dependencies<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"bash\">pip install google-generativeai google-ad-agents<\/code><\/pre>\n<ul>\n<li>\n<p>Create a project folder for your agent.<\/p>\n<\/li>\n<\/ul>\n<pre><code>mkdir adk-example cd adk-example<\/code><\/pre>\n<ul>\n<li>\n<p>Get API Key for Gemini<\/p>\n<ul>\n<li>\n<p>Go to <a href=\"https:\/\/aistudio.google.com\/\" rel=\"noopener noreferrer nofollow\">https:\/\/aistudio.google.com\/<\/a>, sign in, and click Get API Key. <\/p>\n<\/li>\n<li>\n<p>Create a new key and copy it\u2014treat it like a password. <\/p>\n<\/li>\n<li>\n<p>In your project folder, create a file named .env:<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre><code class=\"python\">GEMINI_API_KEY=YOUR_API_KEY_HERE<\/code><\/pre>\n<ul>\n<li>\n<p>Create an <strong>init <\/strong>file and add the following content:<\/p>\n<\/li>\n<\/ul>\n<pre><code># __init__.py from . import agent<\/code><\/pre>\n<ul>\n<li>\n<p>Create an <strong>agent.py <\/strong>file.<\/p>\n<\/li>\n<\/ul>\n<p>Your project structure should look like this:<\/p>\n<pre><code class=\"bash\">my-agent-project\/ \u251c\u2500\u2500 agent.py \u251c\u2500\u2500 __init__.py \u2514\u2500\u2500 .env<\/code><\/pre>\n<ul>\n<li>\n<p>Copy the following code inside your agent.py file:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"python\"># agent.py  import os                     # Provides functions for interacting with the operating system\\ nfrom dotenv import load_dotenv  # Loads environment variables from a .env file from dotenv import load_dotenv import google.generativeai as genai  # Official Google Generative AI SDK aliased as \"genai\" from google.adk.agents import LlmAgent, SequentialAgent  # ADK classes for building language-model agents  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 0) Load .env from this folder # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), \".env\"))  # Read the .env file in the same directory as this script  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 1) Configure the Google Gen AI SDK using your .env # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 api_key = os.getenv(\"GOOGLE_API_KEY\")  # Retrieve the API key from environment variables if not api_key:     raise RuntimeError(\"Missing GOOGLE_API_KEY in .env\")  # Halt if the key is not set genai.configure(api_key=api_key)  # Initialize the generative-ai SDK with your key  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 2) Tool functions that actually call Gemini # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014  def generate_ideas(topic: str) -&gt; str:     \"\"\"Ask Gemini to brainstorm blog post idea for a topic.\"\"\"     model = genai.GenerativeModel(model_name=\"gemini-2.0-flash\")  # Create a Gemini model instance     resp = model.generate_content(         f\"Brainstorm 4\u20136 creative blog post ideas for the topic:\\n\\n{topic}\"     )  # Generate the ideas     return resp.text  # Return only the generated text   def write_content(ideas: str) -&gt; str:     \"\"\"Ask Gemini to expand an outline into a ~300-word draft.\"\"\"     model = genai.GenerativeModel(model_name=\"gemini-2.0-flash\")  # Instantiate the model again     resp = model.generate_content(         \"Expand the following outline into a cohesive ~300-word blog post:\\n\\n\"         f\"{ideas}\"     )  # Generate the full draft     return resp.text  # Return the draft text   def format_draft(draft: str) -&gt; str:     \"\"\"Ask Gemini to format the draft as clean Markdown.\"\"\"     model = genai.GenerativeModel(model_name=\"gemini-2.0-flash\")  # New model instance for formatting     resp = model.generate_content(         \"Format this draft as clean Markdown with headings, sub-headings, and bullet lists:\\n\\n\"         f\"{draft}\"     )  # Generate formatted Markdown     return resp.text  # Return the formatted markdown  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 3) Define your three LLM agents # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014  topic_agent = LlmAgent(     name=\"IdeaAgent\",  # Unique identifier for the agent     model=\"gemini-2.0-flash\",  # Model spec to use     description=\"Brainstorms blog post ideas.\",  # Purpose of this agent     instruction=(         \"Call generate_ideas(topic) with the exact topic string you receive \"         \"and return only the ideas.\"     ),  # How the agent should behave     tools=[generate_ideas],  # List of Python functions it can invoke     output_key=\"ideas\"  # Where to store the result in shared state )  draft_agent = LlmAgent(     name=\"WriterAgent\",     model=\"gemini-2.0-flash\",     description=\"Writes a blog post draft from ideas.\",     instruction=(         \"Call write_content(ideas), where `ideas` is the output from the prior step, \"         \"and return only the draft text.\"     ),     tools=[write_content],     output_key=\"draft\" )  format_agent = LlmAgent(     name=\"FormatterAgent\",     model=\"gemini-2.0-flash\",     description=\"Formats the draft into Markdown.\",     instruction=(         \"Call format_draft(draft), where `draft` is the previous output, \"         \"and return only the final Markdown.\"     ),     tools=[format_draft],     output_key=\"formatted\" )  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 4) Put them in a SequentialAgent pipeline # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014  root_agent = SequentialAgent(     name=\"ContentAssistant\",  # Top-level orchestration agent     sub_agents=[topic_agent, draft_agent, format_agent],  # Steps in order     description=\"Takes a user topic \u2192 generates ideas \u2192 writes draft \u2192 formats as Markdown\" ) <\/code><\/pre>\n<p>Ok, your agent is ready, and now you can run it inside the terminal. <\/p>\n<p>In your project\u2019s parent folder, start the agent with:<\/p>\n<pre><code>adk run [your-project-folder]<\/code><\/pre>\n<p>You\u2019ll see each step\u2019s output in your terminal.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b5a\/f7a\/d00\/b5af7ad0051728f9e0908b9857cc16b6.png\" alt=\"AI Agent in your terminal\" title=\"AI Agent in your terminal\" width=\"2556\" height=\"1133\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/b5a\/f7a\/d00\/b5af7ad0051728f9e0908b9857cc16b6.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b5a\/f7a\/d00\/b5af7ad0051728f9e0908b9857cc16b6.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>AI Agent in your terminal<\/figcaption><\/div>\n<\/figure>\n<p>If you want to use a web UI, you can run the following command from the parent folder:<\/p>\n<pre><code class=\"bash\">adk web<\/code><\/pre>\n<p>Then open the URL shown in your browser and select your project (e.g., <strong>adk-example<\/strong>) in the top left menu.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5ad\/75c\/957\/5ad75c95784565707ba8443fc9499ac5.png\" alt=\"web UI\" title=\"web UI\" width=\"2556\" height=\"1133\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/5ad\/75c\/957\/5ad75c95784565707ba8443fc9499ac5.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5ad\/75c\/957\/5ad75c95784565707ba8443fc9499ac5.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>web UI<\/figcaption><\/div>\n<\/figure>\n<p>Enter your prompt and watch each agent step appear in real time. \ud83d\ude42<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/15f\/63b\/8f7\/15f63b8f7c903398ea3abedb741eed34.png\" alt=\"web UI\" title=\"web UI\" width=\"2555\" height=\"1347\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/15f\/63b\/8f7\/15f63b8f7c903398ea3abedb741eed34.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/15f\/63b\/8f7\/15f63b8f7c903398ea3abedb741eed34.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>web UI<\/figcaption><\/div>\n<\/figure>\n<p>All the code you can download from my GitHub repository &#8212; <a href=\"https:\/\/github.com\/proflead\/how-to-build-ai-agent\" rel=\"noopener noreferrer nofollow\">how to build an AI agent<\/a>.<\/p>\n<p>The full docs of Google\u2019s ADK can be found <a href=\"https:\/\/google.github.io\/adk-docs\/\" rel=\"noopener noreferrer nofollow\">here<\/a>.<\/p>\n<h2>How to Build an AI Agent: A Video Tutorial<\/h2>\n<p>I also created a video tutorial where I take you step by step through each step.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6810a069fec567ba65cc7069\" data-style=\"\" id=\"6810a069fec567ba65cc7069\" width=\"\"><\/div>\n<p><em>Watch on YouTube: <\/em><a href=\"https:\/\/youtu.be\/yVIWyKJPTKo?si=-XUdERnkjL0QcPFX\" rel=\"noopener noreferrer nofollow\"><em>AI Agent Explained: How to Build an AI Agent with Google ADK<\/em><\/a><\/p>\n<h3>Conclusion<\/h3>\n<p>Now you know the difference between AI, workflows, and AI agents\u2014and you\u2019ve built a simple content-assistant agent using Google\u2019s ADK and Python. If you try this out or extend it, I\u2019d love to see what you come up with! Share your projects or questions in the comments. <\/p>\n<p>Thanks for reading, and happy coding!<\/p>\n<p>Cheers! \ud83d\ude09<\/p>\n<p>src:\u00a0<a href=\"https:\/\/proflead.dev\/posts\/ai-agent-explained-google-adk\/\" rel=\"noopener noreferrer nofollow\">Ai Agent Explained<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/905468\/\"> https:\/\/habr.com\/ru\/articles\/905468\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>In this tutorial, I\u2019ll explain in simple terms what AI, AI agents, and workflows are, and then I\u2019ll walk you through building your very first AI agent in Python using Google\u2019s Agent Development Kit (ADK). By the end, you\u2019ll understand the differences between these concepts and have a working content-assistant agent you can run from your terminal or a web interface.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Google ADK: Easiest Way to Build an AI Agent <\/figcaption><\/div>\n<\/figure>\n<h3>Key Concepts<\/h3>\n<p>In the world of modern automation and smart systems, it is helpful to consider three key building blocks: AI, AI agents, and workflows.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Key Concepts<\/figcaption><\/div>\n<\/figure>\n<h4>AI (Artificial Intelligence)<\/h4>\n<p>Think of AI as the \u201cbrain\u201d of technology. It learns patterns from data\u2014text, images, or numbers\u2014and uses them to translate sentences, recognize pictures, or predict the weather. On its own, AI only provides a narrow ability to think or understand; it doesn\u2019t decide when or how to use that ability.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>AI (Artificial Intelligence)<\/figcaption><\/div>\n<\/figure>\n<p><strong>For instance:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>Spam filter<\/strong> in your email: it \u201cknows\u201d patterns of junk mail and flags them for you.<\/p>\n<\/li>\n<li>\n<p><strong>Language translator<\/strong> on your phone: type a sentence in English and it instantly translates it into French.<\/p>\n<\/li>\n<li>\n<p><strong>A photo app<\/strong> that tags \u201cbeach,\u201d \u201cdog,\u201d or \u201csunset\u201d in your pictures automatically.<\/p>\n<\/li>\n<\/ul>\n<h4>Workflows<\/h4>\n<p>Workflows enable you to map out a flowchart of steps that connect various apps and services. You select a trigger, such as a new entry appearing in a spreadsheet, and then define a sequence of actions like sending an email, posting to a chat channel, or invoking an AI process to analyze the data. Once activated, the workflow follows those rules precisely\u2014each step always leads to the next, with no decision-making beyond what you\u2019ve laid out.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Workflows<\/figcaption><\/div>\n<\/figure>\n<p><strong>For instance:<\/strong><\/p>\n<ul>\n<li>\n<p>Whenever someone fills out your Google Sheet, automatically send a summary email to you (or your team).<\/p>\n<\/li>\n<li>\n<p>As soon as your favorite blog publishes a post, post the headline and link in your Slack channel.<\/p>\n<\/li>\n<li>\n<p>When a customer submits your web form, add their info to Salesforce and tag them \u201cnew lead.\u201dPutting It All Together<\/p>\n<\/li>\n<\/ul>\n<h4>AI Agent<\/h4>\n<p>An AI agent is like giving that \u201cbrain\u201d a body and a job. It can take in new information, such as your questions or the contents of a web page, use an AI model to decide what to do, and then run code, call APIs, send an email, or update a spreadsheet. In other words, an AI agent wraps an AI model in rules and tools so it can work for you automatically, planning multiple steps, adjusting if something goes wrong, and even choosing which tool to use next.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>AI Agent<\/figcaption><\/div>\n<\/figure>\n<p><strong>For instance:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>Smart inbox assistant<\/strong>: it reads new emails, summarizes them, drafts replies, and even sends follow-ups if no one responds.<\/p>\n<\/li>\n<li>\n<p><strong>Travel planner bot<\/strong>: you say \u201cbook me a weekend in Chiang Mai,\u201d it searches flights, picks the best price, reserves a hotel, and emails you the itinerary.<\/p>\n<\/li>\n<li>\n<p><strong>Social-media manager<\/strong>: it watches for brand mentions, analyzes sentiment, then posts thank-you replies or escalates complaints to the support team.<\/p>\n<\/li>\n<\/ul>\n<h4>Putting It All Together<\/h4>\n<ul>\n<li>\n<p><strong>AI alone<\/strong> is the smart engine (like a chess computer that knows how to play).<\/p>\n<\/li>\n<li>\n<p><strong>An AI agent<\/strong> is that engine plus instructions and tools (like a chess-playing robot that can decide which tournament to enter, book its own travel, and adjust its strategy if the Wi-Fi drops).<\/p>\n<\/li>\n<li>\n<p><strong>A workflow<\/strong> is a fixed recipe you build by hand (like a conveyor belt in a factory: if one widget arrives, do steps 1\u21922\u21923 every time, no surprises).<\/p>\n<\/li>\n<\/ul>\n<p>Okay, now that we have more clarity on these, let&#8217;s dive into Google&#8217;s ADK.<\/p>\n<h3>What Is Google\u2019s Agent Development Kit?<\/h3>\n<p><a href=\"https:\/\/google.github.io\/adk-docs\/tutorials\/\" rel=\"noopener noreferrer nofollow\"><strong>Google\u2019s Agent Development Kit (ADK)<\/strong>\u00a0<\/a>is an open-source Python toolkit that makes it easier to create AI agents. Think of ADK as a collection of libraries and tools that handle a lot of the heavy lifting so that we can focus on an agent\u2019s logic and abilities instead of low-level details.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Google\u2019s Agent Development Kit<\/figcaption><\/div>\n<\/figure>\n<p><strong>Key features of ADK:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>Flexible &amp; Modular:<\/strong> Start simple or scale to multi-agent workflows without rewriting core code.<\/p>\n<\/li>\n<li>\n<p><strong>Code-First:<\/strong> Define your agent\u2019s logic, tools, and tests entirely in Python.<\/p>\n<\/li>\n<li>\n<p><strong>Tool Integration:<\/strong> Plug in any Python function (API call, data fetch, computation) as an agent capability.<\/p>\n<\/li>\n<li>\n<p><strong>Model-Agnostic:<\/strong> Use Google\u2019s Gemini models or any LLM (OpenAI, Anthropic, Meta) via LiteLLM.<\/p>\n<\/li>\n<li>\n<p><strong>Orchestration &amp; Memory:<\/strong> Built-in context tracking, multi-turn conversation handling, and session memory.<\/p>\n<\/li>\n<\/ul>\n<p>In summary, ADK provides a robust foundation for building an AI agent\u00a0quickly and reliably. Now, let\u2019s prepare our environment and develop our first agent.<\/p>\n<h3>Build a Content Assistant AI Agent<\/h3>\n<p>We are going to build an AI Agent that will help us brainstorm topic ideas, then draft the article content, and then create a formatted draft in markdown. This agent has multiple sub-agents that work together.<\/p>\n<p>Here\u2019s how it works:<\/p>\n<ul>\n<li>\n<p><strong>Idea Agent<\/strong> \u2013 comes up with topic ideas.<\/p>\n<\/li>\n<li>\n<p><strong>Writer Agent<\/strong> \u2013 turns ideas into a draft.<\/p>\n<\/li>\n<li>\n<p><strong>Formatter Agent<\/strong> \u2013 turns the draft into something ready to publish.<\/p>\n<\/li>\n<\/ul>\n<p>Each sub-agent does its part. The main agent runs them all in order.<\/p>\n<h4>Setup and Prerequisites<\/h4>\n<ul>\n<li>\n<p>Download VS Code or another IDE.<\/p>\n<\/li>\n<li>\n<p><strong>Install Python and PIP<\/strong> if you don\u2019t have it.<\/p>\n<\/li>\n<li>\n<p><strong>Create and activate a virtual environment<\/strong> in your project folder:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"bash\">python3 -m venv venv source venv\/bin\/activate   # macOS\/Linux .\\venv\\Scripts\\activate    # Windows<\/code><\/pre>\n<ul>\n<li>\n<p>Install Google\u2019s ADK and Dependencies<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"bash\">pip install google-generativeai google-ad-agents<\/code><\/pre>\n<ul>\n<li>\n<p>Create a project folder for your agent.<\/p>\n<\/li>\n<\/ul>\n<pre><code>mkdir adk-example cd adk-example<\/code><\/pre>\n<ul>\n<li>\n<p>Get API Key for Gemini<\/p>\n<ul>\n<li>\n<p>Go to <a href=\"https:\/\/aistudio.google.com\/\" rel=\"noopener noreferrer nofollow\">https:\/\/aistudio.google.com\/<\/a>, sign in, and click Get API Key. <\/p>\n<\/li>\n<li>\n<p>Create a new key and copy it\u2014treat it like a password. <\/p>\n<\/li>\n<li>\n<p>In your project folder, create a file named .env:<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre><code class=\"python\">GEMINI_API_KEY=YOUR_API_KEY_HERE<\/code><\/pre>\n<ul>\n<li>\n<p>Create an <strong>init <\/strong>file and add the following content:<\/p>\n<\/li>\n<\/ul>\n<pre><code># __init__.py from . import agent<\/code><\/pre>\n<ul>\n<li>\n<p>Create an <strong>agent.py <\/strong>file.<\/p>\n<\/li>\n<\/ul>\n<p>Your project structure should look like this:<\/p>\n<pre><code class=\"bash\">my-agent-project\/ \u251c\u2500\u2500 agent.py \u251c\u2500\u2500 __init__.py \u2514\u2500\u2500 .env<\/code><\/pre>\n<ul>\n<li>\n<p>Copy the following code inside your agent.py file:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"python\"># agent.py  import os                     # Provides functions for interacting with the operating system\\ nfrom dotenv import load_dotenv  # Loads environment variables from a .env file from dotenv import load_dotenv import google.generativeai as genai  # Official Google Generative AI SDK aliased as \"genai\" from google.adk.agents import LlmAgent, SequentialAgent  # ADK classes for building language-model agents  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 0) Load .env from this folder # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), \".env\"))  # Read the .env file in the same directory as this script  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 1) Configure the Google Gen AI SDK using your .env # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 api_key = os.getenv(\"GOOGLE_API_KEY\")  # Retrieve the API key from environment variables if not api_key:     raise RuntimeError(\"Missing GOOGLE_API_KEY in .env\")  # Halt if the key is not set genai.configure(api_key=api_key)  # Initialize the generative-ai SDK with your key  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 2) Tool functions that actually call Gemini # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014  def generate_ideas(topic: str) -&gt; str:     \"\"\"Ask Gemini to brainstorm blog post idea for a topic.\"\"\"     model = genai.GenerativeModel(model_name=\"gemini-2.0-flash\")  # Create a Gemini model instance     resp = model.generate_content(         f\"Brainstorm 4\u20136 creative blog post ideas for the topic:\\n\\n{topic}\"     )  # Generate the ideas     return resp.text  # Return only the generated text   def write_content(ideas: str) -&gt; str:     \"\"\"Ask Gemini to expand an outline into a ~300-word draft.\"\"\"     model = genai.GenerativeModel(model_name=\"gemini-2.0-flash\")  # Instantiate the model again     resp = model.generate_content(         \"Expand the following outline into a cohesive ~300-word blog post:\\n\\n\"         f\"{ideas}\"     )  # Generate the full draft     return resp.text  # Return the draft text   def format_draft(draft: str) -&gt; str:     \"\"\"Ask Gemini to format the draft as clean Markdown.\"\"\"     model = genai.GenerativeModel(model_name=\"gemini-2.0-flash\")  # New model instance for formatting     resp = model.generate_content(         \"Format this draft as clean Markdown with headings, sub-headings, and bullet lists:\\n\\n\"         f\"{draft}\"     )  # Generate formatted Markdown     return resp.text  # Return the formatted markdown  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 3) Define your three LLM agents # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014  topic_agent = LlmAgent(     name=\"IdeaAgent\",  # Unique identifier for the agent     model=\"gemini-2.0-flash\",  # Model spec to use     description=\"Brainstorms blog post ideas.\",  # Purpose of this agent     instruction=(         \"Call generate_ideas(topic) with the exact topic string you receive \"         \"and return only the ideas.\"     ),  # How the agent should behave     tools=[generate_ideas],  # List of Python functions it can invoke     output_key=\"ideas\"  # Where to store the result in shared state )  draft_agent = LlmAgent(     name=\"WriterAgent\",     model=\"gemini-2.0-flash\",     description=\"Writes a blog post draft from ideas.\",     instruction=(         \"Call write_content(ideas), where `ideas` is the output from the prior step, \"         \"and return only the draft text.\"     ),     tools=[write_content],     output_key=\"draft\" )  format_agent = LlmAgent(     name=\"FormatterAgent\",     model=\"gemini-2.0-flash\",     description=\"Formats the draft into Markdown.\",     instruction=(         \"Call format_draft(draft), where `draft` is the previous output, \"         \"and return only the final Markdown.\"     ),     tools=[format_draft],     output_key=\"formatted\" )  # \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014 # 4) Put them in a<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-458115","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/458115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=458115"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/458115\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=458115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=458115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=458115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}