Agent Tool 無上下文記憶,需改用 Sub-agent

問題描述

在 ADK 中,透過 agenttool.New() 將 Agent 包裝成 Agent Tool 後,該 agent 在被呼叫時沒有父 agent 的對話記憶

  • Agent Tool 每次被呼叫都是無狀態的獨立執行
  • 無法存取父 agent 的對話歷史(session history)
  • 適合「給一個輸入、取得一個輸出」的無狀態任務(例如:查資料、分析圖片)

對比:Sub-agent vs Agent Tool

Sub-agent(sub_agents Agent Tool(agenttool.New()
上下文記憶 ✅ 共享父 agent session ❌ 無,每次獨立執行
呼叫方式 transfer_to_agent(agent_name=...) 直接呼叫工具
適合情境 需要對話歷史的複雜流程 無狀態的單次查詢
使用限制 不能掛有 google_search tool 可掛 google_search

情境範例

Agent Tool(無上下文記憶)

適合「翻譯文字」、「分析圖片」等純無狀態任務:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// translator_agent:純無狀態翻譯,不需要對話歷史
translatorAgent, _ := llmagent.New(llmagent.Config{
Name: "translator_agent",
Model: llmModel,
Description: "Translate text to English.",
Instruction: "Translate the given text. Return only the translated result.",
})

// 包裝成 AgentTool,掛到 Tools(非 SubAgents)
rootAgent, _ := llmagent.New(llmagent.Config{
Name: "root_agent",
Model: llmModel,
Tools: []tool.Tool{agenttool.New(translatorAgent, nil)},
})

呼叫時 translator_agent 只會看到當次傳入的 input,不知道之前對話說了什麼

Sub-agent(共享上下文記憶)

適合「建立訂單」、「預約行程」等需要讀取對話歷史的流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// booking_agent:需要知道使用者先前提到的日期、人數
bookingAgent, _ := llmagent.New(llmagent.Config{
Name: "booking_agent",
Model: llmModel,
Description: "Handle reservation booking.",
Instruction: "Create bookings based on conversation context.",
})

// 掛到 SubAgents,透過 transfer_to_agent 呼叫
rootAgent, _ := llmagent.New(llmagent.Config{
Name: "root_agent",
Model: llmModel,
SubAgents: []agent.Agent{bookingAgent},
})

booking_agent 被 transfer 進來時,可以讀取整個 session 的對話歷史(使用者說了什麼日期、幾人等)。

決策原則

需要對話上下文?→ 用 Sub-agent
純無狀態單次查詢?→ 用 Agent Tool

具體判斷:

  • 該 agent 需要知道「使用者之前說了什麼」→ Sub-agent
  • 該 agent 只需要「當次輸入」就能完成任務 → Agent Tool
  • 該 agent 帶有 google_search → 只能用 Agent Tool(ADK 限制)