はじめに
七尾百合子さん、お誕生日 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日