开发者指南:ADK 中的多代理模式

发布: (2025年12月17日 GMT+8 09:40)
13 min read

Source: Google Developers Blog

DEC. 16, 2025

软件开发领域已经吸取了这样一个教训:单体应用无法扩展。无论你是在构建大型电子商务平台,还是复杂的 AI 应用,依赖单一的“一体化”实体都会导致瓶颈、增加调试成本,并限制专门化的性能。

同样的原理也适用于 AI 代理。一个承担过多职责的单一代理会变成“样样通,样样松”。随着指令复杂度的提升,对特定规则的遵循会下降,错误率会叠加,导致越来越多的“幻觉”。如果你的代理出现故障,你不应该必须拆除整个提示来寻找 bug。

可靠性来源于去中心化和专门化。多代理系统(MAS)让你能够构建 AI 版的微服务架构。通过为各个代理分配特定角色(如 ParserCriticDispatcher),你可以构建本质上更具模块化、可测试且可靠的系统。

在本指南中,我们将使用 Google Agent Development Kit(ADK)来演示八种关键设计模式——从顺序流水线到人工在环(Human‑in‑the‑Loop)模式——提供构建生产级代理团队所需的具体模式和伪代码。

1. 顺序管道模式(又称装配线)

把这个模式想象成经典的装配线,Agent A 完成任务后直接把接力棒交给 Agent B。它是线性的、确定性的,而且调试起来非常轻松,因为你总是确切知道数据来自何处。

使用场景: 处理原始文档——Parser → Extractor → Summarizer。

Sequential pattern

在 ADK 中,SequentialAgent 原语会为你处理编排工作。关键在于状态管理:只需使用 output_key 将结果写入共享的 session.state,下一个代理就能准确知道从哪里接手工作。

# ADK Pseudocode

# Step 1: Parse the PDF
parser = LlmAgent(
    name="ParserAgent",
    instruction="Parse raw PDF and extract text.",
    tools=[PDFParser],
    output_key="raw_text"
)

# Step 2: Extract structured data
extractor = LlmAgent(
    name="ExtractorAgent",
    instruction="Extract structured data from {raw_text}.",
    tools=[RegexExtractor],
    output_key="structured_data"
)

# Step 3: Summarize
summarizer = LlmAgent(
    name="SummarizerAgent",
    instruction="Generate summary from {structured_data}.",
    tools=[SummaryEngine]
)

# Orchestrate the Assembly Line
pipeline = SequentialAgent(
    name="PDFProcessingPipeline",
    sub_agents=[parser, extractor, summarizer]
)

2. 协调者 / 调度者模式(亦称礼宾)

有时你不需要链式结构,而是需要一个决策者。在这种模式中,一个中心的、智能的代理充当调度者。它分析用户的意图,并将请求路由到最适合该任务的专职代理。

使用场景: 需要将用户转接到“账单”专员或“技术支持”专员的复杂客服机器人。

协调者‑调度者模式

这依赖于 LLM 驱动的委派。定义一个父级 CoordinatorAgent 并提供一组专职 sub_agents。ADK 的 AutoFlow 机制会根据你为子代理提供的描述来转移执行。

# ADK Pseudocode

billing_specialist = LlmAgent(
    name="BillingSpecialist",
    description="Handles billing inquiries and invoices.",
    tools=[BillingSystemDB]
)

tech_support = LlmAgent(
    name="TechSupportSpecialist",
    description="Troubleshoots technical issues.",
    tools=[DiagnosticTool]
)

# The Coordinator (Dispatcher)
coordinator = LlmAgent(
    name="CoordinatorAgent",
    instruction=(
        "Analyze user intent. Route billing issues to BillingSpecialist "
        "and bugs to TechSupportSpecialist."
    ),
    sub_agents=[billing_specialist, tech_support]
)

3. 并行 Fan‑Out / Gather 模式(又称章鱼模式)

速度至关重要。如果任务之间没有依赖,为什么要一个接一个地运行?在此模式下,多个代理同时执行任务,以降低延迟或获得多元视角。它们的输出随后由最终的“合成器”代理聚合。

使用场景: 自动代码审查——并行运行“安全审计员”、“风格强制器”和“性能分析师”,然后合并它们的反馈。

Parallel fan‑out

ADK 中的 ParallelAgent 同时运行子代理。虽然这些代理在独立的执行线程中运行,但它们共享会话状态。为防止竞争条件,请确保每个代理将数据写入唯一的键。

# ADK Pseudocode

security_auditor = LlmAgent(
    name="SecurityAuditor",
    instruction="Identify security vulnerabilities in the code.",
    tools=[StaticAnalysisTool],
    output_key="security_report"
)

style_enforcer = LlmAgent(
    name="StyleEnforcer",
    instruction="Check code style compliance.",
    tools=[Linter],
    output_key="style_report"
)

performance_analyst = LlmAgent(
    name="PerformanceAnalyst",
    instruction="Analyze performance bottlenecks.",
    tools=[Profiler],
    output_key="performance_report"
)

# Synthesizer that gathers the reports
synthesizer = LlmAgent(
    name="ReviewSynthesizer",
    instruction=(
        "Combine {security_report}, {style_report}, and {performance_report} "
        "into a single cohesive review comment."
    ),
    tools=[Summarizer],
    output_key="final_review"
)

# Parallel orchestration
parallel_review = ParallelAgent(
    name="ParallelCodeReview",
    sub_agents=[security_auditor, style_enforcer, performance_analyst],
    gather_agent=synthesizer
)

清理后的 Markdown 内容

# Define parallel workers
security_scanner = LlmAgent(
    name="SecurityAuditor",
    instruction="Check for vulnerabilities like injection attacks.",
    output_key="security_report"
)

style_checker = LlmAgent(
    name="StyleEnforcer",
    instruction="Check for PEP8 compliance and formatting issues.",
    output_key="style_report"
)

complexity_analyzer = LlmAgent(
    name="PerformanceAnalyst",
    instruction="Analyze time complexity and resource usage.",
    output_key="performance_report"
)

# Fan‑out (The Swarm)
parallel_reviews = ParallelAgent(
    name="CodeReviewSwarm",
    sub_agents=[security_scanner, style_checker, complexity_analyzer]
)

# Gather / Synthesize
pr_summarizer = LlmAgent(
    name="PRSummarizer",
    instruction=(
        "Create a consolidated Pull Request review using "
        "{security_report}, {style_report}, and {performance_report}."
    )
)

# Wrap in a sequence
workflow = SequentialAgent(sub_agents=[parallel_reviews, pr_summarizer])

4. 层次分解(又称俄罗斯套娃)

有时一个任务对单个代理的上下文窗口来说太大。高级代理可以将复杂目标拆解为子任务并进行委派。与路由模式不同,父代理可能只委派任务的一部分,并在继续自己的推理之前等待结果。

在下图中,ReportWriter 并不自行进行研究。它将工作委派给 ResearchAssistant,后者又管理 WebSearchSummarizer 工具。

层次任务分解代理

你可以把子代理当作工具来使用。通过在 AgentTool 中包装一个代理,父代理可以显式调用它,从而将子代理的整个工作流视为一次函数调用。

# ADK Pseudocode

# Level 3: Tool Agents
web_searcher = LlmAgent(
    name="WebSearchAgent",
    description="Searches web for facts."
)

summarizer = LlmAgent(
    name="SummarizerAgent",
    description="Condenses text."
)

# Level 2: Coordinator Agent
research_assistant = LlmAgent(
    name="ResearchAssistant",
    description="Finds and summarizes info.",
    # Coordinator manages the tool agents
    sub_agents=[web_searcher, summarizer]
)

# Level 1: Top‑Level Agent
report_writer = LlmAgent(
    name="ReportWriter",
    instruction=(
        "Write a comprehensive report on AI trends. "
        "Use the ResearchAssistant to gather info."
    ),
    # Wrap the sub‑agent hierarchy as a tool for the parent
    tools=[AgentTool(research_assistant)]
)

5. 生成器与批评者(亦称编辑桌)

生成高质量、可靠的输出往往需要第二双眼睛。在此模式中,你将内容的创建与其验证分离。一个代理充当 Generator(生成器),产生草稿;另一个代理充当 Critic(批评者),根据特定的硬编码标准或逻辑检查对其进行审查。

架构包含条件循环:如果审查通过,循环终止,内容最终确定;如果未通过,反馈会返回给生成器,以生成符合要求的草稿。这在需要语法检查的代码生成或需要合规审查的内容创作中尤为有用。

generator critic agent pattern

在 ADK 中的实现使用了两个原语——管理草稿与审查交互的 SequentialAgent,以及强制质量门和退出条件的父级 LoopAgent

# ADK Pseudocode

# The Generator
generator = LlmAgent(
    name="Generator",
    instruction=(
        "Generate a SQL query. If you receive {feedback}, "
        "fix the errors and generate again."
    ),
    output_key="draft"
)

# The Critic
critic = LlmAgent(
    name="Critic",
    instruction=(
        "Check if {draft} is valid SQL. If correct, output 'PASS'. "
        "If not, output error details."
    ),
    output_key="feedback"
)

# The Loop
loop = LoopAgent(
    name="ValidationLoop",
    sub_agents=[generator, critic],
    condition_key="feedback",
    exit_condition="PASS"
)

Source:

6. 迭代细化(又称雕刻师)

伟大的作品很少在一次草稿中完成。正如人类作者会反复修改、润色和编辑,代理也有时需要多次尝试才能把答案做到尽善尽美。在这种模式中,代理进入一个生成、批评、细化的循环,直到输出达到特定的质量阈值。

不同于 Generator‑and‑Critic 模式侧重二元的通过/未通过,这种模式强调定性改进。Generator 生成粗稿,Critique Agent 提供优化建议,Refinement Agent 根据这些建议对输出进行润色。

迭代细化代理模式 (1)

该模式使用 LoopAgent 实现。关键在于退出机制。虽然可以通过 max_iterations 设置硬上限,ADK 也允许代理在达到质量阈值时提前结束。代理可以在其 EventActions 中将 escalate=True,从而触发退出。

# ADK Pseudocode

# Generator
generator = LlmAgent(
    name="Generator",
    instruction="Generate an initial rough draft.",
    output_key="current_draft"
)

# Critique Agent
critic = LlmAgent(
    name="Critic",
    instruction=(
        "Review {current_draft} and provide improvement suggestions. "
        "If the draft meets quality standards, set {feedback} to 'PASS'."
    ),
    output_key="feedback"
)

# Refinement Agent
refiner = LlmAgent(
    name="Refiner",
    instruction=(
        "Incorporate the suggestions from {feedback} into the draft "
        "and output the refined version."
    ),
    output_key="refined_draft"
)

# Loop Agent
refinement_loop = LoopAgent(
    name="IterativeRefinementLoop",
    sub_agents=[generator, critic, refiner],
    condition_key="feedback",
    exit_condition="PASS",
    max_iterations=5   # optional hard limit
)

LLM Agent 示例

critic = LlmAgent(
    name="Critic",
    instruction="Review {current_draft}. List ways to optimize it for performance.",
    output_key="critique_notes"
)

# Refiner Agent 
refiner = LlmAgent(
    name="Refiner",
    instruction="Read {current_draft} and {critique_notes}. Rewrite the draft to be more efficient.",
    output_key="current_draft"   # Overwrites the draft with a better version
)

# The Loop (Critique → Refine)
loop = LoopAgent(
    name="RefinementLoop",
    max_iterations=3,
    sub_agents=[critic, refiner]
)

# Complete Workflow
workflow = SequentialAgent(sub_agents=[generator, loop])

7. Human‑in‑the‑Loop(人类安全网)

AI 代理功能强大,但在关键决策时有时需要人类掌舵。在此模型中,代理负责基础工作,而人类必须授权高风险操作——尤其是那些不可逆或可能产生重大后果的操作(例如执行金融交易、将代码部署到生产环境,或处理敏感数据)。这可确保安全性和问责制。

图示展示了一个 Transaction Agent 处理日常工作。当需要进行高风险检查时,它会调用 ApprovalTool Agent,该代理会暂停执行并等待人类审阅者给出 “是” 或 “否” 的指示。

human‑in‑the‑loop pattern

ADK 允许您通过自定义工具实现此功能。代理可以调用 approval_tool,该工具会暂停执行或触发外部系统请求人工干预。

# ADK Pseudocode
transaction_agent = LlmAgent(
    name="TransactionAgent",
    instruction="Handle routine processing. If high stakes, call ApprovalTool.",
    tools=[ApprovalTool]
)

approval_agent = LlmAgent(
    name="ApprovalToolAgent",
    instruction="Pause execution and request human input."
)

workflow = SequentialAgent(sub_agents=[transaction_agent, approval_agent])

8. 组合模式(混搭)

现实世界的企业应用很少只适合单一模式。您可能会将这些模式组合起来构建生产级系统。

例如,一个强大的 客户支持 系统可能使用 协调者 来路由请求。如果用户遇到技术问题,该分支可以触发 并行 搜索文档和用户历史记录。最终答案可能会通过 生成器 → 批评者 循环,以确保语气一致性,然后发送给用户。

composite agent pattern

开始前的几个专业提示

  • 状态管理至关重要: 在 ADK 中,session.state 就是你的白板。使用描述性的 output_key 值,以便下游代理能够准确了解它们读取的内容。
  • 描述要清晰: 使用路由时,你的子代理的 description 字段相当于 LLM 的 API 文档。请务必精准。
Back to Blog

相关文章

阅读更多 »