api-server/docs/architecture/adr-001-unified-ai-architecture.md
wangdl 54bc505f7a docs: add ADR-001 unified AI architecture decision record
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>
2026-06-19 20:10:35 +08:00

7.5 KiB
Raw Permalink Blame History

ADR-001统一 AI 架构迁移决策

状态

已接受2026-06-19

背景

当前知习项目存在两套独立的 AI 分析系统,以及一套规则出题系统:

  • 系统 ABullMQ + TypeScript运行中:处理 active-recall 和 feynman-evaluation 分析,通过 AiAnalysisWorker 在 NestJS 进程内执行,写入 AiAnalysisJob/AiAnalysisResult 表,创建 FocusItem,发布 ai.analysis.completed 事件驱动 ReviewCardSubscriber 生成复习卡片。
  • 系统 BRust + 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 存在以下关键问题:

  1. 无任务生产者 — 唯一创建 AiRuntimeJob 的入口 POST /ai/jobs 无人调用
  2. Snapshot 结构不兼容 — Rust 端 LearningAnalysisSnapshot 结构体与 API 端 SnapshotBuilderService 产出的 JSON 结构完全不匹配
  3. Rust 无重计算 — 所有 Pipeline 的独有业务逻辑总和不足 50 行,实际是一个 HTTP 代理层
  4. 数据断层 — Rust 结果写入的表(AiLearningAnalysisWeakPointCandidateNextActionRecommendation)无 iOS/Admin 消费端

同时,当前 API 进程内注册 BullMQ Processor 的部署拓扑存在以下问题:

  • API 进程与 Worker 进程边界模糊Docker 与生产环境配置不一致
  • AppModule 中同时注册 AiAnalysisWorkerDocumentImportWorkerNotificationWorker
  • WorkerModuleworker.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 ProducerQueueService.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

  1. 不修改 AiAnalysisJob / AiRuntimeJob 表结构
  2. 不新建统一 AiJob 模型
  3. 不迁移 Active Recall、Feynman 或 Quiz 业务链路
  4. 不停止 zhixi-heavy-runtime 服务
  5. 不修改 iOS 代码
  6. 不删除任何数据库表
  7. 不修改 AI Prompt、模型或业务结果结构
  8. 不新增 Prisma Migration

架构约束

以下约束在所有批次中持续生效:

  1. AppModule 不允许注册 @Processor()WorkerHost
  2. WorkerModule 不允许暴露公开 HTTP Controller
  3. 不允许新建第三套 AI Job 模型(除 M-AI-02 统一扩展外)
  4. 不允许顺带修改 Prompt、模型选择或业务结果 Schema各自独立 Issue
  5. 没有 iOS/Admin 消费者的任务类型不得启用自动生成
  6. 自动触发必须有频率限制、幂等保护、成本上限

回滚原则

每个 Issue 必须提供独立回滚方案:

  1. 代码层面:回滚提交或 revert PR
  2. 数据库:本批次不涉及 Schema 变更,无需数据回滚
  3. 部署:恢复旧 AppModule Processor 注册,停止独立 Worker service
  4. 队列:验证无双重消费

现有 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