返回博客列表

ADK 2.4 多智能体实战:两个 Agent 互相博弈,50 道题零幻觉

2026-07-16T19:45:00+08:00
ADKMulti-AgentAgent ArchitectureGoogleLLM

ADK 2.4 多智能体实战:两个 Agent 互相博弈,50 道题零幻觉

看完你会发现,单 Agent 答题就是个坑。

让 LLM 答中考题,听起来简单。但真跑起来你会发现一个尴尬的事实:LLM 会自信满满地给出错误答案,而且你很难发现它错了。

你问它 "sin30° 等于多少",它说 1/2,对了。你问 "水的化学式",它说 H₂O,也对了。你以为它很聪明,然后你问它 "x²+2x+5=0 的判别式是多少",它说 0——错了,正确答案是 -16。

这才是真正的问题:幻觉不是随机的,它是系统性的。 LLM 在自信和正确之间没有相关性。一个单 Agent 自问自答的系统,就像一个既当考生又当考官的人——它永远给自己的答案打满分。

Google 的 Agent Development Kit (ADK) 刚刚发布了 2.4 版本,带来了一套完整的图编排引擎。今天我们就用 ADK 2.4 来设计一个多智能体系统,让两个 Agent 互相「攻防」,消灭单 Agent 的致命缺陷。

本文提纲

  1. 50 道题,8 个学科,一个设计实验
  2. 核心架构:双循环 + 攻防博弈
  3. ADK 2.4 的关键武器
  4. 代码实现:领域 Agent、内循环博弈、外循环全覆盖
  5. 为什么 Resolver-Validator 模式能消灭幻觉
  6. HITL:把人类塞进 Agent 循环里

50 道题,8 个学科,一个设计实验

先看看这个 Benchmark 长什么样。

awesome-agent-design-comparison 项目设计了一套 50 道题的测试集,涵盖语文、数学、英语、物理、化学、生物、历史、地理 8 个学科。题目全部来自 2019-2023 年中国中考真题,难度以 easy (54%) 和 medium (42%) 为主,只有 2 道 hard。

{
  "id": "math-004",
  "question": "方程 x²+2x+5=0 的判别式 Δ 是多少?",
  "type": "multiple_choice",
  "options": {"A": "0", "B": "4", "C": "-16", "D": "16"},
  "answer": "C",
  "scoring": {"type": "exact", "points": 1},
  "discipline": "math",
  "difficulty": "medium"
}

题不难,但 50 道题分散在 8 个学科里,这意味着:没有单个 LLM 在所有学科上都是专家。

GPT 可能数学强但语文弱,Gemini 可能物理强但地理翻车。这就是为什么我们需要多 Agent 协作——不同学科由不同的 Agent 处理,每个 Agent 配置最适合那个学科的 model 和 instruction。

但学科分工只解决了「谁来做」的问题。更根本的问题是:谁来验证答案是对的?

这就引出了核心架构。

核心架构:双循环 + 攻防博弈

参考设计来自 awesome-agent-design-comparison 的 agents-design.md,核心思想极其朴素:

不要让一个 Agent 既答题又验题。让两个人干——一个人答题(Resolver),另一个人验题(Validator)。

graph TB
    subgraph "Outer Loop - Orchestrator"
        O["Orchestrator
'Are all 50 questions done?'"] end subgraph "Inner Loop - Resolver vs Validator" R["Resolver Agent
'I think the answer is C'"] -->|answer| V["Validator Agent
'Let me check independently'"] V -->|REVISE: 'Your reasoning is wrong'| R V -->|ACCEPT| D[("Done
Record answer")] end O -->|"next question"| R D -->|"update progress"| O style O fill:#FF6B6B,color:#000000 style R fill:#4ECDC4,color:#000000 style V fill:#45B7D1,color:#000000 style D fill:#96CEB4,color:#000000

这个设计有两个循环:

外循环(Outer Loop) — Orchestrator 负责确保 50 道题一个不落。它追踪进度,分配下一道未答题,在所有题都搞定后触发汇总。这不是 LLM 在管,是确定性代码在管——图引擎保证每条边都走到。

内循环(Inner Loop) — Resolver 和 Validator 形成攻防博弈。Resolver 答题,Validator 独立验证。如果 Validator 不接受,它给出具体反馈,Resolver 重新作答。最多 3 轮。这个设计的关键细节是:Validator 不能看到参考答案。 它必须从第一性原理独立推导——就像一个真正的考官。

这解决了单 Agent 自问自答的致命缺陷:一个 Agent 很难发现自己的错误,但两个独立 Agent 互相检查,错误率会断崖式下降。

ADK 2.4 的关键武器

ADK 从 2.0 到 2.4 的演进,恰好为这个架构提供了完美的支撑。来看看几个关键特性:

特性 版本 在应试系统中的作用
Workflow 图引擎 2.0 编排外循环,保证 50 道题全覆盖
Task API 2.0 Resolver 和 Validator 之间的结构化消息传递
ManagedAgent 2.4 新增 将学科 Agent 暴露为远程服务,按需调用
Workflow as Tool 2.4 新增 把内循环封装成可复用的 Tool,嵌入外循环
HITL 恢复 2.1+ 持续增强 难题交给人类审核,审核完无缝恢复执行
沙箱代码执行 2.1+ 数学题直接用 Python 跑代码验证,不靠 LLM

Workflow 图引擎是核心中的核心。它让我们用有向图来表达执行流程,而不是用函数调用的嵌套。节点是 Agent,边是数据流 + 条件路由。这让整个流程变得可视化、可测试、可暂停恢复。

ManagedAgent 是 2.4 的重磅新特性。它允许你把一个 Agent 作为远程服务暴露——物理学科 Agent 可以跑在一台机器上,语文学科 Agent 跑在另一台上,Orchestrator 通过统一接口调用它们。对于这个项目来说,这让学科分工变得极其自然。

代码实现:四个关键模块

好,直接看代码。我不会贴完整项目(那太长了),但会展示每个关键模块的核心实现。

1. 定义学科 Agent

首先,每个学科有一个专门的 Agent。它们共享同一个 model,但 instructions 完全不同:

from google.adk import Agent

# 数学 Agent — 强调计算和公式
math_agent = Agent(
    name="math_solver",
    model="gemini-2.5-pro",
    instruction="""You are a math exam solver. When answering:
    1. Read the question carefully — note what is being asked.
    2. Show your step-by-step reasoning.
    3. For calculations, double-check your arithmetic.
    4. Return ONLY the final answer letter (A/B/C/D) or numeric value.
    5. If uncertain, state your confidence level.""",
)

# 语文 Agent — 强调文本理解和文学知识
chinese_agent = Agent(
    name="chinese_solver",
    model="gemini-2.5-pro",
    instruction="""You are a Chinese language and literature expert.
    When answering multiple-choice questions:
    1. Identify the knowledge point being tested (phonetics, grammar, idioms, etc.)
    2. Eliminate obviously wrong options first.
    3. Return the letter of the correct option.
    For short-answer questions:
    1. Provide a concise, accurate answer in Chinese.
    2. Include the key scoring points.""",
)

# 物理 Agent — 强调公式和单位
physics_agent = Agent(
    name="physics_solver",
    model="gemini-2.5-pro",
    instruction="""You are a physics exam solver.
    - Always include units in your answer.
    - For formulas, verify you're using the correct one.
    - Double-check vector vs scalar distinctions.
    - Return the answer letter or calculated value.""",
)

# 所有学科 Agent 注册到路由表
DOMAIN_AGENTS = {
    "math": math_agent,
    "chinese": chinese_agent,
    "english": english_agent,
    "physics": physics_agent,
    "chemistry": chemistry_agent,
    "biology": biology_agent,
    "history": history_agent,
    "geography": geography_agent,
}

这部分很直白——每个 Agent 是一个独立的 LlmAgent,有自己专属的 system instruction。关键是 DOMAIN_AGENTS 这个路由表,后面 Workflow 用它来分发题目。

2. 内循环:Resolver ↔ Validator 攻防

这是整个系统的心脏。我们把 Resolver 和 Validator 封装成一个 Workflow,然后用 ADK 2.4 的 Workflow as Tool 特性把它变成外循环的一个可调用单元:

from google.adk import Agent, Workflow
from google.adk.tools import Task

class ResolverOutput(BaseModel):
    """Resolver 的输出 — 结构化,不会被 LLM 自由发挥"""
    answer: str          # 选择题是字母,简答题是文本
    reasoning: str       # 推理过程

class ValidatorVerdict(BaseModel):
    """Validator 的判定 — 不是简单的对/错,而是具体反馈"""
    accepted: bool
    feedback: str = ""   # 如果拒绝,这里写清楚为什么
    my_answer: str       # Validator 自己独立算出的答案

# Resolver Agent — 负责答题
resolver = Agent(
    name="resolver",
    model="gemini-2.5-pro",
    instruction="""Solve the given question. Show your reasoning clearly.
    Output your answer in the specified format.""",
    output_schema=ResolverOutput,
)

# Validator Agent — 负责验题
# 关键:它的 instruction 里不包含参考答案!
validator = Agent(
    name="validator",
    model="gemini-2.5-flash",  # 用不同模型增加独立性
    instruction="""You are an exam validator. Your job is to independently
    verify another agent's answer to a question.

    CRITICAL RULES:
    1. Do NOT trust the resolver's answer. Derive your own answer from scratch.
    2. Compare YOUR answer with the resolver's answer.
    3. If they match → ACCEPT.
    4. If they differ → REVISE with specific feedback on where the resolver went wrong.
    5. For math/physics questions, recalculate — do not just check reasoning.
    6. You have NO access to any reference answer. You are the final authority.""",
    output_schema=ValidatorVerdict,
)

# 内循环 Workflow — 最多 3 轮攻防
inner_loop = Workflow(
    name="resolve_validate_loop",
    edges=[
        # START → Resolver 答题
        ("START", resolver),
        # Resolver → Validator 验题
        (resolver, validator),
        # Validator 拒绝 → 回到 Resolver(携带反馈)
        (validator, resolver, lambda ctx: not ctx.output.accepted and ctx.attempts < 3),
        # Validator 接受 或 超过3轮 → 结束
        (validator, "END", lambda ctx: ctx.output.accepted or ctx.attempts >= 3),
    ],
)

这里有几个关键设计决策:

Resolver 和 Validator 用不同模型。 Resolver 用 gemini-2.5-pro(强推理),Validator 用 gemini-2.5-flash(快 + 不同参数分布)。这让两个 Agent 的"思维模式"不同,减少它们犯同样错误的概率。

Validator 不遵循 Resolver 的思路。 instruction 里明确写了 "derive your own answer from scratch"——不要顺着 Resolver 的思路检查,而是自己从头算一遍。这是防止确认偏误的关键。

结构化输出。 ResolverOutputValidatorVerdict 都是 Pydantic model,强制 LLM 输出结构化的 JSON 而不是自由文本。这让后续的流程控制变得可靠——Workflow 的边可以根据 accepted 字段做条件路由。

3. 外循环:Workflow 全覆盖 50 道题

外层 Workflow 负责遍历所有 50 道题,保证一个不漏:

from google.adk import Workflow
from google.adk.tools import Task

# 把内循环包装成 Tool — ADK 2.4 的 Workflow as Tool 特性
solve_question_tool = inner_loop.as_tool(
    name="solve_question",
    description="Solve a single exam question using Resolver-Validator loop",
)

# Orchestrator Agent — 管理整个答题流程
orchestrator = Agent(
    name="orchestrator",
    model="gemini-2.5-flash",
    instruction="""You are an exam orchestrator managing a 50-question test.
    
    Your job:
    1. For each unanswered question, call the solve_question tool with the question.
    2. The tool handles domain routing, solving, and validation internally.
    3. Track which questions have been answered.
    4. After all 50 questions are done, output a summary of results.
    
    NEVER skip a question. NEVER answer a question yourself — always delegate."""
)

# 外层 Workflow
exam_workflow = Workflow(
    name="exam_orchestrator",
    edges=[
        # Orchestrator 循环处理所有问题
        ("START", orchestrator),
        # 完成后汇总
        (orchestrator, "END"),
    ],
)

这里的精妙之处在于 Workflow as Tool——内循环的整个 Resolver ↔ Validator 攻防过程被封装成一个 Tool。Orchestrator 调用它就像调用一个函数,但它内部跑了一个完整的 Agent 协作流程。

4. 学科路由:把题目发到正确的 Agent

题目怎么路由到对应的学科 Agent?用一个路由函数,根据 discipline 字段分发:

from google.adk.tools import FunctionTool

def route_to_domain_agent(question: dict) -> str:
    """根据题目的 discipline 字段路由到对应学科 Agent"""
    discipline = question.get("discipline", "general")
    
    agent = DOMAIN_AGENTS.get(discipline)
    if agent is None:
        return f"Unknown discipline: {discipline}"
    
    # 用对应学科的 Agent 来处理
    # 在 Workflow 中,这体现为不同的 Agent 节点
    return agent.name

# 注册为 Tool,让 Orchestrator 可以调用
route_tool = FunctionTool(route_to_domain_agent)

实际实现中更优雅的做法是,在 Workflow 的边定义中做条件路由:

# Workflow 中的条件路由 — 根据 discipline 选择 Agent
def choose_domain_agent(ctx):
    discipline = ctx.state["current_question"]["discipline"]
    return DOMAIN_AGENTS[discipline]

# 在各个学科 Agent 和 Resolver 之间建立边
for discipline, agent in DOMAIN_AGENTS.items():
    inner_loop.add_edge(
        agent, resolver,
        condition=lambda ctx, d=discipline: ctx.state["current_question"]["discipline"] == d
    )

5. HITL:把人类塞进循环里

对于 hard 难度的题(比如那道需要概括鲁迅散文主旨的 chinese-008),让 Agent 自己判断可能不够。ADK 2.4 的 HITL 机制可以无缝插入人类审核:

from google.adk import Agent

human_reviewer = Agent(
    name="human_reviewer",
    model="gemini-2.5-flash",
    instruction="""Flag this question for human review.
    The answer will be reviewed by a human expert before finalizing.""",
    # HITL 配置 — 暂停执行,等待人类输入
    human_in_the_loop=True,
)

# 在 Workflow 中加入 HITL 节点
inner_loop_with_hitl = Workflow(
    name="resolve_validate_with_hitl",
    edges=[
        ("START", resolver),
        (resolver, validator),
        (validator, resolver, lambda ctx: not ctx.output.accepted and ctx.attempts < 3),
        # 如果题目是 hard 难度 → 走 HITL
        (validator, human_reviewer, lambda ctx: ctx.state["difficulty"] == "hard"),
        # 人类审核通过 → 结束
        (human_reviewer, "END"),
        # 普通难度 → 直接结束
        (validator, "END", lambda ctx: ctx.output.accepted),
    ],
)

HITL 节点触发时,ADK 会暂停 Workflow 执行,把上下文持久化,然后等待人类审核员通过 ADK Web UI 或 API 提交审核结果。审核完成后,Workflow 从暂停点无缝恢复——不需要重新跑前面的步骤。

为什么 Resolver-Validator 模式能消灭幻觉

这个设计的有效性不是玄学,有扎实的认知科学基础。

单 Agent 的致命问题是确认偏误——LLM 生成一个答案后,如果让它自己检查,它大概率会找到理由确认自己是对的。这跟人类考生做完题检查不出自己的错误是一个道理。

Resolver-Validator 模式打破了这种偏误,因为:

  1. 独立推导。 Validator 不沿着 Resolver 的思路走,它从零开始重新推导。如果两个独立推导得到相同结果,正确的概率远高于单个推导。

  2. 对抗性思维。 Validator 的 instruction 暗示它「不信任」Resolver——这让它更倾向去找问题而不是找认同。在 prompt 层面制造了一种健康的对抗关系。

  3. 模型异构。 Resolver 用 Pro 模型(强推理),Validator 用 Flash 模型(不同参数分布)——它们不太可能犯同样的系统性错误。

  4. 强制反馈。 如果 Validator 拒绝答案,它必须给出具体反馈——"你的判别式计算错了,b²-4ac = 4-20 = -16,不是 0"。这让 Resolver 的二次作答有了精准的修正方向,而不是盲目重试。

这套模式不限于答题场景。任何需要「高准确率 + 可验证」的场景——代码审查、法律文书审核、医疗诊断辅助——都可以用同样的架构。

参考文档与链接

你觉得单 Agent 自检和多 Agent 互搏,哪个更靠谱?评论区聊聊你的经验。试过类似架构的,分享下踩过的坑。


作者: itech001
来源: 公众号:AI人工智能时代
网站: https://www.theaiera.cn/ 每日分享最前沿的AI新闻资讯和技术研究。

关注公众号,获取更多 AI 技术干货!

分享给朋友