AgentDropoutV2: Optimizing Information Flow in Multi-Agent Systems via Test-Time Rectify-or-Reject Pruning

Paper: arXiv:2602.23258 Code: TonySY2/AgentDropoutV2 Code reference: main @ 8790f010 (2026-05-27)

1. Motivation(研究动机)

现有 Multi-Agent Systems(MAS)在复杂数学推理和代码生成中常用多个角色互相补充,但它们的通信往往是全局广播或固定路由:一名 agent 的错误中间结论会进入其他 agent 的上下文,后续 agent 很容易把它当作事实继续推理,形成 cascading error。AgentDropout 这类早期 pruning 思路可以直接丢弃可疑 agent,但“只 reject、不 rectify”会损失本来可修复的信息;结构工程式地改变拓扑或重新 fine-tune agent 又代价高、迁移差。

这篇论文要解决的具体问题是:在不重新训练 base agents 的前提下,如何在 test time 拦截 MAS 中每条待广播的信息,先尝试用可验证的错误模式进行修正,修不好再剪枝,并在剪枝过多时恢复系统完整性。 也就是说,目标不是训练更强单体模型,而是让一个已有 AutoGen/SelectorGroupChat 式 MAS 的信息流更干净。

这个问题值得研究,因为 MAS 的优势来自多 agent 共享中间状态;如果共享通道被错误污染,增加 agent 数量反而可能放大噪声。AgentDropoutV2 把“错误传播控制”做成 test-time firewall:既保留 MAS 的协作结构,又避免把明显有问题的输出继续广播给下游。论文在数学 benchmarks 上报告相对 AutoGen 平均提升约 个百分点,说明这种信息流治理可以直接转化成 task accuracy。

2. Idea(核心思想)

核心 insight 是:MAS 中很多错误并不是随机噪声,而是会反复出现的 failure pattern;这些 pattern 可以被离线蒸馏成 indicator pool,在 test time 作为“可检索的审计规则”指导 agent 局部修正。 因此 AgentDropoutV2 不只问“这个 agent 要不要被丢掉”,而是先问“当前输出可能触发哪些已知错误类型、能否按反馈修好”。

关键创新可以概括为三点:第一,构建 failure-driven indicator pool,把历史失败轨迹中的错误定义和触发条件保存为可检索知识;第二,在每个 agent 输出被广播前,用 rectifier 检索相关 indicators 并产生 violation flag 与诊断反馈;第三,采用 Pass / Retry / Reject 三态门控,修正成功就保留,超过迭代预算仍错误就剪掉,若剪枝后剩余消息数低于阈值则 fallback 到原 MAS。

与 AgentDropout 的本质差异是:AgentDropout 偏向“发现错误后直接删除 agent/output”,AgentDropoutV2 在删除前加入 retrieval-augmented rectification。与普通 self-reflection 的差异是:它不是让 agent 泛泛“再想一遍”,而是用历史 failure indicators 规定检查维度,降低无方向反思带来的 hallucination 或 over-correction。

3. Method(方法)

3.1 MAS 信息流形式化

论文先把 MAS 写成一个有序 agent 序列 。每个 agent 由 backbone model 、role specification 和可观察 message history / knowledge base 组成。给定输入 ,agent 输出为: 输出如何传播由拓扑映射 控制;当 产出 后,所有 successor 的知识库更新为: 控制流由 routing policy 决定下一名活跃 agent: 这个形式化的作用是明确 AgentDropoutV2 的插入点:它不改写 ,而是在 写入其他 agent 的 之前做拦截、审计、修正或剪枝。

Figure 1 解读:图中对比 AgentDropout 和 AgentDropoutV2。前者在发现错误后直接 eliminated;后者先进入 Rectify 循环,只有在多轮反馈后仍无法通过审计才 reject。因此它减少了“可修复信息被过早删除”的风险,也减少了错误消息继续广播的风险。

3.2 整体框架:test-time pipeline + offline indicator pool

Figure 2 解读:上半部分是 test-time rectify-or-reject pipeline:agent 生成输出后,supervisor/rectifier 根据当前任务和输出检索 active indicators,判断是否违反;若违反则把诊断反馈交回原 agent 重新生成,直到通过或达到 。下半部分是 offline pool construction:从失败 MAS trajectories 中抽取错误模式,再通过 embedding retrieval + LLM dedup 得到紧凑 indicator pool。直观上,离线池像“组织记忆”,在线 rectifier 像“基于历史事故清单的安全审计”。

AgentDropoutV2 的 intuition 是:如果错误模式可复用,那么 rectifier 不需要理解所有可能错误,只要能把当前输出映射到若干高相关 indicators,再按这些 indicators 给出 actionability 强的反馈。这样 feedback 比普通 self-reflection 更具体,且 indicator retrieval 只在当前 agent output 的局部上下文上工作,不需要重新训练 MAS。

3.3 Relevant Indicator Retrieval

每个 indicator 是三元组 是错误类型名称, 是 error definition, 是 trigger condition。对第 轮输出 ,rectifier 先提取两个 keyword sets:任务场景 和 agent action ,再用 embedding model 得到查询向量: 随后按 trigger condition embedding 的 cosine similarity 检索 Top- 这里的关键是检索条件不是整段输出相似度,而是“场景 + 动作”到 indicator trigger 的匹配;这让同一个错误定义只在相关上下文中触发。

3.4 Rectify-or-Reject 三态门控

对每个 active indicator ,rectifier 输出 binary violation flag 和诊断理由: 其中 表示违反该 indicator。论文采用 zero-tolerance 聚合:只要任一 indicator 检出错误,全局 error state 就激活;反馈集合只保留触发错误的 rationale: 门控有三种结果:若 ,直接 Pass 并广播 ;若 ,原 agent 带着反馈重新生成: 若到 仍不通过,则 Reject 并令 。最终传递给 successor 的消息是: 剪枝会带来另一个风险:如果保留下来的消息太少,MAS 共识结构会退化。因此论文设置 safety threshold ,当 remaining message count 低于阈值时触发 global fallback,重新走无剪枝的原 MAS,而不是从过稀疏上下文里强行决策。

3.5 Failure-Driven Indicator Pool Construction

离线阶段从 source dataset 出发,对每个样本运行完整 MAS,得到 trajectory 。若最终答案 与 ground truth 不一致,该轨迹进入 failure set 。teacher model 检查失败轨迹中的单个 agent 输出并生成新 indicators: 直接累积 indicators 会导致池子被同质错误占满,所以作者使用 dual-stage deduplication:先把新 indicator 的 definition 和 trigger condition 拼接后 embedding,检索最相似的已有 indicators;再让 dedup LLM 判断它是否代表新的错误模式。形式化为: 若没有训练数据构造 domain-specific pool,论文提供 zero-shot fallback:使用通用 indicator ,其中 总是触发。这对应实验中的 w/ Generic Indicators。

3.6 Released code 中的实现细节与差异

Code reference: main @ 8790f010 (2026-05-27) — pseudocode and mapping based on this commit

论文公式与 released code 实现差异:论文主公式把 写成对 trigger embeddings 的 Top- cosine retrieval;released math main preset configs/release_experiments.json 实际设置为 retrieval_mode="rerank", retrieve_p=20, select_q=5, batch_audit_metrics=true, pass_rate=0.6,即先 embedding top-20,再由 LLM rerank 到最多 5 个 indicators。code-domain main preset 则是 retrieval_mode="direct", direct_k=3, pass_rate=1.0。另一个细节是论文实验设置写 ,但 released dedup script train/Extraction-deduplication-embedding.py 在 duplicate check 中取 k=min(15, len(self.unique_pool))

def retrieve_indicators(supervisor, task: str, agent_output: str):
    summary = supervisor.llm_extract_keywords(task, agent_output)  # problem_scenario + agent_action
    query_text = "Problem Scenario: " + ", ".join(summary["problem_scenario"])
    query_text += ". Agent Action: " + ", ".join(summary["agent_action"])
    query_emb = supervisor.embedding_client.embed(query_text)
 
    if supervisor.retrieval_mode == "random":
        return random_sample(supervisor.metrics, k=supervisor.random_k)
 
    if supervisor.retrieval_mode == "rerank":
        candidates = cosine_topk(supervisor.indicator_embeddings, query_emb, k=supervisor.retrieve_p)
        return supervisor.llm_rerank(task, agent_output, candidates, select_q=supervisor.select_q)
 
    return cosine_topk(supervisor.indicator_embeddings, query_emb, k=supervisor.direct_k)
async def audit_and_rectify(agent, supervisor, task: str, initial_prompt: list[dict], max_retries: int):
    conversation = list(initial_prompt)
    for attempt in range(max_retries + 1):
        output = await agent.reasoning_model.chat(conversation, temperature=0.7)
        indicators = await supervisor.match_metrics(task, output)
        judgements = await supervisor.audit_batch(task, output, indicators, temperature=0.0)
        pass_rate = sum(j.verdict == "correct" for j in judgements) / max(1, len(judgements))
        if pass_rate >= supervisor.pass_rate:
            return output, judgements
        feedback = supervisor.build_feedback(judgements)
        if attempt < max_retries:
            conversation += [{"role": "assistant", "content": output}, {"role": "user", "content": feedback}]
    return output, judgements  # caller may prune it if final judgements still fail
async def run_mas_with_rectify_or_reject(team, supervisor, question: str, decision_maker):
    await team.reset()
    supervisor.reset()
    supervisor.prune_flag = True
    await team.run_stream(task=question)
    retained_messages = supervisor.get_messages_above_threshold()
 
    if len(retained_messages) <= 1:  # released math/code launchers hard-code gamma=1 behavior
        await team.reset()
        supervisor.reset()
        supervisor.prune_flag = False
        await team.run_stream(task=question)
        retained_messages = supervisor.get_messages_above_threshold()
 
    return await decision_maker.run_decision(history_messages=retained_messages, task=question)
async def build_indicator_pool(raw_failure_metrics, deduplicator, embedder):
    unique_pool = []
    for metric in raw_failure_metrics:
        definition = metric["detailed_definition"] + "\n" + metric["evaluator_prompt"]["trigger_condition"]
        metric_embedding = await embedder(definition)
        neighbors = cosine_topk([m["def_embedding"] for m in unique_pool], metric_embedding, k=15)
        is_duplicate = await deduplicator.check_same_error(metric, neighbors, temperature=0.0)
        if not is_duplicate:
            metric["def_embedding"] = metric_embedding
            unique_pool.append(metric)
    trigger_embeddings = [await embedder(m["evaluator_prompt"]["trigger_condition"]) for m in unique_pool]
    return unique_pool, trigger_embeddings
Paper ConceptSource FileKey Class/Function
Public launcher / reproducible presetstest/run_release_experiment.py, configs/release_experiments.jsonmaps benchmark + method preset to scripts; fills metric pools, max_turns, endpoint/model args
Test-time MAS run and fallbacktest/experiments/gsm8k/run_gsm8k.py, similar test/experiments/*/run_*.pyinit_team, reasoning; runs SelectorGroupChat, toggles supervisor.prune_flag, fallback when retained messages <=1
Indicator retrieval and auditingtest/AgentDropout/agents/supervisor_reasoning_pick_metric.pySupervisor._match_metrics, _top_metric_candidates, _rerank_metrics, _calc_score_batch, judge
Agent-side iterative rectificationtest/AgentDropout/agents/math_solver.pyMathSolver.on_messages_stream; loops reflection_time + 1, appends supervisor feedback
Code-domain participantstest/AgentDropout/agents/code_writing.py, test/experiments/humaneval/run_humaneval.pycode agents, internal tests, code-domain supervisor hookup
Indicator pool construction / deduptrain/Extraction-deduplication-embedding.pyDeduplicationPipeline.check_duplicate_llm, process, trigger embedding generation
Released pools and cached embeddingstest/metrics_pool/two_pool/*.json, test/metrics_pool/code_mixed/*.jsonmath deduped/nondedup pools; code mixed pool

4. Experimental Setup(实验设置)

Benchmarks and scale. 数学域包含 GSM8K 1,319、MATH-500 500、AQuA 254、AMC23 40、OlympiadBench 675、OlymMATH Easy 100、OlymMATH Hard 100、AIME24 30、AIME25 30。论文 Appendix Table 5 的一行把最后一个测试集也写成 AIME24;结合正文 benchmark list 与 main table,应理解为 AIME25。代码域包含 MBPP 257、HumanEval 161、CodeContests 165、LiveCodeBenchV1 400。indicator pool construction 使用 MATH 2,000 和 AQuA 2,000 的训练样本,数学 indicator pool 大小为 2,000。

Baselines. 数学主表比较 Single、AutoGen、w/ Generic Indicators、w/ Retrieved Indicators。Single 是单 agent;AutoGen 是 SelectorGroupChat 下的动态 MAS baseline;Generic Indicators 是没有 domain-specific pool 时的通用 audit;Retrieved Indicators 是完整 AgentDropoutV2。Qwen3-4B transfer 表沿用同一组数学 baselines。代码表比较 Single、AutoGen、w/ Generic Indicators。

Models, metrics, and hyperparameters. 论文使用 GPT-4.1-mini-2025-0414 作为 AutoGen selector;reasoning participants 和 rectifier 使用 Qwen3-8B / Qwen3-4B,thinking mode disabled;offline teacher 使用 GPT-4o-2024-08-06,deduplicator 使用 GPT-4.1-mini-2025-0414;embedding model 为 Qwen3-Embedding-8B。指标是各 benchmark 的 accuracy / pass rate(代码域为通过测试的 accuracy)。论文写 SelectorGroupChat max chat turns 为 6、、rectifier temperature 0、其他 agents temperature 0.7;硬件/GPU 信息论文未详细说明。

Released-code launch config. 实际 release 配置在 configs/release_experiments.jsonadv2_math_main 使用 math_deduped pool、retrieval_mode="rerank"retrieve_p=20select_q=5batch_audit_metrics=truepass_rate=0.6retries_times=3adv2_code_main 使用 code_mixed pool、retrieval_mode="direct"direct_k=3pass_rate=1.0retries_times=3。同一配置中大多数 math/code benchmarks 的 max_turns=7,OlympiadBench 为 max_turns=10,这与正文“max chat turns 6”不完全一致,说明 released launcher 以 benchmark-specific max-turns 覆盖运行。

5. Experimental Results(实验结果)

Main math results with Qwen3-8B. 完整 w/ Retrieved Indicators 在 9 个数学 benchmarks 上平均 ,高于 Single 和 AutoGen 。逐项结果为:GSM8K 91.74、MATH-500 78.40、AQuA 87.01、AMC23 75.00、OlympiadBench 51.11、OlymMATH Easy 25.00、OlymMATH Hard 19.00、AIME24 40.00、AIME25 30.00。Generic Indicators 平均 ,说明仅加入 rectify-or-reject 结构就有明显收益;Retrieved Indicators 进一步到 ,尤其 AIME25 从 Generic 的 23.33 提高到 30.00。

Cross-model transfer. 把 Qwen3-8B 构造的 indicator pool 直接迁移到 Qwen3-4B 后,w/ Retrieved Indicators 平均 ,高于 Single 、AutoGen 、Generic 。这表明一部分 failure pattern 具有跨模型可迁移性,但提升幅度小于 8B 主设置;论文解释为复杂任务上 high-level indicators 与较弱模型的基础错误之间存在轻微 misalignment。

Code-domain generalization. 代码域 w/ Generic Indicators 平均 ,高于 Single 和 AutoGen 。具体为 MBPP 68.09、HumanEval 84.50、CodeContests 9.26、LiveCodeBench 32.75;其中 CodeContests 从 AutoGen 6.06 到 9.26,LiveCodeBench 从 29.25 到 32.75,说明 rectify-or-reject 不只适用于数学,也能迁移到有严格 correctness 检查的代码生成任务。

Ablations. 默认完整系统平均 。取消 rectification(0 Iterations)降到 ;2 Iterations 为 ;4 Iterations 为 ,说明过多轮数可能带来 over-correction 或噪声。改变 retrieved indicator 数量也会降低性能:3 indicators 为 ,8 indicators 为 ,支持默认 5 个 active indicators 的平衡。把语义检索替换为 random 5 indicators 平均仅 ,甚至低于 0 Iterations,说明 indicator relevance 是关键。去掉 pool dedup 平均 ,验证冗余 indicators 会挤占 top-k 检索位置,降低多维检查覆盖。

Figure 3 解读:饼图展示不同 benchmark 的通过轮次与 rejected 比例。GSM8K 等简单任务有较高 Pass @ 1st(论文给出 GSM8K 60.1%),而 AIME24/25 等复杂任务有更多多轮 rectification 和超过 60% 的 rejection。这说明 rectification depth 本身也可作为任务难度 proxy:简单题少干预,复杂题更多审计或拒绝。

Figure 4 解读:heatmap 统计不同 benchmarks 的 top-10 常用 indicators 的 Jaccard similarity。基础数学任务如 GSM8K 与 AQuA 有较高重叠(论文给出 0.43),而 GSM8K 与 AIME25 接近无重叠,说明 failure modes 强烈依赖任务族;indicator pool 需要多样性,不能让少数重复错误类型占满检索结果。

Limitations and caveats. 作者没有单独列出 limitations section,但实验中已经暴露几个边界: 不优于默认 3,说明 iterative feedback 可能 over-correct;domain-specific pool 依赖带 ground truth 的历史失败轨迹,zero-shot 时只能退化到 general indicator;fallback 会牺牲 pruning 收益以保护 MAS 完整性。released code 与正文公式/超参存在上面列出的实现差异,复现实验时应以 main@8790f010configs/release_experiments.json 和 benchmark launcher 为准。