AIが自律的にタスク実行!Amazon Bedrock Agent + Lambdaで作るアーキテクチャ

こんにちは、クラウドエンジニアの三﨑・長谷部です。
今回は生成AIの話題に触れながら、「Amazon Bedrock Agent + Lambda」で構成する、Lambdaと連携可能なAIアーキテクチャについて紹介します。

生成AIとただ会話するだけでなく、外部のAPIと連携してリアルタイムの情報を取得することで、その可能性は大きく広がります。
以前の記事では、Function Callingを用いてAIが外部機能を呼び出す仕組みを紹介しましたが、今回はその進化版である Amazon Bedrock Agentを活用し、AIが自動的にLambdaを実行して結果を返す構成を紹介します。

アーキテクチャの紹介:AgentがLambdaを呼び出す仕組み

今回のシステムは、AWS上で構築したサーバーレスアーキテクチャを採用しています。
Bedrock Agentがユーザーからの入力を受け取り、どのアクションを実行すべきかを判断し、対応するLambda関数を呼び出します。

インフラ構成図

この構成では、主に以下のコンポーネントが連携しています。

  1. Amazon Bedrock Agent
    生成AIとの対話を担うサービスです。ユーザーが「${都市名}の天気を教えて」と質問すると、入力内容に応じてAgentがアクショングループを実行します。
  2. アクショングループ (Action Group)
    Agentが呼び出せる機能のまとまりを定義します。ここでは天気情報を取得するLambdaをAction Groupとして登録します。
  3. OpenAPIスキーマ
    どんなAPIが存在し、どんなパラメータが必要かをAgentに伝える仕様書です。Agentはこれを参照し、正確なパラメータを生成してLambdaを呼び出します。
  4. AWS Lambda
    実際の処理を行う関数です。Agentが送ってきたパラメータを解析し、外部APIを呼び出して天気情報を取得します。
  5. 外部API
    天気情報をリアルタイムで提供する外部サービスです。Lambda関数はここからデータを取得し、結果をAgent経由でユーザーに返します。

Bedrock Agentを利用することで、これらのコンポーネントが入力内容をトリガーに連携するようになります。つまり、AIが人の指示を理解し、自動で後続のタスクを実行する流れを実現できます。

Agentのフロー図

実装解説①:Agentへの仕様書(アクショングループスキーマ)

まずは、Bedrock Agentにどんな機能を持っているのかを理解させるための仕様書を定義します。
OpenAPI 3.0 形式で以下のように記述します。

openapi: 3.0.0
info:
  title: Weather API
  version: 1.0.0
  description: 指定された都市の現在の天気を取得するためのAPIです。

paths:
  /get_weather:
    post:
      operationId: getWeather
      summary: 天気情報を取得する
      description: ユーザーが地名と天気について質問した場合、このAPIを使って指定された都市の天気予報を取得します。
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                city:
                  type: string
                  description: '天気を知りたい都市名 (例: 東京、大阪)'
              required:
                - city
      responses:
        '200':
          description: 天気情報の取得に成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  weather:
                    type: string
                  temperature:
                    type: number

このスキーマによって、AIが自動的にAPIの入力形式を理解し、Lambdaを呼び出すための判断基準を持つようになります。

実装解説②:実処理を担うLambda関数

次に、実際にAgentから呼び出されるLambda関数を見ていきます。 この関数は、Agentから渡されたイベントを解析し、外部APIにアクセスして結果を返します。

import json
import urllib3
from typing import Dict, Any

OPEN_METEO_API_URL = "https://api.open-meteo.com/v1/forecast"
LOCATION_COORDINATES = {
    "東京": {"lat": 35.6895, "lon": 139.6917},
    "大阪": {"lat": 34.6937, "lon": 135.5023},
    "札幌": {"lat": 43.0618, "lon": 141.3545},
}

WEATHER_CODE_MAP = {
    0: "快晴",
    1: "晴れ",
    2: "曇り",
    3: "雨",
}

http = urllib3.PoolManager()

def _parse_city_from_event(event: Dict[str, Any]) -> str:
    """Bedrock Agentからのリクエストを解析し、都市名を取得"""
    try:
        content = event["requestBody"]["content"]["application/json"]
        for p in content.get("properties", []):
            if p.get("name") == "city":
                return p.get("value")
    except Exception:
        return ""
    return ""

def _get_weather_data(lat: float, lon: float) -> Dict[str, Any]:
    """外部APIから天気情報を取得"""
    url = f"{OPEN_METEO_API_URL}?latitude={lat}&longitude={lon}&current=temperature_2m,weather_code&timezone=Asia%2FTokyo"
    res = http.request("GET", url)
    return json.loads(res.data.decode("utf-8"))

def _format_response(city: str, data: Dict[str, Any]) -> str:
    """取得した天気情報を日本語で整形"""
    temp = data["current"]["temperature_2m"]
    weather_code = data["current"]["weather_code"]
    weather_desc = WEATHER_CODE_MAP.get(weather_code, "不明")
    return f"{city}の現在の天気は{weather_desc}、気温は{temp}℃です。"

def lambda_handler(event, context):
    city = _parse_city_from_event(event)
    if not city or city not in LOCATION_COORDINATES:
        result = f"指定の都市「{city}」の天気情報は取得できません。"
    else:
        coords = LOCATION_COORDINATES[city]
        weather = _get_weather_data(coords["lat"], coords["lon"])
        result = _format_response(city, weather)

    response = {
        "messageVersion": "1.0",
        "response": {
            "actionGroup": event.get("actionGroup"),
            "apiPath": event.get("apiPath"),
            "httpMethod": event.get("httpMethod"),
            "httpStatusCode": 200,
            "responseBody": {
                "application/json": {"body": result}
            },
        },
    }
    return response

ポイント

  • イベント解析処理
    Bedrock Agentは、OpenAPIスキーマに沿った形式でパラメータを渡します。
    Lambda側ではこのJSON構造を正確に解析し、cityパラメータを抽出する必要があります。
  • レスポンス整形
    Bedrock Agentが理解できるよう、Lambdaの戻り値も特定のJSON形式に整形します。
    responseBody 以下の application/json 構造に整えたデータを返すことで、Agentが正しく結果をユーザーに伝えられるようになります。

まとめ:Bedrock Agentで自律的に計画・実行するAIを簡単に作れる

Bedrock Agentの登場により、AIは外部のAPIと自動的に連携し、処理を実行できるように進化しました。

従来のFunction Callingでは、どの関数を呼ぶかを開発者が制御する必要がありましたが、Bedrock Agentではその多くを自動化できます。
アクショングループスキーマでできることを定義し、Lambdaで実際の処理を実装するだけで、Agentがユーザーの意図を理解し、自動でLambdaを呼び出して結果を返すようになります。

AIが人の代わりに動き、外部システムと自然に連携します。
Bedrock Agentは、自律的に計画・実行するAIを実現するための強力な基盤です。
ぜひ、Agentについてチェックしてみてください。




元の記事を確認する

関連記事