返回博客列表

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 的思路检查,而是自己从头算一遍。这是防止确认偏误的关键。

结构化输出。 ResolverOutput 和 ValidatorVerdict 都是 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人工智能时代(the-ai-era) 网站: https://www.theaiera.top/ 关注每日最新AI新闻和技术博客,主页有更多的文章的AI 技术参考:https://www.theaiera.top

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

分享给朋友