ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用纠错码思想编排编程 Agent:ECC 多 Agent 协作指南

用纠错码思想编排编程 Agent:ECC 多 Agent 协作指南 三个 Agent 会话同时开着我在终端之间来回切一边让它改接口一边在心里默念别把上一轮的修复覆盖掉——这是我早期做 AI 编程最典型的一个下午。真正让我停下来重新想这件事的是 ECC 这套把编程 Agent 组织成工程团队的编排思路。它没有教我怎么写更花哨的提示词而是把一个我一直回避的问题摆到了台面上一个 Agent 犯错和一个团队犯错是两种完全不同的失效模式而后者才是能修的那种。ECC 在这里指的是一套面向编程 Agent 的协作编排范式命名逻辑借的是通信领域的纠错码Error Correcting Code——用冗余的校验角色互相盯防把单个 Agent 的随机性偏差压到可接受的范围内。它解决的不是模型不够聪明而是没人复核、没有契约、出错无法定位。这套东西适合已经用 Agent 写过真实项目、被回归测试和代码覆盖坑过一轮的人也适合刚入门、想知道怎么学 AI Agent 编程该从哪一层入手的人——因为它给你的不是技巧是一套结构。下面我按自己的理解把它完整拆一遍包括角色怎么分、契约怎么写、校验回环怎么跑以及我在实际落地时踩过的那些坑。1. 单个编程 Agent 为什么撑不起一支工程团队1.1 三个绕不过去的失效点先说结论单 Agent 处理小任务是真的香一个函数、一个脚本、一次重构几轮对话就能收敛。但任务一旦跨过五六个文件牵扯到接口契约、数据迁移和回归测试它的表现就会断崖式下滑。我把这种下滑归到三个原因上每一个都不是靠换个更强的模型能解决的。第一个是上下文稀释。Agent 每读一个文件、每改一处代码都在消耗注意力。当对话历史堆到几万 token早期定下的约束比如金额字段统一用 Decimal不要用 float会被淹没在后面的细节里。人写代码也会忘但人会翻回需求文档确认Agent 通常不会主动回头它更倾向于顺着最近的上下文往下推。这不是模型缺陷是任何一种有限窗口系统的共性。第二个是自我验证失效。让同一个模型既写代码又评审代码本质上等于让学生自己批改自己的卷子。模型对自己刚生成的方案有天然的确认倾向它会找理由证明这段逻辑是通的而不是找反例去证伪。你让它自查它大概率回你一句这段实现看起来没问题然后你上线然后线上炸。真正有效的验证必须来自信息隔离的外部视角——这是我后面要重点讲的角色设计基础。第三个是没有契约只有意图。人接到修一下跨月结算的金额偏差会先去问清楚是四舍五入方式不对还是日期边界算错还是币种换算掉了精度Agent 不会问这么多它会直接猜一个最像的原因然后动手。猜对了皆大欢喜猜错了你连它为什么改这里都不知道。任务没有可校验的输入输出定义就没有任何东西能拦住它跑偏。1.2 纠错码的三个要素是怎么被搬进 Agent 流程的ECC 这个命名不是随便起的。纠错码能在一段有噪声的信道里还原原始数据靠的是三件事冗余、校验、纠正。数据本身之外多传几个校验位接收端用校验位算出哪里错了然后定向翻转那个错误的位而不是把整段数据重传。这套思路平移到 Agent 协作上几乎是逐条对应。冗余对应的是多角色独立视角。同一个 diff让三个不同职责的 Agent 各看一遍——评审看设计合理性测试看边界覆盖类型检查看接口一致性。它们的判断依据不同出错方向也不同叠加之后单点偏差被大幅稀释。校验对应的是可执行的验收标准。不是代码写得好不好这种主观判断而是pytest 全绿、mypy 无新增告警、接口返回值结构与契约一致——能跑出布尔结果的东西。纠正对应的是定向回滚加局部修复。发现某一步引入回归正确做法是把那一步的改动单独摘出来重做而不是让 Agent整体再改一遍后者只会引入新的噪声。注意冗余不是让三个 Agent 干同一件事然后投票。职责不同才会产生真正独立的错误分布。三个同质评审员的一致意见价值远低于一个评审加一个测试。1.3 顺便说说 ECC 这个词搜出来的一堆歧义如果你是按关键词搜进来的大概率见过另一种 ECC通信和存储领域的校验原理也就是汉明码、奇偶校验那一套。它的核心是用最少的冗余位定位并纠正单比特错误典型场景是内存条上的 ECC 校验、闪存的数据保护。这套理论里有个概念我特别喜欢叫最小海明距离——两个合法码字之间至少差多少位才保证错误能被检出而不是被误判成另一个合法码。放到 Agent 协作里它对应的是两个角色的判断依据差多少才算独立如果两个评审员用的是同一套提示词、同一个模型、同一份上下文它们之间的距离接近零纠错能力也就是零。还有两个同名的东西需要顺手排掉免得你搜着搜着跑偏一个是企业级 ERP 套件里的 ECC 产品代号跟 Agent 编程没有任何关系另一个是椭圆曲线密码学虽然缩写一样但属于信息安全领域。这三个 ECC 只共享字母不共享血统。我下文所有讨论都特指前一种——用纠错码思想做 Agent 协作编排的那套方法。至于标题里那个 25 万 Star我的态度一直比较冷淡。Star 数是所有技术信号里最弱的一档它衡量的是有多少人觉得这个想法值得收藏不是有多少人真的把它跑在生产流程里。我见过太多高 Star 项目clone 下来十分钟就跑不下去了因为文档里省掉的全是真正的坑。所以这篇拆解不吹数字只讲机制——机制对不对你自己跑一轮就知道。2. ECC 协作机制的核心设计拆解2.1 角色分层不是多开几个窗口就叫团队很多人理解的多 Agent 协作就是同时开三个窗口把同一个需求分别丢进去然后挑一个自己满意的结果。这不叫团队这叫抽奖。真正的角色分层核心在于每个角色的输入不同、输出不同、验收标准也不同。我实际用下来比较稳的一套是五个角色。规划者只做一件事把模糊需求翻译成任务卡定清楚输入输出契约和影响范围它不写实现代码。实现者拿到任务卡和指定文件范围后动手它的可见范围被严格限制在契约声明的路径内范围外的文件它碰不到。评审者只看 diff 和契约不看实现者的思考过程——这一点非常关键一旦它看到我之所以这么改是因为……的解释判断就会被带偏。验证者负责跑测试和静态检查它不改任何源码只输出结论和证据。集成者在多个任务并行时负责合并、解冲突、跑全量回归。这五个角色里规划者和实现者可以共用同一个模型评审者和验证者我建议换一个不同厂商的模型。原因还是那个最小海明距离同一个模型家族在相同任务上的错误倾向是高度相关的换个模型能显著拉开判断差异。这一条没有理论证明纯粹是我自己多轮对比后的经验供你参考。2.2 契约先行把需求变成能跑出布尔值的东西整套路子里最值钱的部分是任务卡。它把一段自然语言需求压缩成一份机器和人都能读的结构。写好的任务卡长这样一个明确的目标句、一份允许修改的路径白名单、一份禁止触碰的路径黑名单、一组输入输出结构定义、若干条可执行的验收条件。我踩过最深的一个坑是早期把验收条件写成代码逻辑正确、无副作用。这种描述对 Agent 完全无效它没法判断自己有没有满足。后来我强迫自己把所有验收条件改写成能被执行器跑出真假的表达式情况立刻好转。比如跨月结算测试用例全部通过、静态检查无新增告警、公开接口的参数个数与契约一致。改完之后的直接收益是Agent 不再需要感觉自己做对了它可以直接跑一遍看结果。任务卡还有个隐性价值就是让错误可归因。单 Agent 模式下代码出问题你只能翻整段对话历史猜是哪一步带歪的。有了任务卡每一步都有明确的输入和验收结果出错时你能精确定位到是契约写漏了边界条件还是实现者越界改了共享模块。没有这个调试成本会高到让你放弃整套流程。2.3 校验回环三轮之内收敛还是果断打回校验回环是整个机制的引擎。实现者交出一版 diff 后评审者和验证者并行介入各自给结论。这里有个硬规则结论必须是枚举值不能是自由文本。我把评审结论统一成approve / reject / need_clarify三档验证结论统一成pass / fail两档任何需要说明的部分单独放在证据字段里必须带上文件名和行号。为什么强制枚举因为自由文本的看起来还行是最可怕的输出。它会让你误以为校验环节跑过了实际上是空转。我有一次连着三个任务都拿到了实现思路清晰基本符合要求结果上线后发现三个都漏了同一个空值分支——评审者压根没去看那个分支只是被 diff 的整洁外观说服了。改成枚举加证据之后approve必须附上已核对契约第 3 条、对应测试文件第 42 行这样的具体凭据空转的空间就被堵死了。回环的轮数要设上限。我的默认值是三轮第一轮实现第二轮针对评审意见定向修复第三轮如果还没过就直接打回给规划者重新拆任务。为什么是三轮不是五轮因为超过三轮还没收敛通常意味着任务本身拆得不对而不是实现者不够努力。继续加轮数只会烧 token而且每多一轮改动叠加引入新回归的概率就上升一次。2.4 用最小距离的思路设计角色差异前面提到过最小海明距离这里展开讲一下它怎么指导实操。判断两个校验角色是否真正独立我会问三个问题它们用的是不是同一个模型它们看到的是不是同一份输入它们的验收标准是不是同一套只要有一项相同独立性就打折。最理想的配置是三个维度全不同评审者换模型、只看 diff 不看对话、按设计原则验收验证者用原模型、看完整仓库、按可执行测试验收。这两者的错误分布几乎不重叠一个漏掉的设计缺陷另一个大概率能在测试里撞出来。反过来如果你配了两个只看 diff 的设计评审它们会同时对同一类问题失明同时放过同一类缺陷——冗余做了纠错能力没做。这个思路还有一个延展用法关键路径上叠加不同类型的校验器。代码逻辑靠测试接口一致性靠类型系统安全敏感路径靠静态扫描规则。它们不是同一个检查的三种实现而是三种正交的检查维度。正交性越高组合起来的最小距离就越大能兜住的错误类型也越多。3. 从零搭一套最小可用的 ECC Agent 团队3.1 目录结构与状态落盘先说一个原则不要把所有状态放在对话历史里。对话是易失的、会被截断的、无法被外部工具读取的。所有角色之间需要传递的东西一律落成文件。我的项目里通常会建一个.ecc/目录结构大致如下。project/ .ecc/ contracts/ # 任务卡一个任务一个 yaml task-042.yaml roles/ # 各角色的系统提示词 planner.md coder.md reviewer.md verifier.md state/ # 每个任务的运行状态机 task-042.json evidence/ # 校验证据评审和验证的输出落盘 task-042-review.json task-042-verify.log src/ tests/state/task-042.json记录的是当前处于哪个阶段、已经跑了几轮、上一轮是谁打回的。这个文件的用处在于任何一次 Agent 调用中断或者超时流程都能从上次的状态恢复不需要重跑整个任务。我在早期没做状态落盘一次网络抖动导致的会话中断就得从头再来一遍一个半小时的 token 消耗直接打水漂。evidence/目录是我坚持保留的第二个东西。它把每次评审的结论、每条验证命令的输出都存下来。事后复盘时你能清楚看到是哪个环节放过的缺陷。没有这份记录为什么这次没拦住永远是个玄学问题。3.2 任务卡怎么写一份可直接抄的模板下面这份模板是我迭代了十几版之后稳定下来的字段不多但每个都有明确用途。id: task-042 goal: 修复跨月结算场景下订单金额的小数偏差 scope: allow: - src/billing/** - tests/billing/** deny: - src/core/** - src/shared/money.py contract: inputs: [order_id: str, settle_month: str] outputs: amount: Decimal, 保留 2 位, 四舍五入用 ROUND_HALF_UP currency: ISO 4217 三字母代码 acceptance: - pytest tests/billing/test_rounding.py::test_cross_month -q 通过 - ruff check src/billing 无新增告警 - mypy src/billing 无新增 error budget: max_rounds: 3 max_files_changed: 6 timeout_minutes: 15几个字段的用意值得单独说。deny列表比allow列表更重要——allow是护栏deny是红线。像src/shared/money.py这种被几十个模块依赖的公共文件一旦让 Agent 顺手改了影响面立刻从局部扩散到全局回归测试都未必能全兜住。budget里的三个参数是成本闸门max_files_changed: 6这条我特意设得比较紧因为改动文件数一旦超过六个我基本能判断这个任务拆得不够细应该退回规划者。提示acceptance里的每一条都必须是能直接复制到终端里跑的命令或者能对应到一条明确的断言。写逻辑正确这种话等于没写。3.3 一次真实的修复流程走查拿上面那张任务卡举例走一遍完整流程。第一轮规划者读完任务卡和仓库结构输出一份改动计划指明问题出在src/billing/settle.py第 88 行的日期边界判断以及需要新增一个跨月测试用例。这一步不写代码只输出计划文件和影响面清单人工确认一遍再往下走——人工介入点放在这里成本最低因为此时还没有任何代码被改动。第二轮实现者拿到计划和allow路径动手改代码。它同时被要求附上一份自述说明每处改动的意图和对应的契约条款。这份自述不传给评审者只作为事后追溯用。实现完成后系统自动跑一遍acceptance里的命令如果连自动检查都过不了直接不进评审环节让实现者自己看输出改。第三轮评审者和验证者并行启动。验证者执行那三条验收命令把原始输出存进evidence/评审者拿到的是原始 diff 加任务卡它看不到实现者的自述也看不到对话历史。评审者必须输出结构化结论{ verdict: reject, reasons: [ { file: src/billing/settle.py, line: 92, issue: 跨月边界仍使用月末最后一天未覆盖闰年 2 月 29 日 } ], must_fix: [补充闰年跨月测试用例], evidence: 契约 acceptance 第 1 条要求覆盖跨月未指定闰年属遗漏 }这份reject会直接喂给实现者作为下一轮的唯一输入。这里的关键是实现者只看拒绝理由不看评审者的完整推理过程。理由足够具体带文件、行号、必须修项它就能定向修推理过程给多了反而会让它开始顺着评审的思路重新写一遍引入不必要的改动。第三轮修完后重新评审通过则进入集成阶段不通过且已用满三轮任务打回规划者重新拆解。整套流程跑下来一个中等规模的 bug 修复大概消耗 8 到 15 万 token比单 Agent 模式贵三到四倍但返工率下降得非常明显。我自己统计过一批任务单 Agent 模式下一周内被重新打开的比例接近四成走完整 ECC 流程的批次掉到了一成出头。3.4 参数与成本并发、锁和超时怎么定并发这块有个必须守住的规则同一个文件在同一时刻只能有一个写者。多 Agent 并行改代码时最容易出的事故是两个实现者同时改了同一个共享文件后提交的那个把前一个的改动整段覆盖掉而且因为 diff 看上去是干净的评审环节根本发现不了。我的做法是在调度层加一把按文件路径粒度的写锁实现者在拿到锁之前不允许写入。超时的取值也有讲究。单轮实现我给 15 分钟上限超了就中断并落盘状态。原因很实际Agent 卡在一个循环里反复尝试的频率比想象中高比如它一直想改deny列表里的文件但被拦住就会不停地换思路重试。给他无限时间它能耗掉你一整天的额度。成本控制上我给自己定过一条线单个任务的 token 消耗超过某个阈值就直接停手人工接管。因为超过这个量级还没收敛说明问题通常在任务定义层面继续让 Agent 磨下去是纯粹的浪费。这条线具体画在哪里跟你用的模型价格有关需要你自己跑几十个任务之后统计出一个中位数再定。4. 踩坑实录与排查速查4.1 Agent 互相甩锅责任归属模糊怎么破这是多 Agent 流程里最先冒出来的问题。表现是评审说实现有问题实现说契约没写清楚规划者说需求就是这样给的三方各执一词任务卡在那儿没人往下推。根因在于角色提示词里没有规定谁在什么情况下必须下结论。我的解法是给每个角色加一条裁决规则评审者的reject必须附带至少一条可执行的修复建议否则该结论无效自动降级为need_clarify并退回规划者规划者收到need_clarify必须补充契约条款或者缩小任务范围不允许原样打回实现者不允许对契约本身提出异议只能就实现方式提异议。这三条一加甩锅的空间基本被堵死因为每个角色的输出都被限定成了必须带具体内容的动作。顺带提一句这类规则不要一开始就写得很复杂。我最初写了一版十几条的裁决规则结果角色之间互相触发的判定条件打架流程更乱了。后来砍到三条核心规则反而稳定。规则数量和稳定性是反比关系这个规律在流程设计里几乎处处成立。4.2 校验环节空转假通过的四种典型信号假通过是这套机制最危险的失效模式因为它让你以为有保护实际上没有。我总结过四种信号看到任何一种都要停下来查。第一种是评审结论过于笼统reasons为空或者只写了整体符合要求。第二种是验证输出没有原始日志evidence/里只有一句测试通过而没有命令的实际输出。第三种是diff 规模与任务复杂度明显不匹配一个涉及跨月结算的任务只改了两行代码。第四种是验收测试文件本身被改动过——这是最隐蔽也最严重的一种。Agent 发现测试跑不过时最省力的方案是去改测试而不是改实现。我的硬规则是tests/目录下已存在的验收用例实现者一律无权修改只允许新增文件。这条规则写进deny列表之后假通过率下降了一个数量级。注意定期抽查evidence/目录里的原始日志是个好习惯。哪怕流程跑得再顺每周抽两三个任务看看日志真实性能提前发现很多悄悄退化的环节。4.3 上下文爆炸与信息丢失跑了几十个任务之后你会遇到另一个问题仓库越来越大Agent 每次都要读一堆文件token 消耗和时间成本同步上升。解法不是加大窗口而是严格限制每个角色的可见范围。实现者只在allow路径内检索规划者只读目录树和接口签名文件评审者只看 diff 加契约。这三个角色的上下文加起来通常比让单个 Agent 读全仓库要少一半以上。信息丢失则表现为另一种症状Agent 改了一处代码但不知道这处代码被谁依赖。这种情况我建议在任务卡里额外加一个impact字段由规划者填写受影响的调用方清单实现者动手前必须先读这几个调用点。这个字段解决了我遇到过的绝大多数改对了但改坏了别处的问题。4.4 常见故障速查表现象大概率原因处理动作评审连续多轮都通过但线上出问题评审输入含实现者自述被带偏隔离输入只给 diff 和契约同一文件被反复改来改去缺少写锁多个实现者并发按路径加写锁串行化写入验收测试突然全绿但代码没实质变化测试文件被 Agent 改动把已有测试文件列入 deny 列表任务跑满三轮仍未收敛任务拆分粒度过粗打回规划者按文件边界重新拆token 消耗异常高Agent 在受限路径上反复重试检查 deny 命中日志必要时人工介入报错信息里出现不认识的依赖实现者引入了范围外改动比对 diff 与 allow 列表回滚越界部分这张表我在团队内部贴了很久新同学上手时遇到的九成问题都能在里面找到对应项。需要补充的是最后一行越界改动往往不是 Agent 故意的而是它在解决问题时顺手改了最近的依赖文件。所以 deny 列表的覆盖面比想象中重要宁可一开始设得严一点遇到合理的例外再逐条放开。5. 学这条路该怎么走给不同阶段的人几句实话5.1 刚入门的人先别急着上多 Agent如果你还在琢磨怎么学 AI Agent 编程我的建议是先把单 Agent 的边界摸清楚。用单 Agent 连续做二十个真实任务记录每一次它跑偏的场景你会发现这些场景是有规律的。摸清规律之后再引入第二个角色效果比一上来就搭五角色体系好得多。原因是不理解单点的失效模式就没法判断多加一个角色到底有没有用你只会得到一个更贵但同样不可靠的系统。具体路径我会这样安排第一周只用单 Agent 加手工验收重点是学会把需求写成任务卡第二周加入一个独立的验证者角色专门跑测试和静态检查第三周再引入评审者。每加一个角色跑十个任务对比一下返工率没有明显改善就砍掉。这个过程有点笨但比照搬一套复杂框架再调试要快得多。5.2 已经在用的人重点该放在契约质量上如果你已经在跑多角色流程提升点大概率不在角色数量上而在任务卡的质量上。我做过一个粗略对比同一批任务把验收条件从模糊描述改成可执行命令之后平均返工轮数从 2.3 轮降到 1.2 轮。改的东西只有一处就是那句必须能跑出真假。这也是我花了最久才想明白的一件事这套机制的核心竞争力从来不是角色设计有多精巧而是你有没有能力把需求翻译成可校验的契约。这个能力和写代码的能力是两种不同的技能需要单独练。练法很土就是每次写任务卡时强迫自己问一句这条验收条件我怎么证明它被满足了答不上来就重写直到能答上来。6. 几点个人体会和后续可扩展的方向我个人在实际操作中的体会是这套流程最反直觉的地方在于——它的价值大部分来自限制而不是来自能力。限制 Agent 能改哪些文件、限制它能看到哪些上下文、限制它有多少轮机会、限制它的输出格式。每加一条限制系统的确定性就上升一点。这跟单 Agent 时代多给它点信息它就能做得更好的直觉是相反的需要一段时间才能转过弯来。最后再分享一个小技巧如果你觉得五角色体系太重可以先做一个最小版本——规划者加实现者加验证者三个角色把评审省掉用更严格的验收命令来替代。我自己有段时间就是这么跑的返工率虽然没有全量版本低但已经比单 Agent 好一大截成本也友好得多。等你发现某类缺陷反复出现、现有验收条件总也拦不住的时候再补上针对这个维度的评审角色按需扩展比一次性搭满要稳得多。这套东西后续还能往两个方向延展。一个是把任务卡沉淀成历史库用过去的契约作为新任务的参考模板同类任务的质量会随着积累逐步提升。另一个是把评估数据接进流水线自动统计每个角色的误判率哪一环经常放过缺陷就针对性调整它的输入和验收标准。这两件事我都在小范围试过效果还不错但样本量还不够下结论等攒够数据再单独写一篇复盘。
返回列表