はじめに
七尾百合子さん、お誕生日 152日目 おめでとうございます! nikkieです。
Agent Development Kit (ADK) でロギング1やOpenTelemetry2を頻繁に素振りしてきましたが、いよいよどのようなプロンプトがGeminiに送られているのか見ていきます。
目次
YouTube Shorts Agent
当ブログでADKの素振りの際に大変お世話になっております。
プロンプトを読むうえで確認しておきたいエージェントの構成はこちら(理解優先の簡略版です)
root_agent = LlmAgent( model="gemini-2.5-pro", # 省略 tools=[ AgentTool(scriptwriter_agent), AgentTool(visualizer_agent), AgentTool(formatter_agent), ], )
ログ(やテレメトリ)を見ると、root_agent
は次のような軌跡をたどっています。
- System Instruction + ツール定義 + userからの「write me a script on how to build AI agents」で
root_agent
呼び出し- -> ShortsScriptwriter 呼び出し
- ShortsScriptwriterの返したテキストをコンテキストに追加して、
root_agent
再呼び出し- -> ShortsVisualizer 呼び出し
- ShortsVisualizerの返したテキストをコンテキストに追加して、
root_agent
再呼び出し- -> ConceptFormatter 呼び出し
- ConceptFormatterの返したテキストをコンテキストに追加して、
root_agent
再呼び出し- -> ユーザに返答する出力
軌跡の理解には、ADK User Groupの資料が参考になりました。
ログをファイルに出力するために、agent.py
に次のようなコードを追加しています。
logging.basicConfig( force=True, # adk webで設定されてしまうルートロガーの設定を無に帰す level=logging.DEBUG, format="%(asctime)s | %(levelname)s | %(name)s:%(funcName)s:%(lineno)d - %(message)s", filename="agent.log" ) logging.getLogger().handlers[0].addFilter(logging.Filter("google_adk"))
root_agent
のプロンプト
一番最初のログがroot_agent
のプロンプトをつかみやすいと思います。
LLM Request: ----------------------------------------------------------- System Instruction: You are the Shorts Content Orchestrator. Your role is to manage the creation of YouTube Shorts content by coordinating specialized child agents (ScriptWriter, VisualCreator, MarkdownFormatter). < https://github.com/google/adk-docs/blob/551e563ebd9dee647e741c61cd3a2a6b27fa93ce/examples/python/agent-samples/youtube-shorts-assistant/shorts_agent_instruction.txt の内容 > You are an agent. Your internal name is "youtube_shorts_agent". The description about you is "You are an agent that can write scripts, visuals and format youtube short videos. You have subagents that can do this" ----------------------------------------------------------- Contents: {"parts":[{"text":"write me a script on how to build AI agents"}],"role":"user"} ----------------------------------------------------------- Functions: ShortsScriptwriter: {'request': {'type': <Type.STRING: 'STRING'>}} ShortsVisualizer: {'request': {'type': <Type.STRING: 'STRING'>}} ConceptFormatter: {'request': {'type': <Type.STRING: 'STRING'>}} -----------------------------------------------------------
「You are an agent.」以降は LlmRequestProcessor によってname
とdescription
から追加されていました。
https://github.com/google/adk-python/blob/v1.11.0/src/google/adk/flows/llm_flows/identity.py#L37-L39
冒頭の「You are the Shorts Content Orchestrator.」と近い内容がADKにより自動で入ることで、『LLMのプロンプトエンジニアリング』36章で見かけた「サンドイッチ」を実現できているように思えます。
Functionsにあるツール(AgentTool)とは別に、「System Instruction」(LlmAgentのinstruction
)にもAgentToolを匂わす情報を入れているのが意外でした。
function callingの例の素振りでは、ツールの情報を追加するだけで、システムプロンプトでの言及までやっていませんでした。
この例ではinstruction
をファイルに外出しして、協働するエージェントや、どのような手順で進めるかをはっきりと記述しています(協働するエージェントは名前を合わせてあげるともっとよさそうです)
AgentTool呼び出し
root_agent
がツールを呼び出すとき、このようなJSONが返されています。
{ "parts": [ { "thought_signature": "<略>", "function_call": { "args": { "request": "Write a script for a YouTube Short on how to build AI agents. The script should be engaging, easy to understand for a beginner audience, and approximately 30-45 seconds long. It needs a strong hook to grab attention, a simplified explanation of the steps involved, and a clear call to action." }, "name": "ShortsScriptwriter" } } ], "role": "model" }
これをADK側でツールのAgentに送ります。
LLM Request: ----------------------------------------------------------- System Instruction: You are 'Pro Short', < https://github.com/google/adk-docs/blob/551e563ebd9dee647e741c61cd3a2a6b27fa93ce/examples/python/agent-samples/youtube-shorts-assistant/scriptwriter_instruction.txt の内容 > You are an agent. Your internal name is "ShortsScriptwriter". ----------------------------------------------------------- Contents: {"parts":[{"text":"Write a script for a YouTube Short on how to build AI agents. The script should be engaging, easy to understand for a beginner audience, and approximately 30-45 seconds long. It needs a strong hook to grab attention, a simplified explanation of the steps involved, and a clear call to action."}],"role":"user"} ----------------------------------------------------------- Functions: -----------------------------------------------------------
ツールのAgentが返したレスポンスは、root_agent
のコンテキストに入ります。
AgentToolとなっているLlmAgentは、root_agent
が「write me a script on how to build AI agents」とユーザからのリクエストを受けたことは知らないわけですね。
root_agent
のコンテキストを消費しないサブエージェントになっていそうです。
終わりに
AgentToolを使ったADKのエージェントのログを読んだところ、プロンプトやLLMのコンテキストについて以下が分かりました
root_agent
は、ユーザ入力や、AgentTool
の呼び出し・返答内容、すべてをコンテキストに持つAgentTool
(のLlmAgent)はroot_agent
から送られてきたプロンプトにだけ返答するroot_agent
とユーザのやり取りは知らない
- ADKでは、
name
をinstruction
冒頭に書くことで、システムプロンプトにおけるサンドイッチができる
宿題事項も挙げておきます
- ログのFunctionsがそのままGeminiに入力されているのだろうか?
- ADKのLlmRequestProcessorの実装に、参考論文や比較実験といった根拠はあるのだろうか?
- descriptionで謎の1字下げはなぜやっている?
- サンドイッチとして使えればメリットになりそうだが、実装の詳細を理解していないと罠にもなりそう(間違えるほうがむしろ簡単になっちゃってるかも)
- 今回ログでたびたび見かけた event_generator が少し気になる
- https://github.com/google/adk-python/blob/v1.11.0/src/google/adk/cli/adk_web_server.py#L855-L883
Convert the events to properly formatted SSE
P.S. エージェント実装はPythonよりJavaScript?
調査不足なのかもですが、ADKの情報、全然見かけないんですよね
ゆるぼ
— ryoppippi (@ryoppippi) 2025年8月14日
pythonでai agent作る時って結局デファクトのSDKってなんですか?
typescriptならvercel ai + mastraっぽいなとは思うのですが
実際皆んなPythonでAIエージェント作る場合、何使って作ってるんだろ、LangChain系? https://t.co/ZSzSwJss1y
— ニケちゃん (@tegnike) 2025年8月14日