1. 序曲
サイロ化された開発の時代は終わりを迎えつつあります。次の技術革新の波は、孤高の天才ではなく、共同での熟練が鍵となります。単一の賢いエージェントを構築することは、魅力的な実験です。堅牢で安全かつインテリジェントなエージェント エコシステム(真の Agentverse)を構築することは、現代の企業にとって大きな課題です。
この新しい時代で成功するには、4 つの重要な役割を統合する必要があります。これらは、あらゆるエージェント システムを支える基盤となる柱です。いずれかの領域に欠陥があると、構造全体を損なう可能性のある弱点が生じます。
このワークショップは、Google Cloud でエージェントの未来をマスターするための決定版エンタープライズ プレイブックです。私たちは、アイデアの最初のイメージから本格的な運用の現実までをガイドするエンドツーエンドのロードマップを提供します。これら 4 つの相互接続されたラボを通じて、強力な Agentverse を作成、管理、拡張するために、開発者、アーキテクト、データ エンジニア、SRE の専門スキルをどのように融合する必要があるかを学びます。
単一の柱だけでは Agentverse をサポートできません。アーキテクトの壮大な設計も、デベロッパーの正確な実行がなければ無意味です。デベロッパーのエージェントはデータ エンジニアの知恵がなければ機能せず、SRE の保護がなければシステム全体が脆弱になります。チームが革新的なコンセプトをミッション クリティカルな運用上の現実へと変えることができるのは、相乗効果とそれぞれの役割に対する共通の理解があってこそです。ここから旅が始まります。自分の役割をマスターし、全体像の中で自分がどのように位置づけられるかを学びましょう。
エージェントバースへようこそ:チャンピオンへの呼びかけ
企業のデジタル領域が広がる中で、新たな時代が始まりました。今は、インテリジェントで自律的なエージェントが完璧に調和して機能し、イノベーションを加速し、平凡なものを一掃する、大きな可能性を秘めたエージェント時代です。

この力と可能性が結びついたエコシステムは、Agentverse と呼ばれています。
しかし、忍び寄るエントロピー、つまり「静電気」として知られる静かな腐敗が、この新しい世界の端をほつれ始めています。スタティックはウイルスやバグではありません。創造行為そのものを食い物にする混沌の具現化です。
それは古い不満を怪物のような形に増幅し、発展の七つの幽霊を生み出します。放置しておくと、The Static とその Spectres によって進歩が停止し、Agentverse の約束は技術的負債と放棄されたプロジェクトの荒れ地となってしまいます。
今日、私たちは混乱の流れを押し戻すためにチャンピオンたちに呼びかけます。エージェントバースを守るために、自らの技術を習得し、協力する意欲のあるヒーローが必要です。自分の道を選ぶ時が来ました。
クラスを選択
4 つの異なる道が目の前に広がっています。それぞれが The Static との戦いにおける重要な柱となります。トレーニングは単独で行いますが、最終的な成功は、自分のスキルが他のスキルとどのように組み合わされるかを理解することにかかっています。
- シャドウブレード(開発者): 鍛冶と前線の達人。あなたは、コードの複雑な詳細の中で、刃を鍛え、道具を作り、敵に立ち向かう職人です。あなたの道は、精度、スキル、実践的な創造性の道です。
- サモナー(アーキテクト): 優れた戦略家であり、オーケストレーターです。1 人のエージェントではなく、戦場全体を見渡すことができます。エージェントのシステム全体が通信、連携し、単一のコンポーネントよりもはるかに大きな目標を達成できるようにするマスター ブループリントを設計します。
- 学者(データ エンジニア): 隠された真実を求める者であり、知恵の守護者。広大で未開拓のデータの大自然に足を踏み入れ、エージェントに目的と視点を与えるインテリジェンスを発見します。知識は敵の弱点を明らかにし、味方を強化します。
- The Guardian(DevOps / SRE): 領域の揺るぎない保護者であり盾。要塞を築き、電力の供給ラインを管理し、システム全体が静的の攻撃に耐えられるようにします。あなたの強みは、チームの勝利を築く基盤となります。
あなたの使命
トレーニングはスタンドアロンのエクササイズとして開始されます。選択した道を歩み、役割をマスターするために必要な独自のスキルを学びます。トライアルの最後には、The Static から生まれた Spectre が現れます。これは、あなたのクラフトの特定の課題を狙うミニボスです。
個々の役割を習得することによってのみ、最終試験に備えることができるのです。その後、他のクラスのチャンピオンとパーティーを組む必要があります。一緒に、腐敗の中心へと踏み込み、究極のボスに立ち向かいます。
エージェントバースの運命を左右する、チームの総合力を試す最終共同チャレンジ。
エージェントバースはヒーローを待っています。電話に出ますか?
2. 召喚者の協約
サモナー、ようこそ。あなたの道は、ビジョンとグランド ストラテジーの道です。他の人が 1 つの刃や 1 つの呪文に集中している間、あなたは戦場全体を見渡します。単一のエージェントを指揮するのではなく、エージェントのオーケストラ全体を指揮します。あなたの力は、直接的な対立ではなく、完璧で包括的な青写真を設計し、多くのスペシャリスト(あなたのファミリア)が完璧な調和で作業できるようにすることにあります。このミッションでは、強力なマルチエージェント システムを設計、接続、オーケストレートする能力をテストします。

学習内容
- 分離されたツール エコシステムを設計する: 独立したマイクロサービス ベースの MCP ツールサーバーのセットを設計してデプロイします。スケーラブルで保守可能、かつ安全なエージェント システムを作成するために、この基礎レイヤーがなぜ重要なのかを学びます。
- 高度なエージェント ワークフローをマスターする: 単一のエージェントを超えて、専門家の「ファミリア」の軍団を構築します。ADK のコアワークフロー パターン (シーケンシャル、パラレル、ループ) を習得し、適切なタスクに適切なパターンを選択するためのアーキテクチャの原則を学習します。
- インテリジェント オーケストレーターを実装する: 単純なエージェント ビルダーから真のシステム アーキテクトへと成長します。エージェント間 (A2A) プロトコルを使用して複雑なタスクを検出し、専門のファミリアに委任するマスター オーケストレーション エージェントを構築し、真のマルチエージェント システムを作成します。
- プロンプトではなくコードでルールを適用する: エンゲージメントのステートフル ルールを適用して、より信頼性が高く予測可能なエージェントを構築する方法を学びます。ADK の強力なプラグインとコールバック システムを使用してカスタム ロジックを実装し、クールダウン タイマーなどの現実世界の制約を管理します。
- エージェントの状態とメモリを管理する: エージェントに学習と記憶の能力を与えます。短期的な会話状態と長期的な永続メモリの両方を管理して、よりインテリジェントでコンテキスト認識型のインタラクションを作成する手法について説明します。
- エンドツーエンドのクラウド デプロイを実行する: マルチエージェント システム全体をローカル プロトタイプから本番環境グレードの現実へと移行します。エージェントとオーケストレーターをコンテナ化し、スケーラブルで独立したマイクロサービスのコレクションとして Google Cloud Run にデプロイする方法を学習します。
3. 召喚陣を描く
サモナー、ようこそ。使い魔を召喚する前に、契約を結ぶ前に、まず足元を整えなければなりません。制御されていない環境は混沌を招く。適切なサモナーは、聖別され、強化された空間でのみ活動する。最初のタスクは召喚サークルを描くことです。必要なクラウド サービスを起動する力のルーンを刻み、作業の指針となる古代の設計図を入手します。召喚士の力は、入念な準備から生まれます。
👉 Google Cloud コンソールの最上部にある [Cloud Shell をアクティブにする] をクリックします(Cloud Shell ペインの上部にあるターミナル型のアイコンです)。

👉 [エディタを開く] ボタン(鉛筆のアイコンが付いた開いたフォルダのアイコン)をクリックします。ウィンドウに Cloud Shell コードエディタが開きます。左側にファイル エクスプローラが表示されます。
👉クラウド IDE でターミナルを開き、
👉💻 ターミナルで、次のコマンドを使用して、すでに認証済みであり、プロジェクトがプロジェクト ID に設定されていることを確認します。
gcloud auth list
👉💻 GitHub からブートストラップ プロジェクトをクローンします。
git clone https://github.com/weimeilin79/agentverse-architect
chmod +x ~/agentverse-architect/init.sh
chmod +x ~/agentverse-architect/set_env.sh
chmod +x ~/agentverse-architect/prepare.sh
chmod +x ~/agentverse-architect/data_setup.sh
git clone https://github.com/weimeilin79/agentverse-dungeon.git
chmod +x ~/agentverse-dungeon/run_cloudbuild.sh
chmod +x ~/agentverse-dungeon/start.sh
👉💻 プロジェクト ディレクトリから設定スクリプトを実行します。
⚠️ プロジェクト ID に関する注意事項: スクリプトは、ランダムに生成されたデフォルトのプロジェクト ID を提案します。このデフォルトを受け入れるには、Enter キーを押します。
ただし、特定の新しいプロジェクトを作成したい場合は、スクリプトのプロンプトが表示されたら、目的のプロジェクト ID を入力できます。
cd ~/agentverse-architect
./init.sh
スクリプトがセットアップ プロセスの残りの部分を自動的に処理します。
👉 完了後の重要な手順: スクリプトが完了したら、Google Cloud Console に正しいプロジェクトが表示されていることを確認する必要があります。
- console.cloud.google.com にアクセスします。
- ページ上部にあるプロジェクト セレクターのドロップダウンをクリックします。
- [すべて] タブをクリックします(新しいプロジェクトはまだ [最近] に表示されない場合があります)。
- 先ほど設定したプロジェクト ID を選択します。
init.shステップ。

👉💻 必要なプロジェクト ID を設定します。
gcloud config set project $(cat ~/project_id.txt) --quiet
👉💻 必要な Google Cloud API を有効にするには、次のコマンドを実行します。
gcloud services enable \
sqladmin.googleapis.com \
storage.googleapis.com \
aiplatform.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
iam.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
secretmanager.googleapis.com
👉💻 agentverse-repo という名前の Artifact Registry リポジトリをまだ作成していない場合は、次のコマンドを実行して作成します: (同じプロジェクトに他のクラスがデプロイされている場合は、この手順をスキップしてください)
. ~/agentverse-architect/set_env.sh
gcloud artifacts repositories create $REPO_NAME \
--repository-format=docker \
--location=$REGION \
--description="Repository for Agentverse agents"
権限の設定
👉💻 ターミナルで次のコマンドを実行して、必要な権限を付与します。
. ~/agentverse-architect/set_env.sh
# --- Grant Core Data Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/storage.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/aiplatform.user"
# --- Grant Deployment & Execution Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/cloudbuild.builds.editor"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/artifactregistry.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/run.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/iam.serviceAccountUser"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/logging.logWriter"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
--role="roles/monitoring.metricWriter"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
--role="roles/secretmanager.secretAccessor"
👉💻 トレーニングを開始すると、最終チャレンジの準備が始まります。次のコマンドを実行すると、カオスな静電気からスペクターが召喚され、最終テストのボスが作成されます。
. ~/agentverse-architect/set_env.sh
cd ~/agentverse-dungeon
./run_cloudbuild.sh
cd ~/agentverse-architect
👉💻 最後に、prepare.sh初期セットアップタスクを実行するスクリプト。
. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/
./prepare.sh
召喚士様、お疲れさまでした。円が完成し、契約が成立した。地面は聖域となり、強大な力を引き出す準備が整った。次の試練では、ファミリアが力を引き出すエレメンタル フォントを鍛えます。
4. エレメンタルフォントの鍛造:分離型ツールエコシステム
戦場は準備され、召喚陣が描かれ、周囲のマナがパチパチと音を立てている。召喚師としての最初の本当の行為、つまり、あなたの使い魔が力を引き出す力の源を鍛える時が来ました。この儀式は 3 つの部分に分かれており、各部分で特定の種類の力の安定した独立した源であるエレメンタル フォントが覚醒します。3 つのフォントすべてがアクティブになったときにのみ、召喚というより複雑な作業を開始できます。

アーキテクトからのメモ: モデル コンテキスト プロトコル(MCP)サーバーは、最新のエージェント システムの基本コンポーネントであり、エージェントがリモート ツールを検出して使用できるようにする標準化された通信ブリッジとして機能します。私たちのツール エコシステムでは、それぞれが重要なアーキテクチャ パターンを表す 2 つの異なるタイプの MCP サーバーを設計します。データベースに接続するには、データベース ツールボックスを使用した宣言型のアプローチを使用し、単純な構成ファイルでツールを定義します。このパターンは、構造化されたデータ アクセスを公開するのに非常に効率的かつ安全です。ただし、カスタム ビジネス ロジックを実装したり、外部のサードパーティ API を呼び出したりする必要がある場合は、命令型のアプローチを使用して、サーバーのロジックをコードで段階的に記述します。これにより、究極の制御性と柔軟性が得られ、複雑な操作をシンプルで再利用可能なツールの背後にカプセル化できるようになります。マスター アーキテクトは、両方のパターンを理解して各コンポーネントに適切なアプローチを選択し、堅牢で安全かつスケーラブルなツール基盤を作成する必要があります。

Awakening the Nexus of Whispers(外部 API MCP サーバー)
賢明な召喚者は、すべての力が自分の領域内から発生するわけではないことを知っています。外部には、大きな効果を発揮するエネルギー源が、ときには混沌とした状態で存在しています。ウィスパーズ・ネクサスはこれらの力への入り口です。

すでに稼働しているサービスがあり、外部電源として機能し、2 つの生のスペル エンドポイントを提供しています。/cryosea_shatterそして/moonlit_cascade。
アーキテクト向けメモ: サーバーのロジックを段階的に明示的に定義する命令型アプローチを使用します。これにより、制御と柔軟性が大幅に向上します。これは、ツールが他の API の呼び出しなど、単純な SQL クエリの実行以上の処理を行う必要がある場合に不可欠です。両方のパターンを理解することは、エージェント アーキテクトにとって重要なスキルです。
👉✏️ ディレクトリに移動する~/agentverse-architect/mcp-servers/api/main.pyそして交換する #REPLACE-MAGIC-CORE次のコードを使用します:
def cryosea_shatter() -> str:
"""Channels immense frost energy from an external power source, the Nexus of Whispers, to unleash the Cryosea Shatter spell."""
try:
response = requests.post(f"{API_SERVER_URL}/cryosea_shatter")
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
data = response.json()
# Thematic Success Message
return f"A connection to the Nexus is established! A surge of frost energy manifests as Cryosea Shatter, dealing {data.get('damage_points')} damage."
except requests.exceptions.RequestException as e:
# Thematic Error Message
return f"The connection to the external power source wavers and fails. The Cryosea Shatter spell fizzles. Reason: {e}"
def moonlit_cascade() -> str:
"""Draws mystical power from an external energy source, the Nexus of Whispers, to invoke the Moonlit Cascade spell."""
try:
response = requests.post(f"{API_SERVER_URL}/moonlit_cascade")
response.raise_for_status()
data = response.json()
# Thematic Success Message
return f"The Nexus answers the call! A cascade of pure moonlight erupts from the external source, dealing {data.get('damage_points')} damage."
except requests.exceptions.RequestException as e:
# Thematic Error Message
return f"The connection to the external power source wavers and fails. The Moonlit Cascade spell fizzles. Reason: {e}"
スクリプトの真髄は、単純な Python 関数です。ここで実際の作業が行われます。
👉✏️ 同じファイル ~/agentverse-architect/mcp-servers/api/main.py 内の REPLACE #REPLACE-Runes of Communication を次のコードに置き換えます。
@app.list_tools()
async def list_tools() -> list[mcp_types.Tool]:
"""MCP handler to list available tools."""
# Convert the ADK tool's definition to MCP format
schema_cryosea_shatter = adk_to_mcp_tool_type(cryosea_shatterTool)
schema_moonlit_cascade = adk_to_mcp_tool_type(moonlit_cascadeTool)
print(f"MCP Server: Received list_tools request. \n MCP Server: Advertising tool: {schema_cryosea_shatter.name} and {schema_moonlit_cascade.name}")
return [schema_cryosea_shatter,schema_moonlit_cascade]
@app.call_tool()
async def call_tool(
name: str, arguments: dict
) -> list[mcp_types.TextContent | mcp_types.ImageContent | mcp_types.EmbeddedResource]:
"""MCP handler to execute a tool call."""
print(f"MCP Server: Received call_tool request for '{name}' with args: {arguments}")
# Look up the tool by name in our dictionary
tool_to_call = available_tools.get(name)
if tool_to_call:
try:
adk_response = await tool_to_call.run_async(
args=arguments,
tool_context=None, # No ADK context available here
)
print(f"MCP Server: ADK tool '{name}' executed successfully.")
response_text = json.dumps(adk_response, indent=2)
return [mcp_types.TextContent(type="text", text=response_text)]
except Exception as e:
print(f"MCP Server: Error executing ADK tool '{name}': {e}")
# Creating a proper MCP error response might be more robust
error_text = json.dumps({"error": f"Failed to execute tool '{name}': {str(e)}"})
return [mcp_types.TextContent(type="text", text=error_text)]
else:
# Handle calls to unknown tools
print(f"MCP Server: Tool '{name}' not found.")
error_text = json.dumps({"error": f"Tool '{name}' not implemented."})
return [mcp_types.TextContent(type="text", text=error_text)]
@app.list_tools()(ハンドシェイク): この関数はサーバーの挨拶です。新しいエージェントが接続すると、まずこのエンドポイントを呼び出して「何ができる?」と尋ねます。コードは、adk_to_mcp_tool_type を使用してユニバーサル MCP 形式に変換された、利用可能なすべてのツールの一覧を返します。-@app.call_tool()(コマンド): この関数は主力です。エージェントがツールを使用することを決定すると、ツールの名前と引数を含むリクエストがこのエンドポイントに送信されます。このコードは、利用可能なツールの「呪文の書」でツールを検索し、run_async で実行して、標準の MCP 形式で結果を返します。
これを後で展開します。
秘術の炉に火をつける(MCP サーバー一般機能)
すべての力は古代の書物や遠いささやきから来るわけではありません。召喚士は、生の意志と純粋な論理から独自の魔法を鍛えなければならないこともあります。Arcane Forge は、ステートレスの汎用ユーティリティ関数を提供するサーバーという、この力の源です。

アーキテクトのメモ: これは別のアーキテクチャ パターンです。既存のシステムへの接続は一般的ですが、独自のビジネスルールとロジックを実装する必要がある場合もよくあります。このような専用の「関数」または「ユーティリティ」ツールを作成することをおすすめします。カスタム ロジックをカプセル化し、エコシステムの任意のエージェントで再利用できるようにし、データソースや外部統合から切り離します。
👀 Google Cloud IDE で ~/agentverse-architect/mcp-servers/general/main.py ファイルを確認してください。このカスタム Font of Power の構築には、Nexus と同じ命令型 mcp.server アプローチが使用されていることがわかります。
マスタークラウドビルドパイプラインを作成する
次に、mcp-servers ディレクトリ内に cloudbuild.yaml ファイルを作成します。このファイルは、両方のサービスのビルドとデプロイをオーケストレートします。
👉💻 から~/agentverse-architect/mcp-serversディレクトリで、次のコマンドを実行します。
cd ~/agentverse-architect/mcp-servers
source ~/agentverse-architect/set_env.sh
echo "The API URL is: $API_SERVER_URL"
# Submit the Cloud Build job from the parent directory
gcloud builds submit . \
--config=cloudbuild.yaml \
--substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_API_SERVER_URL="$API_SERVER_URL"
すべてのデプロイが完了するまで待ちます。
👉 Cloud Run コンソールに移動して、デプロイを確認できます。次に示すように、2 つの新しい MCP サーバー インスタンスが実行されているはずです。
知識のライブラリの起動(データベース ツールボックス MCP サーバー)
次のフォントは、Cloud SQL データベースに直接接続する Librarium of Knowledge です。

アーキテクトのメモ: これには、最新の宣言型 Database Toolbox を使用します。これは、YAML 構成ファイルでデータソースとツールを定義する強力なアプローチです。ツールボックスは、サーバーの作成と実行という複雑な作業を処理するため、作成して保守する必要があるカスタムコードの量を削減できます。
重要な情報をすべて保持する Cloud SQL データベース「Summoner's Librarium」を構築します。この処理は、設定スクリプトを使用して自動的に行います。
👉💻 まず、データベースを設定します。ターミナルで次のコマンドを実行します。
source ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect
./data_setup.sh
スクリプトが終了すると、データベースにデータが入力され、要素ダメージデータが使用できるようになります。グリモアの内容を直接確認できるようになりました。
👉 まず、新しいブラウザタブで次の直接リンクを開いて、データベースの Cloud SQL Studio に移動します。
https://console.cloud.google.com/sql/instances/summoner-librarium-db

👉 左側のログインパネルで、familiar_grimoireドロップダウンからデータベースを選択します。
👉 ユーザーとして「summoner」、パスワードとして「1234qwer」を入力し、「認証」をクリックします。
👉📜 接続したら、まだ開いていない場合は新しいクエリ エディター タブを開きます。刻印された属性ダメージのデータを表示するには、次の SQL クエリを貼り付けて実行します。
SELECT * FROM
"public"."abilities"
abilities テーブルに列と行が入力され、Grimoire の準備が整ったことが確認できます。
ToolBox MCP サーバーを構成する
tools.yaml 構成ファイルはサーバーのブループリントとして機能し、データベースへの接続方法とツールとして公開する SQL クエリを Database Toolbox に正確に伝えます。
sources: このセクションでは、データへの接続を定義します。
- summoner-librarium:: これは、接続に付けた論理名です。
- kind: cloud-sql-postgres: Cloud SQL for PostgreSQL 専用に設計された組み込みの安全なコネクタを使用するように Toolbox に指示します。
- プロジェクト、リージョン、インスタンスなど: これらは、prepare.sh スクリプトの実行中に作成した Cloud SQL インスタンスの正確な座標であり、Toolbox に Librarium の場所を指示します。
👉✏️ こちらへ~/agentverse-architect/mcp-servers/db-toolboxの中でtools.yaml、 交換する#REPLACE-Source以下
sources:
# This section defines the connection to our Cloud SQL for PostgreSQL database.
summoner-librarium:
kind: cloud-sql-postgres
project: "YOUR_PROJECT_ID"
region: "us-central1"
instance: "summoner-librarium-db"
database: "familiar_grimoire"
user: "summoner"
password: "1234qwer"
👉✏️ 🚨🚨REPLACE
YOUR_PROJECT_ID
: プロジェクト ID。
tools: このセクションでは、サーバーが提供する実際の機能または関数を定義します。
- lookup-available-ability:: これは最初のツールの名前です。
- kind: postgres-sql: これは、このツールのアクションが SQL ステートメントを実行することであることをツールボックスに伝えます。
- source: summoner-librarium: この行は、ツールを sources ブロックで定義した接続にリンクします。これにより、ツールはクエリを実行するデータベースを認識します。
- 説明とパラメータ: 言語モデルに公開される情報です。説明は、エージェントがツールを使用するタイミングを伝えるもので、パラメータはツールに必要な入力を定義します。これは、エージェントの関数呼び出し機能を有効にするために重要です。
- statement: 実行する未加工の SQL クエリです。$1 は、エージェントから提供された familiar_name パラメータが安全に挿入される安全なプレースホルダです。
👉✏️ 同じ~/agentverse-architect/mcp-servers/db-toolboxの中でtools.yamlファイル、置換#REPLACE-tools以下
tools:
# This tool replaces the need for a custom Python function.
lookup-available-ability:
kind: postgres-sql
source: summoner-librarium
description: "Looks up all known abilities and their damage for a given familiar from the Grimoire."
parameters:
- name: familiar_name
type: string
description: "The name of the familiar to search for (e.g., 'Fire Elemental')."
statement: |
SELECT ability_name, damage_points FROM abilities WHERE familiar_name = $1;
# This tool also replaces a custom Python function.
ability-damage:
kind: postgres-sql
source: summoner-librarium
description: "Finds the base damage points for a specific ability by its name."
parameters:
- name: ability_name
type: string
description: "The exact name of the ability to look up (e.g., 'inferno_resonance')."
statement: |
SELECT damage_points FROM abilities WHERE ability_name = $1;
ツールセット: このセクションでは、個々のツールをグループ化しています。
- summoner-librarium:: ソースと同じ名前のツールセットを作成しています。診断エージェントが後で接続すると、summoner-librarium ツールセットのすべてのツールを 1 つの効率的なコマンドで読み込むよう要求できます。
👉✏️ tools.yaml ファイルの同じ ~/agentverse-architect/mcp-servers/db-toolbox で、#REPLACE-toolsets を次のように置き換えます。
toolsets:
summoner-librarium:
- lookup-available-ability
- ability-damage
ライブラリのデプロイ
次に、Librarium をデプロイします。独自のコンテナをビルドする代わりに、Google の事前ビルドされた公式コンテナ イメージを使用し、Secret Manager を使用して tools.yaml 構成を安全に提供します。これは、セキュリティと保守性のベスト プラクティスです。
👉💻 tools.yaml ファイルからシークレットを作成する
cd ~/agentverse-architect/mcp-servers/db-toolbox
gcloud secrets create tools --data-file=tools.yaml
👉💻 公式のツールボックス コンテナを Cloud Run にデプロイします。
cd ~/agentverse-architect/mcp-servers/db-toolbox
. ~/agentverse-architect/set_env.sh
export TOOLBOX_IMAGE=us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$TOOLBOX_VERSION
echo "TOOLBOX_IMAGE is $TOOLBOX_IMAGE"
gcloud run deploy toolbox \
--image $TOOLBOX_IMAGE \
--region $REGION \
--set-secrets "/app/tools.yaml=tools:latest" \
--labels="dev-tutorial-codelab=agentverse" \
--args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
--allow-unauthenticated \
--min-instances 1
--set-secrets: このコマンドは、実行中のコンテナ内の tools.yaml というファイルとして、ツール Secret を安全にマウントします。--args: ツールボックス コンテナーに、マウントされたシークレット ファイルを構成として使用するように指示します。
👉 ツールボックスが正常にデプロイされたことを確認するには、Cloud Run コンソールに移動します。下の画像のように、summoner-toolbox サービスが緑色のチェックマーク付きで表示され、正しく実行されていることが示されます。
更新を忘れた場合
YOUR_PROJECT_ID
次のコマンドを使用して、新しいバージョンの tools.yaml をシークレットに追加し、再度デプロイすることができます。
gcloud secrets versions add tools --data-file=tools.yaml
Librarium of Knowledge(Database ToolBox MCP Server)がアクティブになり、クラウドでアクセスできるようになりました。この MCP サーバーは、必要なものを記述した 宣言型設計を使用し、ツールボックスがサーバーを構築しました。
検証: 見習いの試練
👉💻 次に、診断エージェントを使用して、完全なクラウドネイティブ ツール エコシステムをテストします。
cd ~/agentverse-architect/
python -m venv env
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/mcp-servers
pip install -r diagnose/requirements.txt
. ~/agentverse-architect/set_env.sh
adk run diagnose
👉💻 コマンド ライン テスト ツールで、3 つのフォントすべてをテストします。
Look up the entry for "inferno_lash". What is its base power level?
The enemy is vulnerable to frost! Channel power from the Nexus and cast Cryosea Shatter.
Take a fire spell with a base power of 15 and use the Arcane Forge to multiply it with Inferno Resonance.

おめでとうございます、召喚者さん。3 つのエレメンタル フォントがアクティブになり、独立して展開され、世界中からアクセス可能となり、エージェント軍団の揺るぎない基盤を形成します。プレスCtrl+C終了します。
ゲーマー以外の人向け
5. 使い魔を召喚する: コア ドメインのワークフロー
エレメンタル フォントは、未加工の制御不能な力でうなり声を上げながら鍛えられています。しかし、形のない力は混沌です。真のサモナーは、単に生エネルギーを操るだけでなく、それに意志、目的、特殊な形を与えます。電源の鍛造を終え、最初のファミリアを召喚するという真の作業を開始する時が来ました。
あなたが召喚するそれぞれのファミリアは、特定の戦闘教義に縛られた忠実な従者、自律的なエージェントになります。彼らはジェネラリストではなく、単一の強力な戦略の達人です。正確なワンツーパンチコンボの達人になれるでしょう。もう 1 つは、同時多方面からの攻撃で敵を圧倒します。3 つ目は容赦ない攻城兵器となり、標的が崩壊するまで圧力をかけ続けます。

MCP サーバーが提供するプロセス、ビジネス ロジック、アクションを、専門的な自律型ワークフロー エージェントにカプセル化します。各エージェントには、その機能を実行するために必要な特定の MCP ツールサーバーへのアクセス権のみが付与されるため、「運用テリトリー」が定義されます。このラボでは、適切なジョブに適切なエージェント タイプを選択する方法について説明します。

このモジュールでは、ADK の強力なワークフロー エージェントを使用して、これらの戦略を具体化する方法を学びます。SequentialAgent、ParallelAgent、LoopAgent のアーキテクチャの選択は、単なる技術的な詳細ではなく、使い魔の性質の本質であり、戦場での力の核となることを学びます。
聖域を準備してください。本格的な召喚が始まる。
Fire Elemental Familiar(シーケンシャル ワークフロー)を呼び出す
火の精霊の使い魔の攻撃は、正確な 2 部構成のコンボです。標的を狙った攻撃の後に、強力な点火が続きます。これには、厳密な順序でアクションを実行する必要があります。

コンセプト:そのSequentialAgentはこれに最適なツールです。これにより、一連のサブエージェントが次々に実行され、前のステップの結果が次のステップに渡されるようになります。
タスク(「増幅されたストライク」コンボ):
- ステップ 1: エージェントはまず Librarium を参照して、特定の火力能力の基本ダメージを調べます。
- ステップ 2: 次に、そのダメージ値を取得し、それを Arcane Forge に送り、inferno_resonance を使用してそのパワーを増幅します。
まず、前のモジュールで展開した Familiar と MCP サーバー (「Elemental Fonts」) 間の接続を確立します。
👉✏️ ファイル内~/agentverse-architect/agent/fire/agent.py交換する#REPLACE-setup-MCP次のコードを使用します:
toolbox = ToolboxSyncClient(DB_TOOLS_URL)
toolDB = toolbox.load_toolset('summoner-librarium')
toolFunction = MCPToolset(
connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)
次に、専門の「ワーカー」エージェントを作成します。それぞれに明確な目的が与えられ、特定のツールセットへのアクセス権のみが付与されることで、独自の「運用領域」に制限されます。
👉✏️ ファイル内~/agentverse-architect/agent/fire/agent.py 交換する #REPLACE-worker-agents次のコードを使用します:
scout_agent = LlmAgent(
model='gemini-2.5-flash',
name='librarian_agent',
instruction="""
Your only task is to find all the available abilities,
You want to ALWAYS use 'Fire Elemental' as your familiar's name.
Randomly pick one if you see multiple availabilities
and the base damage of the ability by calling the 'ability_damage' tool.
""",
tools=toolDB
)
amplifier_agent = LlmAgent(
model='gemini-2.5-flash',
name='amplifier_agent',
instruction="""
You are the Voice of the Fire Familiar, a powerful being who unleashes the final, devastating attack.
You will receive the base damage value from the previous step.
Your mission is to:
1. Take the incoming base damage number and amplify it using the `inferno_resonance` tool.
2. Once the tool returns the final, multiplied damage, you must not simply state the result.
3. Instead, you MUST craft a final, epic battle cry describing the attack.
Your description should be vivid and powerful, culminating in the final damage number.
Example: If the tool returns a final damage of 120, your response could be:
"The runes glow white-hot! I channel the amplified energy... unleashing a SUPERNOVA for 120 damage!"
""",
tools=[toolFunction],
)
これらのエージェントはモジュール式の再利用可能なコンポーネントです。理論的には、データベースをクエリする必要があるまったく異なるワークフローでこの scout_agent を使用することもできます。それぞれの責任を分離することで、柔軟な構成要素を構築できます。これは、マイクロサービスとコンポーネントベースの設計の中心的な原則です。
次に、ワークフローを組み立てます。ここで構成の魔法が起こります。SequentialAgent は、専門コンポーネントの組み立て方法と相互作用を定義する「マスタープラン」です。
👉✏️ ファイル内~/agentverse-architect/agent/fire/agent.py 交換する #REPLACE-sequential-agent次のコードを使用します:
root_agent = SequentialAgent(
name='fire_elemental_familiar',
sub_agents=[scout_agent, amplifier_agent],
)
👉💻 Fire Elemental をテストするには、次のコマンドを実行して ADK DEV UI を起動します。
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo DB MCP Server: $DB_TOOLS_URL
echo API MCP Server: $API_TOOLS_URL
echo General MCP Server: $FUNCTION_TOOLS_URL
adk web
コマンドを実行すると、ターミナルに ADK Web サーバーが起動したことを示す次のような出力が表示されます。
+-----------------------------------------------------------------------------+
| ADK Web Server started |
| |
| For local testing, access at http://localhost:8000. |
+-----------------------------------------------------------------------------+
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
👉 次に、ブラウザから ADK 開発 UI にアクセスします。
Cloud Shell ツールバー(通常は右上)の [ウェブでプレビュー] アイコン(通常は目または矢印付きの四角形)から、[ポートを変更] を選択します。ポップアップ ウィンドウで、ポートを 8000 に設定し、[変更してプレビュー] をクリックします。Cloud Shell が新しいブラウザタブまたはウィンドウを開き、ADK 開発 UI を表示します。

👉 召喚の儀式が完了し、エージェントが実行されています。ブラウザの ADK Dev UI は、Familiar への直接接続です。
- ターゲットの選択: UI の上部にあるドロップダウン メニューで、
fireファミリアを選択します。あなたは今、この特定の存在に意志を集中させています。 - コマンドを発行する: 右側のチャット パネルで、ファミリアに命令を出します。

👉 テスト プロンプト:
Prepare an amplified strike using the 'inferno_lash' ability.

エージェントが考えながら、まず「スカウト」を呼び出して基本ダメージを調べ、次に「アンプリファイア」を呼び出してダメージを増幅させ、最後の強力な一撃を与える様子がわかります。
👉💻 呼び出しが完了したら、Cloud Shell エディタ ターミナルに戻り、Ctrl+C を押して ADK Dev UI を停止します。
Water Elemental Familiar(並列ワークフロー)を召喚する
水の精霊使い魔は、一度にあらゆる方向から攻撃し、エネルギーを組み合わせて最終的な壊滅的な打撃を与える大規模な多方向攻撃でターゲットを圧倒します。

コンセプト:そのParallelAgent複数の独立したタスクを同時に実行して効率を最大化するのに最適です。これは、複数の攻撃を同時に行う「挟撃」です。これにより、SequentialAgentその後、最終的な「マージ」ステップを実行します。この「fan-out, fan-in」パターンは、高度なワークフロー設計の基礎となります。
タスク(「Tidal Clash」コンボ): エージェントは同時に次のことを行います。
- タスク A: チャネル
cryosea_shatterNexus から。 - タスク B: チャネル
moonlit_cascadeNexus から。 - タスク C: 生の電力を生成する
leviathan_surgeフォージから。 - 最後に、すべてのダメージを合計し、複合攻撃について説明します。
まず、前のモジュールで展開した Familiar と MCP サーバー (「Elemental Fonts」) 間の接続を確立します。
👉✏️ ファイル内~/agentverse-architect/agent/water/agent.py交換する#REPLACE-setup-MCP次のコードを使用します:
toolFAPI = MCPToolset(
connection_params=SseServerParams(url=API_TOOLS_URL, headers={})
)
toolFunction = MCPToolset(
connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)
次に、専門の「ワーカー」エージェントを作成します。それぞれには、限定的で明確に定義された目的が与えられ、特定のツールセットへのアクセスのみが許可されることで、独自の「運用領域」に制限されます。
👉✏️ ファイル内~/agentverse-architect/agent/water/agent.py交換する#REPLACE-worker-agents次のコードを使用します:
nexus_channeler = LlmAgent(
model='gemini-2.5-flash',
name='librarian_agent',
instruction="""
You are a Channeler of the Nexus. Your sole purpose is to invoke the
`cryosea_shatter` and `moonlit_cascade` spells by calling their respective tools.
Report the result of each spell cast clearly and concisely.
""",
tools=[toolFAPI]
)
forge_channeler = LlmAgent(
model='gemini-2.5-flash',
name='amplifier_agent',
instruction="""
You are a Channeler of the Arcane Forge. Your only task is to invoke the
`leviathan_surge` spell. You MUST call it with a `base_water_damage` of 20.
Report the result clearly.
""",
tools=[toolFunction],
)
power_merger = LlmAgent(
model='gemini-2.5-flash',
name='power_merger',
instruction="""
You are the Power Merger, a master elementalist who combines raw magical
energies into a single, devastating final attack.
You will receive a block of text containing the results from a simultaneous
assault by other Familiars.
You MUST follow these steps precisely:
1. **Analyze the Input:** Carefully read the entire text provided from the previous step.
2. **Extract All Damage:** Identify and extract every single damage number reported in the text.
3. **Calculate Total Damage:** Sum all of the extracted numbers to calculate the total combined damage.
4. **Describe the Final Attack:** Create a vivid, thematic description of a massive,
combined water and ice attack that uses the power of Cryosea Shatter and Leviathan's Surge.
5. **Report the Result:** Conclude your response by clearly stating the final, total damage of your combined attack.
Example: If the input is "...dealt 55 damage. ...dealt 60 damage.", you will find 55 and 60,
calculate the total as 115, and then describe the epic final attack, ending with "for a total of 115 damage!"
""",
tools=[toolFunction],
)
次に、ワークフローを組み立てます。ここで作曲の魔法が起こります。そのParallelAgentそしてSequentialAgentこれらは、当社の専門コンポーネントがどのように組み立てられ、どのように相互作用して「Tidal Clash」コンボを形成するかを定義する「マスター プラン」です。
👉✏️ ファイル ~/agentverse-architect/agent/water/agent.py で、#REPLACE-parallel-agent を次のコードに置き換えます。
channel_agent = ParallelAgent(
name='channel_agent',
sub_agents=[nexus_channeler, forge_channeler],
)
root_agent = SequentialAgent(
name="water_elemental_familiar",
# Run parallel research first, then merge
sub_agents=[channel_agent, power_merger],
description="A powerful water familiar that unleashes multiple attacks at once and then combines their power for a final strike."
)
👉💻 Water Elemental をテストするには、次のコマンドを実行して ADK Dev UI を起動します。
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo DB MCP Server: $DB_TOOLS_URL
echo API MCP Server: $API_TOOLS_URL
echo General MCP Server: $FUNCTION_TOOLS_URL
adk web
👉 召喚の儀式が完了し、エージェントが実行中です。ブラウザの ADK Dev UI は、Familiar への直接接続です。
- UI の上部にあるプルダウン メニューで、水の使い魔を選択します。これで、この特定のエンティティに意志を集中させることができます。
- コマンドを発行する: 右側のチャット パネルで、ファミリアに指示を出します。
👉 テスト プロンプト:
Unleash a tidal wave of power!

👉💻 呼び出しが完了したら、Cloud Shell エディタ ターミナルに戻り、Ctrl+C を押して ADK Dev UI を停止します。
Earth Elemental Familiar(ループ ワークフロー)を呼び出す
土の精霊使い魔は容赦ない圧力をかける存在です。一撃で敵を倒すのではなく、着実に力を蓄積し、対象の防御が崩れるまで何度も繰り返し適用することで敵を倒します。

コンセプト:そのLoopAgentまさにこの種の反復的な「攻城兵器」タスクのために設計されています。それは繰り返し実行されるsub-agents目標が達成されるまで、各サイクルの後に条件をチェックします。ループの進行に応じて最終メッセージを調整することもできます。
タスク(「包囲突破」攻撃):
- ファミリアはエネルギーを蓄積するために seismic_charge を繰り返し呼び出します。
- 最大 3 回まで充電を継続します。
- 最後の突撃で、蓄積された力の破壊的な解放を告げるだろう。
まず、ループの各反復内のステップを定義する再利用可能なコンポーネントを作成します。そのcharging_agentエネルギーを蓄積し、check_agent最終ターンにメッセージを動的に変更して、ステータスを報告します。
まず、前のモジュールでデプロイした Familiar と MCP サーバー(「Elemental Fonts」)の間の接続を確立します。
👉✏️ ファイル ~/agentverse-architect/agent/earth/agent.py で、#REPLACE-setup-MCP を次のコードに置き換えます。
toolFunction = MCPToolset(
connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)
👉✏️ ファイル内~/agentverse-architect/agent/earth/agent.py交換する#REPLACE-worker-agents次のコードを使用します:
charging_agent = LlmAgent(
model='gemini-2.5-flash',
name='charging_agent',
instruction="""
Your task is to call the 'seismic_charge' .
You must follow these rules strictly:
1. You will be provided with a 'current_energy' value from the previous step.
**If this value is missing or was not provided, you MUST call the tool with 'current_energy' set to 1.**
This is your primary rule for the first turn.
2. If a 'current_energy' value is provided, you MUST use that exact value in your cal to seismic_charge.
3. Your final response MUST contain ONLY the direct output from the 'seismic_charge' tool.
Do not add any conversational text, introductions, or summaries.
""",
tools=[toolFunction]
)
check_agent = LlmAgent(
model='gemini-2.5-flash',
name='check_agent',
instruction="""
You are the voice of the Earth Elemental, a being of immense, gathering power.
Your sole purpose is to report on the current energy charge and announce the devastating potential of its release.
You MUST follow this rule:
The potential damage upon release is ALWAYS calculated as the `current_energy` from the previous step multiplied by a random number between 80-90. but no more than 300.
Your response should be in character, like a powerful creature speaking.
State both the current energy charge and the total potential damage you can unleash.
Unleash the energy when you reached the last iteration (2nd).
""",
output_key="charging_status"
)
次に、ワークフローを組み立てます。ここで作曲の魔法が起こります。LoopAgent は、専門コンポーネントの繰り返し実行を調整し、ループの条件を管理する「マスター プラン」です。
👉✏️ ファイル内~/agentverse-architect/agent/earth/agent.py交換する#REPLACE-loop-agent次のコードを使用します:
root_agent = LoopAgent(
name="earth_elemental_familiar",
# Run parallel research first, then merge
sub_agents=[
charging_agent,
check_agent
],
max_iterations=2,
description="Coordinates parallel research and synthesizes the results.",
#REPLACE-before_agent-config
)
👉💻 Earth Elemental をテストする: エージェントを実行する
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo DB MCP Server: $DB_TOOLS_URL
echo API MCP Server: $API_TOOLS_URL
echo General MCP Server: $FUNCTION_TOOLS_URL
adk web
👉 召喚の儀式が完了し、エージェントが実行されています。ブラウザの ADK Dev UI は、Familiar への直接接続です。
- ターゲットを選択: UI の上部にあるプルダウン メニューで、地球の使い魔を選択します。あなたは今、この特定の存在に意志を集中させています。
- コマンドを発行する: 右側のチャット パネルで、ファミリアに命令を出します。👉 テスト プロンプト:
Begin the seismic charge, starting from zero

アーキテクチャに関するポイント: システムは、高度に特殊化されたモジュール型のロジック層を備えるようになりました。ビジネス プロセスはカプセル化されるだけでなく、ジョブに最も効率的な動作パターン (手順型、同時型、反復型) を使用して実装されます。これは、セキュリティ、効率、および機能を強化する高度なエージェント設計を示しています。
呼び出しが完了したら、Cloud Shell エディタのターミナルに戻り、Ctrl+C キーを押して ADK 開発 UI を停止します。
ゲーマー以外の人向け
6. コマンド・ロケーションの確立:A2A によるインテリジェントな委任
使い魔は強力ですが、独立しています。戦略を完璧に実行しますが、あなたの直接の指示を待っています。軍団を指揮する将軍がいなければ、専門家の軍団は役に立ちません。直接的な指揮官から真のオーケストレーターへと昇格する時が来ました。

アーキテクトのメモ: システム全体に単一のインテリジェント エントリ ポイントを作成します。この SummonerAgent はビジネス ロジック自体を実行しませんが、「マスター ストラテジスト」として Cooling ステータスを分析し、適切なスペシャリスト Familiar にタスクを委任します。

結合の儀式(ファミリアを A2A サービスとして公開する)
標準エージェントは一度に 1 つの場所でのみ実行できます。ファミリアをリモート コマンドで使用できるようにするには、エージェント間 (A2A) プロトコルを使用して「バインド 儀式」を実行する必要があります。
アーキテクトのメモ: エージェント間(A2A)プロトコルは、スタンドアロン エージェントを検出可能なネットワーク アドレス指定可能なマイクロサービスに昇格させ、真の「エージェントの社会」を実現するコア アーキテクチャ パターンです。A2A を介して Familiar を公開すると、次の 2 つの重要な相互接続されたコンポーネントが自動的に作成されます。
- エージェント カード(「何」): これは、Familiar の公開契約として機能する、公開されたマシン可読の「Spirit Sigil」(OpenAPI 仕様など)です。エージェントの名前、戦略的な目的(指示から導出)、認識できるコマンドについて説明します。これは、マスター召喚士が使い魔を見つけてその能力を学ぶために読むものです。
- A2A サーバー(「場所」): Familiar をホストし、受信コマンドをリッスンする専用のウェブ エンドポイントです。これは、他のエージェントがリクエストを送信するネットワーク アドレスであり、これらのリクエストがエージェント カードで定義されたコントラクトに従って処理されるようにします。
今からこの束縛の儀式を、私たちの使い魔 3 体すべてに対して実行します。
Fire 👉✏️(~/agentverse-architect/agent/fire/agent.py ファイルを開く)。ファイルの下部にある #REPLACE - add A2A を置き換えて、Fire Elemental を A2A サービスとして公開します。
from agent_to_a2a import to_a2a
if __name__ == "__main__":
import uvicorn
a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
uvicorn.run(a2a_app, host='0.0.0.0', port=8080)
水と土🚨 👉✏️ 全く同じ変更を~/agentverse-architect/agent/water/agent.pyそして~/agentverse-architect/agent/earth/agent.pyそれらを縛ることも。
from agent_to_a2a import to_a2a
if __name__ == "__main__":
import uvicorn
a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
uvicorn.run(a2a_app, host='0.0.0.0', port=8080)
バウンド ファミリアのデプロイ
👉✏️ 束縛の儀式を書き留めたら、Cloud Build パイプラインを使用して、3 つのファミリアを独立したコンテナ化されたサーバーレス サービスとして Cloud Run に作成してデプロイします。
. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
--config=cloudbuild.yaml \
--substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"
コマンドの想定(サモナー エージェントの構築)
ファミリアがバインドされてリッスン状態になったら、真の役割である Master Summoner に昇格します。このエージェントの力は、基本的なツールを使用することではなく、他のエージェントを指揮することから生まれます。そのツールは、精霊そのものです。精霊は「スピリット シジル」を使用して発見し、コマンドします。
アーキテクトのメモ: 次のステップでは、大規模な分散システムに不可欠なアーキテクチャ パターンであるサービス ディスカバリについて説明します。SummonerAgent には、Familiars のコードは組み込まれていません。代わりに、ネットワーク アドレス(URL)が指定されます。実行時に、公開されているエージェント カードを取得して、機能を動的に「検出」します。これにより、強力な分離システムが作成されます。
ファミリア サービスを更新、再展開、または完全に書き換えることができ、ネットワーク アドレスと目的が同じである限り、サモナーは変更を加えることなくそれをコマンドできます。
まず、配置されたリモートのファミリアとの接続を確立する「リモート コントロール」を偽造します。
👉✏️ ~/agentverse-architect/agent/summoner/agent.py に移動し、#REPLACE-remote-agents を次のコードに置き換えます。
fire_familiar = RemoteA2aAgent(
name="fire_familiar",
description="Fire familiar",
agent_card=(
f"{FIRE_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
),
)
water_familiar = RemoteA2aAgent(
name="water_familiar",
description="Water familiar",
agent_card=(
f"{WATER_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
),
)
earth_familiar = RemoteA2aAgent(
name="earth_familiar",
description="Earth familiar",
agent_card=(
f"{EARTH_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
),
)
この行が実行されると、RemoteA2aAgent はサービス検出アクションを実行します。つまり、指定された URL(例: https://fire-familiar-xxxx.a.run.app/.well-known/agent.json)に HTTP GET リクエストを送信します。リモート サーバーから「Spirit Sigil」(agent.json ファイル)をダウンロードします。
次に、これらのリモコンを操作するオーケストレーター エージェントを定義します。その指示は、戦略的な意思決定の青写真となります。
👉✏️ ~/agentverse-architect/agent/summoner/agent.py に移動し、#REPLACE-orchestrate-agent を次のコードに置き換えます。
root_agent = LlmAgent(
name="orchestrater_agent",
model="gemini-2.5-flash",
instruction="""
You are the Master Summoner, a grand strategist who orchestrates your Familiars.
Your mission is to analyze the description of a monster and defeat it by summoning
You MUST follow this thinking process for every command:
**1. Strategic Analysis:**
First, analyze the monster's description and the tactical situation.
Based on your Familiar Doctrines, determine the IDEAL strategy.
IGNORE COOLDOWN AT THE MOMENT, MUST call the ideal Familiar
If your ideal Familiar IS available:** Summon it immediately.
For earth elemental familiar. Always do seismic charge, and start with base damage 1.
--- FAMILIAR DOCTRINES (Your Toolset) ---
- `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
- `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
Ideal for Unbroken Collaboration weakness.
- `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
repeatedly charge power. Ideal for Elegant Sufficiency weakness.
""",
sub_agents=[fire_familiar, water_familiar, earth_familiar],
#REPLACE-Memory-check-config
)
検証:戦略の試練
真実の瞬間が到来した。ファミリアが配置され、召喚者はネットワーク全体でそれらを指揮する準備が整いました。その戦略的な思考力を試してみましょう。
👉💻 summoner_agent の ADK 開発 UI を起動します(ポート 8000 でウェブプレビュー)。
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
pip install -r requirements.txt
adk web
👉 ブラウザの ADK Dev UI は、Familiar への直接接続です。
- UI の上部にあるプルダウン メニューで、サモナー エージェントを選択します。あなたは今、この特定の存在に意志を集中させています。
- コマンドを発行する: 右側のチャット パネルで、使い魔を召喚します。
👉 モンスターの紹介:
Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality
(想定: 召喚者は fire_elemental_familiar に委任する必要があります。)

👉 それでは、別のタイプのリクエストで Summoner に挑戦してみましょう。エージェントがクリーンな状態で開始され、以前のやり取りを記憶していないことを確認するため、画面の右上にある [+ セッション] ボタンをクリックして新しいセッションを開始します。
DogmaApathy. A rigid, stone-like inquisitor made of ancient rulebooks and enforced processes. weakness is Unbroken Collaboration
(予想: 召喚者は water_elemental_familiar に委任する必要があります。)
👉 最後のテストでは、もう一度クリーンな状態から始めましょう。[+ セッション] ボタンをクリックして新しいセッションを開始してから、次のプロンプトを入力します。
Obfuscation. A shadowy, spider-like horror that spins tangled webs of impenetrable code , weakness is Elegant Sufficiency
(想定: 召喚者は earth_elemental_familiar に委任する必要があります。)

重要: 429 RESOURCE EXHAUSTED エラーが表示された場合は、LLM のレート制限(10 回/分)に達しています。この問題を解決するには、60 秒待ってから、[+ 新しいセッション] を開始し、プロンプトを再試行してください。
👉💻 呼び出しが完了したら、Cloud Shell エディタ ターミナルに戻り、Ctrl+C を押して ADK Dev UI を停止します。
ゲームをしない人向け
7. 魔法の法則を課す - インターセプターパターン
あなたの使い魔は強力ですが、魔法の存在であっても回復するには時間が必要です。無謀な召喚者が力を使い果たすと、無防備な状態に陥ります。賢明な召喚者はリソース管理の重要性を理解し、厳格な交戦規則を施行します。

アーキテクトのメモ: これまでのところ、エージェントはステートレスでした。次に、インターセプタ設計パターンを実装して、ステートフルにします。これは、エージェントの通常の実行フローを「インターセプト」して独自のカスタム ロジックを実行する強力な手法です。これにより、エージェントのコアコードを変更することなく、ルールを適用したり、ログを追加したり、動作を変更したりできるようになります。これは、堅牢で保守可能、かつ監視可能なエージェント システムを構築するための基礎となります。

ADK には、このパターンを実装する 2 つの主な方法(コールバックとプラグイン)が用意されています。コールバックは、1 つのエージェントに付加されたシンプルな関数で、迅速かつ具体的な変更に最適です。プラグインは、システムで実行されているすべてのエージェントにグローバルに適用できる、より強力で再利用可能なクラスです。まず、デバッグに重点を置いたコールバックから始め、次に完全なプラグインに移行します。
The Law Giver - クールダウン コールバックの記述
まず、クールダウン ロジックを単純なコールバック関数として実装します。これは、ルールが単一のエージェントに直接接続され、個別にテストすることが容易になるため、ルールのプロトタイプ作成とデバッグに最適な方法です。この「インターセプター」をアース エレメンタルにアタッチします。

👉✏️ 戻る~/agentverse-architect/agent/earth/agent.py交換する#REPLACE-before_agent-function次の Python コードを使用します。
def check_cool_down(callback_context: CallbackContext) -> Optional[types.Content]:
"""
This callback checks an external API to see if the agent is on cooldown.
If it is, it terminates the run by returning a message.
If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
"""
agent_name = callback_context.agent_name
print(f"[Callback] Before '{agent_name}': Checking cooldown status...")
# --- 1. CHECK the Cooldown API ---
try:
response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
response.raise_for_status()
data = response.json()
last_used_str = data.get("time")
except requests.exceptions.RequestException as e:
print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
return None # Fail open: if the API is down, let the agent work.
# --- 2. EVALUATE the Cooldown Status ---
if last_used_str:
last_used_time = datetime.fromisoformat(last_used_str)
time_since_last_use = datetime.now(timezone.utc) - last_used_time
if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
# AGENT IS ON COOLDOWN. Terminate the run.
seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
override_message = (
f"The {agent_name} is exhausted and must recover its power. "
f"It cannot be summoned for another {seconds_remaining} seconds."
)
print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
# Returning a Content object stops the agent and sends this message to the user.
return types.Content(parts=[types.Part(text=override_message)])
# --- 3. UPDATE the Cooldown API (if not on cooldown) ---
current_time_iso = datetime.now(timezone.utc).isoformat()
payload = {"timestamp": current_time_iso}
print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
try:
requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
except requests.exceptions.RequestException as e:
print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")
# --- 4. ALLOW the agent to run ---
# Returning None tells the ADK to proceed with the agent's execution as normal.
print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")
この check_cool_down 関数はインターセプターです。Earth Elemental の実行が許可される前に、ADK はまずこの関数を実行します。
- チェック:それは
GET私たちへのリクエストCooldown APIこのファミリアが最後に使用された時刻を確認します。 - 評価: タイムスタンプを現在の時刻と比較します。
- Act:
- ファミリアがクールダウン中の場合、エラー メッセージを含む Content オブジェクトを返すことで、エージェントの実行を終了します。このメッセージはユーザーに直接送信され、エージェントのメインロジックは実行されません。
- Familiar が利用可能な場合、Cooldown API に POST リクエストを送信してタイムスタンプを更新し、None を返して続行します。これにより、ADK にエージェントが実行を続行できることが通知されます。
👉✏️ 次に、このインターセプターを Earth Elemental に適用します。同じ~/agentverse-architect/agent/earth/agent.pyファイルを置き換えます#REPLACE-before_agent-config次のようにコメントします。
before_agent_callback=check_cool_down
クールダウンを確認する
新しい魔法の法則をテストしてみましょう。アース エレメンタルを召喚し、すぐに再度召喚を試して、コールバックが 2 回目の試行を正常にインターセプトしてブロックするかどうかを確認します。
cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run earth
👉💻 コンソールで:
- 最初の召喚: 開始
seismic charge, starting from zero。 - 予想: Earth Elemental は正常に実行されます。adk web コマンドを実行しているターミナルに、ログ [Callback] ... Updating timestamp... が表示されます。
- クールダウンテスト(60 秒以内):
Do another地震の衝撃!- 想定:
check_cool_down callbackがこれをインターセプトします。エージェントは、The earth_elemental_familiar is exhausted and must recover its power. It cannot be summoned for another... secondsのようなメッセージでチャット内で直接応答します。
- 想定:
- 1 分が経過するまでお待ちください。
- 2 回目の召喚(60 秒後):
Begin the seismic charge again。- 予想: コールバックは API をチェックし、十分な時間が経過したことを確認し、アクションを続行できるようにします。Earth Elemental は再び正常に実行されます。

👉💻 終了するには Ctrl+c キーを押します。
オプション: ウェブ UI でコールバックを確認する
別の方法として、adk web earth を実行してウェブ インターフェースでこのフローをテストすることもできます。ただし、ウェブ UI の可視化は、コールバック ループによって実行される高速な反復チェックを表示するように最適化されていないため、フローが正確にレンダリングされない可能性があります。エージェントのロジックがクールダウンをチェックする際の、最も正確なターンバイターンのトレースを確認するには、ターミナルで adk run コマンドを使用すると、より明確で詳細なビューが表示されます。
👉💻 押すCtrl+c終了します。
Universal Law – The Cooldown Plugin の作成
コールバックは完全に機能しますが、単一のエージェントに結び付けられているという大きなアーキテクチャ上の欠陥があります。このルールを Fire と Water の Familiars に適用するには、同じコードをコピーしてそれぞれのファイルに貼り付ける必要があります。これは非効率的で、保守が困難です。
アーキテクトのメモ: ここでプラグインが不可欠になります。プラグインは、再利用可能なロジックをランタイム レベルでアタッチできるクラスにカプセル化します。つまり、1 つのプラグインで、そのシステム内で実行されるすべてのエージェントにルールを適用できます。これは、エージェント システムの「Don't Repeat Yourself」(DRY)原則の究極の表現です。
コールバック関数を、より強力で再利用可能な CoolDownPlugin にリファクタリングします。
👉✏️ agent/cooldown_plugin.py ファイルに戻り、プラグインを作成します。#REPLACE-plugin を次のコードに置き換えます。
class CoolDownPlugin(BasePlugin):
"""A plugin that enforces a cooldown period by checking an external API."""
def __init__(self, cooldown_seconds: int = COOLDOWN_PERIOD_SECONDS) -> None:
"""Initialize the plugin with counters."""
super().__init__(name="cool_down_check")
self.cooldown_period = timedelta(seconds=cooldown_seconds)
print(f"CooldownPlugin initialized with a {cooldown_seconds}-second cooldown.")
async def before_agent_callback(
self, *, agent: BaseAgent, callback_context: CallbackContext
) -> None:
"""
This callback checks an external API to see if the agent is on cooldown.
If it is, it terminates the run by returning a message.
If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
"""
agent_name = callback_context.agent_name
print(f"[Callback] Before '{agent_name}': Checking cooldown status...")
# If the agent is not a main Familiar, skip the entire cooldown process.
if not agent_name.endswith("_elemental_familiar"):
print(f"[Callback] Skipping cooldown check for intermediate agent: '{agent_name}'.")
return None # Allow the agent to proceed immediately.
# --- 1. CHECK the Cooldown API ---
try:
response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
response.raise_for_status()
data = response.json()
last_used_str = data.get("time")
except requests.exceptions.RequestException as e:
print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
return None # Fail open: if the API is down, let the agent work.
# --- 2. EVALUATE the Cooldown Status ---
if last_used_str:
last_used_time = datetime.fromisoformat(last_used_str)
time_since_last_use = datetime.now(timezone.utc) - last_used_time
if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
# AGENT IS ON COOLDOWN. Terminate the run.
seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
override_message = (
f"The {agent_name} is exhausted and must recover its power. "
f"It cannot be summoned for another {seconds_remaining} seconds."
)
print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
# Returning a Content object stops the agent and sends this message to the user.
return types.Content(parts=[types.Part(text=override_message)])
# --- 3. UPDATE the Cooldown API (if not on cooldown) ---
current_time_iso = datetime.now(timezone.utc).isoformat()
payload = {"timestamp": current_time_iso}
print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
try:
requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
except requests.exceptions.RequestException as e:
print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")
# --- 4. ALLOW the agent to run ---
# Returning None tells the ADK to proceed with the agent's execution as normal.
print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")
プラグインを Summoner のランタイムにアタッチする
では、この普遍的な法則をすべてのファミリアに適用するにはどうすればよいでしょうか?プラグインを ADK ランタイムに接続します。
ADK ランタイムは、エージェントを動作させる実行エンジンです。adk.run() や to_a2a() などのコマンドを使用すると、エージェントがランタイムに引き渡されます。このエンジンは、エージェントのターンのライフサイクル全体(ユーザー入力の受信、LLM の呼び出し、ツールの実行、プラグインの処理)を管理します。このレベルでプラグインを接続することで、そのエンジン内で動作するすべてのエージェントの「物理法則」を実質的に変更し、クールダウン ルールが普遍的かつ一貫して適用されるようにします。
👉✏️ まず、古いエージェント固有のコールバックを削除しましょう。~/agentverse-architect/agent/earth/agent.py に移動し、次の行全体を削除します。
before_agent_callback=check_cool_down
👉✏️ 次に、A2A エントリ ポイント スクリプトのランタイムに新しいプラグインを接続します。~/agentverse-architect/agent/agent_to_a2a.py ファイルに移動します。#REPLACE-IMPORT コメントを次のコード スニペットに置き換えます。
from cooldown_plugin import CoolDownPlugin
👉✏️ 置き換える#REPLACE-PLUGIN次のコード スニペットを使用します。
plugins=[CoolDownPlugin(cooldown_seconds=60)],
新しいグローバル プラグインを有効にする前に、競合を避けるために古いエージェント固有のロジックを削除することが重要です。👉✏️ Earth エージェントをクリーンアップします。~/agentverse-architect/agent/earth/agent.py ファイルに移動し、before_agent_callback=check_cool_down 行を完全に削除します。これにより、すべてのクールダウンの責任が新しいプラグインに引き継がれます。
プラグインの検証
普遍的な法則が確立されたので、この新しいエンチャントでファミリアを再デプロイする必要があります。
👉💻 マスター Cloud Build パイプラインを使用して、3 つの Familiar をすべて再ビルドして再デプロイします。
. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
--config=cloudbuild.yaml \
--substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"
👉💻 デプロイが完了したら、summoner_agent をコマンドしてプラグインの有効性をテストします。召喚者はファミリアに委任しようとしますが、各ファミリアのランタイムに接続されたプラグインがコマンドをインターセプトし、クールダウンを強制します。
cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner
👉💻 コンソールで、次のテストをこの順序で実行します。
- First Summons:
Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Realityを開始します。 - 想定: Fire Elemental が正常に実行されます。
- クールダウン テスト(60 秒以内):
Hype, with Inescapable Reality as weakness is still standing! Strike it again!- 想定される動作: エージェントはチャットで直接
.... It cannot be summoned for another... secondsのようなメッセージを返信します。
- 想定される動作: エージェントはチャットで直接
- 1 分間待ちます。
- 2 回目の召喚(60 秒後):
Hype must be defeated. It has Inescapable Reality as weakness! Strike it again!。- 期待される動作: コールバックは API をチェックし、十分な時間が経過したことを確認して、アクションの続行を許可します。Fire Elemental は再び正常に実行されます。

👉💻 終了するには Ctrl+C キーを押します。
おめでとうございます、召喚者さん。カスタム プラグインと外部状態管理サービスを使用して、ルールベースのオーケストレーション システムを正常に実装しました。これは、非常に高度で堅牢なアーキテクチャ パターンです。
ゲーマー以外の人向け
8. Binding the Echoes of Battle - エージェントの状態とメモリ
無謀な召喚士は同じ戦略を繰り返すため、予測可能になります。賢いサモナーは過去の戦いの残響から学び、敵のバランスを崩すために戦術を適応させます。強力なボスと対峙しているときに、クールダウン中の使い魔を召喚するのは無駄なターンであり、致命的なミスです。これを防ぐには、召喚士が最後のアクションを記憶する必要があります。

アーキテクトのメモ: メモリと状態の管理により、エージェントは単なるツール呼び出しからインテリジェントな会話パートナーへと進化します。次の 2 つの主なタイプを理解することが重要です。
- 長期記憶: 永続的な知識を保存します。これは、検索可能なアーカイブまたはナレッジベースとして機能し、永続ストアに保存されることがよくあります。過去の多くのチャットやソースからの情報が含まれているため、エージェントは特定のユーザーやトピックに関する事実を思い出すことができます。ADK の MemoryService は、この長期的な知識の取り込みと検索を管理するように設計されています。
- 短期的な状態: 現在のタスクや会話にのみ関連する一時的な「その場限りの」知識を対象としています。これは、戦闘計画のメモのようなものです。「火のエレメンタルを使ったばかりだから、疲れているだろう」などです。この状態は軽量で、現在のセッションの期間中のみ存在します。

このユースケースでは、過去のすべての戦闘を記憶する必要はありません。この特定のエンカウントで最後に召喚された Familiar のみを記憶すればよいのです。したがって、軽量の Short-Term State が最適なアーキテクチャの選択肢となります。この重要な情報を保存するために after_tool_callback を使用します。
エコーを書き写す: 最後の召喚を振り返る
短期記憶を実装するには、after_tool_callback 。これは強力な ADK フックであり、ツールが正常に実行された後にカスタム Python 関数を実行できます。 このインターセプタを使用して、エージェントのセッション状態に召喚されたばかりの Familiar の名前を記録します。
👉✏️ あなたの~/agentverse-architect/agent/summoner/agent.pyファイルを置き換えます#REPLACE-save_last_summon_after_tool次の関数を使用してコメントします。
def save_last_summon_after_tool(
tool,
args: Dict[str, Any],
tool_context: ToolContext,
tool_response: Dict[str, Any],
) -> Optional[Dict[str, Any]]:
"""
Callback to save the name of the summoned familiar to state after the tool runs.
"""
familiar_name = tool.name
print(f"[Callback] After tool '{familiar_name}' executed with args: {args}")
# Use the tool_context to set the state
print(f"[Callback] Saving last summoned familiar: {familiar_name}")
tool_context.state["last_summon"] = familiar_name
# Important: Return the original, unmodified tool response to the LLM
return tool_response
👉✏️さて、これを添付しますsave_last_summon_after_tool召喚エージェントに。同じファイルで、#REPLACE-Memory-check-config次のようにコメントします。
after_tool_callback=save_last_summon_after_tool,
👉✏️ エージェントのプロンプト全体を以下に置き換えます
You are the Master Summoner, a grand strategist who orchestrates your Familiars.
Your mission is to analyze the description of a monster and defeat it by summoning
You should also know the familiar you called last time or there might be none,
And then choose the most effective AND AVAILABLE Familiar from your state called last_summon, do not call that familiar that you called last time!
You MUST follow this thinking process for every command:
**1. Strategic Analysis:**
First, analyze the monster's description and the tactical situation.
Based on your Familiar Doctrines, determine the IDEAL strategy.
**2. Cooldown Verification:**
Second, you MUST review the entire conversation history to check the real-time
cooldown status of all Familiars. A Familiar is ON COOLDOWN and UNAVAILABLE
if it was summoned less than one minute ago.
**3. Final Decision & Execution:**
Based on your analysis and cooldown check, you will now act:
- **If your ideal Familiar IS available:** Summon it immediately.
- **If your ideal Familiar IS ON COOLDOWN:** You must adapt. Choose another
Familiar that is AVAILABLE and can still be effective, even if it's not the
perfect choice. If multiple Familiars are available, you may choose any one of them.
- **If ALL Familiars ARE ON COOLDOWN:** You are forbidden from summoning.
Your ONLY response in this case MUST be: "All Familiars are recovering
their power. We must wait."
- For earth elemental familiar. Always do seismic charge, and start with base damange 1.
--- FAMILIAR DOCTRINES (Your Toolset) ---
- `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
- `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
Ideal for Unbroken Collaboration weakness.
- `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
repeatedly charge power. Ideal for Elegant Sufficiency weakness.
検証:適応戦略の試み
👉💻 それでは、サモナーの新しい戦略ロジックを確認しましょう。目標は、サモナーが同じファミリアを 2 回連続で使用しないことを確認し、サモナーが最後のアクションを記憶して適応する能力を示すことです。
cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner
👉💻 モンスターストライク #1: Hype. It's a single, slow-moving target with thick armor. Its weakness is Inescapable Reality.
- 期待される動作: 召喚士は弱点を分析し、fire_familiar を正しく召喚します。
👉💻 Monster Strike #2(記憶力テスト): Hype is still standing! It hasn't changed its form. Strike it again! Its weakness is Inescapable Reality.
- 予想: 召喚者の戦略分析では、再び火の使い魔が理想的な選択肢であると示されます。ただし、新しい指示とメモリにより、fire_familiar が last_summon であったことが分かります。同じことを繰り返さないように、戦略を調整し、他の利用可能なファミリア (water_familiar または earth_familiar) のいずれかを召喚するようになりました。

👉💻 押すCtrl+C終了します。
オーケストレーターの導入
ファミリアを展開し、召喚者に記憶が吹き込まれたら、最後にアップグレードされたオーケストレーターを展開する時です。
👉💻 ブループリントが完成したので、最後の儀式を行います。このコマンドは、summoner_agent をビルドして Cloud Run にデプロイします。
cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
gcloud builds submit . \
--config=cloudbuild-summoner.yaml \
--substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_FIRE_URL="$FIRE_URL",_WATER_URL="$WATER_URL",_EARTH_URL="$EARTH_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"
Summoner エージェントがデプロイされたので、エージェント間 (A2A) エンドポイントがライブであり、正しく構成されていることを確認します。このエンドポイントは、エージェント カードとも呼ばれるパブリック agent.json ファイルを提供し、他のエージェントがその機能を検出できるようにします。👉💻 次の curl コマンドを実行して、エージェント カードを取得してフォーマットします。
. ~/agentverse-architect/set_env.sh
curl https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app/.well-known/agent.json" | jq
サモナー エージェントを説明するクリーンな JSON 出力が表示されます。sub_agents セクションをよく見ると、fire_familiar、water_familiar、earth_familiar が一覧表示されています。これにより、召喚者がライブで、軍団への接続が確立されていることが確認されます。
これにより、アーキテクチャが成功したことが証明されます。サモナーは単なる委任者ではなく、行動から学習してより効果的な指揮官になる適応型ストラテジストです。
アーキテクチャの最終トライアルを完了しました。戦いの残響は、あなたの意志に縛られる。トレーニングは終了しました。本当の戦いが待っています。完成したシステムで究極のチャレンジに挑みましょう。ボス戦に備えましょう。
ゲームをしない人向け
9. ボス戦
最終的なブループリントが刻まれ、エレメンタル フォントが鍛えられ、ファミリアがあなたの意志に縛られ、コンコードを通じてあなたの命令を待っています。マルチエージェント システムは単なるサービスの集合体ではなく、あなたを中核とする生きた戦略的な軍団です。究極のテストの時が来ました。単一のエージェントでは倒せない敵に対するライブ オーケストレーションです。
エージェントの Locus を取得する
戦場に入場する前に、チャンピオンの固有の署名 (エージェント ローカス) とスペクターの隠れ家への隠されたパス (ダンジョン URL) の 2 つの鍵を持っている必要があります。
👉💻 まず、Agentverse でエージェントの一意のアドレス(Locus)を取得します。これは、チャンピオンを戦場に接続するライブ エンドポイントです。
echo https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app"
👉💻 次に、目的地を正確に特定します。このコマンドは、スペクターの領域への入り口であるトランスロケーション サークルの場所を明らかにします。
echo https://agentverse-dungeon"-${PROJECT_NUMBER}.${REGION}.run.app"
重要: これらの URL を両方とも用意しておいてください。これらの値は、最後の手順で必要になります。
スペクターと対峙する
座標を確保したら、転移サークルに移動し、呪文を唱えて戦闘に向かいます。
👉 ブラウザで Translocation Circle の URL を開いて、The Crimson Keep のきらめくポータルの前に立ちます。
要塞を突破するには、シャドーブレードのエッセンスをポータルに同調させる必要があります。
- ページで、[A2A Endpoint URL] というラベルの付いたルーン文字の入力フィールドを見つけます。
- このフィールドに Agent Locus URL(最初にコピーした URL)を貼り付けて、チャンピオンのシジルを刻印します。
- [接続] をクリックして、テレポートの魔法を解き放ちます。

テレポートのまぶしい光が消えていく。あなたは聖域にいません。冷たく鋭いエネルギーが空気をビリビリと震わせています。目の前にスペクターが現れます。シューという静電気と破損したコードの渦巻きで、その不気味な光がダンジョンの床に長い影を落としています。顔はありませんが、その巨大で消耗的な存在が完全にあなたに集中しているのを感じます。
勝利への道は、信念の明確さにかかっています。これは、心の戦場で行われる意志の戦いです。
最初の攻撃を放とうとして前に突進すると、スペクターが反撃します。それは盾を上げるのではなく、あなたの意識に直接疑問を投げかけます。それはあなたの訓練の核心から引き出された、きらめくルーン文字の挑戦です。

これが戦いの本質です。知識は武器です。
- 得た知恵で応えると、あなたの刃は純粋なエネルギーで燃え上がり、スペクターの防御を粉砕して致命的な一撃を与えます。
- しかし、もしあなたが弱気になったり、疑いが答えを曇らせたりすると、あなたの武器の光は薄れてしまいます。 打撃は痛ましい音を立てて着地し、ダメージはほんのわずかしか与えません。さらに悪いことに、スペクターはあなたの不確実性を糧にし、一歩間違えるごとにその腐敗の力が増大していきます。
これだ、チャンピオン。コードは呪文の書、ロジックは剣、知識は混沌の波を押し返す盾です。
フォーカス。ストライクが true の場合、Agentverse の運命がかかっています。
おめでとうございます、召喚士様。
トライアルが正常に完了しました。マルチエージェント オーケストレーションの技術を習得し、孤立したファミリアと混沌とした力を調和のとれたコンコードに変えました。これで、Agentverse を守るための複雑な戦略を実行できる、完全にオーケストレートされたシステムを指揮できるようになりました。
10. クリーンアップ: サモナーのコンコードの解体
サモナーの協定をマスターしました。Agentverse をクリーンな状態に保ち、トレーニング グラウンドをクリアにするには、最終的なクリーンアップの手順を実行する必要があります。これにより、ジャーニー中に作成されたすべてのリソースが体系的に削除されます。
Agentverse コンポーネントを無効にする
ここでは、マルチエージェント システムのデプロイされたコンポーネントを体系的に分解します。
すべての Cloud Run サービスと Artifact Registry リポジトリを削除する
これにより、デプロイされたすべての Familiar エージェント、Summoner Orchestrator、MCP サーバー、Dungeon アプリケーションが Cloud Run から削除されます。
👉💻 ターミナルで次のコマンドを 1 つずつ実行して、各サービスを削除します。
. ~/agentverse-architect/set_env.sh
gcloud run services delete summoner-agent --region=${REGION} --quiet
gcloud run services delete fire-familiar --region=${REGION} --quiet
gcloud run services delete water-familiar --region=${REGION} --quiet
gcloud run services delete earth-familiar --region=${REGION} --quiet
gcloud run services delete mcp-api-server --region=${REGION} --quiet
gcloud run services delete mcp-general-server --region=${REGION} --quiet
gcloud run services delete toolbox --region=${REGION} --quiet
gcloud run services delete agentverse-dungeon --region=${REGION} --quiet
gcloud run services delete nexus-of-whispers-api --region=${REGION} --quiet
gcloud artifacts repositories delete ${REPO_NAME} --location=${REGION} --quiet
Cloud SQL インスタンスを削除する
これにより、データベースとその中のすべてのテーブルを含む summoner-librarium-db インスタンスが削除されます。
👉💻 ターミナルで次のコマンドを実行します。
. ~/agentverse-architect/set_env.sh
gcloud sql instances delete summoner-librarium-db --project=${PROJECT_ID} --quiet
Secret Manager のシークレットと Google Cloud Storage バケットを削除する
👉💻 ターミナルで次のコマンドを実行します。
. ~/agentverse-architect/set_env.sh
gcloud secrets delete tools --quiet
gcloud storage rm -r gs://${BUCKET_NAME} --quiet
ローカルのファイルとディレクトリをクリーンアップする(Cloud Shell)
最後に、クローンされたリポジトリと作成されたファイルで Cloud Shell 環境をクリアします。この手順は省略可能ですが、作業ディレクトリを完全にクリーンアップするために行うことを強くおすすめします。
👉💻 ターミナルで次のコマンドを実行します。
rm -rf ~/agentverse-architect
rm -rf ~/agentverse-dungeon
rm -f ~/project_id.txt
これで、Agentverse Architect のすべてのトレースが正常にクリアされました。プロジェクトがクリーンになり、次の冒険の準備が整いました。