はじめに
こんにちは、アプリケーションサービス本部ディベロップメントサービス3課の北出です。
最近、AIエージェントという言葉をよく耳にするようになりました。Amazon Bedrock AgentCoreは聞きますが、調べてもなかなか理解しづらかったです。 AIエージェントの理解のために、まずはGUIベースでAIエージェントを作ることができるということで、Amazon Bedrock Agents を使って「天気を教えてくれるエージェント」を作ってみました。
コードを書くのは AWS Lambda 関数だけで、あとはマネジメントコンソールからの設定で完結するので、エージェントの仕組みを理解するのにちょうど良い題材だと思います。
「AIエージェントが気になるけど触ったことがない」という方の参考になれば幸いです。
今回作るもの
ユーザーが「東京の天気を教えて」と聞くと、エージェントが天気APIを呼び出して日本語で回答してくれるチャットエージェントです。
アーキテクチャ
ユーザー → Bedrock Agent(Claude) → Action Group → Lambda 関数 → Open-Meteo API
基盤モデル: Anthropic Claude 3.5 Sonnet
天気API: Open-Meteo(APIキー不要・全世界対応・無料)
リージョン: アジアパシフィック(東京)
ap-northeast-1
前提条件
AWSアカウント
Bedrock のモデルアクセスで Claude が有効化されていること
Bedrock Agents の仕組み
手順に入る前に、今回使う Bedrock Agents の仕組みを簡単に説明します。
全体の流れ
ユーザー
「東京の天気教えて」
│
▼
基盤モデル(Claude)
推論: "天気を取得する関数を呼ぼう"
│
▼
アクショングループ(GetWeather)
関数: get_current_weather
パラメータ: latitude, longitude
│
▼
Lambda 関数(weather-agent-function)
[latitude, longitude]を受け取って、天気APIを呼び出して結果を返す
│
▼
Open-Meteo API(天気データ取得)
│
▼
基盤モデル(Claude)
結果を自然言語に整形
│
▼
ユーザーに回答
「東京は一部曇り、気温14.4°C...」
ポイントは、エージェント自身は天気APIを直接叩くわけではないということです。Claude が「この質問に答えるには天気情報が必要だ」と推論し、アクショングループに定義された関数を呼び出す判断をします。(MCPのtoolsをAIが判断して実行するイメージに近いです)
アクショングループとは
アクショングループは、エージェントに「あなたはこういう操作ができますよ」と教えるインターフェース定義です。
もう少し具体的に言うと:
エージェントへの指示文(プロンプト) = エージェントの「考え方」を定義する
アクショングループ = エージェントの「行動」を定義する(何ができるか、どう実行するか)
レストランで例えると:
| 概念 | 例え |
|---|---|
| エージェント(Claude) | シェフ |
| 指示文 | 「あなたは和食専門です」という役割説明 |
| アクショングループ | メニュー表(何が作れるかの一覧) |
| Lambda 関数 | 厨房(実際に料理を作る場所) |
今回の天気エージェントでは、アクショングループに以下を定義します:
アクショングループ: GetWeather
└── 関数: get_current_weather
├── パラメータ: latitude(緯度)必須
└── パラメータ: longitude(経度)必須
→ 実行先: Lambda 関数
エージェントはこの定義を見て、「ユーザーが天気を聞いている → get_current_weather を呼べばいい → 緯度と経度が必要だ → 東京なら35.6762と139.6503だ」と推論して Lambda を呼び出します。
処理の流れ
- ユーザーが「東京の天気教えて」と入力
- Claude が推論:「
get_current_weatherをlatitude=35.6762, longitude=139.6503で呼ぼう」 - Bedrock が Lambda 関数を呼び出し、パラメータを渡す
- Lambda が天気APIを叩いてデータを返す
- Claude が結果を受け取り、自然言語に整形して回答を生成
この「推論 → ツール呼び出し → 回答生成」のループがエージェントの基本的な動作です。
手順
1. Lambda関数の作成
まず、天気APIを呼び出す Lambda 関数を作成します。
Lambda コンソールから以下の設定で関数を作成します。
関数名:
weather-agent-functionランタイム: Python 3.14
アーキテクチャ: arm64
コードを以下に置き換えます。
import json import urllib.request def get_weather(latitude, longitude): """Open-Meteo APIで天気情報を取得する""" url = ( f"https://api.open-meteo.com/v1/forecast?" f"latitude={latitude}&longitude={longitude}" f"¤t=temperature_2m,weather_code,wind_speed_10m,relative_humidity_2m" f"&timezone=auto" ) req = urllib.request.Request(url) with urllib.request.urlopen(req) as res: return json.loads(res.read().decode()) WEATHER_CODES = { 0: "快晴", 1: "おおむね晴れ", 2: "一部曇り", 3: "曇り", 45: "霧", 48: "着氷性の霧", 51: "弱い霧雨", 53: "霧雨", 55: "強い霧雨", 61: "弱い雨", 63: "雨", 65: "強い雨", 71: "弱い雪", 73: "雪", 75: "強い雪", 80: "弱いにわか雨", 81: "にわか雨", 82: "激しいにわか雨", 95: "雷雨", 96: "雹を伴う雷雨", 99: "激しい雹を伴う雷雨", } def lambda_handler(event, context): action_group = event.get("actionGroup", "") function_name = event.get("function", "") parameters = event.get("parameters", []) params = {p["name"]: p["value"] for p in parameters} latitude = params.get("latitude", "35.6762") longitude = params.get("longitude", "139.6503") weather_data = get_weather(latitude, longitude) current = weather_data.get("current", {}) temperature = current.get("temperature_2m", "不明") weather_code = current.get("weather_code", 0) wind_speed = current.get("wind_speed_10m", "不明") humidity = current.get("relative_humidity_2m", "不明") weather_desc = WEATHER_CODES.get(weather_code, "不明") result = ( f"現在の天気: {weather_desc}\n" f"気温: {temperature}°C\n" f"湿度: {humidity}%\n" f"風速: {wind_speed} km/h" ) return { "messageVersion": "1.0", "response": { "actionGroup": action_group, "function": function_name, "functionResponse": { "responseBody": { "TEXT": { "body": result } } } } }
デプロイしたら、「設定」→「一般設定」からタイムアウトを 30秒 に変更しておきます。
Lambda単体テスト
エージェントと連携する前に、Lambda 単体で動作確認しておくと安心です。
テストイベントに以下を設定して実行します。
{ "messageVersion": "1.0", "agent": {"name": "weather-agent", "id": "test", "alias": "test", "version": "1"}, "inputText": "東京の天気を教えて", "sessionId": "test-session", "actionGroup": "GetWeather", "function": "get_current_weather", "parameters": [ {"name": "latitude", "type": "string", "value": "35.6762"}, {"name": "longitude", "type": "string", "value": "139.6503"} ] }
「現在の天気: ○○」のようなレスポンスが返ってくれば成功です。

2. Bedrock Agent の作成
Bedrock コンソールから「エージェント」→「エージェントを作成」で以下を設定します。
エージェント名:
weather-agent説明:
天気情報を教えてくれるエージェント

モデルと指示文の設定
エージェントビルダー画面で、モデルに Anthropic Claude 3.5 Sonnet を選択し、以下の指示文を設定します。
あなたは天気情報を提供するアシスタントです。 ユーザーから場所を聞かれたら、その場所の緯度・経度を推定して天気情報を取得してください。 主要都市の緯度・経度: - 東京: 緯度 35.6762, 経度 139.6503 - 大阪: 緯度 34.6937, 経度 135.5023 - 名古屋: 緯度 35.1815, 経度 136.9066 - 札幌: 緯度 43.0618, 経度 141.3545 - 福岡: 緯度 33.5904, 経度 130.4017 - ニューヨーク: 緯度 40.7128, 経度 -74.0060 - ロンドン: 緯度 51.5074, 経度 -0.1278 回答のルール: 1. 必ず日本語で回答する 2. 天気情報を分かりやすくフォーマットして表示する 3. 場所が曖昧な場合はユーザーに確認する 4. 天気に基づいたアドバイス(傘が必要か等)も添える

アクショングループの追加
「アクショングループ」セクションから「追加」をクリックし、以下を設定します。
アクショングループ名:
GetWeather説明:
指定された緯度・経度の現在の天気情報を取得するアクショングループタイプ: 関数の詳細で定義
Lambda関数:
weather-agent-function
関数の定義:
| 項目 | 値 |
|---|---|
| 関数名 | get_current_weather |
| 説明 | 指定された緯度と経度の現在の天気情報(気温、天候、湿度、風速)を取得します |
パラメータ:
| 名前 | 説明 | タイプ | 必須 |
|---|---|---|---|
latitude |
天気を取得したい場所の緯度(例: 35.6762) | string | はい |
longitude |
天気を取得したい場所の経度(例: 139.6503) | string | はい |

3. Lambda のリソースベースポリシー設定
ここが注意が必要なポイントでした。Bedrock Agents が Lambda 関数を呼び出すには、リソースベースポリシーの追加が必要です。
Lambda コンソール → weather-agent-function →「設定」→「アクセス権限」→「リソースベースのポリシーステートメント」→「アクセス権限を追加」で以下を設定します。
| 項目 | 値 |
|---|---|
| ポリシーステートメント | AllowBedrockAgentInvoke |
| プリンシパル | bedrock.amazonaws.com |
| ソースARN | arn:aws:bedrock:ap-northeast-1:<アカウントID>:agent/<エージェントID> |
| アクション | lambda:InvokeFunction |
エージェントIDは、Bedrock コンソールのエージェント画面上部で確認できます。
この設定を忘れると、テスト時に Access denied while invoking Lambda function エラーになります。

4. テスト
エージェントビルダー画面で「準備」をクリックし、右側のテストパネルから動作確認します。
東京の天気を教えて
と入力すると、以下のような回答が返ってきます。
東京の現在の天気をお知らせします: - 天候: 一部曇り - 気温: 14.4°C - 湿度: 69% - 風速: 5.4 km/h アドバイス: 今日は一部曇りですが、比較的穏やかな天気です。気温は14.4°Cとやや涼しいので、 軽めのジャケットや上着があると快適に過ごせるでしょう。
プロンプトで指示した通り、日本語で回答し、天気に基づいたアドバイスも添えてくれています。

5. エイリアス作成とAPIからの呼び出し
テストが成功したら、エイリアスを作成してプログラムから呼び出せるようにします。
エージェント画面の「エイリアス」タブ →「エイリアスを作成」で、エイリアス名 prod を作成します。
必要なIDの確認
APIからの呼び出しには以下の2つのIDが必要です。
| ID | 確認場所 |
|---|---|
| エージェントID | エージェント画面上部 |
| エイリアスID | 「エイリアス」タブ → prod の「エイリアスID」列 |
AWS CLI でも確認できます。
# エージェントID確認 aws bedrock-agent list-agents --region ap-northeast-1 # エイリアスID確認 aws bedrock-agent list-agent-aliases --agent-id <エージェントID> --region ap-northeast-1
Python(boto3)での呼び出し
Bedrock Agents はストリーミングレスポンスを返すため、AWS CLI では直接呼び出せません。Python SDK(boto3)の Amazon Bedrock Agent Runtime クライアントを使います。
import boto3 AGENT_ID = "<エージェントID>" ALIAS_ID = "<エイリアスID>" REGION = "ap-northeast-1" client = boto3.client("bedrock-agent-runtime", region_name=REGION) response = client.invoke_agent( agentId=AGENT_ID, agentAliasId=ALIAS_ID, sessionId="test-session-001", inputText="東京の天気を教えて", ) completion = "" for event in response.get("completion"): chunk = event["chunk"] completion += chunk["bytes"].decode() print(completion)
実行すると、コンソールのテストパネルと同じ回答が返ってきます。
同じ sessionId を使い続けると会話の文脈が保持されるので、連続した質問も可能です。
まとめ
今回は Amazon Bedrock Agents を使って天気エージェントを作成しました。
Lambda 関数1つとコンソール設定だけでAIエージェントが作れる
アクショングループで「エージェントができること」を定義し、Lambda で実装する
リソースベースポリシーの設定を忘れずに
boto3 の
invoke_agentでプログラムからも呼び出せる
エージェントの基本的な仕組み(推論 → ツール呼び出し → 回答生成)を体験するのに良い題材だと思います。次は AgentCore も試してみます。