1. はじめに
概要
このラボでは、シンプルな chatbot を超えて、分散マルチエージェント システム を構築します。
単一の LLM で質問に回答できますが、現実世界の複雑さには、専門的な役割が必要になることがよくあります。バックエンド エンジニアに UI の設計を依頼したり、デザイナーにデータベース クエリの最適化を依頼したりすることはありません。同様に、1 つのタスクに焦点を当て、互いに連携して複雑な問題を解決する専門の AI エージェントを作成できます。
以下で構成されるコース作成システム を構築します。
- 調査エージェント:
google_searchを使用して最新情報を検索します。 - 判定エージェント: 調査の品質と完全性を評価します。
- コンテンツ作成エージェント: 調査結果を構造化されたコースに変換します。
- オーケストレーター エージェント: これらのスペシャリスト間のワークフローと通信を管理します。
前提条件
- Python の基礎知識。
- Google Cloud コンソールに関する知識。
演習内容
- ウェブを検索できるツールを使用するエージェント(
researcher)を定義します。 judgeに Pydantic を使用して構造化出力を実装します。- Agent-to-Agent(A2A) プロトコルを使用してリモート エージェントに接続します。
LoopAgentを構築して、調査エージェントと判定エージェントの間にフィードバック ループを作成します。- ADK を使用して、分散システムをローカルで実行します。
- マルチエージェント システムを Google Cloud Run にデプロイします。
アーキテクチャとオーケストレーションの原則
コードを記述する前に、これらのエージェントがどのように連携するかを理解しましょう。コース作成パイプライン を構築します。
システム設計

エージェントによるオーケストレーション
標準エージェント(調査エージェントなど)は作業を行います。オーケストレーター エージェント (LoopAgent や SequentialAgent など)は他のエージェントを管理します。独自のツールはありません。ツールは委任です。
LoopAgent: コードのwhileループのように動作します。条件が満たされる(または最大イテレーション回数に達する)まで、エージェントのシーケンスを繰り返し実行します。これはリサーチループに使用します。- 調査エージェント が情報を検索します。
- 判定エージェント が評価します。
- 判定エージェント が「不合格」と判断した場合、`EscalationChecker` はループを続行します。
- 判定エージェント が「合格」と判断した場合、`EscalationChecker` はループを終了します。
SequentialAgent: 標準のスクリプト実行のように動作します。エージェントを順番に実行します。これは高レベル パイプライン に使用します:- まず、リサーチループ を実行します(適切なデータで終了するまで)。
- 次に、コンテンツ ビルダー を実行します(コースを作成するため)。
これらを組み合わせることで、最終的な出力を生成する前に自己修正できる堅牢なシステムを作成します。
2. セットアップ
環境設定
- Cloud Shell を開く: Google Cloud コンソールの右上にある [Cloud Shell をアクティブにする] アイコンをクリックします。
スターター コードを取得する
- スターター リポジトリのクローンをホーム ディレクトリに作成します。
cd ~ git clone --depth 1 --filter=blob:none --sparse https://github.com/GoogleCloudPlatform/devrel-demos.git temp-repo && cd temp-repo && git sparse-checkout set agents/build-with-ai/production-ready-ai/prai-roadshow-lab-1-starter && cd .. && mv temp-repo/agents/build-with-ai/production-ready-ai/prai-roadshow-lab-1-starter . && rm -rf temp-repo cd prai-roadshow-lab-1-starter - API を有効にする: 次のコマンドを実行して、必要な Google Cloud サービスを有効にします。
gcloud services enable \ run.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ aiplatform.googleapis.com \ compute.googleapis.com - エディタでこのフォルダを開きます。
依存関係のインストール
依存関係の管理には uv を使用します。
- プロジェクトの依存関係をインストールします。
# Ensure you have uv installed: pip install uv uv sync - 環境変数を設定します。
- ヒント: プロジェクト ID は、Cloud Console ダッシュボードで確認できます。または、
gcloud config get-value projectを実行して確認することもできます。
.envファイルを作成します。これにより、セッションが切断された場合に簡単に再読み込みできます。cat <<EOF > .env export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project) export GOOGLE_CLOUD_LOCATION=global export GOOGLE_GENAI_USE_VERTEXAI=true EOF - ヒント: プロジェクト ID は、Cloud Console ダッシュボードで確認できます。または、
- 環境変数をソースします。
警告: 環境変数は、新しいターミナル セッション間で保持されません。新しいターミナルタブを開いた場合は、source .envsource .envを実行して復元します。
3. 🕵️ 調査エージェント

調査エージェント はスペシャリストです。唯一の仕事は情報を検索することです。これを行うには、ツール(Google 検索)にアクセスする必要があります。
調査エージェントを分離する理由
詳細: 1 つのエージェントですべてを行うのはなぜですか?
小規模で集中的なエージェントは、評価 とデバッグ が容易です。調査が不適切な場合は、調査エージェントのプロンプトを反復処理します。コースのフォーマットが不適切な場合は、コンテンツ作成エージェントを反復処理します。モノリシックな「すべてを行う」プロンプトでは、1 つのものを修正すると別のものが壊れることがよくあります。
- Cloud Shell で作業している場合は、次のコマンドを実行して Cloud Shell エディタを開きます。
ローカル環境で作業している場合は、任意の IDE を開きます。cloudshell workspace . agents/researcher/agent.pyを開きます。- TODO を含むスケルトンが表示されます。
- 次のコードを追加して、
researcherエージェントを定義します。# ... existing imports ... # Define the Researcher Agent researcher = Agent( name="researcher", model=MODEL, description="Gathers information on a topic using Google Search.", instruction=""" You are an expert researcher. Your goal is to find comprehensive and accurate information on the user's topic. Summarize your findings clearly. If you receive feedback that your research is insufficient, use the feedback to refine your next search. DO NOT output any function calls. Provide your research directly as text. """, ) root_agent = researcher
重要なコンセプト: ツールの使用
Gemini 3 を使用する場合、Google 検索ツールは自動的に利用可能になります。Gemini 2.5 などの別のモデルを使用している場合は、Agent() コンストラクタに追加のパラメータとして tools=[google_search] を渡す必要があります。ADK は、このツールを LLM に記述する複雑さを処理します。モデルが情報を必要と判断すると、構造化されたツール呼び出しが生成され、ADK は Python 関数 google_search を実行し、結果をモデルにフィードバックします。
4. ⚖️ 判定エージェント

調査エージェントは懸命に作業しますが、LLM は怠惰になる可能性があります。作業を確認する判定エージェント が必要です。判定エージェントは調査を受け入れ、構造化された合格/不合格の評価を返します。
構造化出力
詳細: ワークフローを自動化するには、予測可能 な出力が必要です。長文のテキスト レビューは、プログラムで解析するのが困難です。JSON スキーマ(Pydantic を使用)を適用することで、判定エージェントがブール値 pass または fail を返すようにします。これにより、コードで確実に処理できます。
agents/judge/agent.pyを開きます。JudgeFeedbackスキーマとjudgeエージェントを定義します。# 1. Define the Schema class JudgeFeedback(BaseModel): """Structured feedback from the Judge agent.""" status: Literal["pass", "fail"] = Field( description="Whether the research is sufficient ('pass') or needs more work ('fail')." ) feedback: str = Field( description="Detailed feedback on what is missing. If 'pass', a brief confirmation." ) # 2. Define the Agent judge = Agent( name="judge", model=MODEL, description="Evaluates research findings for completeness and accuracy.", instruction=""" You are a strict editor. Evaluate the 'research_findings' against the user's original request. If the findings are missing key info, return status='fail'. If they are comprehensive, return status='pass'. """, output_schema=JudgeFeedback, # Disallow delegation because it should only output the schema disallow_transfer_to_parent=True, disallow_transfer_to_peers=True, ) root_agent = judge
重要なコンセプト: エージェントの動作の制限
disallow_transfer_to_parent=True と disallow_transfer_to_peers=True を設定します。これにより、判定エージェントは構造化された JudgeFeedback のみを返すようになります。 ユーザーと「チャット」したり、別のエージェントに委任したりすることはできません。これにより、ロジックフローの決定論的コンポーネントになります。
5. 🧪 単独でのテスト
接続する前に、各エージェントが動作することを確認できます。ADK を使用すると、エージェントを個別に実行できます。
重要なコンセプト: インタラクティブ ランタイム
adk run は、ユーザーが「ユーザー」となる軽量環境を起動します。これにより、エージェントの指示とツールの使用状況を個別にテストできます。ここでエージェントが失敗した場合(Google 検索を使用できないなど)、オーケストレーションで確実に失敗します。
- 調査エージェントをインタラクティブに実行します。特定のエージェント ディレクトリを指定します。
# This runs the researcher agent in interactive mode uv run adk run agents/researcher - チャット プロンプトに次のように入力します。
Google 検索ツールを使用して回答を返す必要があります。注: プロジェクト、ロケーション、Vertex の使用が設定されていないことを示すエラーが表示された場合は、プロジェクト ID が設定されていることを確認し、次のコマンドを実行します。Find the population of Tokyo in 2020export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project) export GOOGLE_CLOUD_LOCATION=global export GOOGLE_GENAI_USE_VERTEXAI=true - チャットを終了します(Ctrl+C)。
- 判定エージェントをインタラクティブに実行します。
uv run adk run agents/judge - チャット プロンプトで、次のように入力をシミュレートします。
調査結果が短すぎるため、Topic: Tokyo. Findings: Tokyo is a city.status='fail'`status='fail'` が返されます。
6. ✍️ コンテンツ作成エージェント

コンテンツ作成エージェント はクリエイティブ ライターです。承認された調査結果をコースに変換します。
agents/content_builder/agent.pyを開きます。content_builderエージェントを定義します。content_builder = Agent( name="content_builder", model=MODEL, description="Transforms research findings into a structured course.", instruction=""" You are an expert course creator. Take the approved 'research_findings' and transform them into a well-structured, engaging course module. **Formatting Rules:** 1. Start with a main title using a single `#` (H1). 2. Use `##` (H2) for main section headings. 3. Use bullet points and clear paragraphs. 4. Maintain a professional but engaging tone. Ensure the content directly addresses the user's original request. """, ) root_agent = content_builder
重要なコンセプト: コンテキストの伝播
「コンテンツ作成エージェントは調査エージェントが検索した内容をどのように認識するのですか?」と思われるかもしれません。ADK では、パイプライン内のエージェントが session.state を共有します。後で、オーケストレーターで、調査エージェントと判定エージェントがこの共有状態に出力を保存するように構成します。コンテンツ作成エージェントのプロンプトは、この履歴に効果的にアクセスできます。
7. 🎻 オーケストレーター

オーケストレーター は、マルチエージェント チームのマネージャーです。特定のタスクを実行するスペシャリスト エージェント(調査エージェント、判定エージェント、コンテンツ作成エージェント)とは異なり、オーケストレーターの仕事はワークフローを調整し、エージェント間で情報が正しく流れるようにすることです。
🌐 アーキテクチャ: Agent-to-Agent(A2A)

このラボでは、分散システム を構築します。すべてのエージェントを単一の Python プロセスで実行するのではなく、独立したマイクロサービスとしてデプロイします。これにより、各エージェントは個別にスケーリングでき、システム全体をクラッシュさせることなく失敗できます。
これを実現するために、Agent-to-Agent(A2A) プロトコルを使用します。
A2A プロトコル
詳細: 本番環境システムでは、エージェントは異なるサーバー(または異なるクラウド)で実行されます。A2A プロトコル は、HTTP 経由で互いを検出して通信するための標準的な方法を作成します。RemoteA2aAgent は、このプロトコルの ADK クライアントです。
agents/orchestrator/agent.pyを開きます。- コメント
# TODO: Define connections to remote agentsまたはリモート エージェント定義のセクションを見つけます。 - 次のコードを追加して、接続を定義します。インポートの後 、他のエージェント定義の前 に配置してください。
# ... existing code ... # Connect to the Researcher (Localhost port 8001) researcher_url = os.environ.get("RESEARCHER_AGENT_CARD_URL", "http://localhost:8001/a2a/agent/.well-known/agent-card.json") researcher = RemoteA2aAgent( name="researcher", agent_card=researcher_url, description="Gathers information using Google Search.", # IMPORTANT: Save the output to state for the Judge to see after_agent_callback=create_save_output_callback("research_findings"), # IMPORTANT: Use authenticated client for communication httpx_client=create_authenticated_client(researcher_url) ) # Connect to the Judge (Localhost port 8002) judge_url = os.environ.get("JUDGE_AGENT_CARD_URL", "http://localhost:8002/a2a/agent/.well-known/agent-card.json") judge = RemoteA2aAgent( name="judge", agent_card=judge_url, description="Evaluates research.", after_agent_callback=create_save_output_callback("judge_feedback"), httpx_client=create_authenticated_client(judge_url) ) # Content Builder (Localhost port 8003) content_builder_url = os.environ.get("CONTENT_BUILDER_AGENT_CARD_URL", "http://localhost:8003/a2a/agent/.well-known/agent-card.json") content_builder = RemoteA2aAgent( name="content_builder", agent_card=content_builder_url, description="Builds the course.", httpx_client=create_authenticated_client(content_builder_url) )
8. 🛑 エスカレーション チェッカー
ループには停止する方法が必要です。判定エージェントが「合格」と判断した場合は、すぐにループを終了してコンテンツ作成エージェントに移動します。
BaseAgent を使用したカスタム ロジック
詳細: すべてのエージェントが LLM を使用するわけではありません。シンプルな Python ロジックが必要になることもあります。BaseAgent を使用すると、コードを実行するだけのエージェントを定義できます。この場合、セッションの状態を確認し、EventActions(escalate=True) を使用して LoopAgent に停止を通知します。
agents/orchestrator/agent.pyに移動します。EscalationCheckerTODO プレースホルダを見つけます。- 次の実装に置き換え ます。
class EscalationChecker(BaseAgent): """Checks the judge's feedback and escalates (breaks the loop) if it passed.""" async def _run_async_impl( self, ctx: InvocationContext ) -> AsyncGenerator[Event, None]: # Retrieve the feedback saved by the Judge feedback = ctx.session.state.get("judge_feedback") print(f"[EscalationChecker] Feedback: {feedback}") # Check for 'pass' status is_pass = False if isinstance(feedback, dict) and feedback.get("status") == "pass": is_pass = True # Handle string fallback if JSON parsing failed elif isinstance(feedback, str) and '"status": "pass"' in feedback: is_pass = True if is_pass: # 'escalate=True' tells the parent LoopAgent to stop looping yield Event(author=self.name, actions=EventActions(escalate=True)) else: # Continue the loop yield Event(author=self.name) escalation_checker = EscalationChecker(name="escalation_checker")
重要なコンセプト: イベントによる制御フロー
エージェントはテキストだけでなく、イベント とも通信します。escalate=True でイベントを生成することで、このエージェントは親(LoopAgent)にシグナルを送信します。LoopAgent は、このシグナルをキャッチしてループを終了するようにプログラムされています。
9. 🔁 リサーチループ

フィードバック ループが必要です。調査 -> 判定 ->(不合格)-> 調査 -> ...
agents/orchestrator/agent.pyに移動します。research_loop定義を追加します。EscalationCheckerクラスとescalation_checkerインスタンスの後 に配置します。research_loop = LoopAgent( name="research_loop", description="Iteratively researches and judges until quality standards are met.", sub_agents=[researcher, judge, escalation_checker], max_iterations=3, )
重要なコンセプト: LoopAgent
LoopAgent は、sub_agents を順番に処理します。
researcher: データを検索します。judge: データを評価します。escalation_checker:yield Event(escalate=True)を行うかどうかを決定します。escalate=Trueが発生すると、ループは早期に終了します。それ以外の場合は、調査エージェントから再開します(max_iterationsまで)。
10. 🔗 最終パイプライン

最後に、すべてをまとめます。
agents/orchestrator/agent.pyに移動します。- ファイルの下部に
root_agentを定義します。既存のroot_agent = Noneプレースホルダを置き換えます。root_agent = SequentialAgent( name="course_creation_pipeline", description="A pipeline that researches a topic and then builds a course from it.", sub_agents=[research_loop, content_builder], )
重要なコンセプト: 階層構成
research_loop はエージェント(LoopAgent)です。SequentialAgent の他のサブエージェントと同様に扱います。この構成可能性により、単純なパターン(シーケンス内のループ、ルーター内のシーケンスなど)をネストして複雑なロジックを構築できます。
11. 💻 ローカルで実行する
すべてを実行する前に、ADK が分散環境をローカルでシミュレートする方法を見てみましょう。
詳細: ローカル開発の仕組み
マイクロサービス アーキテクチャでは、すべてのエージェントが独自のサーバーとして実行されます。デプロイすると、4 つの異なる Cloud Run サービスが作成されます。4 つのターミナルタブを開いて 4 つのコマンドを実行する必要がある場合、ローカルでのシミュレーションは困難です。
このスクリプトは、調査エージェント(ポート 8001)、判定エージェント(8002)、コンテンツ作成エージェント(8003)の uvicorn プロセスを開始します。RESEARCHER_AGENT_CARD_URL などの環境変数を設定し、オーケストレーター(ポート 8004)に渡します。これは、後でクラウドで構成する方法とまったく同じです。

- オーケストレーション スクリプトを実行します。
これにより、4 つの個別のプロセスが開始されます。perl -pi -e 's/us-central1/global/g' run_local.sh ./run_local.sh - テスト:
- Cloud Shell を使用している場合: [ウェブでプレビュー] ボタン(ターミナルの右上)-> [ポート 8080 でプレビュー] -> [ポートを変更] をクリックして
8000にします。 - ローカルで実行している場合: ブラウザで
http://localhost:8000を開きます。 - プロンプト: "コーヒーの歴史に関するコースを作成してください。"
- 確認: オーケストレーターが調査エージェントを呼び出します。出力は判定エージェントに送られます。判定エージェントが失敗した場合、ループは続行されます。
- 「Internal Server Error」 / 認証エラー: 認証エラー(
google-auth関連など)が表示された場合は、ローカル マシンで実行している場合はgcloud auth application-default loginを実行していることを確認してください。Cloud Shell で、GOOGLE_CLOUD_PROJECT環境変数が正しく設定されていることを確認します。 - ターミナル エラー: 新しいターミナル ウィンドウでコマンドが失敗した場合は、環境変数(
GOOGLE_CLOUD_PROJECTなど)を再エクスポートしてください。
- Cloud Shell を使用している場合: [ウェブでプレビュー] ボタン(ターミナルの右上)-> [ポート 8080 でプレビュー] -> [ポートを変更] をクリックして
- エージェントの単独テスト: システム全体が実行されている場合でも、ポートを直接ターゲットにすることで、特定のエージェントをテストできます。これは、チェーン全体をトリガーせずに特定のコンポーネントをデバッグする場合に便利です。注: これらはウェブページではなく API エンドポイントです。ブラウザからアクセスすることはできません。代わりに、
curlを使用して実行されていることを確認します(エージェント カードを取得するなど)。- 調査エージェントのみ(ポート 8001):
- ステータスを確認します(
urlエンドポイントを見つけます)。curl http://localhost:8001/a2a/agent/.well-known/agent-card.json - クエリを送信します(A2A JSON-RPC プロトコルを使用)。
curl -X POST http://localhost:8001/a2a/agent \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "message/send", "id": 1, "params": { "message": { "message_id": "test-1", "role": "user", "parts": [ { "text": "What is the capital of France?", "kind": "text" } ] } } }'
- ステータスを確認します(
- 判定エージェントのみ(ポート 8002):
- ステータスを確認します。
curl http://localhost:8002/a2a/agent/.well-known/agent-card.json - クエリを送信します。
curl -X POST http://localhost:8002/a2a/agent \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "message/send", "id": 1, "params": { "message": { "message_id": "test-2", "role": "user", "parts": [ { "text": "Topic: Tokyo. Findings: Tokyo is the capital of Japan.", "kind": "text" } ] } } }'
- ステータスを確認します。
- コンテンツ作成エージェントのみ(ポート 8003):
curl http://localhost:8003/a2a/agent/.well-known/agent-card.json - オーケストレーター(ポート 8004):
curl http://localhost:8004/a2a/agent/.well-known/agent-card.json
- 調査エージェントのみ(ポート 8001):
12. 🚀 Cloud Run にデプロイする
最終的な検証はクラウドで実行されます。各エージェントを個別のサービスとしてデプロイします。
デプロイ構成について
エージェントを Cloud Run にデプロイするときに、動作と接続を構成するためにいくつかの環境変数を渡します。
GOOGLE_CLOUD_PROJECT: エージェントがロギングと Vertex AI の呼び出しに正しい Google Cloud プロジェクトを使用するようにします。GOOGLE_GENAI_USE_VERTEXAI: Gemini API を直接呼び出すのではなく、モデル推論に Vertex AI を使用するようにエージェント フレームワーク(ADK)に指示します。GOOGLE_CLOUD_LOCATION: 使用するエンドポイントをエージェント フレームワーク(ADK)に指示します。[AGENT]_AGENT_CARD_URL: これはオーケストレーターにとって重要です。オーケストレーターにリモート エージェントの場所を通知します。 これをデプロイされた Cloud Run URL(特にエージェント カードのパス)に設定することで、オーケストレーターはインターネット経由で調査エージェント、判定エージェント、コンテンツ作成エージェントを検出して通信できるようになります。
- サブエージェントをデプロイする(並列):時間を節約するため、調査エージェント、判定エージェント、コンテンツ作成エージェントを同時にデプロイします。3 つの新しいターミナルタブを開きます。各 新しいタブで、次のコマンドを実行して環境を設定します。
タブ 1: 調査エージェントのデプロイを実行します。cd ~/prai-roadshow-lab-1-starter source .env タブ 2: 判定エージェントのデプロイを実行します。gcloud run deploy researcher \ --source agents/researcher/ \ --region us-west1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \ --set-env-vars GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION \ --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true" タブ 3: コンテンツ作成エージェントのデプロイを実行します。gcloud run deploy judge \ --source agents/judge/ \ --region us-west1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \ --set-env-vars GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION \ --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"gcloud run deploy content-builder \ --source agents/content_builder/ \ --region us-west1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \ --set-env-vars GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION \ --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true" - URL をキャプチャする:3 つのデプロイがすべて完了したら、元のターミナル に戻ります(オーケストレーターをデプロイします)。次のコマンドを実行して、サービス URL をキャプチャします。
RESEARCHER_URL=$(gcloud run services describe researcher --region us-west1 --format='value(status.url)') JUDGE_URL=$(gcloud run services describe judge --region us-west1 --format='value(status.url)') CONTENT_BUILDER_URL=$(gcloud run services describe content-builder --region us-west1 --format='value(status.url)') echo "Researcher: $RESEARCHER_URL" echo "Judge: $JUDGE_URL" echo "Content Builder: $CONTENT_BUILDER_URL" - オーケストレーターをデプロイする: キャプチャした環境変数を使用して、オーケストレーターを構成します。
URL をキャプチャします。gcloud run deploy orchestrator \ --source agents/orchestrator/ \ --region us-west1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars RESEARCHER_AGENT_CARD_URL=$RESEARCHER_URL/a2a/agent/.well-known/agent-card.json \ --set-env-vars JUDGE_AGENT_CARD_URL=$JUDGE_URL/a2a/agent/.well-known/agent-card.json \ --set-env-vars CONTENT_BUILDER_AGENT_CARD_URL=$CONTENT_BUILDER_URL/a2a/agent/.well-known/agent-card.json \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \ --set-env-vars GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION \ --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"ORCHESTRATOR_URL=$(gcloud run services describe orchestrator --region us-west1 --format='value(status.url)') echo $ORCHESTRATOR_URL - フロントエンドをデプロイする:
gcloud run deploy course-creator \ --source app \ --region us-west1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars AGENT_SERVER_URL=$ORCHESTRATOR_URL \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT - リモート デプロイをテストする: デプロイしたオーケストレーターの URL を開きます。Google のサーバーレス インフラストラクチャを利用してエージェントをスケーリングし、完全にクラウドで実行されるようになりました。ヒント: すべてのマイクロサービスとその URL は Cloud Run インターフェースにあります。
13. まとめ
おめでとうございます!プロダクション レディな分散マルチエージェント システムを構築してデプロイできました。
達成したこと
- 複雑なタスクを分解した: 1 つの巨大なプロンプトではなく、作業を専門の役割(調査エージェント、判定エージェント、コンテンツ作成エージェント)に分割しました。
- 品質管理を実装した:
LoopAgentと構造化されたJudgeを使用して、高品質の情報のみが最終ステップに到達するようにしました。 - 本番環境向けに構築した: Agent-to-Agent(A2A) プロトコルと Cloud Run を使用して、各エージェントが独立したスケーラブルなマイクロサービスであるシステムを作成しました。これは、単一の Python スクリプトですべてを実行するよりもはるかに堅牢です。
- オーケストレーション:
SequentialAgentとLoopAgentを使用して、明確な制御フロー パターンを定義しました。
次のステップ
これで基盤ができたので、このシステムを拡張できます。
- ツールを追加する: 調査エージェントに内部ドキュメントまたは API へのアクセス権を付与します。
- 判定エージェントを改善する: より具体的な条件や「Human in the Loop」ステップを追加します。
- モデルを切り替える: エージェントごとに異なるモデルを使用してみます(判定エージェントには高速なモデル、コンテンツ作成エージェントには強力なモデルなど)。
これで、Google Cloud で複雑で信頼性の高いエージェント ワークフローを構築できるようになりました。