# 组卷流程与知识点题目不足应对措施分析 ## 一、整体组卷流程概览 ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ ExamTypeStrategy::buildParams() - 根据 assembleType 构建组卷参数 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ 0,9 摸底 → buildChapterDiagnosticParams() │ │ 1,8 智能组卷 → buildChapterIntelligentParams() │ │ 2 知识点组卷 → buildKnowledgePointAssembleParams() ← 含 QuestionExpansionService │ │ 3 教材组卷 → buildTextbookAssembleParams() │ │ 4 通用 / 5 错题本 → buildGeneralParams / buildMistakeParams │ └─────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────────┐ │ LearningAnalyticsService::generateIntelligentExam() │ │ 1. 获取 kp_codes、exclude_question_ids │ │ 2. 优先获取错题(如有) │ │ 3. getQuestionsFromBank() - 从题库按知识点/章节/难度选题,应用 exclude_question_ids │ │ 4. selectQuestionsByMastery() - 按掌握度/题型/难度二次筛选 │ │ 5. applyTypeAwareDifficultyDistribution() - 题型感知难度分布 │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## 二、「知识点题目不足」涉及的层级 | 层级 | 含义 | 典型触发场景 | |------|------|--------------| | **整体不足** | 指定 kp_codes 下题目总数 < total_questions | 知识点组卷、教材组卷、智能组卷 | | **某难度范围不足** | 基础/中等/拔高某一档题目不够 | QuestionLocalService 难度分布 | | **某题型不足** | 选择/填空/解答某一题型不够 | IntelligentExamGeneration、applyTypeAwareDifficultyDistribution | | **去重后不足** | selectQuestionsByMastery 去重后数量变少 | 重复题目被去除 | --- ## 三、各环节的应对措施(现状) ### 3.1 ExamTypeStrategy(参数构建) | 措施 | 所在位置 | 说明 | |------|----------|------| | **QuestionExpansionService 扩展** | `buildKnowledgePointAssembleParams`(assembleType=2) | 仅在**知识点组卷**时,基础题池不足会扩展:Step1 直接知识点 → Step2 同知识点 → Step3 子知识点(1层) → Step4 薄弱点 → Step5 子知识点(2层) | | **教材组卷** | `buildTextbookAssembleParams` | **不做扩展**,严格按章节关联知识点 | | **摸底/智能组卷** | `buildChapterDiagnosticParams` / `buildChapterIntelligentParams` | 最终调用 `buildKnowledgePointAssembleParams`,依赖扩展逻辑 | ### 3.2 LearningAnalyticsService::getQuestionsFromBank | 措施 | 条件 | 说明 | |------|------|------| | **智能补充** `getSupplementaryQuestionsForGrade` | `totalNeeded > 0 && count < totalNeeded && grade !== null` | 从**同年级同教材**的其他知识点补充题目,避免超纲 | | **返回所有可用题目** | 无条件 | 不再做 limit 截断,把所有符合条件的题目交给上层 | **⚠️ 重要限制**:`grade === null` 时**不会触发智能补充**,只返回当前知识点能查到的题目。 ### 3.3 LearningAnalyticsService::selectQuestionsByMastery | 措施 | 说明 | |------|------| | 数量不足时全用 | `count(questions) < totalQuestions` 时打 warning,但仍使用所有可用题目 | | 去重后不足时补充 | 从 `selectedQuestions` 中选未选过的题目补齐到目标数量 | ### 3.4 QuestionLocalService(难度分层选题) | 措施 | 说明 | |------|------| | 难度范围不足时记录 | 某难度档题目不够时打 warning,不截断,继续选 | | 从剩余题目补充 | 按 `getSupplementOrder` 的次级桶顺序补充 | | 次级桶仍不足 | 从未使用题目中随机补齐 | ### 3.5 applyTypeAwareDifficultyDistribution(题型感知难度分布) | 措施 | 说明 | |------|------| | 题型内补充 | 某题型难度分布不满足目标时,从该题型剩余题目补充 | | 跨题型补充 | 总数不足时,按 fill → choice → answer 优先级跨题型补足 | ### 3.6 IntelligentExamGeneration(Filament 页面) | 措施 | 说明 | |------|------| | 批量生成题目 | 题库不足时调用 `batchGenerateQuestions()` 生成题目 | | 题型不足时跨题型补充 | 某题型可用数量不足,从 choice/fill/answer 其他题型补充 | --- ## 四、当前缺口与建议 ### 4.1 grade 未传入时无法智能补充 ✅ 部分实现 **实现**: - **教材组卷**:`buildTextbookAssembleParams` 在 `grade` 缺失时从 `textbooks` 表根据 `textbook_id` 推断 `grade`。 - **智能组卷**(buildIntelligentAssembleParams):`grade` 缺失时从教材推断。 - **章节摸底 / 按知识点顺序学习**:按需求保持不补充,刻意不传 `grade`。 ### 4.2 教材组卷智能补充 ✅ 已实现 **实现**:教材组卷在题目不足时触发 `getSupplementaryQuestionsForGrade` 智能补充,且**仅从同教材前章节**(`textbookCatalogNodeIds` + `textbook_id`)补充,未学章节不会补充。 ### 4.3 按知识点维度的题目不足 **现状**:`selectQuestionsByMastery` 按知识点分组、按掌握度排序,但没有「某知识点题目不足时」的显式策略。 **影响**:当希望每个知识点都有一定题量时,若某知识点题目很少,可能被其他知识点挤占,导致该知识点覆盖不足。 **建议**: - 如需「知识点均匀覆盖」,可在 `selectQuestionsByMastery` 中增加按知识点最小题数的保障逻辑(例如每知识点至少 1 题,再按掌握度/题型等补足总题量)。 ### 4.4 补充来源与 exclude 的一致性 ✅ 已实现 **实现**:`getSupplementaryQuestionsForGrade` 已新增 `exclude_question_ids` 参数,智能补充时排除学生已做题目。 ### 4.5 仅从前章节补充(未学章节不补充)✅ 已实现 **实现**:当传入 `textbookCatalogNodeIds` 时,通过 `getEarlierChapterNodeIds` 限制补充范围为同教材中「选中章节及之前」的节点(`sort_order <= max(选中章节)`),避免补充未学章节的题目。 ### 4.6 是否允许「重复选题」的配置 **现状**:组卷一律使用 `exclude_question_ids` 排除已做题目,没有「允许重复」的开关。 **建议**: - 若业务允许(如复习模式、薄弱点强化),可增加 `allow_repeat` 之类参数;当 `allow_repeat=true` 时,不传或清空 `exclude_question_ids`。 --- ## 五、流程汇总(按题型) ``` 知识点组卷(assembleType=2): ExamTypeStrategy → QuestionExpansionService 扩展(直接 KP → 子 KP → 薄弱点) → getStudentAnsweredQuestionIds → exclude_question_ids LearningAnalyticsService → getQuestionsFromBank(有 grade 时触发智能补充) → selectQuestionsByMastery(不足时用全部可用题目 + 去重后补充) → applyTypeAwareDifficultyDistribution(题型/难度不足时跨题型/跨难度补充) 教材组卷(assembleType=3): ExamTypeStrategy → 按章节获取 kp_codes,无扩展 → getStudentAnsweredQuestionIds → exclude_question_ids LearningAnalyticsService → getQuestionsFromBank(有 grade/textbook_id 时触发智能补充) → 若 grade 缺失,智能补充不生效 摸底 / 智能组卷(0/9, 1/8): 最终走 buildKnowledgePointAssembleParams → 有 assembleType=2 时走 QuestionExpansionService → 其余同上 ``` --- ## 六、结论 当前组卷流程对「题目不足」已有较完整的应对链路: 1. **参数构建层**:知识点组卷有 QuestionExpansionService 扩展。 2. **题库查询层**:`getQuestionsFromBank` 在 `grade` 有值时,会从同年级同教材其他知识点智能补充。 3. **选题层**:`selectQuestionsByMastery` 在数量不足时使用全部可用题目,并在去重后补齐。 4. **难度/题型层**:QuestionLocalService 和 applyTypeAwareDifficultyDistribution 都有跨难度、跨题型的补充逻辑。 主要改进方向: - 保证出卷入口尽量传入 `grade` / `textbook_id`,以启用智能补充。 - 在智能补充中引入 `exclude_question_ids`,避免补充已做题目。 - 视业务需要,为教材组卷增加「同教材其他知识点补充」逻辑。 - 视业务需要,在选题逻辑中增加「知识点最小覆盖」或「允许重复」等策略。