工作流编排模式:规划-执行-验证流水线
工作流编排模式:规划-执行-验证流水线
学习目标
- 理解 OMX 的三阶段标准工作流及其门控机制
- 掌握 Autopilot 严格循环流水线的自动衔接与回退
- 了解阶段门控的具体实现(完成门、共识证据门、质量门控)
- 理解模式状态机的生命周期管理
前置知识
本章涉及工作流编排的通用原理,建议先阅读:
下文假设你已理解上述概念,直接聚焦 Oh-My-Codex 的具体实现。
项目实践
三阶段标准工作流
OMX 的推荐工作流是一个三阶段流水线:
各阶段的职责:
| 阶段 | 技能 | 输入 | 产出 | 门控 |
|---|---|---|---|---|
| 需求澄清 | $deep-interview | 用户模糊的需求 | 已回答的问题列表 + 澄清后的规范 | 所有问题已回答 |
| 方案审批 | $ralplan | 澄清后的规范 | PRD + 测试规范 + ADR | Architect + Critic 共识 |
| 多目标执行 | $ultragoal | 批准的计划 | 代码变更 + 审计日志 | 三方质量门控 |
阶段门控的具体实现
Deep-Interview → Ralplan 门控
伪代码(src/autopilot/deep-interview-gate.ts):function evaluateDeepInterviewGate(state): // 检查1: 完成门 allQuestionsAnswered = state.questions.length > 0 && state.questions.every(q => q.answered)
// 检查2: 用户授权跳过门 userSkipAuth = findUserAuthorization(userActions, "deep-interview")
if allQuestionsAnswered: return { passed: true, reason: "All questions answered" } if userSkipAuth && userSkipAuth.explicit: return { passed: true, reason: "User authorized skip" }
return { passed: false, reason: "Unanswered questions remain" }Ralplan → Ultragoal 门控
伪代码(src/autopilot/ralplan-gate.ts):function evaluateRalplanGate(state): // 需要 tracker-backed native architect AND critic 共识证据 // 必须按 Architect → Critic 顺序 architectEvidence = findEvidence("architect_review", state) criticEvidence = findEvidence("critic_review", state)
if not architectEvidence: return { passed: false, reason: "Missing architect review" } if not criticEvidence: return { passed: false, reason: "Missing critic review" } if not isSequentialOrder(architectEvidence, criticEvidence): return { passed: false, reason: "Reviews not in Architect-then-Critic order" }
consensus = architectEvidence.passed && criticEvidence.passed return { passed: consensus, reason: consensus ? "Consensus reached" : "Architect/Critic disagreement" }为什么要求 Architect → Critic 顺序:Critic 可以看到架构师的审查结果,但必须独立判断。这防止了”两个角色同时审查但互相忽略”的情况。
Autopilot 严格循环流水线
Autopilot FSM(src/autopilot/fsm.ts)定义了完整的自动流水线:
$deep-interview → $ralplan → $ultragoal → $code-review → $ultraqa伪代码(Autopilot FSM 循环):async function runAutopilot(brief): maxReviewCycles = 10
for cycle in 1..maxReviewCycles: // 阶段1: 需求澄清 interviewResult = await runSkill("deep-interview", { brief }) if not evaluateDeepInterviewGate(interviewResult): continue // 重试
// 阶段2: 方案审批 planResult = await runSkill("ralplan", { spec: interviewResult.spec }) if not evaluateRalplanGate(planResult): continue // 回退到 ralplan 修改
// 阶段3: 多目标执行 execResult = await runSkill("ultragoal", { plan: planResult.plan })
// 阶段4: 代码审查 reviewResult = await runSkill("code-review", { changes: execResult.changes })
// 阶段5: 质量验收 qaResult = await runSkill("ultraqa", { review: reviewResult })
if qaResult.verdict == "clean": return { status: "complete", cycles: cycle }
// 非清洁 → 回退到 ralplan,携带审查发现 brief = `Fix these issues: ${qaResult.findings}`
return { status: "max_cycles_exceeded", cycles: maxReviewCycles }Autopilot 模式状态文件(.omx/state/autopilot-state.json):
伪代码:{ "active": true, "currentPhase": "ultragoal", // deep-interview | ralplan | ultragoal | team | ralph | code-review | ultraqa "iteration": 1, "reviewCycle": 2, "maxReviewCycles": 10, "startedAt": "2026-06-05T..."}模式状态机
OMX 的模式状态机(src/modes/base.ts)管理所有工作流模式的生命周期:
伪代码:interface ModeState { mode: string // "autopilot" | "ralph" | "team" | "ultragoal" | ... active: boolean phase: string // 当前阶段 iteration: number // 迭代计数 startedAt: string}
// 状态转换function startMode(mode, initialPhase): assertValidTransition(currentMode, mode) writeState({ mode, active: true, phase: initialPhase })
function updateMode(mode, newPhase): state = readState() assert state.mode == mode state.phase = newPhase writeState(state)
function cancelMode(mode): state = readState() state.active = false writeState(state)工作流转换规则:
| 当前模式 | 允许转换到 | 禁止转换到 |
|---|---|---|
| deep-interview | ralplan, cancel | ralph, autopilot(需先完成规划) |
| ralplan | ultragoal, cancel | ralph, team(需先获得共识) |
| ralph | cancel, complete | autopilot(ralph 是独立循环) |
| autopilot | cancel | team(模式不兼容) |
工作流转换规则的具体实现
伪代码(state/skill-active.ts):function evaluateWorkflowTransitionRules(newSkill, currentState): // 规则1: 规划技能必须先于执行技能 if newSkill in EXECUTION_SKILLS and currentState.lastSkill not in PLANNING_SKILLS: if not hasPlanningArtifact(currentState): return { allowed: false, reason: "Planning artifact required before execution" }
// 规则2: 不兼容模式不能重叠 if newSkill == "team" and currentState.activeSkill == "autopilot": return { allowed: false, reason: "Team and Autopilot modes are incompatible" }
// 规则3: 终止技能不能在激活后再次启动 if newSkill in TERMINAL_SKILLS and currentState.activeSkill in TERMINAL_SKILLS: return { allowed: false, reason: "Cannot start new terminal skill while one is active" }
return { allowed: true }问题与规避
| 问题 | 后果 | OMX 的规避策略 |
|---|---|---|
| 门控条件过于严格 | 流水线频繁阻塞 | 用户授权跳过门作为逃生舱 |
| 审查循环超限 | 无限循环消耗资源 | maxReviewCycles = 10 硬性上限 |
| 模式状态丢失 | 会话重启后无法恢复 | 模式状态持久化到 .omx/state/ |
| 阶段跳过无审计 | 无法追溯为何跳过某阶段 | 所有跳过都记录到状态文件 |
设计取舍
为什么 Autopilot 选择严格循环而非灵活编排?
OMX 的 Autopilot 模式采用固定的流水线顺序,不支持用户自定义节点顺序。
优势:
- 可预测性:用户知道每一步会做什么
- 门控保障:每个阶段间都有预设的门控
- 简化调试:问题可以追溯到具体阶段
代价:
- 灵活性低:某些任务可能不需要需求澄清阶段
- 学习成本:用户需要理解流水线才能有效使用
替代方案:
- 用户自定义流水线(如 LangGraph 的方式):更灵活但增加了配置复杂度
- Agent 自主选择阶段:更智能但不可预测
参考来源
- Oh-My-Codex v0.18.9 源码 —
src/autopilot/fsm.ts(Autopilot FSM) - Oh-My-Codex v0.18.9 源码 —
src/autopilot/deep-interview-gate.ts(面试门控) - Oh-My-Codex v0.18.9 源码 —
src/autopilot/ralplan-gate.ts(Ralplan 门控) - Oh-My-Codex v0.18.9 源码 —
src/modes/base.ts(模式状态机) - Oh-My-Codex v0.18.9 源码 —
src/state/skill-active.ts(技能激活状态)