整体架构
Autopilot 是一个六阶段流水线,每个阶段有明确的输入、执行者、输出文件。前一阶段必须完成后才能进入下一阶段。
你的需求 → Phase 0 → Phase 1 → Phase 2 → Phase 3 → Phase 4 → Phase 5 → 完成
spec.md 计划文件 代码 QA 审核 清理
Phase 0 — 需求扩展(Expansion)
目标: 把一句话需求变成可执行的技术规格。
执行步骤:
- 检查是否已有 ralplan 共识计划或 deep-interview 规格 → 有则跳过
- 检查需求是否太模糊 → 太模糊则建议先做 deep-interview
- Analyst (Opus) 提取功能需求
- Architect (Opus) 写技术规格
输出文件: .omc/autopilot/spec.md
我们的 spec.md 包含:
- §1 系统架构(Next.js + PostgreSQL + Auth.js)
- §2 数据模型(12 张表,每张表的列、类型、约束、索引)
- §3 核心功能与用户流程(学习、修行、记录、反馈、管理员)
- §4 非功能需求(性能、安全、无障碍、国际化)
- §5 MVP 范围(哪些做,哪些不做)
- §6 API 路由表(28 个端点,方法、用途、权限)
- §7 数据库模式(触发器、RLS、SLA 监控、反游戏化)
- §8 验证规则(三层防御:客户端 Zod + 服务端 Zod + 数据库 CHECK)
- §9 错误处理规范(标准 JSON 格式,8 种错误码)
- §10 未决问题(7 个待确认的设计决策)
没有 spec.md 的后果: 开发时不知道要建多少表、写多少个 API、数据怎么流转,只能瞎猜。
Phase 1 — 实施计划(Planning)
目标: 把规格变成可执行的任务清单,并验证计划的正确性。
执行步骤:
- Architect (Opus) 读 spec,拆成里程碑
- 每个里程碑标注输出文件、依赖关系
- Critic (Opus) 审核计划,对照 spec 找遗漏和错误
- 修改计划直到 Critic 通过
输出文件: .omc/plans/autopilot-impl.md
为什么 Critic 审核很重要:
在我们的项目中,Critic 发现了 15 个问题:
┌──────────────┬──────────────────────────────────────────────────────────────┐
│ 问题类型 │ 具体发现 │
├──────────────┼──────────────────────────────────────────────────────────────┤
│ 依赖关系错误 │ M7(教师面板)依赖 M6(反馈 API),但计划写了 M4→M7 并行 │
├──────────────┼──────────────────────────────────────────────────────────────┤
│ 缺失 API │ 3 个课程/课程详情 REST 端点未列出 │
├──────────────┼──────────────────────────────────────────────────────────────┤
│ 安全漏洞 │ CSRF 保护完全没有 │
├──────────────┼──────────────────────────────────────────────────────────────┤
│ 数据缺失 │ 管理员内容 CRUD 的 API 路由没写 │
├──────────────┼──────────────────────────────────────────────────────────────┤
│ 业务逻辑 │ 反馈自动创建条件未说明(需 visibility≠private + 有活跃教师) │
└──────────────┴──────────────────────────────────────────────────────────────┘
没有实施计划的后果: 不知道从哪里开始写代码,不知道哪些文件可以并行写,不知道依赖顺序,编写时容易遗漏整套功能模块。
Phase 2 — 并行执行(Execution)
目标: 按照实施计划写代码。
执行策略:
- 独立的里程碑分配给不同 Agent 并行执行
- 基础层(数据库、认证、中间件)先写,上层页面后写
- Agent 按复杂度分级:
- Haiku → 简单任务(改注释、格式化)
- Sonnet → 标准任务(写页面、API 路由)
- Opus → 复杂任务(架构设计、重构)
我们这个项目的并行分配:
我(主线程)写基础层 Agent 1 (Sonnet) Agent 2 (Sonnet)
├─ drizzle/schema.ts (12表) ├─ app/layout.tsx ├─ app/api/practice-logs/
├─ lib/db.ts ├─ components/layout/ ├─ app/api/reflections/
├─ lib/errors.ts ├─ app/signin/page.tsx ├─ app/api/admin/users/
├─ lib/rls.ts ├─ app/onboarding/page.tsx ├─ app/api/admin/courses/
├─ middleware.ts ├─ app/profile/page.tsx ├─ app/api/admin/lessons/
├─ auth.ts ├─ app/courses/ ├─ app/api/internal/
├─ drizzle.config.ts ├─ app/lessons/[id]/ ├─ app/teacher/
├─ messages/en.json ├─ hooks/useVideoProgress.ts ├─ app/admin/
└─ 各种配置文件 └─ components/lesson/ └─ 所有管理后台 API
三个执行者同时工作,完成后主线程合并 → 修复编译错误 → 67 个源文件,0 TypeScript 错误。
Phase 3 — QA 循环(Quality Assurance)
目标: 确保代码能编译、能构建、测试能通过。
执行循环:
- npm run build → fail
- 分析错误 → 修复 → 重试
- 同一错误出现 3 次 → 停止并报告给用户
- 最多 5 轮
我们遇到的实际问题:
RSC 页面在 build 时尝试连接数据库 → 数据库不存在 → 构建失败。
修复:所有数据库查询页面加 export const dynamic = 'force-dynamic',阻止静态预渲染。修完后 26 条路由全部构建成功。
Phase 4 — 多维度审核(Validation)
目标: 三个专家从不同角度审查代码,确保功能完整、安全、代码质量。
三个审核者并行运行:
┌──────────────────────────┬────────────┬───────────────────────────────────────────────────────┐
│ 审核者 │ 角色 │ 关注点 │
├──────────────────────────┼────────────┼───────────────────────────────────────────────────────┤
│ Architect (Opus) │ 功能完整性 │ 对照 spec,检查是否所有 API、数据表、功能流程都实现了 │
├──────────────────────────┼────────────┼───────────────────────────────────────────────────────┤
│ Security-Reviewer (Opus) │ 安全漏洞 │ OWASP Top 10、CSRF、XSS、SQL 注入、认证绕过 │
├──────────────────────────┼────────────┼───────────────────────────────────────────────────────┤
│ Code-Reviewer (Sonnet) │ 代码质量 │ 重复代码、类型安全、命名规范、架构一致性 │
└──────────────────────────┴────────────┴───────────────────────────────────────────────────────┘
我们项目中各审核者的发现:
Architect:
- CSRF 是空壳(不实际拒绝请求)
- completed_at 生成列缺失
- reject teacher 函数调用错误的 API
- 3 个 REST API 路由缺失
Security-Reviewer:
- CSRF 保护无效
- 缺少安全头(CSP、HSTS 等)
- JWT session 30 天太长
- sandbox 属性有 allow-same-origin
Code-Reviewer:
- force-dynamic 在 6 个 client 组件上无效
- 多处 as any 绕过类型检查
- 视频播放追踪在 iframe 加载时就触发(不应在播放前触发)
- RBAC 逻辑在两个文件中重复
全部修复后才算审核通过。
Phase 5 — 清理(Cleanup)
删除所有状态文件:
.omc/state/sessions/*/autopilot-state.json
.omc/state/autopilot-state.json
输出总结给用户。