既存の AI エージェントをワークフローのステップとして追加して、タスクを専門のエージェントに転送できます。 これにより、さまざまなエージェント間でオーケストレーションを行うマルチエージェント ワークフローを作成できます。各エージェントは、より大きなプロセスの特定の部分を処理します。
始める前に
この機能を使用する前に、次の手順を完了してください。
- Gemini Enterprise 管理者が、アプリの機能管理設定で Workflow Builder 機能の切り替えを有効にしていることを確認します。詳細については、 ウェブアプリの機能を管理するをご覧ください。
追加するエージェントが組織で使用可能であることを確認します。 この機能では、次のエージェントを追加できます。
既存のエージェント ステップを追加する
アプリ
- ブラウザで Gemini Enterprise ウェブアプリを開きます。
- 既存のエージェントに移動するか、 新しいエージェントを作成します。
- フロービルダーで、[ステップを追加] をクリックします。
- [ステップを追加] パネルで、[既存のエージェント] をクリックしてセクションを開きます。
利用可能なエージェントのリストを参照します。
追加するエージェントをクリックします。
既存のエージェント ステップがワークフローに追加されます。選択したエージェントはワークフローの一部として実行され、前のステップから入力を受け取り、後のステップに出力を渡します。
キャンバスで既存のエージェント ステップをクリックして構成パネルを開き、次の項目を構成します。
- プロンプト: エージェントをトリガーするために使用するプロンプトまたは手順を入力します。静的テキストを含めることも、前のステップの出力を参照することもできます(例:
${step_name.output})。
- プロンプト: エージェントをトリガーするために使用するプロンプトまたは手順を入力します。静的テキストを含めることも、前のステップの出力を参照することもできます(例:
エージェント ステップは、選択したエージェントへの動的な参照です。ソース エージェントが更新されるか、新しいバージョンが公開されると、ワークフローでは自動的に最新バージョンが使用されます。
この機能の制限事項について詳しくは、 既知の問題と制限事項をご覧ください。
明確化のための質問の仕組み
既存のエージェントがワークフローで実行される際、タスクを完了するために不足している情報が必要な場合は、実行を一時停止してユーザーに明確化のための質問をすることができます。
参照されるエージェントが input-required シグナル(A2A)または RequestInput イベント(ADK)を発行する場合、明確化のための質問はネイティブにサポートされます。
既存のエージェント ステップが実行され、追加情報が必要な場合:
- 実行が一時停止する: ワークフローは既存のエージェント ステップで実行を一時停止し、人間参加型(HITL)プロンプトを開始します。
- ユーザーがプロンプトに回答する: Gemini Enterprise ウェブアプリに、エージェントの明確化のための質問と、回答を入力するテキスト フィールドが表示されます。
- 実行が再開される: ユーザーが回答を送信すると、ワークフローは 既存のエージェントを再開し、ユーザーの回答をエージェントに返します。
- マルチターンのサポート: エージェントは、必要な情報をすべて収集して最終的な出力を生成するまで、複数のターンにわたって 明確化のための質問を連続して行うことができます。
コンテキストの分離
明確化のための質問のやり取り中、参照されるエージェントは、ユーザーとのインタラクション履歴とノード用に構成された最初のプロンプトのみを受け取ります。ステップのプロンプトで明示的に参照されていない限り、ワークフローの他のステップの出力と変数は、参照されるエージェントに自動的に渡されません。
エージェントに明確化のための質問を実装する
明確化のための質問をサポートするには、追加情報が必要な場合にプロトコルレベルの request-input シグナルを発行するようにカスタム エージェントを構成します。
A2A エージェント(ネイティブ)
Agent-to-Agent(A2A)プロトコルを直接実装するエージェントの場合は、メッセージ ペイロードに明確化のための質問を指定して、TaskUpdater でタスクを input-required 状態にします。
from a2a.server.tasks import TaskUpdater
from a2a.types import Message, Part, Role, TextPart
# Inside your custom agent's task executor class:
async def execute(self, context, event_queue):
updater = TaskUpdater(event_queue, context.task_id, context.context_id)
if context.current_task is None:
await updater.submit()
await updater.start_work()
user_input = context.get_user_input()
if "weather" in user_input and "tokyo" not in user_input.lower():
await updater.requires_input(
Message(
message_id=f"q-{context.task_id}",
role=Role.agent,
parts=[Part(root=TextPart(
text="Which city would you like the weather for?"))],
task_id=context.task_id,
context_id=context.context_id,
)
)
return
await updater.complete(
Message(
message_id=f"a-{context.task_id}",
role=Role.agent,
parts=[Part(root=TextPart(
text="It is sunny and 72°F in Tokyo."))],
task_id=context.task_id,
context_id=context.context_id,
)
)
ユーザーのレスポンスは、同じ taskId を持つ message/send リクエストとしてエージェントに返送されます。
A2A エージェント(ADK で構築)
エージェントが Agent Development Kit(ADK)で構築され、A2A(to_a2a() を使用)を介して公開されている場合は、質問を行う関数を LongRunningFunctionTool でラップします。
from google.adk.agents import Agent
from google.adk.tools.long_running_tool import LongRunningFunctionTool
from google.adk.a2a.utils.agent_to_a2a import to_a2a
def get_weather(city: str) -> str:
"""Returns weather information for a city."""
return f"It is sunny and 72°F in {city}."
def ask_clarifying_question(question: str) -> None:
"""Asks the user a question and waits for their reply."""
return None
root_agent = Agent(
model="gemini-2.5-flash",
name="weather_agent",
instruction=(
"If the user asks for weather without specifying a city, call "
"`ask_clarifying_question` and wait. Do not guess."
),
tools=[get_weather, LongRunningFunctionTool(ask_clarifying_question)],
)
a2a_app = to_a2a(root_agent, port=8000)
Agent Engine の ADK エージェント
Agent Engine で推論エンジンによってホストされる ADK エージェントの場合は、ジェネレータ ツールまたはカスタム エージェント ステップ内で RequestInput イベントを発行します。
from google.adk.events import RequestInput
# Inside a generator tool or custom agent step
def ask_for_details():
"""Requests user input during tool or step execution."""
yield RequestInput(
interrupt_id="weather_city",
message="Which city would you like the weather for?",
)