循环代理
LoopAgent
LoopAgent
是一种工作流代理,能够以循环(即迭代)方式执行其子代理。它会重复运行一系列代理,直到达到指定迭代次数或满足终止条件。
当您的工作流程涉及重复操作或迭代优化时(例如代码修订),请使用 LoopAgent
。
示例
- 假设您需要构建一个能生成食物图片的代理,但有时当您想生成特定数量物品(例如5根香蕉)时,生成的图片中物品数量可能不符(例如出现7根香蕉)。您有两个工具:
generate_image
和count_food_items
。由于您希望持续生成图片直到正确生成指定数量物品或达到最大迭代次数,此时应使用LoopAgent
构建代理。
与其他工作流代理相同,LoopAgent
并非由大模型驱动,因此其执行过程是确定性的。需要注意的是,工作流代理仅关注执行机制(即循环执行),而不涉及内部逻辑——工作流代理的工具或子代理可能会使用大模型,也可能不会。
工作原理
当调用 LoopAgent
的 run_async()
方法时,它会执行以下操作:
- 子代理执行:按顺序遍历
sub_agents
列表,对每个子代理调用其run_async()
方法 -
终止检查:
关键点在于,
LoopAgent
本身并不具备停止循环的决策能力。您必须实现终止机制来避免无限循环。常用策略包括:max_iterations
:在LoopAgent
中设置最大迭代次数,循环将在达到该次数后终止- 子代理触发终止:设计一个或多个子代理来评估条件(例如"文档质量是否达标?"、"是否达成共识?")。当条件满足时,子代理可通过抛出自定义事件、在共享上下文中设置标志位或返回特定值来发出终止信号
完整示例:文档迭代优化
假设您需要对文档进行迭代优化:
- 写手代理:
LlmAgent
,负责生成或优化主题草稿 -
评审代理:
LlmAgent
,负责评估草稿并提出改进建议
在此配置中,LoopAgent
将管理整个迭代流程。CriticAgent
可被设计为当文档质量达到满意水平时返回"STOP"信号来终止迭代。或者,也可以通过 max_iterations
参数限制循环次数,或实现外部逻辑来决策终止时机。本例中循环最多运行五次,确保优化过程不会无限持续。
完整代码
from google.adk.agents.loop_agent import LoopAgent
from google.adk.agents.llm_agent import LlmAgent
from google.genai import types
from google.adk.sessions import InMemorySessionService
from google.adk.runners import Runner
# --- Constants ---
APP_NAME = "doc_writing_app"
USER_ID = "dev_user_01"
SESSION_ID = "session_01"
GEMINI_MODEL = "gemini-2.0-flash"
# --- State Keys ---
STATE_INITIAL_TOPIC = "quantum physics"
STATE_CURRENT_DOC = "current_document"
STATE_CRITICISM = "criticism"
writer_agent = LlmAgent(
name="WriterAgent",
model=GEMINI_MODEL,
instruction=f"""
You are a Creative Writer AI.
Check the session state for '{STATE_CURRENT_DOC}'.
If '{STATE_CURRENT_DOC}' does NOT exist or is empty, write a very short (1-2 sentence) story or document based on the topic in state key '{STATE_INITIAL_TOPIC}'.
If '{STATE_CURRENT_DOC}' *already exists* and '{STATE_CRITICISM}', refine '{STATE_CURRENT_DOC}' according to the comments in '{STATE_CRITICISM}'."
Output *only* the story or the exact pass-through message.
""",
description="Writes the initial document draft.",
output_key=STATE_CURRENT_DOC # Saves output to state
)
# Critic Agent (LlmAgent)
critic_agent = LlmAgent(
name="CriticAgent",
model=GEMINI_MODEL,
instruction=f"""
You are a Constructive Critic AI.
Review the document provided in the session state key '{STATE_CURRENT_DOC}'.
Provide 1-2 brief suggestions for improvement (e.g., "Make it more exciting", "Add more detail").
Output *only* the critique.
""",
description="Reviews the current document draft.",
output_key=STATE_CRITICISM # Saves critique to state
)
# Create the LoopAgent
loop_agent = LoopAgent(
name="LoopAgent", sub_agents=[writer_agent, critic_agent], max_iterations=2
)
# Session and Runner
session_service = InMemorySessionService()
session = session_service.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID)
runner = Runner(agent=loop_agent, app_name=APP_NAME, session_service=session_service)
# Agent Interaction
def call_agent(query):
content = types.Content(role='user', parts=[types.Part(text=query)])
events = runner.run(user_id=USER_ID, session_id=SESSION_ID, new_message=content)
for event in events:
if event.is_final_response():
final_response = event.content.parts[0].text
print("Agent Response: ", final_response)
call_agent("execute")