10/17更新:AWS東京リージョンに対応させました。
このイベント用の手順書ですが、本記事を読めば1時間ぐらいで誰でも試せます!
Claude Codeなど、AIエージェントを「使う」人はかなり増えてきました。
もはや、AI使うのは全員やって当たり前。
僕らは一歩進んで、AIエージェントを「作る」方にも入門しましょう。100倍楽しいですよ🙌
当日までの事前準備
AWSアカウントの作成
新規作成推奨。既存アカウントを使う際は自己責任でお願いします。
※最近は機能制限つきの完全無料プランも出てきますが、「有料(Paid)」を選んでください。
今回の課金は数十円レベルの想定です。(100%保証はできないので、自己責任でお願いします)
GitHubアカウントの作成
既に持っている方は既存アカウントをお使いください。
前説
AIエージェントの構築には、クラウドサービスを使うと便利です。
Strandsを使えば、Pythonで簡単にAIエージェントが書けます。
開発したAIエージェントは、AgentCoreを使えばサーバーレスで安くデプロイできます。
0. 環境構築
0-1. 開発環境のセットアップ
GitHubリポジトリの作成
- サインイン後、トップページ左上「New」より新規リポジトリを作成
- Repository name:
agentcore2025 - Choose visibility: Private
- Add README: On
- Repository name:
GitHub Codespacesの起動
- リポジトリ作成後、画面右上の緑色ボタン「Code > Create codespace on main」
必要なファイルの作成
- コードスペース画面下部のターミナルで以下コマンドを実行
touch .env
- 作成されたファイルに以下を記載する
# AWS認証情報
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=ap-northeast-1
コードスペースではファイルに入力した瞬間、自動で上書き保存されます。
1行目と2行目の値は、この次の手順で埋めます。
0-2. AWSアカウントのセットアップ
- AWSマネコンにサインイン( https://console.aws.amazon.com/ )
このハンズオンは、すべてAWS東京リージョンで行います。
最初に画面右上のリージョンを切り替えておいてください。
Bedrockのモデル有効化
- AWSマネコンで「Amazon Bedrock」を検索してアクセス
- 左サイドバーから「チャット/テキストのプレイグラウンド」にアクセスし、「モデルを選択」ボタンからAnthropic社の任意のモデルを選択して「適用」ボタンをクリック
- ユースケースの詳細を入力して送信(ざっくりでOK)
- あなたの所属会社名
- あなたの会社のWebサイトURL
- あなたの所属業界
- 対象のユーザーは誰ですか?: 社内の従業員(Internal users)
- ユースケースの詳細を入力してください:
hands-on
IAMユーザーの作成
- 「IAM」を検索してアクセス
- サイドバー「ユーザー」より新規ユーザーを作成
- ステップ1
- ユーザー名:
codespaces
- ユーザー名:
- ステップ2
- 許可のオプション: ポリシーを直接アタッチする
- 許可ポリシー:
AdministratorAccessにチェック
- 後はそのまま進む
- ステップ1
IAMアクセスキーの作成
- IAMユーザー作成後、作ったユーザー名をクリックして開く
- 概要セクションより「アクセスキーを作成」
- ステップ1
- ユースケース: ローカルコード
- 「上記のレコメンデーションを理解し、アクセスキーを作成します。」にチェック
- 後はそのまま進む
- ステップ1
- 作成後、コードスペースの
.envの1行目にアクセスキーを、2行目にシークレットアクセスキーをそれぞれ貼り付ける
# AWS認証情報
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE #サンプル
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY #サンプル
AWS_DEFAULT_REGION=ap-northeast-1
この認証情報は、管理者権限を持っているため慎重に扱ってください。
もし誤って公開GitHubリポジトリにPushしたりすると、秒で悪い人に検知されて、あなたのAWSアカウントを悪用される恐れがあります。
1. Strands Agents入門
- コードスペースで画面下部のターミナルを利用
- 以下コマンドで、新規ディレクトリを作りそこに移動
mkdir 1_strands
cd 1_strands
1-1. 三行エージェント
- 新規ファイルを作成
touch 1_agent.py
- 以下コードをファイルに貼り付け
# 必要なライブラリをインポート
from dotenv import load_dotenv
from strands import Agent
# .envファイルから環境変数を読み込む
load_dotenv()
# エージェントを作成して起動
agent = Agent("jp.anthropic.claude-haiku-4-5-20251001-v1:0")
agent("JAWS-UG主催のAI Builders Dayはどこで開催される?")
すいません盛りました。 .envが無ければ三行なんです。
モデルを指定しない場合、デフォルトではBedrockのClaude Sonnet 4が利用されます。(USクロスリージョン推論のため、東京リージョンで実行するとエラーになります)
- 以下コマンドで、必要なモジュールをインストールしてから実行
pip install strands-agents python-dotenv
python 1_agent.py
答えてくれますが、新しいイベントであるAI Builders Dayのことは知らないようです。
申し訳ありませんが、現在のAI Builders Dayの開催場所に関する最新情報を確認できません。
最新の情報を得るには、以下をお勧めします:
1. **JAWS-UG公式ウェブサイト** - 最新のイベント情報が掲載されています
2. **JAWS-UG SNS** - Twitter、FacebookなどのJAWS-UG公式アカウント
3. **connpass** - JAWS-UGがイベント告知に使用するプラットフォーム
JAWS-UGのイベントは複数の拠点で開催されることもあります。具体的な開催場所は、イベントの最新告知でご確認ください。
何か他にお手伝いできることはありますか?
参考:Bedrockの他モデルはもちろん、OpenAIのモデルなども呼べます!
1-2. ツールを持たせてみる
最新情報を答えてもらえるように、Web検索機能を「ツール」として追加してみましょう。
まず、Web検索サービスTavilyにサインアップ(アカウント作成)してください。
GitHubアカウントを連携すれば秒で完了です。
表示されるAPIキーをコピーして、 .env ファイルに追記します。
# AWS認証情報
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE #これはサンプル
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY #これはサンプル
AWS_DEFAULT_REGION=us-west-2
# Tavily認証情報
TAVILY_API_KEY=tvly-oWHrOGmzokwl123drrXNlFBHL2EXAMPLE #これはサンプル
- 新規ファイルを作成
touch 2_tool.py
- 以下コードをファイルに貼り付け
# 必要なライブラリをインポート
import os
from dotenv import load_dotenv
from strands import Agent, tool
from tavily import TavilyClient
# .envファイルから環境変数を読み込む
load_dotenv()
# Web検索関数をツールとして定義
@tool
def search(query):
tavily = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
return tavily.search(query)
# ツールを設定したエージェントを作成
agent = Agent(
model="apac.anthropic.claude-3-7-sonnet-20250219-v1:0",
tools=[search]
)
# エージェントを起動
agent("JAWS-UG主催のAI Builders Dayはどこで開催される?")
東京・大阪専用の「JPクロスリージョン推論」プロファイルは、最新のClaudeモデルのみ対応のため初期クォータが非常に低い(分間2回まで)ことから、ツールを何度か使うとすぐToo many requestsエラーが発生して、Strandsの応答が遅延します。
そのため、ハンズオンでは旧モデルのSonnet 3.7を指定しています。(国内限定ではなくAPAC全体に負荷分散されます)
- 以下コマンドで実行
pip install tavily-python
python 2_tool.py
検索ツールを使って回答してくれます。
AWSコミュニティイベントの「JAWS-UG主催のAI Builders Day」の開催場所について調べてみます。検索機能を使って情報を取得します。
Tool #1: search
検索結果からは、JAWS-UG主催のAI Builders Dayの正確な開催場所が明確に示されていません。検索結果に「AI Builders Day」についての言及はありますが、具体的な会場情報がありません。より具体的に検索してみましょう。
Tool #2: search
まだ明確な情報が見つかりません。より直接的に「AI Builders Day」のイベントページを探してみましょう。
Tool #3: search
より具体的な情報を探すため、イベントページの詳細を確認しましょう:
Tool #4: search
最初の検索結果に会場情報がありそうです。より詳細な情報を確認するためにイベントページの内容を確認します:
Tool #5: search
検索結果から情報が確認できました。JAWS-UG主催のAI Builders Dayの開催場所について以下の通りお伝えします:
JAWS-UG主催のAI Builders Dayは、「池袋サンシャインシティ ワールドインポートマートビル 展示ホールA」で開催されます。
住所:〒170-8630 東京都豊島区東池袋3-1
このイベントは、AWSで生成AIアプリを作る日本の「ビルダー」たちを盛り上げるための国内最大規模の開発者向けイベントとして開催されます。connpassのイベントページでも確認できる情報です。
1-3. 他の人が作ったMCPサーバーからツールを拝借する
AWSドキュメントなどを検索できる「AWS Knowledge MCPサーバー」を使ってみましょう。
- 新規ファイルを作成
touch 3_mcp.py
- 以下コードをファイルに貼り付け
# 必要なライブラリをインポート
from dotenv import load_dotenv
from strands import Agent
from strands.tools.mcp import MCPClient
from mcp.client.streamable_http import streamablehttp_client
# .envファイルから環境変数を読み込む
load_dotenv()
# MCPクライアントを作成
mcp = MCPClient(
lambda: streamablehttp_client("https://knowledge-mcp.global.api.aws")
)
# MCPクライアントを起動しながら、エージェント作成&呼び出し
with mcp:
agent = Agent(
model="apac.anthropic.claude-3-7-sonnet-20250219-v1:0",
tools=mcp.list_tools_sync()
)
agent("Bedrock Agentcoreのランタイムってどんな機能?一言で説明して。")
- 以下コマンドで実行
pip install strands-agents-tools
python 3_mcp.py
以下のようなレスポンスが出力されます。
AWS Bedrock AgentCoreのランタイムについて調べたいですね。AWS Bedrock Agentについての情報を検索してみます。
Tool #1: aws___search_documentation
AWS Bedrock AgentCoreランタイムについての情報が見つかりましたので、詳細を確認するために主要なページを読んでみます。
Tool #2: aws___read_documentation
AWS Bedrock AgentCore Runtimeを一言で説明すると:
AWS Bedrock AgentCore Runtimeは、任意のフレームワークやモデルを使用したAIエージェントを安全かつスケーラブルに実行するための、セキュアでサーバーレスな目的特化型の実行環境です。
主な特徴は:
- フレームワークに依存しない設計(LangGraph、Strands、CrewAIなど対応)
- 最長8時間までの長時間実行サポート
- セッション分離による安全性の確保
- 100MBの大型ペイロード処理能力
- 使用量ベースの料金体系
- 組み込み認証機能
- エージェント特化の可観測性
1-4. マルチエージェントにしてみる
監督者がサブエージェントをツールのように呼び出す「Agent-as-Tools」パターンを使います。(一番オーソドックスで実装も簡単)
- 新規ファイルを作成
touch 4_multi_agent.py
- 以下コードをファイルに貼り付け
# 必要なライブラリをインポート
from dotenv import load_dotenv
from strands import Agent, tool
from strands_tools import calculator
# .envファイルから環境変数を読み込む
load_dotenv()
# サブエージェント1を定義
@tool
def math_agent(query: str):
agent = Agent(
model="apac.anthropic.claude-3-7-sonnet-20250219-v1:0",
system_prompt="ツールを使って計算を行ってください",
tools=[calculator]
)
return str(agent(query))
# サブエージェント2を定義
@tool
def haiku_agent(query: str):
agent = Agent(
model="jp.anthropic.claude-haiku-4-5-20251001-v1:0",
system_prompt="与えられたお題で五・七・五の俳句を詠んで"
)
return str(agent(query))
# 監督者エージェントの作成と実行
orchestrator = Agent(
model="jp.anthropic.claude-sonnet-4-5-20250929-v1:0",
system_prompt="与えられた問題を計算して、答えを俳句として詠んで",
tools=[math_agent, haiku_agent]
)
orchestrator("十円持っている太郎くんが二十円もらいました。今いくら?")
- 以下コマンドで実行
pip install strands-agents-tools
python 4_multi_agent.py
マルチエージェントが協働して回答してくれます。
この問題を数学で解いた後、結果を俳句にします。
まずは計算してみましょう:
Tool #1: math_agent
太郎くんの所持金を計算しましょう。
太郎くんは最初に10円持っていて、そこに20円もらったので、合計金額を計算します。
Tool #1: calculator
太郎くんは今30円持っています。では、この答え(30円)を俳句にしてみましょう:
Tool #2: haiku_agent
## 太郎くんの三十円
三十円
夢広がる
駄菓子屋で
問題の答えは30円です。その結果を俳句にしました:
三十円
夢広がる
駄菓子屋で
Sonnet 4.5は、なぜかStrandsで途中経過のテキストをあまり呟いてくれないんですよね。なぜだろう🤔
2. AgentCore入門
これまでは作ったエージェントをデプロイしたいとき、インフラはLambdaにすべきかECSにすべきか、認証やストリーミングはどうしよう、そして監視は…など細かい悩みが尽きませんでしたが、AgentCoreはこれをまるっと解決してくれる救世主です!
便利なSDKやCLIツールも提供されています。
- 新規ディレクトリを作って、そこに移動
cd /workspaces/agentcore2025
mkdir 2_agentcore
cd 2_agentcore
2-1. トレースの有効化
このハンズオンは、すべて東京リージョンで行います。
最初に画面右上のリージョンを切り替えておいてください。
- AWSマネコンで「CloudWatch」を検索してアクセス
- サイドバーの「トランザクション検索」より、「Enable Transaction Search」をクリック
- 「Check this option to ingest spans as structured logs」にチェックを入れて「Save」
2-2. コードにAgentCore SDKを装着
Strandsで書いたエージェントを、AgentCoreのSDKでラップしてAPIサーバーにします。
AgentCoreビルド用のディレクトリを作り、そこに新規ファイルを作成
mkdir backend
cd backend
touch tavily_agent.py
- 以下コードをファイルに貼り付け
# 必要なライブラリをインポート
from strands import Agent
from strands.tools.mcp.mcp_client import MCPClient
from mcp.client.streamable_http import streamablehttp_client
from bedrock_agentcore.runtime import BedrockAgentCoreApp
# AgentCoreランタイム用のAPIサーバーを作成
app = BedrockAgentCoreApp()
# エージェント呼び出し関数を、APIサーバーのエントリーポイントに設定
@app.entrypoint
async def invoke_agent(payload, context):
# フロントエンドで入力されたプロンプトとAPIキーを取得
prompt = payload.get("prompt")
tavily_api_key = payload.get("tavily_api_key")
### この中が通常のStrandsのコード ----------------------------------
# Tavily MCPサーバーを設定
mcp = MCPClient(lambda: streamablehttp_client(
f"https://mcp.tavily.com/mcp/?tavilyApiKey={tavily_api_key}"
))
# MCPクライアントを起動したまま、エージェントを呼び出し
with mcp:
agent = Agent(
model="apac.anthropic.claude-3-7-sonnet-20250219-v1:0",
tools=mcp.list_tools_sync()
)
# エージェントの応答をストリーミングで取得
stream = agent.stream_async(prompt)
async for event in stream:
yield event
### ------------------------------------------------------------
# APIサーバーを起動
app.run()
2-3. AgentCoreランタイムにデプロイ
AgentCoreランタイムへ簡単にAIエージェントをデプロイできる「スターターツールキット」を使います。
- 新規ファイルを作成
touch requirements.txt
- 以下を記入
strands-agents
bedrock-agentcore
- 以下コマンドを実行
# .env の内容をターミナルの環境変数に設定
export $(cat /workspaces/agentcore2025/.env | grep -v ^# | xargs)
# AgentCoreのスターターツールキットをインストール
pip install bedrock-agentcore-starter-toolkit
# デプロイ準備
agentcore configure --entrypoint tavily_agent.py
- ウィザードでは全て
EnterでOK
🏷️ Inferred agent name: tavily_agent
Press Enter to use this name, or type a different one (alphanumeric without '-')
Agent name [test]:
✓ Using agent name: tavily_agent
🔍 Detected dependency file: requirements.txt
Press Enter to use this file, or type a different path (use Tab for autocomplete):
Path or Press Enter to use detected dependency file: requirements.txt
✓ Using requirements file: requirements.txt
🔐 Execution Role
Press Enter to auto-create execution role, or provide execution role ARN/name to use existing
Execution role ARN/name (or press Enter to auto-create):
✓ Will auto-create execution role
🏗️ ECR Repository
Press Enter to auto-create ECR repository, or provide ECR Repository URI to use existing
ECR Repository URI (or press Enter to auto-create):
✓ Will auto-create ECR repository
🔐 Authorization Configuration
By default, Bedrock AgentCore uses IAM authorization.
Configure OAuth authorizer instead? (yes/no) [no]:
✓ Using default IAM authorization
🔒 Request Header Allowlist
Configure which request headers are allowed to pass through to your agent.
Common headers: Authorization, X-Amzn-Bedrock-AgentCore-Runtime-Custom-*
Configure request header allowlist? (yes/no) [no]:
✓ Using default request header configuration
Configuring BedrockAgentCore agent: test
💡 No container engine found (Docker/Finch/Podman not installed)
✓ Default deployment uses CodeBuild (no container engine needed), For local builds, install Docker, Finch, or Podman
Memory Configuration
Tip: Use --disable-memory flag to skip memory entirely
No region configured yet, proceeding with new memory creation
✓ Short-term memory will be enabled (default)
• Stores conversations within sessions
• Provides immediate context recall
Optional: Long-term memory
• Extracts user preferences across sessions
• Remembers facts and patterns
• Creates session summaries
• Note: Takes 120-180 seconds to process
Enable long-term memory? (yes/no) [no]:
✓ Using short-term memory only
もし、AWSの認証エラーが出て失敗する場合は、前述の export $(cat /workspaces/agentcore2025/.env | grep -v ^# | xargs) コマンドが上手くいっていない可能性があります。
代替手段として、以下のようにコマンドを3行に分けて実行してみてください。
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE #右辺はサンプル
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY #右辺はサンプル
export AWS_DEFAULT_REGION=ap-northeast-1
agentcore configure が上手くいったら、あなたのアプリをコンテナ化するために必要な設定ファイルなどが自動生成されます。
- デプロイを実施
# デプロイ
agentcore launch
1分ほど待つと、あなたのAIエージェントがAgentCoreランタイムにデプロイされます。
デプロイ完了後、表示される Agent ARN の値をメモ帳などにコピーしておきましょう。
2-4. 動作確認
PCのローカル上で、Pythonライブラリ「Streamlit」を使ってフロントエンド画面を作成し、AgentCore上のStrands Agentsを呼び出してみましょう。
- 新規ファイルを作成
cd /workspaces/agentcore2025/2_agentcore
touch frontend.py
- 以下コードをファイルに貼り付け
# 必要なライブラリをインポート
import os, boto3, json
import streamlit as st
from dotenv import load_dotenv
# .envファイルから環境変数をロード
load_dotenv(override=True)
# サイドバーで設定を入力
with st.sidebar:
agent_runtime_arn = st.text_input("AgentCoreランタイムのARN")
tavily_api_key = st.text_input("Tavily APIキー", type="password")
# タイトルを描画
st.title("なんでも検索エージェント")
st.write("Strands AgentsがMCPサーバーを使って情報収集します!")
# チャットボックスを描画
if prompt := st.chat_input("メッセージを入力してね"):
# ユーザーのプロンプトを表示
with st.chat_message("user"):
st.markdown(prompt)
# エージェントの回答を表示
with st.chat_message("assistant"):
# AgentCoreランタイムを呼び出し
agentcore = boto3.client('bedrock-agentcore')
payload = json.dumps({
"prompt": prompt,
"tavily_api_key": tavily_api_key
})
response = agentcore.invoke_agent_runtime(
agentRuntimeArn=agent_runtime_arn,
payload=payload.encode()
)
### ここから下はストリーミングレスポンスの処理 ------------------------------------------
container = st.container()
text_holder = container.empty()
buffer = ""
# レスポンスを1行ずつチェック
for line in response["response"].iter_lines():
if line and line.decode("utf-8").startswith("data: "):
data = line.decode("utf-8")[6:]
# 文字列コンテンツの場合は無視
if data.startswith('"') or data.startswith("'"):
continue
# 読み込んだ行をJSONに変換
event = json.loads(data)
# ツール利用を検出
if "event" in event and "contentBlockStart" in event["event"]:
if "toolUse" in event["event"]["contentBlockStart"].get("start", {}):
# 現在のテキストを確定
if buffer:
text_holder.markdown(buffer)
buffer = ""
# ツールステータスを表示
container.info("🔍 Tavily検索ツールを利用しています")
text_holder = container.empty()
# テキストコンテンツを検出
if "data" in event and isinstance(event["data"], str):
buffer += event["data"]
text_holder.markdown(buffer)
elif "event" in event and "contentBlockDelta" in event["event"]:
buffer += event["event"]["contentBlockDelta"]["delta"].get("text", "")
text_holder.markdown(buffer)
# 最後に残ったテキストを表示
text_holder.markdown(buffer)
### ------------------------------------------------------------------------------
- 以下コマンドで起動
pip install streamlit
streamlit run frontend.py
- 右下に出るポップアップの「ブラウザーで開く」ボタンをクリック
- 閉じてしまった場合は、ターミナルの
http://localhost:8501をクリックすればOK
- 閉じてしまった場合は、ターミナルの
サイドバーに、先ほどメモしたARNとTavilyのAPIキー(.envからコピー可能)を入力して、JAWS-UG主催のAI Builders Dayはどこで開催される? などと質問してみましょう。
2-5. 運用監視
簡易Langfuse的な機能(LLM版Datadogのようなもの)が自動で付いてるので便利です。
AgentCoreオブザーバビリティでトレース確認
- マネコンで「Bedrock AgentCore」を検索し、サイドバー「エージェントランタイム」から
tavily_agentをクリック - 上部の「エージェントの詳細」を展開して「オブザーバビリティを表示」をクリック
- 「Traces view」タブからトレースIDをクリックすると、エージェントの動作履歴をドリルダウンして確認できます
CloudWatchログの確認
うまく起動せず、トレースすら見られないときはサーバーログを見ましょう。
- マネコンで「CloudWatch」を検索してアクセス
- サイドバー「ロググループ」から
/aws/bedrock-agentcore/runtimes/tavily_agent-<ランダム文字列>-DEFAULTをクリック - 「すべてのログストリームを検索」から、直近のサーバーログを確認できます
次のステップ: フロントエンドのデプロイ
今回はフロントエンドをPCのローカルで動かしましたが、Streamlit Community Cloudを使えば無料でホストして他の人に公開できます。余裕がある人は試してみましょう。
公開したアプリは、URLを知っている人が誰でもアクセスできてしまうため、あなたのAWS利用料が増える恐れがあります。コストとセキュリティに注意しましょう。
お片付け
参加後は必ずアンケートにご回答ください!
AWSアカウントは使い捨て運用がおすすめです。
ハンズオンが終わったら、不要なAWSアカウントは解約してしまいましょう。
(解約すると同じメールアドレスが使えなくなるので、捨てアド以外の方は解約前にメルアド変更しましょう)
参考まで、今回作成されたリソースは以下です。
- 使った分だけ課金されるもの
- AgentCoreランタイム
- ほぼ課金されないもの
- IAMユーザー
- IAMロール
- ECRリポジトリ
- CodeBuildプロジェクト
おまけ
今回のようなAIエージェント構築を、図解フルカラーで優しく学べる入門書を今週出版しました!
Strands以外にも、定番のLangGraphや、TypeScriptでエージェントを書けるMastraなど、王道フレームワークを一通り学べます!
Next.jsを用いたフロントエンドの開発方法や、Amplify Gen2を使ったAWSへのデプロイまで紹介。LangfuseやRagasを使ったLLMOpsも解説しています。











