
AgentCore CLI で自作したAIエージェントを GenU に統合してみた
はじめに
こんにちは!AI 事業本部のこーすけです。
前回・前々回の記事では、GenU の AgentCore 機能の有効化と AgentBuilder を紹介しました。
今回は、GenU の外部で独自のエージェントを作成し、GenU の UI に統合するところまでを紹介します。エージェントのデプロイには、新しくリリースされた AgentCore CLI を使います。
今回やること
- AgentCore CLI でエージェントプロジェクトを作成
- 天気予報ツールを実装
- ローカルで動作確認
- AWS にデプロイ
- GenU の
agentCoreExternalRuntimesに ARN を追加して統合
完成すると、GenU のチャット UI から自作の天気予報エージェントを選択して使えるようになります。
AgentCore CLI とは
AgentCore CLI は、Amazon Bedrock AgentCore 向けのターミナルツールです。まだ Public Preview ですが、エージェントの作成からデプロイまでを 4 つのコマンドで完結できます。
agentcore create # プロジェクト作成
agentcore dev # ローカル開発サーバー起動
agentcore deploy # AWS へデプロイ
agentcore invoke # デプロイ済みエージェントの実行
対応しているエージェントフレームワークは以下の通りです。
| フレームワーク | 対応モデル |
|---|---|
| Strands Agents | Bedrock(Claude 等) |
| LangChain / LangGraph | 各種 |
| Google ADK | Gemini |
| OpenAI Agents | OpenAI |
今回は個人的に使い慣れている Strands Agents + Bedrock を使います。
インストール
npm install -g @aws/agentcore
以下、今回使用した環境になります。
| ツール | バージョン |
|---|---|
| AgentCore CLI | 0.3.0-preview.6.1 |
| Node.js | v22.12.0 |
| Python | 3.11.1 |
| uv | 0.7.19 |
| AWS CLI | 2.26.4 |
エージェントの作成
まずは、AgentCore CLI を使ってエージェントを作成します。
ステップ 1: プロジェクト作成
agentcore create を実行すると、対話形式でプロジェクトの設定を選択できます。
agentcore create
設定値は次のようにしました。
Name: WeatherAgent
Language: Python
Build: Container
Protocol: HTTP
Framework: Strands
Model: Bedrock (us.anthropic.claude-sonnet-4-5-20250514-v1:0)
Memory: None
Network: PUBLIC
-
プロジェクト名:WeatherAgent

-
エージェントを追加するか:Yes

-
エージェント名:MyAgent

-
新規エージェントを作成するか:作成する

-
Language:Python

-
Build:Container

-
Protocol:HTTP

-
Framework:Strands Agents SDK

-
Model:Bedrock API Key が不要なため Bedrock が手軽です。

-
Memory:None

-
Network:PUBLIC

最後に確認画面が出ます。

作成が完了したらプロジェクトディレクトリに移動します。
cd WeatherAgent
生成されるプロジェクト構造は以下の通りです。
WeatherAgent/
├── agentcore/
│ ├── agentcore.json # リソース設定
│ ├── aws-targets.json # デプロイ先設定
│ └── cdk/ # CDK インフラ(自動生成)
└── app/
└── MyAgent/
└── main.py # エージェントのコード
デフォルトで生成されるエージェントのコードはこちらになります。
from strands import Agent, tool
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from model.load import load_model
from mcp_client.client import get_streamable_http_mcp_client
from memory.session import get_memory_session_manager
app = BedrockAgentCoreApp()
log = app.logger
# MCP クライアントの定義
mcp_clients = [get_streamable_http_mcp_client()]
# ツールの定義
tools = []
@tool
def add_numbers(a: int, b: int) -> int:
"""Return the sum of two numbers"""
return a+b
tools.append(add_numbers)
for mcp_client in mcp_clients:
if mcp_client:
tools.append(mcp_client)
def agent_factory():
cache = {}
def get_or_create_agent(session_id, user_id):
key = f"{session_id}/{user_id}"
if key not in cache:
cache[key] = Agent(
model=load_model(),
session_manager=get_memory_session_manager(session_id, user_id),
system_prompt="You are a helpful assistant. Use tools when appropriate.",
tools=tools
)
return cache[key]
return get_or_create_agent
get_or_create_agent = agent_factory()
@app.entrypoint
async def invoke(payload, context):
log.info("Invoking Agent.....")
session_id = getattr(context, 'session_id', 'default-session')
user_id = getattr(context, 'user_id', 'default-user')
agent = get_or_create_agent(session_id, user_id)
stream = agent.stream_async(payload.get("prompt"))
async for event in stream:
if "data" in event and isinstance(event["data"], str):
yield event["data"]
if __name__ == "__main__":
app.run()
ステップ 2: 天気予報ツールの実装
app/MyAgent/main.py を編集して、天気予報ツールを追加します。
天気予報を取得するための API には Open-Meteo API を使用しました。Open-Meteo API はオープンソースの API であり、無料で API キーも不要なのでデモに最適でした。
変更のポイントは以下の 3 点です。
- 天気予報ツールの追加:
@toolデコレータでget_weatherを定義し、Open-Meteo API から天気情報を取得する。 - 会話履歴の引き継ぎ: GenU のフロントエンドは毎回の会話履歴を
messagesとして送信してくるため、Agent(messages=messages)で渡して会話を継続できるようにする。(ただし今回はテキストデータのみ抽出しているので画像や添付ファイルには対応していません。) - 出力形式を GenU に合わせる: ストリーミングの部分は GenU 側が期待する出力形式になるように合わせる。(GenU 側の Agent のコードは
generative-ai-use-cases-jp/packages/cdk/lambda-python/generic-agent-core-runtime/src/agent.pyに記述されているのでここの実装に合わせました。)
import json
import urllib.request
from strands import Agent, tool
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from model.load import load_model
app = BedrockAgentCoreApp()
log = app.logger
@tool
def get_weather(city: str) -> str:
"""指定された都市の現在の天気を取得します。
Args:
city: 天気を取得したい都市名(例: Tokyo, New York, London)
"""
# 都市名から緯度経度を取得(Open-Meteo Geocoding API)
geo_url = f"https://geocoding-api.open-meteo.com/v1/search?name={city}&count=1&language=ja"
with urllib.request.urlopen(geo_url) as response:
geo_data = json.loads(response.read())
if "results" not in geo_data:
return f"都市 '{city}' が見つかりませんでした。"
location = geo_data["results"][0]
lat = location["latitude"]
lon = location["longitude"]
name = location.get("name", city)
# 天気情報を取得(Open-Meteo Weather API)
weather_url = (
f"https://api.open-meteo.com/v1/forecast?"
f"latitude={lat}&longitude={lon}"
f"¤t=temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m"
f"&timezone=Asia/Tokyo"
)
with urllib.request.urlopen(weather_url) as response:
weather_data = json.loads(response.read())
current = weather_data["current"]
return (
f"{name} の現在の天気\n"
f"気温: {current['temperature_2m']}°C\n"
f"湿度: {current['relative_humidity_2m']}%\n"
f"風速: {current['wind_speed_10m']} km/h"
)
def process_prompt(prompt):
"""GenU が送る prompt(ContentBlock 配列)からテキストを抽出する。"""
if isinstance(prompt, str):
return prompt
if isinstance(prompt, list):
texts = [block["text"] for block in prompt if isinstance(block, dict) and "text" in block]
return "\n".join(texts) if texts else ""
return str(prompt)
@app.entrypoint
async def invoke(payload):
log.info("Invoking Agent.....")
# GenUのフロントエンドが送るペイロードから会話履歴と現在の入力を取得
messages = payload.get("messages", [])
prompt = process_prompt(payload.get("prompt", ""))
agent = Agent(
model=load_model(),
system_prompt="あなたは天気予報アシスタントです。ユーザーが都市名を伝えると、現在の天気を取得して日本語で回答します。",
tools=[get_weather],
messages=messages,
)
# GenUのフロントエンドにレスポンス形式を合わせる
async for event in agent.stream_async(prompt):
if "event" in event:
yield event
if __name__ == "__main__":
app.run()
ステップ 3: ローカルテスト
続いて、ローカルサーバを立ち上げテストをしてみます。事前にデプロイ予定の環境にスイッチロールしてからコマンドを実行してください。
agentcore dev
対話できるウィンドが立ち上がるので、試しに今日の東京の天気を聞いてみましょう。

追加したget_weatherを使いバッチリ回答してくれています!

AWS へデプロイ
ローカルでの動作確認ができたのでAWSにデプロイします。
ステップ 4: デプロイ
agentcore deploy
およそ5分くらいでデプロイが完了しました。

続いて、ステータスを確認します。
agentcore status

作成された Runtime ARNが表示されます。こちらは GenU に統合する際に必要になるので控えておきましょう。
arn:aws:bedrock-agentcore:ap-northeast-1:123456789012:runtime/xxxxxxxx
ここで一つ注意点があります。レスポンス形式を変更したため、agentcore invoke のレスポンス結果は空になります。実際のエージェントは正常に動作しており、GenU のフロントエンドから呼び出せば正しくレスポンスが表示されます。
そのため、以下のコマンドでの動作検証はうまくいきません。
agentcore invoke "今日の大阪の天気を教えてください" --agent MyAgent
GenU に統合する
続いて、GenU の修正に移ります。
ステップ 5: parameter.ts の編集
GenU の packages/cdk/parameter.ts に、デプロイした Runtime の ARN を agentCoreExternalRuntimes として追加します。
const envs: Record<string, Partial<StackInput>> = {
myenv: {
modelRegion: "us-east-1",
createGenericAgentCoreRuntime: true,
agentBuilderEnabled: true,
agentCoreExternalRuntimes: [
{
name: 'WeatherAgent',
arn: 'arn:aws:bedrock-agentcore:ap-northeast-1:123456789012:runtime/xxxxxxxx',
description: 'This is WeatherAgent.',
},
],
},
};
ステップ 6: GenU を再デプロイ
npm run cdk:deploy
ステップ 7: 動作確認
GenU の AgentCore ページを開くと、ランタイム選択のドロップダウンに WeatherAgent が追加されています。

「東京の天気を教えてください」と送信すると、天気予報エージェントが Open-Meteo API を呼び出して回答してくれます。
トレースを開くと、get_weather ツールが呼び出されていることが確認できます。さらに会話の履歴も加味した回答をしてくれていることが確認できますね。

おわりに
AgentCore CLI を使うと、CDK やインフラのコードを一切書かずに、わずか数コマンドでエージェントを AWS にデプロイできました。GenU との統合も agentCoreExternalRuntimes に ARN を追加するだけなので非常に手軽ですね。
3回にわたって GenU の AgentCore 周りを紹介しましたが、まとめると以下のような使い分けになるかと思います。
| やりたいこと | 方法 |
|---|---|
| エージェントをすぐ使いたい | createGenericAgentCoreRuntime: true |
| UI からノーコードでエージェントを作りたい | agentBuilderEnabled: true |
| 独自ロジックのエージェントを統合したい | agentCoreExternalRuntimes |
GenUでも独自エージェントの実装に集中できる環境が整ってきていると感じます。










