Freeze the architecture decision for 8-batch unified AI migration. Covers current/target topology, API/Worker process boundaries, 5 Processors, Heavy Runtime disposition, phase-1 non-goals, rollback principles, and cross-batch constraints. Includes Appendix A: worker dependency closure audit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.5 KiB
7.5 KiB
ADR-001:统一 AI 架构迁移决策
状态
已接受(2026-06-19)
背景
当前知习项目存在两套独立的 AI 分析系统,以及一套规则出题系统:
- 系统 A(BullMQ + TypeScript,运行中):处理 active-recall 和 feynman-evaluation 分析,通过
AiAnalysisWorker在 NestJS 进程内执行,写入AiAnalysisJob/AiAnalysisResult表,创建FocusItem,发布ai.analysis.completed事件驱动ReviewCardSubscriber生成复习卡片。 - 系统 B(Rust + HTTP 轮询,闲置):
zhixi-heavy-runtime独立进程,支持 5 种分析类型(learning_state_analysis、weak_point_analysis、next_action_planning、quiz_generation、flashcard_generation),通过轮询AiRuntimeJob表获取任务,调用 DeepSeek API,结果写入多个相互独立的领域表。 - 系统 C(规则出题,运行中):
QuizService.create()通过纯文本拼接生成测验题目,不调用任何 AI 模型。
系统 B 存在以下关键问题:
- 无任务生产者 — 唯一创建
AiRuntimeJob的入口POST /ai/jobs无人调用 - Snapshot 结构不兼容 — Rust 端
LearningAnalysisSnapshot结构体与 API 端SnapshotBuilderService产出的 JSON 结构完全不匹配 - Rust 无重计算 — 所有 Pipeline 的独有业务逻辑总和不足 50 行,实际是一个 HTTP 代理层
- 数据断层 — Rust 结果写入的表(
AiLearningAnalysis、WeakPointCandidate、NextActionRecommendation)无 iOS/Admin 消费端
同时,当前 API 进程内注册 BullMQ Processor 的部署拓扑存在以下问题:
- API 进程与 Worker 进程边界模糊,Docker 与生产环境配置不一致
AppModule中同时注册AiAnalysisWorker、DocumentImportWorker、NotificationWorkerWorkerModule和worker.main.ts已存在但未独立使用
决策
采用 8 批次渐进式迁移,将 AI 分析能力从 BullMQ + Rust 双系统统一到单一 BullMQ + TypeScript 架构。
目标架构拓扑
┌─────────────┐
│ iOS App │
└──────┬──────┘
│ HTTP
┌──────▼──────┐
│ zhixi-api │ NestJS (仅 Controller + Queue Producer)
│ :3000 │ 不注册任何 @Processor()
└──────┬──────┘
│ Redis (BullMQ)
┌──────▼──────┐
│ zhixi-worker│ NestJS (仅 @Processor())
│ (无端口) │ AiAnalysisWorker + DocumentImportWorker
└──────┬──────┘ + NotificationWorker + AuditLogProcessor
│ HTTP + FileCleanupProcessor
┌──────▼──────┐
│ DeepSeek │
│ API │
└──────────────┘
API Process 职责
- 暴露所有 HTTP Controller
- 注入 Queue Producer(
QueueService.add()) - 不注册任何
@Processor()或WorkerHost - 不启动 BullMQ Worker 实例
Worker Process 职责
- 注册所有
@Processor()和WorkerHost - 消费 BullMQ 队列
- 调用 AI Workflow → DeepSeek API
- 写入分析结果表
- 发布领域事件
- 不暴露 HTTP 端口
Heavy Runtime 当前处置
- 第一阶段保持部署但不修改
- 不停止 Rust 进程
- 不删除
AiRuntimeJob及相关表 - M-AI-08 正式退场
迁移批次
| 批次 | 名称 | 范围 |
|---|---|---|
| M-AI-01 | Worker 进程边界与部署收口 | 拆分 API/Worker 进程,不改变业务 |
| M-AI-02 | 统一 AiJob 数据库 Expand | 扩展 AiAnalysisJob,新增 Artifact/Snapshot/Outbox |
| M-AI-03 | 统一 Job Engine、Registry 与 Outbox | AiJobService + Registry + 双队列 |
| M-AI-04 | Active Recall 端到端迁移 | 切换生产者,iOS 展示真实结果 |
| M-AI-05 | Feynman 与 ReviewCard 可靠链路 | Outbox 替代进程内 EventEmitter |
| M-AI-06 | AI Quiz 端到端迁移 | 迁移 Rust Prompt/Schema,异步生成 |
| M-AI-07 | 后台学习分析与推荐闭环 | learning_state/weak_point/next_action |
| M-AI-08 | Heavy Runtime 退场与 Legacy Contract | 停止 Rust,归档表 |
第一阶段非目标(M-AI-01)
- 不修改
AiAnalysisJob/AiRuntimeJob表结构 - 不新建统一 AiJob 模型
- 不迁移 Active Recall、Feynman 或 Quiz 业务链路
- 不停止
zhixi-heavy-runtime服务 - 不修改 iOS 代码
- 不删除任何数据库表
- 不修改 AI Prompt、模型或业务结果结构
- 不新增 Prisma Migration
架构约束
以下约束在所有批次中持续生效:
AppModule不允许注册@Processor()或WorkerHostWorkerModule不允许暴露公开 HTTP Controller- 不允许新建第三套 AI Job 模型(除 M-AI-02 统一扩展外)
- 不允许顺带修改 Prompt、模型选择或业务结果 Schema(各自独立 Issue)
- 没有 iOS/Admin 消费者的任务类型不得启用自动生成
- 自动触发必须有频率限制、幂等保护、成本上限
回滚原则
每个 Issue 必须提供独立回滚方案:
- 代码层面:回滚提交或 revert PR
- 数据库:本批次不涉及 Schema 变更,无需数据回滚
- 部署:恢复旧 AppModule Processor 注册,停止独立 Worker service
- 队列:验证无双重消费
现有 Processor 清单
| Processor | 队列 | 文件 |
|---|---|---|
AiAnalysisWorker |
ai-analysis |
workers/ai-analysis.worker.ts |
DocumentImportWorker |
document-import |
workers/document-import.worker.ts |
NotificationWorker |
notification |
workers/notification.worker.ts |
AuditLogProcessor |
audit-logs |
modules/admin-audit-log/audit-log.processor.ts |
FileCleanupProcessor |
file-cleanup |
modules/files/file-cleanup.processor.ts |
模块依赖图(当前)
AppModule
├── WorkerModule (已存在但未独立使用)
│ ├── AiAnalysisWorker
│ ├── DocumentImportWorker
│ └── NotificationWorker
├── QueueModule
│ ├── BullModule.forRootAsync (Redis 连接)
│ └── BullModule.registerQueue (6 个队列)
├── AiAnalysisModule
│ ├── AiAnalysisController (HTTP 端点)
│ └── AiAnalysisService (BullMQ Producer)
├── ActiveRecallModule
│ └── ActiveRecallService (BullMQ Producer 调用者)
├── ReviewModule
│ ├── ReviewController (HTTP 端点)
│ ├── ReviewCardSubscriber (监听 ai.analysis.completed)
│ └── ReviewService
├── AiRuntimeModule
│ ├── UserAiController (HTTP 端点)
│ └── RuntimeInternalController (Rust 内部端点)
├── AdminAuditLogModule
│ └── AuditLogProcessor (@Processor)
└── FilesModule
└── FileCleanupProcessor (@Processor)
后续 Issue 引用
后续 M-AI-01 Issue 必须引用本文档(ADR-001)作为架构约束依据。
证据
- 当前部署:
docker-compose.yml:1-70— API 和 Worker 共享同一 NestJS 实例 - Worker 模块:
worker.module.ts:1-20— 已定义但未独立使用 - Worker 入口:
worker.main.ts:1-10— 已存在但未被 Docker/生产独立调用 - 现有架构文档:
docs/ai-runtime-architecture.md— 描述 Rust Heavy Runtime 架构 - BullMQ 版本:
bullmq@5.77.1、@nestjs/bullmq@11.0.4