Wb-Flow:基于并行波次的Agentic Coding工程化实践
发布时间:2026/8/29 6:25:47 作者:尧图编辑部 阅读量:1,286

Agentic Coding 的瓶颈往往不是单个 Agent 不会写代码而是多个 Agent 同时工作时缺少“谁先做、谁后做、做完了怎么验收”的约束。Wb-Flow 所强调的 “Planned, Parallel Waves”就是把 AI 编程从“连续对话式改码”转成“先规划、再分波次并行执行、最后统一验证”的工程化流程。这篇文章会拆解这套模式的核心概念、计划文件结构、最小协调器实现以及落地时最容易踩的坑。1. Wb-Flow 是什么从“让 AI 连续改代码”到“规划后按波次并行”1.1 Agentic Coding 为什么会失控大多数 Agentic Coding 工具的工作方式很相似开发者给 Agent 一个目标Agent 读取代码仓库生成修改计划然后逐文件编辑、运行测试、根据报错修复最后提交变更。这种模式在单一需求上表现不错。但一旦需求变大问题就会暴露出来。第一是上下文窗口限制。Agent 在一个长会话里读过的文件、做过的决策会被逐步挤到上下文之外越到后面对项目结构的理解越模糊容易出现“前面改过的东西后面又改了一遍”。第二是修改顺序过于线性。需求拆成十个子任务后如果 Agent 按顺序一个一个做后一个任务可能因为前一个任务的实现细节而被迫调整原计划如果同步并行交给多个 Agent又会因为任务之间没有依赖分析而互相覆盖文件。第三是验证缺失。很多 Agent 只做“能跑起来”级别的检查缺少针对业务行为的断言。代码虽然能编译但功能语义已经被改坏。Wb-Flow 要解决的问题就是给 Agentic Coding 套上一套工程化流程让多个 Agent 在有限冲突的范围内并行而不是放任自由发挥。1.2 Wb-Flow 的核心思路Plan、Wave、GateWb-Flow 的名字里有两个关键限定词Planned 和 Parallel Waves。翻译成中文就是“有计划的并行波次”。这套模式里有几个核心概念。概念含义作用Plan对一次开发任务的完整计划说明要改哪些模块、拆成哪些任务、任务之间的依赖是什么Wave一批互不依赖、可以并行执行的任务集合提高 Agent 并行度同时控制冲突范围Task最小可执行单元一个 Agent 实例只负责一个 Task有明确输入、输出和验收条件Gate波次结束后的验证门禁编译、测试、静态检查等全部通过Wave 才算完成Checkpoint每个 Wave 完成后的代码基线与记录失败时可以回滚到上一个稳定状态一个 Wave 里的任务可以并行但 Wave 之间有严格顺序。这样做的好处是同一个波次内的任务被设计成“较少文件交集”冲突概率低不同波次之间的任务有依赖关系必须等前一波次验证通过后才开始。1.3 与普通多 Agent 并行开发的差异如果只是开多个终端同时让几个 Agent 各自干活那不是 Wb-Flow只是无约束并行。普通并行开发的问题在于缺少依赖管理。两个 Agent 同时修改同一个 Service 类各自测试通过合并时却产生冲突或者一个 Agent 依赖另一个 Agent 刚生成的接口却发现接口签名还没有落地。Wb-Flow 的差异在于三点任务拆分不是随意的而是先做依赖分析把强依赖关系排除出同一个 Wave。每个 Wave 有明确入口和出口入口是波次依赖的基线代码出口是验证通过后的新基线。并行只发生在 Wave 内部跨 Wave 仍然是串行保证系统在任意时刻都处于相对可控的状态。2. 一套可落地的 Wb-Flow 工作流设计2.1 整体流程先计划、再拆解、后执行Wb-Flow 的完整流程可以概括为六个阶段。需求分析把业务需求转化为技术目标。模块拆解识别代码仓库中需要改动的模块。依赖分析找出任务之间的读写依赖、接口依赖、测试依赖。波次编排把无依赖任务放进同一个 Wave把强依赖任务拆到不同 Wave。并行执行每个 Task 由一个 Agent 实例执行产出代码和测试结果。验证合并Wave 内所有任务完成后统一跑测试通过后合并到主分支。在实际项目中第 1 到第 4 步由人或编排器完成第 5 步交给 Agent第 6 步由 CI 或协调器完成。推荐把计划和编排放到版本控制里因为可审查、可回滚。2.2 计划文件作为唯一事实来源不要把计划只放在 Agent 的对话上下文里否则任务一多就无法追踪。Wb-Flow 推荐把计划落成一个文件包含仓库信息、波次列表、任务定义、验证命令和合并策略。这个文件的价值不只是给 Agent 看更是给整个人类团队看。Code Review 时评审者需要回答三件事这个需求拆得合理吗每个 Wave 的边界是否清晰每个任务的验收标准是否可执行计划文件一旦进入版本控制就变成了“唯一事实来源”。后续所有执行、排错、复盘都以它为基础。2.3 波次设计与依赖规则波次设计是 Wb-Flow 最核心的工作。划分是否合理直接决定并行效率与冲突数量。判断两个 Task 是否可以放进同一个 Wave可以看以下规则。判断依据可以同 Wave不能同 Wave文件交集完全不重叠或只有测试文件重叠改同一组核心类接口依赖Task A 不依赖 Task B 创建的接口Task A 必须调用 Task B 尚未实现的接口数据迁移各自迁移独立表同一张表的 schema 顺序变更测试影响测试包隔离两个 Task 都会修改同一套集成测试用例回滚影响失败时互不影响一个回滚会导致另一个无法工作依赖分析不需要完美只需要保证“被依赖的任务先进入前一个 Wave”并且“同一 Wave 内没有明显读写冲突”。如果两个任务都绕不开同一个核心接口那就不要犹豫拆成两个 Wave。3. 环境准备与最小项目结构3.1 你需要哪些前置工具Wb-Flow 本身不是一款单一工具而是一种工作流模式。实现它的工具可以选择现成编排系统也可以写一个轻量协调器。最少需要以下环境。工具版本建议用途Git2.x管理分支、基线、合并Python3.10编写轻量协调脚本PyYAML5.4解析计划文件Code Agent CLI按实际选择执行单个 Task 的 Agent 入口项目构建工具Maven / Gradle / npm / pip 等执行验证命令测试框架项目既有框架提供行为级验证这里的关键点是Agent CLI 必须支持“非交互式执行一个任务”。也就是说它要能接受一个任务描述文件然后自动完成代码修改最后退出并返回状态码。如果 Agent 只能打开交互式终端那很难被编排系统可靠驱动。3.2 仓库目录与任务文件一个典型 Wb-Flow 项目可以在仓库根目录下建一个.wbflow/目录。wb-flow-demo/ ├── .wbflow/ │ ├── plan.yaml │ └── tasks/ │ ├── t101.md │ ├── t102.md │ └── t201.md ├── src/ │ ├── main/ │ └── test/ └── README.mdplan.yaml描述整体编排tasks/下的 Markdown 文件描述每个 Task 的具体指令。之所以把指令拆成独立文件是为了让 Agent 在干净上下文里读取任务而不是在多个任务之间共享一份超长提示词。3.3 计划文件示例下面是一个简化但完整的plan.yaml。project: order-service base_branch: main waves: - id: wave-1 description: 建立领域模型和数据访问层 parallel: 2 tasks: - id: t101 description: 创建 Order 领域模型 instruction_file: .wbflow/tasks/t101.md target_files: - src/main/java/com/demo/order/Order.java - src/main/java/com/demo/order/OrderStatus.java validation: - mvn -pl order-service compile - mvn -pl order-service test -DtestOrderModelTest - id: t102 description: 创建 OrderRepository 接口 instruction_file: .wbflow/tasks/t102.md target_files: - src/main/java/com/demo/order/OrderRepository.java - src/test/java/com/demo/order/OrderRepositoryTest.java validation: - mvn -pl order-service compile - mvn -pl order-service test -DtestOrderRepositoryTest - id: wave-2 description: 实现订单创建用例并接入对外接口 parallel: 1 tasks: - id: t201 description: 实现 OrderService.createOrder instruction_file: .wbflow/tasks/t201.md target_files: - src/main/java/com/demo/order/OrderService.java - src/test/java/com/demo/order/OrderServiceTest.java validation: - mvn -pl order-service test -DtestOrderServiceTest这里parallel表示该 Wave 最大并发 Agent 数量。Wave 1 的两个任务分别改Order和OrderRepository文件没有交集可以并行。Wave 2 依赖前一个 Wave 生成的领域模型所以必须串行等待。注意target_files是给编排器和冲突检测用的不应该当作 Agent 的“禁止越界清单”。Agent 仍然可能因为编译需要而修改其他文件编排器需要在验证阶段统一检查实际变更范围。4. 实现一个最小 Wb-Flow 协调器4.1 读取计划协调器的职责很简单读计划、按 Wave 执行、收集结果。用 Python 写一个最小版本非常直接。import sys from pathlib import Path import yaml def load_plan(plan_path: Path) - dict: with plan_path.open(r, encodingutf-8) as f: return yaml.safe_load(f)需要先安装依赖。pip install pyyaml4.2 串行执行波次并行执行任务每一个 Wave 内部的任务可以并行但 Wave 之间必须串行。为了保证同一 Wave 内不互相干扰可以为每个 Task 创建独立分支Task 完成后先回到基线分支再启动下一个 Task。下面是一个最小执行函数。import subprocess from concurrent.futures import ThreadPoolExecutor, as_completed def run_command(command: str, cwd: str) - bool: result subprocess.run( command, shellTrue, cwdcwd, capture_outputTrue, textTrue, ) return result.returncode 0 def execute_task(task: dict, repo_path: str, base_branch: str): task_id task[id] branch f{base_branch}-{task_id} commands [ fgit checkout {base_branch}, fgit checkout -b {branch}, fagent run --task {task[instruction_file]}, ] for command in commands: if not run_command(command, repo_path): return {task_id: task_id, status: failed, stage: command} validation_results {} for validation in task.get(validation, []): validation_results[validation] run_command(validation, repo_path) if all(validation_results.values()): run_command(git add ., repo_path) run_command(fgit commit -m feat: {task_id} completed, repo_path) return {task_id: task_id, status: success, validation: validation_results} return {task_id: task_id, status: validation_failed, validation: validation_results} def execute_wave(wave: dict, repo_path: str, base_branch: str): task_results [] parallel wave.get(parallel, 1) with ThreadPoolExecutor(max_workersparallel) as pool: futures { pool.submit(execute_task, task, repo_path, base_branch): task for task in wave[tasks] } for future in as_completed(futures): task_results.append(future.result()) return task_results这个示例的核心思路是“每个任务一个临时分支 独立 Agent 进程”。不要试图让多个 Agent 同时在一个工作目录里改文件这样会覆盖彼此的进度。更好的做法是用git worktree为每个任务建立独立工作目录但最小示例中已经足够说明流程。4.3 验证门禁与结果汇总Wave 内全部任务执行后协调器需要做统一的验证门禁而不只是看每个任务自己的验证命令是否通过。def run_wave_gate(wave: dict, repo_path: str, base_branch: str): # 合并 Wave 内所有成功任务分支到临时集成分支 for task in wave[tasks]: branch f{base_branch}-{task[id]} run_command(fgit checkout -b wave-integration, repo_path) run_command(fgit merge {branch}, repo_path) gates wave.get(wave_validation, []) gate_results {} for gate in gates: gate_results[gate] run_command(gate, repo_path) return gate_results如果 Wave 门禁失败不应该直接把代码合回主分支。正确做法是把成功的 Task 分支保留在执行现场的归档分支里同时记录失败日志回滚集成测试分支。Wave 门禁应至少包括全量编译。与 Wave 相关的集成测试。静态代码检查。变更文件范围检查。5. 执行与验证如何判断一个 Wave 真的完成5.1 单任务验证单个 Task 的验证不能只依赖 Agent 自己输出“修改完成”。编排器需要主动执行 Task 里声明的validation命令。常见错误是只跑编译不跑测试。编译只能证明语法正确无法证明行为正确。推荐每个 Task 同时包含验证层级命令示例验证目标编译mvn compile/npm run build类型和语法正确单元测试mvn test -DtestOrderModelTestTask 自身逻辑正确接口契约mvn test -DtestRepositoryIntegrationTest与相邻模块的契约一致格式检查mvn spotless:check/npm run lint代码风格统一注意单元测试命中范围要尽量精确。如果一个 Task 的验证命令会跑整个项目的全部测试那么一个无关测试失败也会阻塞任务增加排查成本。5.2 波次验证单个 Task 都通过后还需要在“集成”视角做一次验证。因为两个 Task 在各自分支上单独测试可能通过合并到一起后可能冲突或者因为共享测试资源而互相影响。典型的 Wave Gate 命令如下。git checkout main git checkout -b wave-integration git merge task-branch-1 git merge task-branch-2 mvn verify这里的关键点是“验证必须发生在合并后的集成结果上”而不是分别验证后直接合入主分支。5.3 观察点与日志Agentic Coding 的排障比普通开发更难因为中间过程是自动生成的。协调器必须记录足够的执行日志。每个 Task 至少记录Task ID。使用的 Agent 命令。生成的实际文件变更列表。每个验证命令的输出摘要。分支名和提交 SHA。开始时间、结束时间、状态码。日志文件建议统一放到.wbflow/logs/wave-1/下方便后续复盘。6. 常见问题与排错路径6.1 三个典型坑坑一把所有任务塞进一个 Wave文件冲突严重现象多个 Agent 同时改同一个 Service合并时冲突率高解决冲突的时间远超并行节省的时间。原因波次设计阶段没有分析文件读写依赖。处理方式先做模块边界分析把改同一核心类的任务拆到不同 Wave。如果冲突仍不可避免降低parallel值甚至改为串行。坑二验证命令太弱只编译不测试现象Agent 报告成功但集成测试后业务逻辑错误需要返工。原因Validation 只配置了compile。Agent 把行为改错但语法完全正确。处理方式每个 Task 至少配一条行为测试命令Wave Gate 里再加入跨模块集成测试。坑三Agent 上下文过长后一个任务被前一个任务干扰现象同一个 Agent 进程被连续用于多个 Task后面的 Task 使用了前面 Task 的局部假设。原因没有为每个 Task 启动独立进程或者使用同一个对话上下文。处理方式每一个 Task 必须使用独立的 Agent 进程读取独立的instruction_file不要在长会话里叠加多个目标。6.2 从现象倒推根因的检查顺序如果 Wave 执行失败不要直接看代码逻辑先按以下顺序排查。确认计划文件里的base_branch是否正确。确认每个 Task 的分支是否从同一基线创建。检查 Agent 是否真的执行了instruction_file而不是靠内置 prompt 猜测。查看 Task 的validation命令是否在 Agent 执行后自动运行。检查验证失败是编译失败、测试失败还是静态检查失败。如果是合并冲突找出冲突文件确认是否属于波次内部依赖设计失误。如果是环境问题检查依赖安装、JDK 版本、Node 版本等是否与基线一致。对于多 Agent 并发场景还可以增加一个排错手段关闭并行把parallel改成 1重跑同一 Wave。如果能通过说明问题大概率是任务间的资源竞争或文件冲突而不是代码逻辑本身。7. 最佳实践与生产落地清单7.1 任务拆分粒度Task 拆得太小协调器开销和分支管理成本会高于收益拆得太大Agent 又要处理超长上下文和多个职责。推荐以“一个类或一个模块的一组内聚改动”为最小单位。例如创建实体类是一个 Task。创建对应 Repository 是另一个 Task。实现一个 Service 方法可以是一个 Task。修改数据库迁移脚本不要和业务代码塞进同一个 Task。对每个 Task都要能回答三个问题输入基线是什么要改哪些文件可验证的行为结果是什么7.2 并行度与冲突控制parallel并不是越大越好。并发数量越高对机器资源、Git 分支管理、验证命令隔离性的要求也越高。建议按以下经验值起步场景建议并行度学习环境仅验证流程2中小型业务模块文件边界清晰2 - 4大型仓库模块隔离完善4 - 8需要共享数据库或测试环境1 - 2如果验证命令依赖外部资源比如同一个测试数据库并行执行多个 Task 很容易互相污染数据。此时要么为每个 Task 准备隔离测试库要么把并行度降到 1。7.3 生产环境额外保障学习环境里一个 Python 脚本加一个 Agent CLI 就能跑通。生产环境落地 Wb-Flow还需要补齐以下能力。能力说明分支保护禁止 Agent 直接推送任意代码到 main所有变更必须经过 Wave Gate审计日志Agent 的每一次命令、每一个验证输出都要留痕配置外置plan.yaml中的命令最好不要写死路径使用环境变量失败回滚保留每个 Wave 的基线 Tag失败时可以快速恢复资源隔离并发 Agent 使用独立临时目录或git worktree容量告警监控并发 Agent 数、构建队列、日志量防止资源耗尽一个很实际的建议是不要让协调器直接与共享开发分支交互。每个 Wave 使用独立集成分支通过 MR/PR 合入主分支这样人类开发者仍然有最终把关的入口。7.4 发布前检查清单Wb-Flow 流程真正用于项目交付前建议逐项确认下面这张清单。[ ] 计划文件已提交到版本控制 [ ] 每个 Task 有独立 instruction_file [ ] 每个 Wave 内的 task 已做文件交集检查 [ ] 每个 Task 至少包含一个行为级验证命令 [ ] Wave Gate 包含集成测试和静态检查 [ ] 生产环境不允许 Agent 直推主分支 [ ] 并发 Agent 使用了独立工作目录 [ ] 失败后可以凭日志和基线 Tag 回滚 [ ] 验证命令不会依赖共享测试环境的脏数据 [ ] 每个 Wave 执行完成后有人类 Code Review 节点这张清单不是摆设。它解决的是 Wb-Flow 最核心的工程问题让 AI 生成的代码变更“有计划、可验证、能回滚”。8. 扩展方向Wb-Flow 的模式可以继续演进例如把plan.yaml交给一个“规划 Agent”自动生成让规划 Agent 先扫一遍代码依赖关系再输出波次编排结果。此时人类只需要审查计划而不需要逐条手写任务。也可以把 Wave Gate 接到现有 CI/CD 流水线中让每个 Wave 自动触发构建、测试、SonarQube 检查再决定是否进入合并队列。如果再配合 GitLab CI 或 GitHub Actions 的并发任务能力整条链路会更接近生产级。最值得记住的一点是Agentic Coding 的价值不取决于 Agent 单个任务写得多快而取决于整个变更流程是否能被计划、验证和回滚。Wb-Flow 的 Planned Parallel Waves 提供的正是这一层工程化保障。