Files

14 KiB
Raw Permalink Blame History

Octopus 工单驱动的工作流体系

Octopus 不只是一个会写代码的终端 AI 代理——它是一套以工单为契约、以门禁为骨架的工程化工作流体系。每一个功能、每一个修复、每一次重构,都作为一张类型化工单进入管线,沿着确定的路由前进,穿过强制的评审与验证门禁,最终带着完整的可审计记录落进主干。

为什么需要工单驱动

AI 代理写代码的能力已经足够强,真正的工程难题在于治理。在 Octopus 中,工单(issue)不是旁路的需求登记簿,而是流程的驱动轴,它同时解决四件事:

难题 工单驱动给出的答案
边界 一张工单天然划定"做什么 / 不做什么",代理的每次行动都有明确授权范围
验收 工单携带验收标准(acceptance criteria),完成与否可被第三方验证,而不是"看起来对了"
审计 从分解、评审、实现到验证,每一步都产出持久化工件,事后可以回答"这个变更为什么发生、经过谁之手"
并行 多个人类与多个代理会话基于工单分工协作,互不踩踏(配合 git worktree 会话隔离)

支撑这一切的铁律是声明纪律(claim discipline:任何状态断言——"测试通过"、"缺陷已修复"、"工作完成"——都必须有当轮产出的新鲜证据(命令、输出、退出码)支撑。置信不是证据,上一次运行的结果不是证据,"改动看起来对"更不是证据。

类型驱动路由:标签即流程

每张工单的 Kind/* 标签决定它的整条流程路线——进入哪个技能、跳过哪些阶段、哪些门禁必须保留。这套路由由一张路由表workflow-routing.yaml)声明式定义,主会话在任何动作之前先经 Step 0 路由解析route_resolver)查表,而不是临场自由发挥。

当前路由表速览:

工单类型 入口技能 保留的强制门禁 语义要点
Kind/Epic analyze-dag review-dag, verify 需求聚合 → 分解为任务 DAG(见下节)
Kind/Feature analyze-dag review-dag, review-code, verify 新功能同样走 DAG 管线;退化情形(工单自带实现)保留 review-code
Kind/Task 继承父级 review-code, verify DAG 父级下的子工单,走任务路由 implement → review-code → verify
Kind/Bug implementbugfix 模式) review-code, verify 缺陷报告本身就是规格说明——无需需求/设计阶段,但修复必须被证明
Kind/Security implementbugfix 模式) review-code, verify 紧急缺陷处理;若改动认证/权限契约,属设计级触发 → 升格 Kind/Feature
Kind/Refactor implementrefactor 模式) review-code, verify 行为保持不变的重构;大型跨文件重构在迭代内分批
Kind/Testing implement review-code, verify 仅测试变更;verify 强制(测试必须跑绿)
Kind/Process review-artifact(过程审计) audit-process 改的是 .octopus/ 工作流系统本身——先审计再落地
Kind/Documentation 直接编辑 (可选轻量评审) 文档不进完整管线,除非它编码了一份契约
Kind/MVP 交互模式(无管线) 早期概念:工单体即文档,维护决策日志与债务登记
无标签 自然语言匹配 按匹配结果 未标注的工单行为与路由启用前完全一致

三条结构性原则:

  1. 路由是纯增量的(additive:路由只能跳过某类工单不需要的阶段,永远不能削弱强制门禁。路由表的 skip 与技能自身的强制门取交集——两边都同意可跳,才算可跳。
  2. 标签错了不悄悄改:如果 Kind/Bug 挂在了一个功能形态的工单上,代理不会擅自改标签,而是按标签走路由、同时显式上报不匹配——标签的正确性归创建者所有。
  3. 大 Bug 升格规则:根因是设计决策、或改动共享契约/公共 API/数据迁移的缺陷,已经超出了 Bug 类型的容量——强制升格 Kind/Feature 走小型 DAG(预期 1–3 节点),绝不把设计级变更硬塞进 bugfix 通道。

DAG 工单管线:分解即计划

Kind/EpicKind/Feature 进入 DAG 工单管线——工作流体系最核心的特征。传统做法里"路线图 → 需求 → 设计 → 迭代计划"是四份会互相漂移的文档;Octopus 把它们合并成一份任务 DAG 工件

analyze-dag 分解 ──▶ 任务 DAG 工件 ──▶ review-dag 单门 ──PASS──▶ 建 Kind/Task 子工单
                     (节点=验收标准      (TOPO/REQMAP/           │
                      边=跨节点契约       RELEASE 三维评审)        ▼
                      拓扑=执行计划)                       每张子工单:
                                                 implement → review-code → verify

分解(analyze-dag。Analyst 把 Epic 分解为一张任务 DAG:每个 task 节点就是一条可验收的工作项,每条边是节点之间的契约(跨会话接口承诺),拓扑顺序就是执行计划。分解产出即冻结副本,后续所有会话以它为共同基线。

单门评审(review-dag。三个维度并行评审:TOPO(拓扑合理吗)、REQMAP(验收标准覆盖需求吗)、RELEASE(切分可发布吗)。这一道门替代了旧体系的"设计空间评审 + 迭代计划评审"两道门,且结构性永不裁剪never_trim)。

深度即档位(size_derivation。评审深度不是拍脑袋定的,由 DAG 的实测属性派生:

维度 D1 D2 D3 D4
节点数 ≤3 48 915 >15
跨会话边数 0 ≤3 ≥4
契约变更面 仅新增 破坏性

取三维最坏值定 D1–D4,D1 由 1 名评审员 2 轮收敛,D4 是 5 名评审员(TOPO:2 REQMAP:2 RELEASE:1 分维)最多 4 轮。分解即定档——不再需要人工挂规模标签。

运行期增长信号。实现期现实与分解漂移时,管线不装死:节点分裂、出现评审范围外的新跨会话边、已冻结契约被破坏——任何一条触发都强制重新派生深度 + 重跑 review-dag。工单类型也不是一成不变的:现实超出标签容量时,"按书面执行、把疑点摆上桌面"、可见地重分类。

里程碑汇聚(verify_milestone。跨会话扇入 ≥2 的汇聚点自动焊入里程碑;全部入边任务完成且绿灯后触发集成验证(DoD 矩阵由 DAG 切片自动生成)。里程碑本身不建工单——它的完成定义由 verify 承担。

强制门禁:review-code 与 verify

管线里的每段生产工作后面都紧跟一道评审门禁,没有例外路径

  • review-code——代码评审门。按风险档位并行派出最多 10 名独立评审员(Explorer 子代理),每人一个维度对照评审清单扫描,Worker 编排者汇总发现、开发者修订,迭代至收敛。DAG 任务模式下评审对照冻结的 DAG 节点规格与跨会话契约做范围比对——节点实现蔓延出分解边界本身就是发现。
  • verify——验证门。运行迭代的 DoD(完成定义)矩阵、集成测试、NFR 校验与回归检查。迭代在所有 DoD 项通过之前不算完成——无论代码看起来多好。
  • 评审轮次预算。默认 2 轮、高风险 3 轮封顶——超预算未收敛即 STOP,剩余发现转入技术债务登记册收口,不允许无限马拉松式评审。

人机决策门:自动批准的边界

代理需要不停地做流程决策("评审通过了,进入下一阶段吗?")。Octopus 把决策门分成性质完全不同的两类:

执行类门禁可以白名单放行auto_approve.stages 声明哪些阶段的问题可自动通过(如 review-codeverifyaudit-process)。即便自动放行,还有一条活人降级链:有真人在线看着会话(L1)→ 问题落到 Gitea 工单评论等回复(L2)→ 才轮到推荐项自动默认(L3)。

业务决策永远必须人答。以下类别的问题无条件强制人工确认destructive 铁律,任何白名单都不覆盖):

  1. 合并 PR 到主干 / 打 tag / 发版 / 上生产
  2. 生产数据库写入(含迁移、回填)
  3. 计费与套餐变更
  4. 组织 / 租户结构变更
  5. 删除持久资源
  6. 超出会话生命周期的持久配置写入

一条阶段白名单授予的是"执行门可以不间断前进",永远不是"业务决策可以自问自答"。

工单生命周期治理

  • 认领与 WIP 上限:开放的无主工作票超过上限(默认 40 张)时,新工作票必须携带排期证据,否则降为登记册行——用机制而非纪律防止工单堆积。
  • 冲刺降档(sprint-mode:冲刺期间独立工单创建冻结、登记照常(严重度零丢失),开关回落后登记行按正常链路升格。失败证据类工单不受降档影响——失败必须立即可见。
  • MVP 早期概念模式:一张工单、一个线程、零管线开销;工单体即文档(每决策一行:选了什么/为什么/何时失效)。出现第二个消费者、外部契约或决策冲突即"毕业"——升格标签,反向进入 DAG 管线的回填模式。
  • 生产者预检(preflight:复盘阶段统计每条路线首轮评审 FAIL/WARN 的高频根因,把 Top 根因作为检查清单注入该路线的实现派发(如"动手前每个验收标准必须映射到可证伪的测试断言")——在人犯错之前提醒人,而不是在评审里再抓一遍。清单项的进入与退出都有数据阈值,提示词永不自动变异。

两层工件体系:过程即档案

每个工作流运行(run)的所有产物落入两层工件体系,索引守卫保证可恢复、可审计:

位置 受众 内容
Tier 1 .octopus/runs/{slug}/ 机器 运行索引、DAG 冻结副本、每轮评审发现 JSON、DoD 矩阵
Tier 2 Gitea wiki {slug}/ 空间 评审综合报告、计划页、叙述性文档

配套的压缩纪律保证长管线跑得完:上下文压缩只发生在干净的阶段边界(工件已持久化之后),且由容量触发器驱动;压缩后代理不依赖对话记忆,而是重读持久化工件恢复现场。任何压缩摘要开头都有身份卡,先核对身份再继续干活——防止拿着上一个会话的残影做这个会话的决定。

多智能体协作模型

Octopus 的主会话是协调者而非工人

  • Explorer 子代理——只读探索:找文件、搜模式、回答"X 怎么工作",结果即时返回;
  • Worker 子代理——多步执行:写代码、跑测试、修失败,先持久化产出再结束
  • 并行派发——独立子任务一次性并行发出,避免主会话上下文被文件内容与工具输出淹没。

会话级隔离由 git worktree 纪律保障:并发分支工作必须各占独立 worktree(主 checkout 单占用),分支劫持事故有审计日志可归因;子代理共享同一工作流 worktree——隔离发生在工作流之间,而不是协同的子代理之间。

合并队列:落地的最后一道秩序

代码评审收敛后,PR 打上 ready-to-merge 标签进入服务端串行合并队列

  • 队头 PR 由协调机器人校验"标签 + 双绿(CI 检查 + 合并门)+ 风险双检(有 Risk/Low 且无 Risk/High"后 approve 并合并;
  • 非队头 PR 自动做 keep-mergeable 保活(绝不手写合并 main 的保活提交);
  • 机械类低风险 PR(依赖升级、锁文件、bot 作者)走 fast-lane 快速通道自动补标签;
  • 真冲突的 PR 经 merge-tree 预探后出队留痕,不动分支。

一张工单的完整旅程

以一个新功能为例,把所有机制串起来:

  1. 创建:功能工单打上 Kind/Feature 标签,写清动机与验收期望;
  2. 路由:主会话 Step 0 查路由表 → DAG 管线,先过过程评估门再动手;
  3. 分解analyze-dag 产出任务 DAG——节点是验收标准、边是契约、拓扑是计划;实测属性派生出 D1–D4 档位;
  4. 单门review-dag 三维并行评审(拓扑/需求映射/可发布性),迭代至收敛 PASS;
  5. 拆票:聚合代理为每个任务节点建一张 Kind/Task 子工单,父工单聚合状态总览;
  6. 实现:每张子工单独立走 implement(含生产者预检)——在独立 worktree 分支上;
  7. 代码评审review-code 多评审员对照节点规格与冻结契约并行扫描,轮次预算内收敛;
  8. 验证verify 跑 DoD 矩阵与集成测试;跨会话汇聚点触发里程碑验证;
  9. 落地PR 打 ready-to-merge 进合并队列,双绿 + 风险双检通过后自动合并进主干;
  10. 归档:全部工件已在两层体系留档,工单关闭——过程即档案。

小结

工单驱动不是"给 AI 加了个 TODO 列表",而是一套完整的工程治理契约:

  • 类型即路由——标签决定流程,流程不再临场发挥;
  • 分解即计划——一份 DAG 工件替代四份会漂移的文档;
  • 门禁即质量——评审与验证不可绕过、不可裁剪、有轮次预算;
  • 证据即真相——没有新鲜证据的状态断言一律无效;
  • 工件即档案——过程可恢复、决策可追溯;
  • 人在环上——执行门可自动,业务决策永远人工。

这套体系本身也是工单驱动的:对 .octopus/ 工作流系统的任何改进都走 Kind/Process 过程审计路由——系统吃自己的狗粮。