nikkie-ftnextの日記

イベントレポートや読書メモを発信

Agent Development Kit の (Llm)Agent の sub_agents と tools 〜YouTube Shorts エージェントを例に〜

はじめに

七尾百合子さん、お誕生日 42日目 おめでとうございます! nikkieです。

Agent Development Kitを素振りしたり情報収集したりする中で知った学びです。

目次

Getting started with Agent Development Kit (sub_agents)

YouTubeの動画を元に、手を動かしました1

youtube_shorts_agentroot_agentでもある)は3つのサブエージェントを持ちます。

youtube_shorts_agent = LlmAgent(
    name="youtube_shorts_agent",
    # 略
    sub_agents=[scriptwriter_agent, visualizer_agent, formatter_agent],
)

サブエージェントにはtransferされます。
youtube_shorts_agentがユーザの入力に対して、例えばサブエージェントscriptwriter_agentにtransferしたとき、(youtube_shorts_agentはもう出番がなく)サブエージェントscriptwriter_agentがユーザに応答します

なおADKでは、LlmAgentAgentとも呼ばれます。
https://google.github.io/adk-docs/agents/llm-agents/

The LlmAgent (often aliased simply as Agent) is a core component in ADK, (略)

LlmAgenttools引数

ADKでは他のエージェントにtransferするものなのかー」ととらえていたところ、Google Cloud JapanのZenn記事に衝撃を受けます。

この記事ではsub_agentsは使っていません
代わりにtoolsに関数を指定しています。

planning_client_agent = LlmAgent(
    name='planning_client_agent',
    # 略
    tools=[
        generate_plan,
        update_plan,
        evaluate_plan,
    ],
)

toolsの関数の中でgoogle-genaiを使って、GeminiのAPIを呼び出しています。
planning_client_agentgenerate_planして、update_planして、evaluate_planとtoolを使います(これはReAct2ですよね)

tools引数を知ってADKのドキュメントを眺めていると、Agent-as-a-Toolという概念を知りました。
https://google.github.io/adk-docs/tools/function-tools/#3-agent-as-a-tool

transferするsub_agentsと比較して

Agent-as-a-Tool: When Agent A calls Agent B as a tool (using Agent-as-a-Tool), Agent B's answer is passed back to Agent A, which then summarizes the answer and generates a response to the user

(意訳)Agent AがAgent Bをtoolとして呼び出すと、Bの回答はAgent Aに渡されます
Agent AがBの回答を要約して(Aが)ユーザに応答します。

google.adk.tools.agent_tool.AgentToolでくるむと、Agent-as-a-Toolとなります!

tools=[AgentTool(agent=agent_b)]

Agent-as-a-Tool で YouTube Shorts エージェントを実装

「Getting started with Agent Development Kit」の例をsub_agentsからtoolsに変えました。

変更点は実はわずかです

+from google.adk.tools.agent_tool import AgentTool

youtube_shorts_agent = LlmAgent(
    # 略
-     sub_agents=[scriptwriter_agent, visualizer_agent, formatter_agent],
+     tools=[
+         AgentTool(scriptwriter_agent),
+         AgentTool(visualizer_agent),
+         AgentTool(formatter_agent),
+     ],
)

「write me a script on how to build AI agents」を送ると、youtube_shorts_agentがtoolを使っていって回答してくれました。
transferしていないんです!
必要と判断した順に呼び出していってます!

なお、Agent-as-a-Toolにしたことで、サブエージェントでなくなったのでBuilt-in toolのGoogle Searchが動くようになっています。
ref: https://github.com/google/adk-python/issues/53#issuecomment-2798906767

scriptwriter_agent = LlmAgent(
    # 略
-    # tools=[google_search],
+    tools=[google_search],
    output_key="generated_script",  # Save result to state
)

終わりに

GoogleADKでAgent (LlmAgent)を組み合わせるときに、2つのやり方があります

  • sub_agents:サブエージェントへのtransfer(子から親には戻らない)
  • tools:toolとして呼び出し(Agent-as-a-Tool。子から親に戻る)

今の私の理解では

  • root_agentに複数のタスク(例えば翻訳とコードレビューのようにぜんぜん違うタスク)を持たせるときはsub_agents
    • タスクごとにtransferしてよいため
  • タスクを担当するエージェントは他のエージェントをAgent-as-a-Tool
    • transferせずに、ReActしてタスクを遂行する
    • 他のエージェントは必須でなく、関数をtool useしてもよい

ということかなと考えています


  1. この記事でWorkflow agentsを次回予告しましたが、ごめんなさい。Agent-as-a-Toolが気になっちゃいました
  2. Reasoning and Acting