Googleさんの「Agent Development Kit（ADK）」を使ったエージェント実装を試してみる（公式のクイックスタートの手順 ＋α）

## はじめに

以下の記事やポストで見かけた「Agent Development Kit」をさっそく試してみた話です（公式のクイックスタートの手順をなぞっていきま）。

●［速報］Google Cloudが「Agent Development Kit」をオープンソースで公開へ。100行以下のコードでMCPやガードレールを備えたエージェントを開発可能 － Publickey
 https://www.publickey1.jp/blog/25/google_cloudagent_development_kit100mcp.html

https://x.com/schroneko/status/1910005966667735236


## 関連情報

今回の話に関連する情報をいくつかピックアップして掲載してみます。

後で見てみようと思ってメモしたものになります（また、本文中の他の箇所にリンクなどを掲載した記事の記載は、こちらでは省略しています）。


### 公式の情報

以下、公式のページのリンクなどです。

- [Agent Development Kit](https://google.github.io/adk-docs/)
- [Agent Development Kit エージェントを使用する  |  Generative AI on Vertex AI  |  Google Cloud](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/use/adk?hl=ja)
- [Agent Development Kit: Making it easy to build multi-agent applications - Google Developers Blog](https://developers.googleblog.com/ja/agent-development-kit-easy-to-build-multi-agent-applications/)

### 公式の情報以外

●[リリース] Agent Development Kit を試してみた #GoogleCloudNext | DevelopersIO
 https://dev.classmethod.jp/articles/agent-development-kit-quickstart-googlecloudnext/


## 実際に試してみる

公式のクイックスタートをなぞる形で、実際に試してみます。

### 仮想環境を準備

[過去に Python の SDK・ライブラリなどのお試しをする際](https://qiita.com/youtoy/items/ae1dd6ee36ac35c6e519)によく使っている、Python の仮想環境を準備します。

以下、自分が持っている環境のうち、2パターンの内容を掲載しています。
一つは、Windows で pyコマンド（Python Launcher for Windows）を使うパターンで、2つ目は Mac で Python のコマンドを使うパターンです。

```powershell:Windows で pyコマンド（Python Launcher for Windows）
py -m venv myenv
myenv\Scripts\activate
```

```zsh: Mac で Python のコマンド
python -m venv myenv
source myenv/bin/activate
```

### 仮想環境内での下準備

仮想環境内での下準備を進めます。

手順は、以下の公式のクイックスタートの内容です。

●Quickstart - Agent Development Kit
 https://google.github.io/adk-docs/get-started/quickstart/

#### Agent Development Kit（google-adk）のインストール

pip コマンドで google-adk をインストールします。

```powershell
pip install google-adk
```

#### フォルダ・ファイルの準備

公式のクイックスタートで「2. Create Agent Project ＞ Project structure」という項目に書いてある、フォルダ・ファイルを準備します。

「multi_tool_agent」フォルダを作成し、その下に 3つのファイルを置く形です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/51faab89-3426-4fbc-9ef7-841ba7334e29.png)

仮想環境を作ったフォルダ内の構成は、以下になりました。
（仮想環境を作ったフォルダの直下には、「multi_tool_agent」フォルダと「myenv」フォルダの 2つのみがある構成）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a7a41ca1-0e38-4cd2-a5c0-e0d36e0af474.png)

この後、「multi_tool_agent」フォルダ以下に置いた 3つのファイルについて、中身を作っていきます。

### ファイルの準備の続き： ファイルの中身を作る

それでは、「multi_tool_agent」フォルダ以下のファイルに関し、中身を作っていきます。


#### 「__init__.py」の内容

以下は「__init__.py」の内容です。

```python:multi_tool_agent/__init__.py
from . import agent
```


#### 「agent.py」の内容

以下は「agent.py」です。

```python:multi_tool_agent/agent.py
import datetime
from zoneinfo import ZoneInfo
from google.adk.agents import Agent

def get_weather(city: str) -> dict:
    """Retrieves the current weather report for a specified city.

    Args:
        city (str): The name of the city for which to retrieve the weather report.

    Returns:
        dict: status and result or error msg.
    """
    if city.lower() == "new york":
        return {
            "status": "success",
            "report": (
                "The weather in New York is sunny with a temperature of 25 degrees"
                " Celsius (41 degrees Fahrenheit)."
            ),
        }
    else:
        return {
            "status": "error",
            "error_message": f"Weather information for '{city}' is not available.",
        }


def get_current_time(city: str) -> dict:
    """Returns the current time in a specified city.

    Args:
        city (str): The name of the city for which to retrieve the current time.

    Returns:
        dict: status and result or error msg.
    """

    if city.lower() == "new york":
        tz_identifier = "America/New_York"
    else:
        return {
            "status": "error",
            "error_message": (
                f"Sorry, I don't have timezone information for {city}."
            ),
        }

    tz = ZoneInfo(tz_identifier)
    now = datetime.datetime.now(tz)
    report = (
        f'The current time in {city} is {now.strftime("%Y-%m-%d %H:%M:%S %Z%z")}'
    )
    return {"status": "success", "report": report}


root_agent = Agent(
    name="weather_time_agent",
    model="gemini-2.0-flash-exp",
    description=(
        "Agent to answer questions about the time and weather in a city."
    ),
    instruction=(
        "I can answer your questions about the time and weather in a city."
    ),
    tools=[get_weather, get_current_time],
)
```


#### 「.env」の内容（Google AI Studio経由）

公式ドキュメントで示されている「.env」の内容は以下のとおりです。
Google AI Studio経由で使う場合と、Google Cloud の Vertex AI経由で使う場合とが書かれています（Vertex AI経由のほうはコメントアウトされた状態）。

```zsh:公式ドキュメントでの multi_tool_agent/.env の記載
# If using Gemini via Google AI Studio
GOOGLE_GENAI_USE_VERTEXAI="False"
GOOGLE_API_KEY="paste-your-actual-key-here"

# # If using Gemini via Vertex AI on Google CLoud
# GOOGLE_CLOUD_PROJECT="your-project-id"
# GOOGLE_CLOUD_LOCATION="your-location" #e.g. us-central1
# GOOGLE_GENAI_USE_VERTEXAI="True"
```


自分は Google AI Studio経由で使うので、「.env」の内容は以下としました。

```zsh:multi_tool_agent/.env
GOOGLE_GENAI_USE_VERTEXAI="False"
GOOGLE_API_KEY="【Google AI Studio の APIキー】"
```

上記の「.env」の「【Google AI Studio の APIキー】」の部分は、[Google AI Studio で取得](https://aistudio.google.com/apikey)した APIキーを設定してください。


### 処理の実行

それでは、公式の以下の部分に書かれたコマンドで、処理を実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d93a3030-a319-42dd-860c-96bb7ac4e831.png)

以下のコマンドを実行したところ、サーバーのプロセスが立ち上がったというメッセージなどが表示されました。

```zsh:zsh
adk web
```

![2025-04-10_17-22-33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f954c9bc-70d5-43ae-bcde-4addc138608c.jpeg)


#### ブラウザでアクセスしてやりとりする

ブラウザでアクセスして、エージェントとのやりとりを試します。

先ほどのメッセージ内に書かれていた、 http://localhost:8000/ にアクセスして、左上のエージェントを選択するメニューから「multi_tool_agent」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/91b504d1-2492-402e-a39a-39dd9f7ebb33.png)

その後、以下のような画面になりました。

![2025-04-10_17-25-26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/18e89127-7b4c-412b-ad13-8faeb8f712a4.jpeg)

そして、以下のように[エージェントとのやりとりを実際に試すことができました](https://x.com/youtoy/status/1910253832870986025)。

![2025-04-10_17-40-40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/5cf9626e-9160-4adc-992b-9eb698b4ea9b.jpeg)

エージェントの実装をサクッと試すことができました！


## 【追記】 コードに少しだけ手を加えてみた

公式サンプルの内容に関して、少しだけ手を加えて回答可能な対象を増やしてみました。

具体的には、以下のとおりで「東京／Tokyo」に関しても回答ができるようにしてみました（また、東京の天気に関する回答は、日本語で答える実装にしてみました）。

https://x.com/youtoy/status/1910261323528917348


### コードの内容

agent.py の内容に少しだけ変更を加えたものは、以下になります。


```python
import datetime
from zoneinfo import ZoneInfo
from google.adk.agents import Agent

def get_weather(city: str) -> dict:
    """Retrieves the current weather report for a specified city.

    Args:
        city (str): The name of the city for which to retrieve the weather report.

    Returns:
        dict: status and result or error message.
    """
    if city.lower() == "new york":
        return {
            "status": "success",
            "report": (
                "The weather in New York is sunny with a temperature of 25 degrees"
                " Celsius (41 degrees Fahrenheit)."
            ),
        }
    elif city.lower() in ["tokyo", "東京"]:
        return {
            "status": "success",
            "report": (
                "東京の天気は晴れで、気温は22度です。"
            ),
        }
    else:
        return {
            "status": "error",
            "error_message": f"Weather information for '{city}' is not available.",
        }


def get_current_time(city: str) -> dict:
    """Returns the current time in a specified city.

    Args:
        city (str): The name of the city for which to retrieve the current time.

    Returns:
        dict: status and result or error message.
    """
    if city.lower() == "new york":
        tz_identifier = "America/New_York"
    elif city.lower() in ["tokyo", "東京"]:
        tz_identifier = "Asia/Tokyo"
    else:
        return {
            "status": "error",
            "error_message": f"Sorry, I don't have timezone information for {city}.",
        }

    tz = ZoneInfo(tz_identifier)
    now = datetime.datetime.now(tz)
    report = (
        f'The current time in {city} is {now.strftime("%Y-%m-%d %H:%M:%S %Z%z")}'
    )
    return {"status": "success", "report": report}


root_agent = Agent(
    name="weather_time_agent",
    model="gemini-2.0-flash-exp",
    description=(
        "Agent to answer questions about the time and weather in a city."
    ),
    instruction=(
        "I can answer your questions about the time and weather in a city."
    ),
    tools=[get_weather, get_current_time],
)
```