見出し画像

AI Agent 「Extension」の作り方を深ぼる

ここでは、「Extension という仕組みを使ってエージェントに外部APIを呼び出してもらう」ための実装例を、Google Vertex AI を想定した形で示します。
大まかな流れは下記のようになります。

  1. Extensionの役割を定義する

  2. Extension内部で呼び出す外部APIの準備(必要に応じて)

  3. Extensionクラスを実装

  4. エージェント(モデル)にExtensionを教える

  5. エージェントを起動して実際に使う

以下は 「天気情報を取得する」 Extension を例とし、架空の天気API(OpenWeatherMapなど)を呼ぶ形にしてみます。
(実際に動かす場合は、Vertex AI環境が必要・APIキーが必要など前提がいくつかある点はご注意ください。)


1. Extensionの役割を定義する

まず「天気を調べたい」というタスクをエージェントが実行するため、以下を想定します:

  • エージェントへの質問例: 「明日の東京の天気はどう?」

  • Extensionのやること:

    1. 東京の位置情報やクエリパラメータを整形して天気APIを呼ぶ

    2. 結果として得られた気温や天候をエージェントへ返す

エージェントは「天気Extensionがあるなら、それを呼び出そう」と推論し、その結果を取り込んでユーザーに回答を返します。


2. 外部APIの準備(例: OpenWeatherMapなど)

すでにあるAPIを利用する場合は、この段階は飛ばしてOK

本例では「OpenWeatherMap」という有名な天気APIを使う例を想定します。

  • 実際には OpenWeatherMap でAPIキーを取得し、GET https://api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key} のようなリクエストを行います。

  • レスポンスは JSON で返ってきます。

たとえばレスポンスはこんなイメージ:

{
  "coord": { "lon": 139.69, "lat": 35.69 },
  "weather": [
    {
      "id": 803,
      "main": "Clouds",
      "description": "broken clouds"
    }
  ],
  "main": {
    "temp": 300.15,
    "pressure": 1012,
    "humidity": 44
  },
  ...
}

ここから main.temp や weather[0].description を抜き出して返したい、という流れになります。


3. Extensionクラスを実装する

以下の例では、Vertex AIの拡張機能向けに Extension クラスを継承/または生成するやり方を説明します。
(将来的にAPI仕様やVertex AIのバージョンによってインターフェースが変わる可能性がある点はご了承ください)

3.1 Extensionを作るためのインポートと下準備

import requests
import json
import vertexai

# Vertex AI の「preview.extensions」からExtensionを読み込み
from vertexai.preview.extensions import Extension

# プロジェクトIDなどの設定
PROJECT_ID = "YOUR_PROJECT_ID"
REGION = "us-central1"  # 例
vertexai.init(project=PROJECT_ID, location=REGION)
  • requests は外部APIを呼び出すために使用(Python標準ライブラリ以外ですが、Vertex AI環境で許可されているか要確認)。

  • vertexai.init() でVertex AIの環境初期化を行います。

3.2 Extensionクラスの作り方

Extensionには大きく分けて次の情報を持たせます。

  1. Extension名やバージョン

  2. 内部で呼ぶAPIのエンドポイントや認証など

  3. エージェントに提示する「どんな引数をとるか」「どう返すか」というサンプル

本例では「City名を引数に取り、天気情報(WeatherやTemperature)を返す」想定です。

class WeatherExtension(Extension):
    # Extensionの名前や簡単な説明
    name = "weather_lookup"
    description = "都市の天気情報を取得するためのExtension"
    version = "v1"

    # 例として、Extensionの呼び出し方をエージェントに教えるExamples(プロンプト例)を作る
    examples = [
        {
            # ここではエージェントが Extension を呼ぶときの
            # (Action)や(Action Input)の例を簡単に書いておける
            "input": "What is the weather in Tokyo?",
            "action_name": "weather_lookup",
            "action_params": {
                "city_name": "Tokyo"
            },
            "output": {
                "weather": "Clouds",
                "temperature": "300.15K"
            }
        }
    ]

    def execute(self, city_name: str):
        """
        実際のExtensionのメインロジック。
        city_nameを使って外部API(OpenWeatherMapなど)を呼び出し、結果を整形して返す。
        """
        # ここであなたのOpenWeatherMapのAPIキーを読み込む
        API_KEY = "YOUR_OPENWEATHERMAP_API_KEY"

        # エンドポイントURLを組み立て
        url = f"https://api.openweathermap.org/data/2.5/weather"
        params = {
            "q": city_name,
            "appid": API_KEY,
            "lang": "ja",  # 日本語対応
            "units": "metric"  # 摂氏で返す例
        }

        response = requests.get(url, params=params)
        data = response.json()

        if response.status_code != 200:
            # エラー処理
            return {
                "weather": None,
                "temperature": None,
                "error": data.get("message", "Unknown error")
            }
        
        # 天気の概要
        weather_desc = data["weather"][0]["main"]  # "Clouds" / "Rain" etc
        # 気温
        temperature = data["main"]["temp"]  # 摂氏
        # 必要なら他の項目も取得
        return {
            "weather": weather_desc,
            "temperature": f"{temperature}C",
            "city": city_name
        }

3.3 注意点

  • 実行環境の制限:
    Vertex AIのEnvironmentによっては外部ライブラリのrequestsが使えない可能性もあります。別の方法(例えば urllib.request )を使うか、カスタムコンテナなどを利用して要件を整える必要があるかもしれません。

  • 認証情報の管理:
    API_KEYをコードに直接書くとセキュリティ的に問題があるので、実運用では「Secret Manager」などで安全に管理するのがおすすめです。


4. エージェント(モデル)にExtensionを教える

Extensionを定義しただけではエージェントはまだ認識していません。
実行時にエージェントへ「このExtensionが使えますよ」と登録 する必要があります。

# Extensionクラスのインスタンス化
weather_extension = WeatherExtension.from_custom_class(WeatherExtension)

# あるいは最近の仕様であれば直接 weather_extension = WeatherExtension() でもOKの可能性あり

# あとはエージェントに渡す形でセットアップ
from vertexai.generative_models import GenerativeModel

# 使いたいモデルを指定
model = GenerativeModel("gemini-1.5-flash-001")  # 例

# Extensionsをリストにまとめる
extensions_list = [weather_extension]

# モデルにExtensionsを連携させて会話を行う
question = "What's the weather in Tokyo right now?"
response = model.generate_content(question, extensions=extensions_list)

print(response.candidates[0].content) 
# → 「現在の東京の天気はCloudsで、温度は24Cです」といった回答が来る想定

上記の generate_content(...) 呼び出し時に、モデルは「weather_lookup」Extensionが使える」と教えてもらい、かつExamplesを参照して、「あ、東京の天気を聞かれてるからExtensionを呼ぶ」と推論→ execute() メソッドが実行されます。

  • 内部的には、モデルの推論プロンプトに「利用できるExtensionとして weather_lookup がある。呼び出す時は city_name を指定してexecuteせよ」といった情報が付与されます。

  • モデルはExtensionを呼ぶアクションを出力し、Vertex AIの仕組みがそれを受け取って execute(city_name="Tokyo") を実行 → 結果を再度モデルに返す→最終的な自然言語応答が生成されます。


5. Extensionを実際に使うときの流れ

  1. ユーザーが自然言語で質問を投げる
    例:「明日の東京の天気は?」
    (厳密には「明日」というパラメータの扱いなど別の問題がありますが、Extensionをバージョンアップして対応可能)

  2. エージェントが「これは天気Extensionが必要だ」と判断

    • Extensionが提供するExamplesやモデルの推論ルールをもとに、
      「天気情報は weather_lookup Extensionを呼んで取得する」
      と決める。

  3. Extensionの execute(city_name="Tokyo") が呼ばれる

    • HTTPリクエストで天気APIへアクセスし、データを返す。

  4. 戻ってきた天気情報をエージェントが受け取る

    • たとえば weather="Clouds", temperature="26C" など。

    • エージェントはこれを使って最終的な文章「東京の天気は曇りで気温は26度です」と生成する。

  5. ユーザーへの回答

    • 自然言語文章が返される。


6. よくある疑問・注意点

  1. Extensionで入力スキーマ・出力スキーマを厳密に定義したい

    • 開発時には「city_nameはstr型で必須」「返却されるJSONはこういう構造」といったスキーマを明確にしておくと、モデルに渡すExamplesがより正確になり、精度が高まります。

  2. モデルが正しくExtensionを使ってくれない場合がある

    • モデルは「Extensionを使う」という手順をテキスト推論から生成しているため、Examplesの質が大きく影響します。

    • 「こういう質問が来たらこうExtensionを呼ぶ」というサンプルをいくつか増やしてあげると成功率が高まります。

  3. Extensionを複数持つ場合

    • extensions=[weather_extension, flight_extension, code_interpreter_extension, ...] と並べて登録できます。

    • モデルは「どれを使うか」を推論で決める(または人間が固定して呼ぶ方法もあり)。


まとめ

Extensionの作り方 は、ざっくり以下の流れになります。

  1. どんな外部APIを呼ぶかを決め、必要ならAPIキーやリクエスト仕様を確認

  2. Extensionクラス(vertexai.preview.extensions.Extension を継承/利用)を作り、

    • execute() の中にAPI呼び出しロジックを書く

    • examples 等に「入力パラメータとその使い方」を示すサンプルを入れておく

    • 必要に応じて name, version, description など設定

  3. Vertex AIのモデル生成時に、そのExtensionを登録

    • model.generate_content(user_message, extensions=[your_extension])

  4. エージェントが必要に応じてExtensionを呼び出す(背後ではexecuteメソッドが動く)

これで、エージェントが自動的に外部APIを活用できる ようになります。
「天気Extension」の例以外にも、フライト予約APIや地図検索APIなど、同様の手順でさまざまなExtensionを作り、エージェントに合わせて統合することが可能です。

  • ポイント:

    • モデル(LLM)はテキストを生成するだけではなく、「Extensionを呼んで結果を再利用する」という“マルチステップ”の動きをとれます。

    • Extensionで外部のリアルタイム情報を取得できるようになることで、エージェントがより幅広いシーンで実用的に動作するようになるわけです。

以上が「AI AgentのExtensionの作り方」の一例になります。
実際の環境ではAPIキー管理や認証、ネットワーク制限など、細かい設定が必要ですが、「まずExtensionクラスを定義して、エージェントに登録し、executeメソッドでAPIを叩く」という流れさえ理解できれば、カスタムのExtensionを作って業務システムに組み込むことができます。ぜひ試してみてください。

お気軽にご相談ください

RAGを使って業務効率化を実現したい方、新規事業の可能性を探りたい方、まずはRAGのよろず相談会でお話してみませんか?

みなさまの課題やご要望をじっくり伺い、一緒に具体的な進め方を考えていけたらうれしいです。

下記のGoogleフォームからお気軽にご連絡ください!


いいなと思ったら応援しよう!