上个月我负责的一个信息聚合类Agent项目几乎停摆。现象很典型任务拆分后交给4个并行Agent去跑每个都很快返回了结果但合并到一起时A和B的结论完全对立C的结果建立在A的输出之上D与B互相印证又互相拆台。我盯着合并报告看了半小时脑子里只剩一个问题——这套系统里到底谁说了算回头看真正的问题不是某个Agent能力不行而是整个并行体系缺了一个东西对错的判定机制。任务可以并行但谁对谁错这件事必须有比单个Agent更可靠的一层来兜底。这篇文章我想完整复盘一下我是怎么用任务DAG、质量审校和证据仲裁三个层次把多Agent并行之后谁来判断对错这个核心问题拆解并解决的。文章会覆盖原理、工程实现、踩坑记录适合正在做多Agent协作、Agent框架选型或者Agent编排开发的工程师参考。1. 并行的礼物与陷阱任务一拆散对错就说不清了1.1 单Agent的独裁为什么扛不住在真正落到多Agent并行之前多数项目都经历过单Agent阶段。单Agent处理长任务时本质上是一条串行决策链读上下文、推理、生成中间步骤、再读新上下文、再推理。整个过程由同一个上下文池驱动好处是逻辑自洽每一步都基于前一步的结果不会出现左右手打架的情况。但单Agent的瓶颈很现实上下文窗口有限token预算有限长任务跑到后半段就开始忘事推理深度也受限于单次生成的长度。这也是为什么大家开始做任务拆分——把一个大任务拆成多个子任务分给不同Agent并行跑效率有了肉眼可见的提升。拆了之后效率确实上去了。但有一个问题被很多人低估每个Agent只盯着自己那一段没有任何人看全局。当所有局部结果汇总回来时局部正确叠加在一起并不等于全局正确。1.2 并行之后我踩过的四个失控场景这四个场景是并行Agent系统里反复出现的几乎可以当成预警清单用输出冲突。两个Agent基于同一份输入推导出互相矛盾的结果而且各自都能给出看似完整的推导链。我在项目里遇到的最极端情况是Agent A引用文档第12页的说明支持方案XAgent B引用文档第15页的说明支持反方结论两份引用都真实存在冲突真实存在但谁对谁错没有一个Agent能回答。错误传播。上游Agent的一个小错误经过并行分支被复制放大。比如检索Agent在提取数据时少了一位数下游负责分析、生成、审校的多个Agent全部基于这个错误数据展开工作。最麻烦的是这种错误在DAG里不是线性传播而是网状扩散。排查时你根本找不到源头因为每个下游Agent的输出看起来都很正常。置信度通胀。几乎每个Agent在输出时都会给一个confidence分数。但不同Agent的置信度标定完全不一样。有的Agent习惯给0.9有的Agent默认0.6你把这些分数放在一起做加权平均等于拿不同计量单位的数字做算术。分数高不代表更可信只能说明这个Agent更自信。审校缺位。传统工作流里最终结果有一个负责人拍板。多Agent并行之后谁拍板很多人的第一反应是让主控Agent来。但主控Agent本质上也是一个LLM它的判断同样受上下文长度、指令优先级、prompt措辞影响。让一个LLM去裁决一堆LLM的输出等于让被告给自己定罪很难有真正的客观性。这四个场景叠加在一起就是我文章开头说的那个停摆项目的完整镜像。1.3 一个没有答案的伪命题加一个更聪明的Agent来拍板遇到对错争议时我第一个想到的补救方案是再放一个仲裁Agent进去让它综合所有Agent的输出做最终判断。实测下来这个方案只能解决50%的问题。因为仲裁Agent的输入是其他Agent的输出摘要而摘要在生成过程中已经丢失了大量细节。还有更隐蔽的问题如果仲裁Agent看到的是Agent A说X可行Agent B说X不可行它的判断很容易受先看到谁的锚定效应影响。prompt里先放A的输出还是先放B的输出结果可能完全不同。所以用一个聪明Agent去裁决其他Agent这条路走不通。正确的做法不是增加一个更聪明的裁判而是建立一套机制让任务以有依赖关系的结构被编排让每个产出经过独立质量审校让冲突通过证据链而不是模型嗓门来裁决。下面我会按这三个层次展开。2. 任务DAG让任务编排先有秩序才有资格谈对错2.1 为什么是DAG而不是简单的Map-Reduce很多人一听说并行就想到Map-Reduce把任务拆开同时跑再把结果并起来。这套模型适合无依赖的批量操作比如同时请求多个接口、批量翻译多段文本。但在真实业务里任务之间几乎没有纯并行关系。举个我项目里的真实例子。用户让Agent系统分析一份行业研究报告并输出投资建议。这个任务会被拆成文档清洗、数据提取、行业趋势分析、风险识别、结论生成。其中行业趋势分析需要数据提取完成之后才能开始结论生成需要趋势分析和风险识别两个子任务都完成后才能开工。这种有依赖的并行用DAG来表达是最直观的节点是任务边是依赖关系。DAG的拓扑结构决定了哪些任务可以同时跑、哪些任务必须等别人跑完、哪些任务是汇合点。把依赖关系显式建模之后谁先谁后就不再依赖某个Agent的临场判断而是由结构决定。2.2 构建DAG的三步法我在项目里把DAG构建拆成三个步骤每一步都有对应的工程动作第一步任务切分。把用户目标拆成原子任务。划分粒度很关键太粗则并行度不足太细则上下文碎片化严重。我的经验是一个任务的输入输出边界越清晰越适合做原子任务。第二步依赖标注。对每个原子任务标注它的前置依赖。这一步不用靠纯人工可以让规划Agent先产出一版依赖列表再由规则引擎校验合法性。校验的核心就是两条不能出现循环依赖每个任务必须有明确的输入来源。第三步拓扑排序与分层并行。对DAG做拓扑排序得到执行批次。同一批次内没有任何依赖关系的任务可以并行执行不同批次之间保持严格的先后顺序。这一步可以用一个很经典的分层遍历算法实现。2.3 分层并行的实现一段可以直接用的代码我贴一段我在项目里实际用的分层并行核心代码用Python写的逻辑很直接from collections import defaultdict, deque class TaskDAG: def __init__(self, tasks): # tasks: list of dict, 每个dict包含 # {task_id: str, dependencies: [str, ...]} self.tasks {t[task_id]: t for t in tasks} self.adj defaultdict(list) self.indegree {} for t in tasks: self.indegree[t[task_id]] len(t[dependencies]) for dep in t[dependencies]: self.adj[dep].append(t[task_id]) def get_parallel_batches(self): q deque([tid for tid, deg in self.indegree.items() if deg 0]) batches [] while q: batch [] for _ in range(len(q)): tid q.popleft() batch.append(tid) for nxt in self.adj[tid]: self.indegree[nxt] - 1 if self.indegree[nxt] 0: q.append(nxt) batches.append(batch) return batches def validate(self): # 检测是否有环跑一遍拓扑排序看节点数是否对得上 count 0 q deque([tid for tid, deg in self.indegree.items() if deg 0]) while q: tid q.popleft() count 1 for nxt in self.adj[tid]: self.indegree[nxt] - 1 if self.indegree[nxt] 0: q.append(nxt) return count len(self.tasks)get_parallel_batches返回的batches列表就是可以直接交给调度器消费的执行计划。每个batch内的任务并行执行batch之间串行等待。这个结构在后面做质量审校和证据仲裁时非常有用——仲裁不是在所有任务跑完之后才开始而是可以在DAG的汇合点分批进行。2.4 并行度不是越高越好DAG建好之后我踩过一个很实在的坑为了让整个流程更快把同一批次内的所有任务全部并发执行结果反而更慢了。原因很简单底层模型服务的并发能力有限。任务全部放出去请求在模型服务端排队每个Agent的响应时间从3秒变成15秒整体延迟不降反升。而且并行任务过多还会导致上下文碎片化——每个Agent拿到的上下文更短推理质量下降下游审校要处理的问题反而变多了。我现在的做法是给DAG执行器加一个并发上限参数默认控制在4到6个并行任务之间具体取决于远端并发配额。不要盲目追求全并行多数场景下分层并行加有限并发是效率和稳定性的平衡点。3. 质量审校在Agent交付物和最终答案之间建一条质检流水线DAG解决的是任务怎么跑但它不解决结果怎么信。每个Agent的原始输出不能直接作为最终答案的一部分。这正是质量审校环节存在的意义。3.1 三层审校模型格式、语义、事实我在项目里实践了一套三层审校模型每一层解决一类问题格式层审校。检查Agent输出是否符合约定的结构。比如要求返回JSON就检查能否被正常解析要求返回带引用的结论就检查引用字段是否齐全。这一层是最容易被忽视的因为LLM生成的内容看起来都像那么回事但一旦解析失败下游全部报错。格式审校建议用确定性规则实现不要用LLM又快又可靠。语义层审校。检查输出是否答非所问、是否遗漏关键信息、是否符合上游约束。比如上游任务明确要求必须给出两个备选方案语义审校就要检查输出里是否真的有两个方案。这一层可以交给专门的审校Agent来做但要注意独立性。事实层审校。检查输出中的事实性信息是否与外部可信源一致。比如数据提取Agent声称该行业过去三年复合增长率为18.5%事实审校就要拿这个数字与原始文档核对。这一层最复杂、最贵但对证据仲裁来说恰恰是最重要的基础。3.2 独立性原则审校Agent不能和执行Agent共享一套脑子三层审校里语义层和事实层涉及LLM判断我一开始想得很简单让主Agent在最后统一审一遍不就行了结论是不行。我见过一个项目让写报告的执行Agent同时审核自己的报告结果约七成错误会被放过去。原因很微妙执行Agent在生成内容时已经形成了立场审校时它会下意识地维护自己的立场。即便prompt里明确写着请严格审查并指出错误它还是会倾向于认为我写的没问题。这个问题的本质是审校Agent的独立性不够。后来我把审校链路彻底独立出来审校Agent不接触执行Agent的prompt和上下文只接收产物和审校规则使用独立的prompt模板甚至可以让不同的底层模型担任审校角色。这样做的代价是额外消耗token但换来的是真正有意义的质检。还有一个细节如果你在用的是Agent框架注意把执行harness和agent的职责分清楚。执行harness负责调度、状态管理、上下文传递agent负责具体任务产出。审校环节应该挂在harness层面而不是agent内部。否则agent在自我检查时读到的还是自己那套思维链独立性依然为零。3.3 审校失败之后重试、降级、人工介入审校通过率不可能做到100%。我在项目里统计过语义层和事实层的审校通过率大约在80%到90%之间。所以必须定义审校不通过之后怎么办否则质检线一卡整个流程就死等。我的处理策略分三级重试。如果审校发现的是局部问题比如某段数据引用缺失把原任务和审校意见一起打回给执行Agent要求修订。注意重试时要给执行Agent提供审校报告而不是只说一句你的输出有问题。降级。如果重试一次仍然无法通过且当前任务的产出不影响最终结果的核心结论可以降级处理——把它标记为低置信度内容在最终输出中明确标注而不是强行隐藏。人工介入。对于事实层审校失败且涉及关键结论的内容一律转人工。多Agent并行系统里保留一个人工兜底入口不是认输而是负责任。自动化系统的价值在于把人工的工作量从100%降到5%而不是强行追求0%。4. 证据仲裁Agent各执一词时靠什么定案质量审校处理的是单个Agent的产出是否合格。但多个Agent产出互相冲突这件事单靠审校解决不了它需要独立的仲裁机制。这也是谁来判断对错最直接的答案。4.1 仲裁的三条基本盘我在设计仲裁机制时定了三条基本盘缺一不可引用可溯。任何一条用于仲裁的信息必须有明确的来源。来源可以是数据源文件也可以是上游Agent的任务ID。没有来源的信息不管看起来多么合理都不具备仲裁效力。置信度标定。不同Agent的confidence分数不能直接比较必须先做归一化标定。我在项目里的做法是用历史数据统计每个Agent的置信度得分与实际准确率的映射关系生成一张校准表。仲裁时用校准后的准确率替代原始confidence。这个细节很关键但它经常被忽略因为需要积累一批历史数据才能做项目初期往往没有。交叉验证。两个Agent结论冲突时如果能有第三条独立的证据来源做交叉验证仲裁就有了抓手。比如Agent A说增长率为18.5%Agent B说是15.2%这时候如果有一个外部数据库或原始文档可以直接核对仲裁就变成了查证而不是裁决。4.2 一道简单的仲裁规则流程我把仲裁逻辑写成了一段流程性的代码方便你理解它的工作方式def arbitrate(task_id, candidates): # candidates: list of dict # 每个包含 {agent_id, output, evidence, raw_confidence} scores [] for cand in candidates: if not has_valid_evidence(cand[evidence]): # 证据缺失直接出局 scores.append((0.0, cand)) continue calibrated_conf calibrate( cand[agent_id], cand[raw_confidence] ) evidence_score eval_evidence(cand[evidence]) # 外部事实基准校验的加成项 fact_boost 0.0 if match_external_source(cand[output]): fact_boost 0.15 scores.append((calibrated_conf evidence_score fact_boost, cand)) scores.sort(keylambda x: x[0], reverseTrue) return scores[0][1] if scores[0][0] 0.3 else None关键点是仲裁结果不是简单的谁分高选谁而是有一个最低门槛。所有候选者的仲裁得分都低于阈值时仲裁器返回None走人工介入流程而不是硬选一个相对最好的。这个设计救过我很多次——因为矮子里拔将军在多Agent系统里往往会把一个错误的结论包装成正确的。4.3 几条实用的仲裁经验说几条从实际项目里沉淀下来的经验比理论更重要新鲜度优先。如果两个Agent引用了同一份资料但版本不同优先采信更新版本。这个规则听上去很简单但在仲裁代码里经常被遗忘。汇合点分批仲裁。仲裁不是所有任务跑完之后再做。DAG里每个汇合点多个分支归到一个下游任务的地方都可以做一次局部仲裁。这样错误在传播途中就被拦截了不用等到最后才集中爆发。无法仲裁时显式声明存疑。多Agent系统里有些冲突确实是信息不足导致的强行仲裁只会制造虚假的确定性。遇到这种情况我在最终报告里会明确标注存疑此结论在多个来源之间存在冲突需人工确认。这个声明对用户来说比一个被包装成确定结论的猜测要可靠得多。4.4 把一个错误结论做成验证样本我做过一个印象很深的样本测试。有两个Agent对一组行业数据做趋势判断一个说是上升通道一个说是平台期。两个Agent都引用了不同来源的统计口径。仲裁模块通过交叉验证发现说平台期的Agent引用的数据源是带滞后效应的二手数据而说上升通道的Agent引用的是原始数据。最终仲裁采信了后者并且在报告中标注了存疑提示。这个案例让我意识到一件事多Agent并行的很大一部分冲突本质不是Agent能力问题而是信息源质量问题。仲裁机制真正要做的是把哪个信息源在当前场景下更可信这件事显式化。这也解释了为什么要保留完整证据链——没有证据链仲裁就是凭空猜测。5. 可落地的工程架构DAG、审校与仲裁怎么串起来前三章分别讲了三个层次这一章把它们串起来给出一个实际能跑的工程架构。5.1 执行管线全景我在项目里最终落地的管线是这样的用户请求进入后先由规划模块生成任务清单和依赖关系构建TaskDAGDAG开始分层执行每批任务通过调度器分发给执行Agent执行Agent的产出先进入格式审校再进入语义审校最后是事实审校多个任务在DAG汇合点汇总后如果存在冲突进入仲裁模块仲裁通过的结论进入最终报告仲裁失败的标记存疑或转人工每个Agent的产出、审校结果、仲裁依据全部写入运行日志形成完整证据链。用一句话概括DAG决定了任务的形态质量审校决定了单点产出的可信度证据仲裁决定了冲突结论的最终归属。5.2 审校与仲裁如何喂回DAG这套架构里有一个容易被忽略的闭环审校和仲裁的结果会反过来影响DAG的执行策略。比如某个Agent的产出频繁在语义审校中不通过调度器应该降低该Agent的权重或者把它标记为需要复查的高风险节点。再比如仲裁发现某条数据源反复被判定为不可靠可以在后续任务的prompt里标注不要使用该数据源。这样系统会越用越准而不是每次都在同一个地方栽跟头。我实现这个闭环的方式是维护一个运行时元信息表记录每个Agent和质量相关的事件统计。DAG执行器每次生成新计划前先读这张表做动态调整。5.3 我踩过的几个坑你可以直接绕开最后分享几个贴近工程实践的教训。第一个坑是审校Agent用模型过大。一开始我让审校Agent也用最强模型结果成本直接翻倍而且审校速度成为瓶颈。后来调整为格式层用规则引擎语义层用中等模型事实层只在关键节点上最强模型。效果没有下降成本降了大约四成。第二个坑是仲裁只看结论不看过程。早期的仲裁模块只接收Agent的最终结论和confidence分数结果遇到很多结论看起来合理推理链条全是漏洞的案例。后来我把证据链检验前置到仲裁之前强制要求候选结论必须附带可验证的推理摘要才把这类问题压下去。第三个坑是并行度和上下文碎片化的平衡。前面提过并发任务太多会导致每个Agent拿到的上下文变短推理质量下降。我在实际项目里测出来的经验值是对于中等复杂度的任务单个Agent的上下文如果低于3000 token质量会明显下滑。所以调度器分配任务时我会同步做上下文预算检查而不是单纯看任务数量。第四个坑比较隐蔽DAG的汇合点如果审校失败很容易进入重试死循环。比如下游任务依赖三个上游产出其中一个审校不通过重试了三次还是失败整个汇合点就卡死了。后来我加了一个规则同一个节点最多重试两次第三次直接走降级路径把不通过的部分标记为存疑让下游任务在有缺陷但可用的输入上继续运行。这套体系跑下来最大的感受是多Agent并行的问题很难靠增加一个更聪明的Agent解决而是要靠结构性的机制——DAG管秩序质量审校管单点可信度证据仲裁管冲突归属。三者各司其职系统才算真正闭环。我在后续项目里一度还想把仲裁结果做成可视化面板让用户直接看到每一条最终结论背后的证据链。这个方向还没完全做完但至少比两个Agent吵一架然后一个神秘裁判拍板要令人安心得多。