用 Google ADK 编排多 Agent 工作流:Sequential、Loop、Parallel 实战拆解

用 Google ADK 编排多 Agent 工作流:Sequential、Loop、Parallel 实战拆解

单个 LLM Agent 能干的事有限。让它写代码还行,让它写完代码再审查再重构,一个 Agent 就容易乱。Google 在 2025 年开源了 Agent Development Kit(ADK),专门解决多 Agent 编排问题。核心思路:把复杂任务拆成多个专职 Agent,用工作流 Agent 控制执行顺序。

ADK 提供了三种工作流 Agent:SequentialAgent(顺序执行)、LoopAgent(循环迭代)、ParallelAgent(并行执行)。这三个东西本身不调用 LLM,只负责调度。具体的 LLM 调用在子 Agent 里完成。

我用 ADK 搭了几个实际场景,记录下代码和踩过的坑。

安装和基础设置

bash 复制代码
pip install google-adk

ADK 依赖 Gemini 模型,需要一个 Google AI API Key:

bash 复制代码
export GOOGLE_API_KEY="your-key-here"

基础结构很简单------定义 LlmAgent,指定 model 和 instruction,用 output_key 把结果存到 state 里。state 是所有子 Agent 共享的字典,这是多 Agent 之间传数据的唯一通道。

python 复制代码
from google.adk.agents import LlmAgent

agent = LlmAgent(
    name="MyAgent",
    model="gemini-2.5-flash",
    instruction="你是一个Python开发者,根据需求写代码。",
    output_key="result"  # 结果存到 state["result"]
)

SequentialAgent:流水线模式

最直观的模式。三个 Agent 按顺序跑:A 跑完 → B 拿 A 的结果跑 → C 拿 B 的结果跑。

实际场景:代码生成流水线。写代码 → 审查 → 重构,三步串联。

python 复制代码
from google.adk.agents import SequentialAgent, LlmAgent

MODEL = "gemini-2.5-flash"

writer = LlmAgent(
    name="CodeWriter",
    model=MODEL,
    instruction="""根据用户需求写Python代码。
    只输出代码块,不要解释。""",
    output_key="draft_code"
)

reviewer = LlmAgent(
    name="CodeReviewer",
    model=MODEL,
    instruction="""审查以下代码,找出bug和改进点。

代码:
```python
{draft_code}

逐条列出问题,不要重写代码。""", output_key="review_notes" )

refactorer = LlmAgent( name="CodeRefactorer", model=MODEL, instruction="""根据审查意见重构代码。

原始代码:

python 复制代码
{draft_code}

审查意见: {review_notes}

输出重构后的完整代码。""", output_key="final_code" )

pipeline = SequentialAgent( name="CodePipeline", sub_agents=[writer, reviewer, refactorer] )

ini 复制代码
数据流走 state:writer 的输出写入 `state["draft_code"]`,reviewer 的 instruction 里用 `{draft_code}` 引用这个值,它的输出再写入 `state["review_notes"]`,refactorer 同时引用两个 state key。

**踩坑记录:**

1. `output_key` 不能省。不设 output_key,下游 Agent 拿不到上游的结果,instruction 里的 `{draft_code}` 会被渲染成空字符串。这个错误不报错,只是结果不对,排查起来很痛苦。

2. instruction 里的变量名必须跟 output_key 完全一致。写成 `{code}` 但 output_key 是 `"draft_code"`,不会报错,渲染出来也是空的。

3. 子 Agent 的 `include_contents` 参数默认会把整个对话历史塞给每个子 Agent。在流水线模式下建议设成 `'none'`,只通过 state 传数据,不然 reviewer 收到一堆不相关的历史消息。

```python
reviewer = LlmAgent(
    name="CodeReviewer",
    model=MODEL,
    include_contents='none',  # 只看 state,不看历史
    instruction="...",
    output_key="review_notes"
)

LoopAgent:迭代改进模式

有些任务不是跑一次就够的。比如写文章------初稿写完,修改,再看,再改,直到满意为止。LoopAgent 就是干这个的。

它会反复执行子 Agent 列表,直到达到最大迭代次数,或者某个子 Agent 主动调用 escalate 退出循环。

场景:迭代式文档改进。Writer 写草稿,Critic 评审,如果没问题就退出,有问题就继续改。

python 复制代码
from google.adk.agents import LoopAgent, LlmAgent
from google.adk.tools.tool_context import ToolContext

def exit_loop(tool_context: ToolContext):
    """文档质量达标时调用此函数退出循环。"""
    tool_context.actions.escalate = True
    return {}

writer = LlmAgent(
    name="Writer",
    model="gemini-2.5-flash",
    include_contents='none',
    instruction="""你是技术文档作者。
    
当前文档:
{current_doc}

评审意见:
{critic_feedback}

根据评审意见改进文档。如果没有评审意见,根据主题 {topic} 写初稿。
只输出文档内容。""",
    output_key="current_doc"
)

critic = LlmAgent(
    name="Critic",
    model="gemini-2.5-flash",
    include_contents='none',
    instruction="""审查这份文档:

{current_doc}

检查标准:
1. 至少包含3个代码示例
2. 有清晰的章节结构
3. 没有事实错误

如果全部达标,调用 exit_loop 函数。
否则列出需要改进的地方。""",
    tools=[exit_loop],
    output_key="critic_feedback"
)

loop = LoopAgent(
    name="DocRefiner",
    sub_agents=[writer, critic],
    max_iterations=5
)

关键细节:

退出循环靠 tool_context.actions.escalate = True。这不是一个配置项,而是要定义一个 tool 函数,让 Critic Agent 在满意时主动调用它。escalate 的意思是"把控制权交回上层",LoopAgent 收到这个信号就停止循环。

max_iterations 是安全网。LLM 做判断有概率出错------Critic 可能永远不满意,也可能忘记调用 exit_loop。设个上限防止死循环。实测下来,大多数文档改进任务 3-4 轮就收敛了,5 轮足够。

还有一个坑:Writer 第一轮跑的时候,{critic_feedback} 在 state 里不存在。ADK 的处理方式是把它渲染成空字符串,不会报错。所以 instruction 里要写清楚"如果没有评审意见就写初稿",不然 Writer 可能对着空的反馈发呆。

ParallelAgent:并行加速

独立任务并行跑,最直接的提速手段。三个调研任务串行要 30 秒,并行可能 12 秒搞定。

场景:竞品分析。同时调研三个竞品,最后汇总。

python 复制代码
from google.adk.agents import ParallelAgent, SequentialAgent, LlmAgent
from google.adk.tools import google_search

MODEL = "gemini-2.5-flash"

def make_researcher(name, topic, output_key):
    return LlmAgent(
        name=name,
        model=MODEL,
        instruction=f"""调研 {topic} 的最新动态。
        用 Google Search 搜索,总结关键发现。
        输出2-3句话的摘要。""",
        tools=[google_search],
        output_key=output_key
    )

r1 = make_researcher("LangChainResearch", "LangChain", "langchain_result")
r2 = make_researcher("CrewAIResearch", "CrewAI", "crewai_result")
r3 = make_researcher("AutoGenResearch", "AutoGen", "autogen_result")

parallel = ParallelAgent(
    name="CompetitorResearch",
    sub_agents=[r1, r2, r3]
)

merger = LlmAgent(
    name="ReportMerger",
    model=MODEL,
    instruction="""根据以下三份调研结果写竞品分析报告:

LangChain: {langchain_result}
CrewAI: {crewai_result}
AutoGen: {autogen_result}

对比优劣势,给出推荐。""",
    output_key="final_report"
)

# 先并行调研,再串联汇总
full_pipeline = SequentialAgent(
    name="CompetitorAnalysis",
    sub_agents=[parallel, merger]
)

注意事项:

  1. 并行 Agent 之间不共享 state。每个分支独立跑,各自往 state 里写结果。如果两个并行 Agent 写同一个 output_key,结果不可预测------谁后写谁赢。所以每个并行子 Agent 的 output_key 必须不同。

  2. ParallelAgent 等所有子 Agent 跑完才返回。如果一个子 Agent 卡住了(比如 API 超时),整个 ParallelAgent 都会等。生产环境建议给每个子 Agent 加超时控制。

  3. 并行 + 串行组合是最常见的用法。上面的例子就是:先 ParallelAgent 并行调研,结果存到 state,再用 SequentialAgent 串联一个 Merger 做汇总。这个模式可以套很多场景------并行爬数据 → 串行汇总报告、并行翻译多语言 → 串行质检。

三种模式怎么选

不用纠结,根据任务依赖关系选:

  • 上游输出是下游输入 → SequentialAgent
  • 需要反复改进直到达标 → LoopAgent
  • 多个独立任务互不依赖 → ParallelAgent

实际项目里经常混合用。上面竞品分析的例子就是 Parallel 嵌套在 Sequential 里。再复杂一点,可以在 Sequential 的某一步放一个 LoopAgent:先并行采集 → 串行清洗 → 循环迭代优化 → 最终输出。

ADK 的工作流 Agent 本身不跑 LLM,只是调度器。开销很小,嵌套也不会增加额外的 API 调用。

实测数据

我用竞品分析场景跑了对比(3 个调研 + 1 个汇总):

模式 耗时 API 调用次数
全部 Sequential 38s 4
Parallel + Sequential 15s 4

API 调用次数一样,但并行模式快了 60%。调研任务越多,并行的优势越大。

代码生成流水线(SequentialAgent,3 步)平均耗时 12 秒,相当于 3 次 Gemini 调用的时间。没有额外开销。

LoopAgent 的文档迭代场景,平均 3.2 轮收敛,耗时 25 秒。设 max_iterations=5 从来没跑满过。

几个实用建议

调试用 include_contents='none' 默认情况下每个子 Agent 能看到完整对话历史,排查问题时很难分清 Agent 到底在看什么输入。设成 none,强制所有数据走 state,数据流一目了然。

别在 instruction 里硬编码模型特定的格式。 比如 "输出 JSON 格式"------如果下游 Agent 期望的是纯文本,中间就要加解析逻辑。让 Agent 输出自然语言,需要结构化数据时用 Pydantic + output_schema。

state key 用有意义的名字。 别用 result1、result2。当 Agent 数量超过 5 个,state 里有十几个 key 的时候,命名不清晰会直接影响可维护性。

生产环境加监控。 ADK 的 before_agent_callbackafter_agent_callback 可以在每个 Agent 执行前后插入逻辑------记日志、统计耗时、检查 state 完整性。

python 复制代码
from google.adk.agents.callback_context import CallbackContext

def log_agent_start(callback_context: CallbackContext):
    print(f"[{callback_context.agent_name}] 开始执行")
    # 也可以记录 state 快照

pipeline = SequentialAgent(
    name="Pipeline",
    sub_agents=[writer, reviewer],
    before_agent_callback=log_agent_start
)

ADK 的文档在 adk.dev,GitHub 仓库是 google/adk-python。三种工作流 Agent 加起来覆盖了大部分多 Agent 编排需求。比自己用 asyncio 手搓调度逻辑要省事很多。

相关推荐
love530love2 小时前
ComfyUI:为什么说它是 AIGC 应用层面的集大成者?
人工智能·pytorch·windows·aigc·devops·comfyui·extensions
Cobyte4 小时前
Agent Skills 系统的本质原理
前端·aigc·ai编程
码农阿强5 小时前
GPT-5.5 与 GPT-5.5-Pro 技术差异及接口接入实践
人工智能·gpt·ai·aigc·ai编程·ai写作·gpu算力
我没胡说八道5 小时前
论文AI改写工具深度实测测评|避坑对比、优劣短板、场景适配全解析
人工智能·经验分享·深度学习·aigc·论文·wps
武雄(小星Ai)5 小时前
GitHub Copilot Desktop 多 Agent 实测
人工智能·aigc·agent
冬奇Lab15 小时前
理发师会被 AI 取代吗?这可能是 AI 时代最有意思的一个社会学问题
人工智能·aigc
我是宝库16 小时前
英文专业论文,可以用维普AIGC检测查AI率吗?
人工智能·aigc·英文论文·论文查重·turnitin系统·turnitin·维普aigc检测
大拿爱科技16 小时前
低清视频修复怎么接入批处理?AI画质增强流程拆解
人工智能·自动化·aigc·音视频
后端小肥肠1 天前
漫画工坊续篇 | Coze+Skill 实现老纪漫画完整制作全流程
人工智能·aigc·agent