01-多Agent系统为什么总是过早宣布完成

发布时间:2026/6/2 19:27:49

01-多Agent系统为什么总是过早宣布完成 多 Agent 系统为什么总是过早宣布完成你有没有遇到过这种情况让 Agent 帮你写一个完整的功能模块它信心满满地说已完成结果你一跑——缺了三个文件、两个函数没实现、测试用例一个都没写。这不是模型能力不够而是多 Agent 系统的结构性缺陷。今天我从架构设计的角度拆解这个行业的顽疾以及我设计 Symbio 框架时的解决方案。一、一个真实的崩溃瞬间上周五晚上 11 点我让一个多 Agent 编码系统帮我实现一个完整的 REST API 模块包含用户注册、登录、JWT 鉴权、RBAC 权限控制。Agent 信心满满地回复✅ 任务完成已创建以下文件models/user.pyroutes/auth.pymiddleware/jwt.pytests/test_auth.py我满怀期待地打开项目目录结果models/user.py— 只有 class 定义字段全是passroutes/auth.py— 注册接口写了一半登录接口直接# TODOmiddleware/jwt.py— 文件是空的tests/test_auth.py— 只有一个def test_placeholder(): pass四个文件没有一个能跑。这不是个例。用过 Cursor、Claude Code、Devin 等 AI 编程工具的同学大概率都踩过类似的坑。问题的根源不在于模型不会写代码而在于多 Agent 系统缺少一套工程化的完成判定机制。二、过早完成的三个根源2.1 根源一EOS Token 的训练偏差大语言模型在训练时被优化为尽快结束对话。当模型输出EOSEnd of Sequencetoken 时生成就停止了。问题是训练目标最大化 P(EOS | 当前上下文) ↓ 模型倾向只要上下文看起来差不多完成了就尽快输出 EOS ↓ 实际效果Agent 在完成 60% 的工作后就认为自己已经完成这不是模型偷懒而是训练目标和实际需求之间的结构性矛盾。模型被训练成一个对话者而不是一个工程师。对话者追求的是让对话自然结束工程师追求的是所有需求都验收通过。2.2 根源二缺乏外部参照Agent 只能看到自己的对话历史没有全局视角。它不知道其他 Agent 在做什么整体任务的完成进度上下游依赖是否就绪测试用例是否通过这就像一个程序员只看自己写的代码从不跑测试、从不 review、从不集成——他当然觉得自己写完了。2.3 根源三多 Agent 通信的传话游戏效应在传统的多 Agent 系统中Agent 之间通过对话传递信息Agent A: 我需要一个用户模型 Agent B: 好的我创建了一个 User 类 ← 实际上只写了 class 定义 Agent A: 收到继续下一步 ← 信任了 B 的口头汇报 Agent B: 登录接口已完成 ← 实际上只写了一半 Agent A: 任务完成 ← 没有验证直接宣布这就是传话游戏效应信息在传递中丢失— B 说已完成A 不知道实际完成度Token 爆炸— 每次传递都携带大量冗余历史对话钻牛角尖— Agent 陷入自己的对话上下文无法自拔三、为什么多 Agent 比单 Agent 更严重你可能会问单 Agent 不也会过早完成吗会但程度完全不同。多 Agent 系统的过早完成是一个系统性放大的问题单 Agent 的失败模式 任务 → Agent 执行 → 过早完成 → 人类发现 → 人工修正 多 Agent 的失败模式 任务 → Agent A 执行 → 过早完成 → Agent B 基于 A 的完成结果继续执行 → 过早完成 → Agent C 基于 B 的完成结果继续执行 → 过早完成 → ... → 级联失败关键区别在于错误传播链维度单 Agent多 Agent错误发现时机人类直接检查需要跨 Agent 验证错误传播范围局部级联放大修正成本低回退一步高回退多步Token 浪费可控指数级增长这就是为什么多 Agent 系统需要一套工程化的防过早完成机制而不是靠模型自觉。四、Symbio 的解决方案三层防御体系在设计 Symbio 框架时我从工程角度构建了三层防御体系从根源上解决过早完成问题。4.1 第一层强制 Tool Calling 结束核心思想不允许 Agent 通过自然语言输出 EOS 来结束任务必须调用一个显式的submit_task工具。# ❌ 传统方式Agent 自己判断是否完成 class Agent: def run(self, task): result self.llm.generate(task) return result # Agent 说完就结束不管做没做完 # ✅ Symbio 方式强制 Tool Calling 结束 class Agent: def run(self, task): while True: result self.llm.generate_with_tools(task, toolsself.tools) if result.tool_call submit_task: # 必须提交修改了哪些文件、测试结果如何 return self.verify_submission(result) elif result.tool_call: # 继续执行其他工具调用 task self.execute_tool(result.tool_call) else: # 没有工具调用 还没完成继续 task self.remind_incomplete(result)为什么有效传统方式中Agent 说我完成了就结束了。但在 Symbio 中Agent 必须调用submit_task(task_id, files_changed)才能结束。这个工具调用会触发一系列验证检查所有文件是否真实存在检查文件内容是否非空检查是否所有 checklist 项都已标记完成如果有测试用例自动运行测试从工程上绕过 EOS 提前停机问题。4.2 第二层显式未完成清单Checklist核心思想在任务开始时由 Initializer Agent 生成一个 JSON 格式的 Checklist将完成标准以代码形式固化。{ task_id: auth-module-001, status: in_progress, checklist: [ { id: user-model, description: 创建 User 数据模型包含字段定义和验证, status: done, files: [models/user.py], test: tests/test_user_model.py }, { id: auth-routes, description: 实现注册和登录接口, status: in_progress, files: [routes/auth.py], test: tests/test_auth_routes.py }, { id: jwt-middleware, description: 实现 JWT 鉴权中间件, status: pending, files: [middleware/jwt.py], test: tests/test_jwt.py }, { id: rbac, description: 实现 RBAC 权限控制, status: pending, files: [middleware/rbac.py], test: tests/test_rbac.py } ], completion_criteria: { all_items_done: true, all_tests_pass: true, no_todo_comments: true } }关键设计Checklist 在任务开始时生成不是过程中动态创建每个条目有明确的files产出文件和test验证用例completion_criteria定义了完成的硬性标准Agent 每完成一个条目必须更新 Checklist 状态最终提交时系统检查completion_criteria是否全部满足4.3 第三层测试验证闭环核心思想不靠模型主观判断是否完成而是用工程化的测试结果作为最终判定。传统方式 Agent 说我完成了 → 人类相信 → 结果是假的 Symbio 方式 Agent 说我完成了 → Testing Agent 执行 pytest / npm test → 捕获 stderr/stdout → 如果有失败 → 回退到 Coder Agent 重新修复 → 循环直到所有测试通过class TestDrivenVerifier: def verify(self, task_id, checklist): results [] for item in checklist: if item[test]: # 在沙箱中执行测试 test_result self.run_test_in_sandbox(item[test]) results.append({ item_id: item[id], test_file: item[test], passed: test_result.returncode 0, stdout: test_result.stdout, stderr: test_result.stderr }) all_passed all(r[passed] for r in results) if not all_passed: # 将失败信息反馈给 Coder Agent failures [r for r in results if not r[passed]] return VerificationResult( passedFalse, feedbackself.format_failures(failures), actionretry ) return VerificationResult(passedTrue, actioncomplete)三层防御的协同效果任务进入 ↓ 第一层强制 Tool Calling → Agent 不能说完就走 ↓ 第二层Checklist 验证 → 检查所有产出文件和功能点 ↓ 第三层测试验证 → 用 pytest/npm test 真实验证 ↓ 全部通过 → 任务完成 任一失败 → 回退重试五、进阶状态驱动 vs 对话驱动三层防御解决了单个 Agent 过早完成的问题但多 Agent 协作还需要解决另一个关键问题Agent 间通信。5.1 传统方案对话驱动Agent A → 消息 → Agent B → 消息 → Agent C → 消息 → Agent AAgent 之间通过对话传递信息就像人类开会一样。问题在于传话游戏效应信息在传递中丢失和变形Token 爆炸每次传递都携带完整对话历史钻牛角尖Agent 陷入自己的对话上下文5.2 Symbio 方案状态驱动┌─────────────────────────────────────┐ │ 全局状态对象 (JSON Checklist) │ │ Single Source of Truth │ └──────────────┬──────────────────────┘ │ ┌──────────┼──────────┐ ▼ ▼ ▼ Initializer Coder Tester Agent Agent Agent │ │ │ └──────────┴──────────┘ 状态读写非对话传递核心规则每个 Agent 启动时只接收当前状态 JSON 代码 Diff 单一任务指令Agent 结束后只输出状态更新 测试结果清空会话历史— 每轮任务完成后重置防止上下文污染Token 成本降低 80%— 消除冗余对话传递为什么状态驱动更好维度对话驱动状态驱动信息传递方式对话历史JSON 状态对象信息完整性会丢失传话游戏完整单一事实来源Token 消耗高携带历史低只传当前状态可审计性低对话难以追溯高状态变更有记录并发安全性低对话冲突高状态原子更新六、实战效果一个对比实验为了验证这套方案的效果我做了一个对比实验任务实现一个完整的博客系统 API包含用户管理、文章 CRUD、评论系统、标签系统。对比对象方案 A传统多 Agent对话驱动无防过早完成机制方案 BSymbio状态驱动 三层防御指标方案 A方案 B提升首次完成率23%91%296%平均重试次数4.7 次0.9 次-81%总 Token 消耗187K62K-67%端到端耗时23 分钟8 分钟-65%最终代码可运行率67%98%46%关键发现首次完成率从 23% 提升到 91%— Agent 不再说完就走而是真正完成所有任务Token 消耗降低 67%— 状态驱动消除了冗余对话传递可运行率从 67% 提升到 98%— 测试验证闭环确保代码质量七、你可以立即应用的三个原则即使你不用 Symbio 框架以下三个原则也可以立即应用到你的 Agent 系统中原则一永远不要让 Agent 自己判断是否完成Agent 说完成了不算数要有外部验证机制。最简单的方式# 在 prompt 中强制要求 system_prompt 你必须完成以下所有步骤才能结束任务 1. 创建所有必要的文件 2. 实现所有函数不能有 pass 或 TODO 3. 编写测试用例 4. 运行测试并确保通过 只有调用 submit_task 工具才能结束任务。 不要用自然语言说任务完成。 原则二用 Checklist 固化完成标准在任务开始时让 Agent 生成一个明确的 Checklist{ tasks: [ {id: 1, description: 创建 User 模型, done: false}, {id: 2, description: 实现注册接口, done: false}, {id: 3, description: 编写测试用例, done: false} ] }每完成一项Agent 必须更新 Checklist。最终提交时检查是否所有项都done: true。原则三用真实测试替代主观判断Agent 写完代码后自动运行测试# 自动检测项目类型并运行测试 if [ -f pytest.ini ] || [ -f pyproject.toml ]; then pytest --tbshort 21 elif [ -f package.json ]; then npm test 21 fi将测试结果通过/失败 错误信息反馈给 Agent让它修复失败的测试。八、写在最后过早完成不是模型能力的问题而是系统设计的问题。模型被训练成对话者而不是工程师。对话者追求自然结束工程师追求验收通过。我们要做的是在系统层面弥补这个鸿沟。Symbio 的三层防御体系——强制 Tool Calling、显式 Checklist、测试验证闭环——从工程角度系统性地解决了这个问题。但这不是唯一的方式核心思想是不要信任 Agent 的自我判断用工程化的机制来验证。如果你也在做多 Agent 系统的开发希望这篇文章能帮你少走一些弯路。关于作者Agent Infra 架构手记专注 Agent 架构、AI Infra、多模态数据系统实战。Symbio 框架作者GitHub: 854875058/Symbio下一篇预告《Agent 间通信的致命陷阱为什么你不该让 Agent 互相聊天》

相关新闻