api-server/docs/architecture/m-ai-08-learning-analysis-migration-contract.md
wangdl 5628e6db90
All checks were successful
Deploy API Server / build-and-unit (push) Successful in 36s
Deploy API Server / current-integration (push) Successful in 30s
Deploy API Server / backward-compat (push) Successful in 0s
Deploy API Server / deploy (push) Successful in 1m2s
docs(M-AI-08-01): AI workflow inventory + learning analysis migration contract
Inventory: 17 AI workflows cataloged. 6 migrated, 4 in M-AI-08 scope,
5 deferred, 2 legacy pending retirement. Confirmed M-AI-08 as final
core business migration milestone.

Contract: 4 Runtime job types (learning_state/weak_point/next_action/
flashcard) to be merged into unified learning_analysis Job. Data source
matrix, snapshot schema, evidence schema, topology frozen.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-22 21:31:29 +08:00

15 KiB
Raw Blame History

M-AI-08 学习综合分析迁移契约

审计日期2026-06-22 契约状态:冻结(待 M-AI-08-01 验收) 对应里程碑M-AI-08 学习综合分析、学习建议与 AI 迁移闭环


目录

  1. 当前链路审计
  2. 目标链路
  3. 数据源矩阵
  4. 聚合窗口
  5. Snapshot Schema
  6. Output Schema
  7. Evidence Schema
  8. 触发模型
  9. 幂等契约
  10. Artifact 矩阵
  11. 权限与隐私
  12. Feature Flag
  13. 回滚流程
  14. 架构异常与不确定项

1. 当前链路审计

1.1 四种 Runtime 作业类型

Job Type 产出实体 promptVersion outputSchemaVersion 现状
learning_state_analysis AiLearningAnalysis learning_state_v1 analysis_output_v1 Runtime 轮询
weak_point_analysis WeakPointCandidate weak_point_v1 weak_point_output_v1 Runtime 轮询
next_action_planning NextActionRecommendation next_action_v1 next_action_output_v1 Runtime 轮询
flashcard_generation Flashcard flashcard_gen_v1 flashcard_output_v1 Runtime 轮询

1.2 当前时序Runtime 轮询路径)

POST /api/ai/jobs { jobType: "learning_state_analysis", targetType, targetId }
→ UserAiService.createAnalysisJob()
  `src/modules/ai-runtime/user-ai.service.ts:199`
  ├─ settings 检查 (:201-206)
  ├─ jobType 验证 (:210-214)
  ├─ 幂等检查 (:225-233)
  ├─ 配额+预算 (:252-267)
  ├─ SnapshotBuilderService.buildSnapshot() (:270)
  │  `src/modules/ai-runtime/snapshot-builder.service.ts:75`
  │  ├─ fetchBehaviorData() — DailyLearningActivity, LearningSession
  │  ├─ aggregateProgress() — MaterialReadingProgress
  │  ├─ aggregateContent() — KnowledgeItem可选
  │  ├─ calculateScores() — Quiz/Review/ActiveRecall/Feynman metrics
  │  ├─ computeSignals() — engagement/consistency/streaks/patterns
  │  └─ buildDeviceContext() — 平台/时区/设备
  ├─ PriorityRulesService.computeJobPriority() (:279)
  └─ aiRuntimeJob.create (:282-299)

外部 Runtime 轮询
→ POST /internal/runtime/jobs/poll → pollJobs() (:22)
→ POST /internal/runtime/jobs/:id/lock → lockJob() (:85)
→ GET /internal/runtime/jobs/:id/snapshot → getSnapshot() (:153)
→ Runtime 执行 AI 调用prompt/schema 外部管理)
→ POST /internal/runtime/jobs/:id/result → submitResult() (:220)
  └─ persistResult() (:286)
     ├─ learning_state_analysis → AiLearningAnalysis.create (:295-311)
     ├─ weak_point_analysis → WeakPointCandidate.create (:313-337)
     └─ next_action_planning → NextActionRecommendation.create (:339-365)

1.3 数据模型

AiLearningAnalysis (schema.prisma:2173-2194):

id, userId, jobId, snapshotId, targetType, targetId,
learningState, summary, riskLevel, confidence, evidence (Json),
nextActionIds (Json), promptVersion, schemaVersion

WeakPointCandidate (schema.prisma:2198-2216):

id, userId, jobId, snapshotId, targetType, targetId,
knowledgePointId, title, reason, confidence, evidence (Json),
status (active/resolved)

NextActionRecommendation (schema.prisma:2220-2239):

id, userId, jobId, snapshotId, actionType, targetType, targetId,
title, reason, priority, estimatedMinutes, deviceSuitability,
status (active/resolved)

LearningAnalysisSnapshot (schema.prisma:2058-2083):

id, userId, scopeType, scopeId, snapshotVersion, sourceDataVersion,
privacyScope, userProfile, aiSettings, deviceContext,
learningBehaviorSummary, materialProgressSummary, contentStructureSummary,
behaviorSignals, scoreSignals, constraints, allowedModelFields

1.4 拓扑(冻结)

审计确认:learning_state_analysisweak_point_analysisnext_action_planning 三者各自独立调用模型,由外部 Runtime 分别执行。

M-AI-08 迁移决策:将三者合并为一个 learning_analysis Job一次模型调用同时产出综合分析 + 薄弱点 + 建议。

单一 learning_analysis Job
  → 一次 AiGateway 调用
  → LearningAnalysisProjector
    → AiLearningAnalysis综合分析
    → WeakPointCandidate × N薄弱点
    → NextActionRecommendation × N建议
    → AiJobArtifact × N

flashcard_generation 保持独立(不属于"学习分析"范畴)。

1.5 数据来源分类

数据 来源 可信度 Snapshot 处理
userId JWT 可信 直接包含
learningGoal UserLearningProfile 可信 直接包含
dailyAvailableMinutes UserLearningProfile 可信 聚合
qualityPreference UserAiSettings 可信 直接包含
学习时长 DailyLearningActivity 可信 仅聚合后进入
活跃天数 DailyLearningActivity 可信 聚合指标
复习完成率 ReviewCard + ReviewLog 可信 聚合指标
Quiz 正确率 QuizAttempt 可信 聚合指标
Active Recall 表现 AiAnalysisResult 可信 聚合指标
Feynman 弱点 FocusItem + AiAnalysisResult 可信 聚合指标
知识点进度 KnowledgeItem + MaterialReadingProgress 可信 列表(限量+截断)
设备/时区 DeviceContext服务端推断 可信 直接包含
学习时长(客户端声明) 不可信 禁止进入
掌握度(客户端声明) 不可信 禁止进入
JWT / API Key Request Header 禁止进入
完整对话历史 禁止进入

1.6 副作用矩阵

副作用 当前 Unified
配额消耗 quota.incrementJobCount 保持
UsageLog Runtime 记录 Engine 记录
更新用户画像
更新知识点掌握度
创建通知
自动生成复习卡
自动执行建议 否(禁止)
Snapshot 创建 SnapshotBuilderService SnapshotBuilder复用

2. 目标链路

手动/定时触发
→ LearningAnalysisExecutionRouter
  ├─ [legacy] → UserAiService.createAnalysisJob()
  └─ [unified] →
       LearningAnalysisSnapshotBuilder.build()
       → AiJobCreationService.createJob()
       → Job + Snapshot + Outbox
       → BullMQ (ai-background)
       → Worker → AiJobExecutionEngine
         EXECUTE: LearningAnalysisExecutor (AiGateway)
         VALIDATE: SchemaValidator + EvidenceValidator + BusinessValidator
         PROJECT: LearningAnalysisProjector
           → AiLearningAnalysis + WeakPointCandidate × N
           + NextActionRecommendation × N + Artifact
           → markSucceeded

3. 数据源矩阵

数据源 Prisma 模型 Snapshot 包含方式
用户学习目标 UserLearningProfile 直接字段
AI 设置 UserAiSettings 直接字段
每日学习活动 DailyLearningActivity 聚合totalDuration/activeDays/sessionCount
学习会话 LearningSession 聚合avgSessionDuration/completionRate
阅读进度 MaterialReadingProgress 列表(限量 50仅标题+进度)
知识项 KnowledgeItem 列表(限量 200仅标题+摘要)
复习记录 ReviewCard + ReviewLog 聚合dueCount/completedCount/accuracy/overdue
Quiz 结果 QuizAttempt + QuizAnswer 聚合accuracy/byType/byKnowledgeItem
Active Recall AiAnalysisResult 聚合count/avgScore/weaknesses
Feynman 评估 AiAnalysisResult + FocusItem 聚合count/weaknesses/focusItems
设备上下文 服务端推断 直接字段platform/timezone
连续学习 StreakRecord 聚合指标

4. 聚合窗口

参数 默认值 说明
windowStart 请求时确定 Snapshot 固定,不漂移
windowEnd 请求时确定 与 windowStart 配对
timezone 服务端推断 用户设备时区
sourceCutoffAt 请求时 数据截止时间
aggregationVersion 语义版本 算法版本,变化时重新分析
行为窗口 7 天 学习行为数据
成绩窗口 30 天 Quiz/复习/Active Recall 成绩

5. Snapshot Schema

interface LearningAnalysisSnapshot {
  schemaVersion: string;          // "learning-analysis-v1"
  snapshot: {
    userId: string;
    triggerType: 'manual' | 'scheduled';
    operationId: string;
    windowStart: string;          // ISO8601
    windowEnd: string;
    timezone: string;             // IANA
    aggregationVersion: string;
    sourceCutoffAt: string;

    learningGoal?: string;
    qualityPreference?: string;
    dailyAvailableMinutes?: number;

    studyMetrics: {
      totalStudyDuration: number;
      activeDays: number;
      sessionCount: number;
      averageSessionDuration: number;
      completionRate: number;
    };

    reviewMetrics: {
      reviewDueCount: number;
      reviewCompletedCount: number;
      reviewAccuracy: number;
      overdueCount: number;
      retentionTrend: number;     // -1 to 1
    };

    quizMetrics: {
      quizCount: number;
      attemptCount: number;
      accuracy: number;
      accuracyByQuestionType: Record<string, number>;
    };

    activeRecallMetrics: {
      count: number;
      avgScore: number;
      weaknessCount: number;
    };

    feynmanMetrics: {
      count: number;
      weaknessCount: number;
      focusItemCount: number;
    };

    knowledgeProgress: {
      totalItems: number;
      completedItems: number;
      inProgressItems: number;
      weakItems: Array<{ id: string; title: string }>;
    };

    dataQuality: {
      availableSources: string[];
      missingSources: string[];
      sampleSize: number;
      coverageStart?: string;
      coverageEnd?: string;
      insufficientDataReasons: string[];
    };

    promptKey: string;
    promptVersion: string;
    modelTier: string;
    inputSchemaVersion: string;
    outputSchemaVersion: string;
    createdAt: string;
  };
}

6. Output Schema

interface LearningAnalysisOutput {
  summary: string;
  strengths: Array<{
    title: string;
    description: string;
    evidenceRefs: EvidenceRef[];
  }>;
  weaknesses: Array<{
    title: string;
    description: string;
    knowledgePointId?: string;
    evidenceRefs: EvidenceRef[];
  }>;
  trends: Array<{
    metricKey: string;
    direction: 'improving' | 'declining' | 'stable';
    description: string;
    evidenceRefs: EvidenceRef[];
  }>;
  risks: Array<{
    title: string;
    severity: 'low' | 'medium' | 'high';
    description: string;
    evidenceRefs: EvidenceRef[];
  }>;
  recommendations: Array<{
    actionType: string;
    title: string;
    reason: string;
    priority: number;
    estimatedMinutes?: number;
    targetType?: string;
    targetId?: string;
    evidenceRefs: EvidenceRef[];
  }>;
  confidence: number;             // 0.0-1.0
  dataQuality: {
    overall: 'sufficient' | 'limited' | 'insufficient';
  };
  insufficientData: boolean;
}

7. Evidence Schema

每个结论必须附带 evidenceRefs

interface EvidenceRef {
  sourceType: 'study_metric' | 'review_metric' | 'quiz_metric'
    | 'active_recall' | 'feynman' | 'knowledge_progress';
  metricKey: string;             // e.g. "reviewAccuracy", "quizAccuracy"
  entityId?: string;             // knowledgeItemId / quizId / analysisResultId
  windowStart: string;
  windowEnd: string;
}

8. 触发模型

触发类型 幂等键 说明
manual learning-analysis:manual:<operationId> 用户手动触发,同一操作重试相同 Job
scheduled learning-analysis:scheduled:<userId>:<windowStart>:<windowEnd>:<policyVersion> 定时触发,同一窗口唯一

9. 幂等契约

请求级

  • 同一 operationId → 同一 Job
  • 同一 scheduled window → 同一 Job
  • 禁止 Date.now()/random 回退

投影级

  • analysisId = deterministic(jobId)
  • recommendationId = deterministic(jobId + ordinal)
  • 入口 Artifact 检查 + P2002 catch

10. Artifact 矩阵

实体 artifactType artifactId
AiLearningAnalysis learning_analysis analysis.id
WeakPointCandidate weak_point candidate.id
NextActionRecommendation recommendation recommendation.id
Flashcard (单独) flashcard flashcard.id

M-AI-02 已冻结 learning_analysisrecommendation 等 artifactType。


11. 权限与隐私

  • 所有数据必须属于同一 userId
  • 禁止其他用户数据进入 Snapshot
  • 禁止跨用户 evidenceRefs
  • 公开错误不泄漏 Snapshot/validatedOutput
  • Admin 可查看所有(现有权限制)

12. Feature Flag

Flag Name: LEARNING_ANALYSIS_ENGINE_MODE
Values:    legacy | unified
Default:   legacy

13. 回滚流程

unified → legacy:
  1. 修改 Flag → legacy
  2. 新触发走 Legacy Runtime 轮询
  3. 已创建 Unified Job 继续完成
  4. 已生成分析保留
  5. 无需数据库回滚

14. 架构异常与不确定项

阻塞项

# 异常 说明 处理
A1 无 learning_state/weak_point/next_action Prompt 模板 当前由 Runtime 管理 M-AI-08-03 需新增内联 Prompt
A2 无对应 Output Schema 同上 M-AI-08-03 需新增 Zod Schema
A3 flashcard_generation prompt/schema 缺失 同 Quiz 模式 延期或并入 M-AI-08

不确定项

问题 建议
三个 Job Type 合并策略 当前三者独立,合并为一个 learning_analysis 需验证业务合理性 M-AI-08-01 中确认后冻结
flashcard_generation 归属 语义上更接近 Quiz 生成而非学习分析 建议纳入 M-AI-08 作为独立 Definition

附录:关键文件索引

用途 路径 关键行号
分析入口 src/modules/ai-runtime/user-ai.service.ts :199 createAnalysisJob, :11-17 JOB_TYPE_CONFIG
Runtime 持久化 src/modules/ai-runtime/internal/runtime-internal.service.ts :286 persistResult, :295-365 四种类型分支
Snapshot 构建 src/modules/ai-runtime/snapshot-builder.service.ts :75 buildSnapshot, :259 aggregateBehavior
Priority 规则 src/modules/ai-runtime/priority-rules.service.ts :45 computePriorityRules
AiLearningAnalysis prisma/schema.prisma :2173-2194
WeakPointCandidate prisma/schema.prisma :2198-2216
NextActionRecommendation prisma/schema.prisma :2220-2239
LearningAnalysisSnapshot prisma/schema.prisma :2058-2083
UserLearningProfile prisma/schema.prisma :1912-1932
UserAiSettings prisma/schema.prisma :1936-1953
学习趋势 Workflow src/modules/ai/workflows/learning-trend.workflow.ts :30 execute
学习趋势 Prompt src/modules/ai/prompts/learning-trend.prompt.ts :1 system prompt