使用 Google ADK 建構 AI 代理

1. 簡介

在本程式碼研究室中,您將使用 Google 的 Agent Development Kit (ADK) 和 Gemini,逐步建構第一個 AI 代理。您將建立基本的網誌文章撰寫代理程式,規劃及撰寫內容,展現推論和行動的核心概念。

學習內容

  • 設定 ADK 開發環境。
  • 使用 Planner 和 Writer 建立多代理系統。
  • 在本機執行代理,並透過 ADK 網路 UI 與其互動。

軟硬體需求

  • 網路瀏覽器,例如 Chrome
  • 電腦上已安裝 Python 3.10 以上版本。
  • Google AI Studio API 金鑰。

本程式碼研究室適合各種程度的開發人員,包括初學者。

預估時間:30 分鐘。

2. 圖像指南:什麼是 AI 代理?

開始建構前,我們先快速瞭解 AI 代理程式是什麼,以及常見的模式。

什麼是 AI 代理?

what-are-ai-agents.png

簡單來說,代理程式是一種軟體,不僅能回答問題,還能做出決策並採取行動。代理程式不會像傳統聊天機器人一樣產生單一回覆,而是會查看您的要求、找出要採取的步驟、呼叫 API、執行程式碼、查看結果,然後決定下一步動作。

foundation-reasoning-acting.png

其中最清楚的說明來自研究論文「ReAct:在語言模型中整合推理和行動」。該論文的概念簡單但強大:語言模型不應只生成文字,而是可以逐步推理、採取行動 (例如呼叫工具或 API)、觀察結果,然後決定下一步。

推論、行動、觀察和調整的循環,是現代 AI 代理運作的基礎。這也與 Google Cloud 對 AI 代理的定義一致:具備推論、規劃和記憶能力,且有足夠的自主性,可代表使用者進行調整和決策。

三種代理行為模式

並非所有代理程式的行為都相同。您可以從三種廣泛模式來思考:

three-agent-behaviour-patterns.png

  1. 循序代理程式:這類代理程式會依序執行各個步驟,就像生產線一樣:步驟 1、步驟 2,然後是步驟 3。這類代理程式可預測,但缺乏彈性。
  2. 反應型代理:這類代理會當下決定,查看目前狀態並詢問「我接下來該怎麼做?」。可能這次使用工具 A,下次使用工具 B。這類代理很靈活,但不會預先規劃。
  3. 審議或規劃代理程式:這類代理程式會暫停以草擬計畫,然後執行。以預訂旅遊行程為例,您不會隨機購買機票,而是會選擇日期、飯店、安排步驟,然後完成預訂。

哪一個才是「正確」的?這取決於問題。如果是簡單、可預測的流程,循序式就沒問題。如果是動態工作,反應式會比較好。如果是具有依附關係的多步驟目標,則需要規劃代理程式。

在本實驗室中,我們將建構「審議/規劃」代理程式,先建立大綱,然後撰寫網誌文章!

3. 事前準備

建立 Google Cloud 帳戶和專案

如要在本實驗室稍後將代理程式部署至 Google Cloud Run,您需要 Google Cloud 帳戶和已啟用帳單的專案。

  1. 登入 Google Cloud 控制台。建立新專案或重複使用現有專案。如果沒有 Google 帳戶,請先建立帳戶
  2. 接著,您需要在 Cloud 控制台中啟用帳單,才能使用 Cloud 資源。完成這個程式碼研究室的費用應該不到幾美分。Google Cloud 新使用者也可能符合價值$300 美元的免費試用方案資格。
  3. 記下專案 ID (所有 Google Cloud 專案的專屬名稱)。您需要使用這項資訊設定及部署代理程式。

取得 Google AI Studio API 金鑰

如要使用 Gemini 模型,您需要 Google AI Studio 的 API 金鑰。

  1. 前往 Google AI Studio
  2. 點選「Get API Key」(取得 API 金鑰)
  3. 建立新金鑰或使用現有金鑰。複製金鑰,以供稍後使用。

4. 建立 Blog Writer 代理專案結構

在這個步驟中,您要在本機電腦上設定目錄和檔案,存放部落格文章撰寫代理程式的程式碼。

1. 建立部落格文章撰寫代理工作區

開啟終端機並執行下列指令,為網誌撰寫代理程式建立專屬目錄,然後前往該目錄:

mkdir bloggeragent
cd bloggeragent

2. 初始化代理程式檔案

Google ADK 架構會直接從專案目錄載入代理工作流程。請直接在 bloggeragent 的根目錄中建立必要檔案:

touch requirements.txt .env __init__.py agent.py

5. 安裝依附元件並設定環境

在這個步驟中,您將設定 Python 虛擬環境、安裝 Google ADK 框架,並設定環境變數,以使用 Gemini 模型驗證您的網誌代理。

1. 設定代理程式需求

開啟 bloggeragent 目錄中的 requirements.txt 檔案,然後在其中新增下列內容,指定部落格文章撰寫代理程式所需的套件:

google-adk==2.2.0
python-dotenv

2. 為代理程式建立虛擬環境

bloggeragent 目錄中,建立並啟用 Python 虛擬環境,隔離代理程式的套件:

python3 -m venv .venv
source .venv/bin/activate

3. 安裝 ADK 架構

安裝 requirements.txt 中定義的依附元件,為本機工作區安裝 Google ADK:

pip install -r requirements.txt

4. 設定代理程式 API 憑證

開啟您在專案根目錄中建立的 .env 檔案,然後新增 Gemini API 金鑰:

GOOGLE_API_KEY=your_api_key

your_api_key 替換成從 Google AI Studio 複製的金鑰。

6. 建構多代理網誌文章撰寫工具

在這個步驟中,您將實作部落格文章撰寫代理系統的核心工作流程。

您將建構複雜的多代理系統,而非簡單的單一提示聊天機器人,該系統會使用自我修正迴圈和大綱驗證,撰寫高品質的技術文章。這遵循我們稍早討論的審議/規劃模式。

架構總覽

img/agent-architecture.png

系統中的專業人員代理程式互動方式如下:

設定 init.py

在文字編輯器中開啟 __init__.py,並新增下列匯入項目,將代理程式工作流程公開給執行器:

from . import agent

編寫網誌文章撰寫代理工作流程

在程式碼編輯器中開啟 agent.py,然後新增下列程式碼,定義 Planner、Writer、Validation Checkers 和主要 Blogger 代理程式:

import os
import sys
from pathlib import Path
import datetime

from dotenv import load_dotenv
from google.adk.agents import Agent, LoopAgent
from google.adk.tools import agent_tool

# env config
load_dotenv()

MODEL = os.getenv("MODEL", "gemini-flash-latest")

# Sub-Agent: Planner
blog_planner = Agent(
   name="BlogPlanner",
   model=MODEL,
   description="Creates a practical, skimmable outline in Markdown.",
   instruction="""
You are a technical content strategist. Produce a clear Markdown outline with:
- Title
- Short intro
- 4–6 main sections (each with 2–3 bullets)
- Conclusion

If `codebase_context` exists in state, weave in specific sections/snippets.
Return only the outline in Markdown.
""",
   output_key="blog_outline",
)

class OutlineValidationChecker(Agent):
   def __init__(self):
       super().__init__(
           name="OutlineValidationChecker",
           model=MODEL,
           description="Validates that the outline is usable.",
           instruction="""
Check the outline in state `blog_outline`. If it has a title, intro, 4–6 sections, and a conclusion, respond exactly "ok".
Otherwise respond exactly "retry" and list missing pieces.
""",
           output_key="validation_result",
       )

robust_blog_planner = LoopAgent(
   name="RobustBlogPlanner",
   description="Retries planning if validation fails.",
   sub_agents=[blog_planner, OutlineValidationChecker()],
   max_iterations=3,
)

# Sub-Agent: Writer
blog_writer = Agent(
   name="BlogWriter",
   model=MODEL,
   description="Writes a technical blog post from the outline.",
   instruction="""
Write a complete Markdown article from the outline in `blog_outline`.

Guidelines:
- Audience: software engineers; skip basics and focus on practical insight.
- Explain both the 'how' and 'why'.
- Include concise code snippets when helpful.
- Follow the outline's structure (H2/H3).
- Output only the final article in Markdown (no fence around the whole post).
""",
   output_key="blog_post",
)

class BlogPostValidationChecker(Agent):
   def __init__(self):
       super().__init__(
           name="BlogPostValidationChecker",
           model=MODEL,
           description="Validates the final post.",
           instruction="""
Check `blog_post` for: intro, clear sections matching the outline, conclusion, and technical clarity.
If passes, respond "ok". Else respond "retry" with the specific fixes.
""",
           output_key="validation_result",
       )

robust_blog_writer = LoopAgent(
   name="RobustBlogWriter",
   description="Retries writing if validation fails.",
   sub_agents=[blog_writer, BlogPostValidationChecker()],
   max_iterations=3,
)

# Expose planner/writer as tools so the root agent can call them explicitly
planner_tool = agent_tool.AgentTool(agent=robust_blog_planner)
writer_tool  = agent_tool.AgentTool(agent=robust_blog_writer)

# Root Agent: Plan → Write 
root_agent = Agent(
   name="Blogger",
   model=MODEL,
   description="Minimal multi-agent blogger that plans and writes.",
   instruction=f"""
If the user gives a topic:
1) Call the planner tool to generate the outline.
2) Call the writer tool to produce the full draft.
3) End with 3 alternate titles and 2 tweet-length hooks.

Date: {datetime.datetime.now().strftime("%Y-%m-%d")}
""",
   tools=[
       planner_tool, # calls RobustBlogPlanner
       writer_tool,  # calls RobustBlogWriter
   ],
)

瞭解代理架構

接著來細看您剛在 agent.py 中新增的程式碼主要元件,瞭解如何實作多代理規劃和撰寫工作流程:

1. BlogPlanner 子代理

blog_planner 代理負責規劃內容。它會根據使用者提供的主題,以 Markdown 格式產生結構化的大綱 (包含標題、簡介、4 到 6 個章節和結論)。大綱會儲存到共用狀態字典中,鍵為 "blog_outline"

2. OutlineValidationChecker

OutlineValidationChecker 代理程式會充當品質閘道,審查狀態中產生的 "blog_outline"。如果大綱有效,代理程式會回應 "ok"。否則,代理程式會傳回 "retry",以及缺少的內容清單。

3. RobustBlogPlanner 迴圈

為避免代理程式產生不良大綱,我們將規劃工具和驗證檢查程式包裝在 LoopAgent 內,並命名為 robust_blog_planner。如果驗證失敗並傳回 "retry",迴圈會自動再次執行規劃工具 (最多 3 次),確保在進入下一個階段前完成自我修正。

4. BlogWriter 子代理

大綱完成後,blog_writer 代理會從狀態讀取 "blog_outline",並以 Markdown 格式生成完整的技術文章,文章結構與大綱相符,且內容專為軟體工程師量身打造。

5. BlogPostValidationChecker 和 RobustBlogWriter 迴圈

與大綱相同,最終文章會經過 BlogPostValidationChecker 驗證,確保所有重要章節都存在且清楚明瞭。撰稿者和查核者會進入 robust_blog_writer 迴圈,如果查核者發現問題,系統最多會自動修正 3 次。

6. 將迴圈公開為工具

我們使用 AgentTool 將規劃工具迴圈 (robust_blog_planner) 和撰寫工具迴圈 (robust_blog_writer) 包裝成工具 (planner_toolwriter_tool)。這樣一來,其他代理就能呼叫這些複雜的工作流程,就像呼叫簡單的工具一樣。

7. Blogger 根層級代理

root_agent (命名為 Blogger) 會自動化調度管理整個工作流程。收到主題後,指令會引導模型:

  1. 呼叫 planner_tool 以產生經過驗證的大綱。
  2. 呼叫 writer_tool,根據大綱撰寫草稿。
  3. 最後生成 3 個替代標題和 2 個推文開頭。

這個多代理程式迴圈架構可確保可靠性,因為系統會在向使用者顯示輸出內容前,先找出並修正 LLM 格式或結構錯誤!

7. 執行及測試代理

現在來看看代理程式的實際運作情形!

1. 啟動 ADK 網頁版 UI

確認終端機位於 bloggeragent 專案根目錄,且虛擬環境已啟動 (source .venv/bin/activate),然後啟動網頁介面:

adk web

2. 與代理程式互動

  1. 開啟瀏覽器並前往 http://127.0.0.1:8000 (或您指定的連接埠)。
  2. 您應該會看到 ADK 網頁 UI,其中載入了 Blogger 代理及其視覺版面配置 (顯示指向 RobustBlogPlanner 和 RobustBlogWriter 工具的 Blogger 根代理):ADK 網頁 UI Blogger 代理圖表
  3. 在訊息方塊中輸入技術主題,然後按下 Enter 鍵。以下是一些有趣的測試提示,可用於評估代理程式:
    • How to build an AI agent using planning loops
    • Explain the difference between REST and gRPC in microservices
    • A guide to using Python's asyncio for backend concurrency
    • Why developers should use Docker for local database setups
  4. 在 UI 中觀看執行追蹤記錄。您會看到 BlogPlanner 建立大綱、OutlineValidationChecker 驗證大綱,以及 BlogWriter 根據大綱撰寫最終草稿:ADK 網頁介面對話追蹤和輸出

8. 部署至 Cloud Run

您已確認代理程式可在本機運作,現在請將其部署至 Google Cloud Run,供其他人使用!

Google Cloud Run 是代管運算平台,可讓您執行能透過網路要求或 Pub/Sub 事件叫用的無狀態容器。

1. 部署作業的必要條件

如要將部落格文章撰寫代理程式部署至 Cloud Run,您需要在本機電腦上安裝並驗證 Google Cloud CLI (gcloud):

  1. 安裝 Google Cloud CLI:如果尚未安裝,請按照作業系統 (macOS、Windows 或 Linux) 適用的 Google Cloud CLI 安裝指南操作。
  2. 驗證本機終端機:安裝完成後,請在終端機中執行下列指令,登入 Google Cloud 帳戶:
    gcloud auth login
    
  3. 驗證驗證:確認帳戶已成功登入,且您可以存取 Google Cloud 資源:
    gcloud auth list
    

2. 設定 Google Cloud 專案

在終端機中設定有效專案:

gcloud config set project <YOUR_PROJECT_ID>

啟用建構及部署容器化代理程式所需的 Google Cloud 服務:

gcloud services enable \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com

由於 ADK 部署指令會使用 Google Cloud Build 自動執行建構程序,因此您必須授予預設運算服務帳戶使用 Cloud Build 的權限。

執行下列指令,找出專案編號:

gcloud projects describe <YOUR_PROJECT_ID> --format="value(projectNumber)"

執行下列指令,繫結必要的 IAM 角色 (將 替換為您的專案 ID,並將 替換為上述指令傳回的編號)。

  1. 授予 Cloud Build 建構容器的權限:
gcloud projects add-iam-policy-binding <YOUR_PROJECT_ID> \
  --member="serviceAccount:<PROJECT_NUMBER>-compute@developer.gserviceaccount.com" \
  --role="roles/cloudbuild.builds.builder"
  1. 授予 Gemini Enterprise 存取權,讓部署的代理程式無需 API 金鑰即可叫用 Gemini 模型:
gcloud projects add-iam-policy-binding <YOUR_PROJECT_ID> \
  --member="serviceAccount:<PROJECT_NUMBER>-compute@developer.gserviceaccount.com" \
  --role="roles/aiplatform.user"

3. 設定本機環境變數

如要簡化部署指令並避免輸入錯誤,請在終端機工作階段中將專案 ID 設為環境變數:

export PROJECT_ID="<YOUR_PROJECT_ID>"

4. 使用 ADK CLI 部署

ADK CLI 提供簡化的指令,可將代理程式部署至 Cloud Run。

確認虛擬環境已啟動,且您位於 bloggeragent 專案目錄中,然後執行部署指令:

# Deploy using ADK
adk deploy cloud_run \
  --project=$PROJECT_ID \
  --region=us-east1 \
  --service_name=bloggeragent \
  --with_ui \
  . \
  -- \
  --set-env-vars GOOGLE_GENAI_USE_VERTEXAI=TRUE,MODEL=gemini-3.5-flash,GOOGLE_CLOUD_LOCATION=global

在部署過程中,終端機會提示您回答下列兩個問題:

  1. 確認建立存放區
    Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-east1] will be created.
    
    Do you want to continue (Y/n)?
    
    輸入 Y 並按下 Enter 鍵。
  2. 允許未經驗證的存取要求
    Allow unauthenticated invocations to [bloggeragent] (y/N)?
    
    輸入 y 並按下 Enter 鍵 (這樣就能在瀏覽器中公開存取 ADK Web UI)。

5. 存取已部署的代理

部署完成後,指令會輸出網址。在瀏覽器中開啟該網址,即可存取目前運作中的公開 ADK 網頁 UI!

9. 清理

如要避免系統持續向您的 Google Cloud 帳戶收取費用,請刪除本程式碼研究室建立的資源。

1. 刪除 Cloud Run 服務

刪除已部署的 bloggeragent 服務:

gcloud run services delete bloggeragent --region=us-east1 --quiet

2. 刪除 Artifact Registry 存放區

刪除為儲存建構的容器映像檔而建立的 Docker 存放區:

gcloud artifacts repositories delete cloud-run-source-deploy --location=us-east1 --quiet

3. 停止本機伺服器

如要停止本機 ADK 伺服器,請在執行伺服器的終端機中按下 CTRL+C,然後停用虛擬環境:

deactivate

10. 恭喜

恭喜!您已使用 Google 的 ADK 和 Gemini 建構第一個 AI 代理。

目前所學內容

  • AI 代理的核心概念 (推論和行動)。
  • 如何使用 Google ADK 建構多代理系統。
  • 如何使用網路 UI 執行及測試代理。

後續步驟

  • 嘗試為代理新增工具 (例如網頁搜尋或 API 呼叫)。
  • 請繼續觀看第 2 部影片,瞭解如何整合 MCP 伺服器!

參考文件