feat: phase 4 of AI pipeline hardening — quiz & content quality
- src/lib/random.js: Fisher–Yates shuffle/sample/pickInt; replace every
biased .sort(() => 0.5 - Math.random()) site in testService.
- testService: debias correctIndex via prompt + runtime re-roll (up to 2x
when one position holds >50%); quality gate rejecting <4 distinct
options, banned filler ("all of the above" etc) and explanations
shorter than 20 chars; dedup new questions against the existing bank
via normalised question text.
- Quiz schema/tool/prompt require difficulty ('easy'|'medium'|'hard');
db.getQuizBank defaults legacy records to 'medium' on read.
- learningService.generateCustomTopic: kebab-case slug ID from the
polished label with collision suffixes; default learning_relevance
'standard' when the model omits it.
- Tests for random helpers, dedup/quality-gate behaviour and the
extended quiz schema.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -122,6 +122,8 @@ export const learningAllSchema = z.object({
|
||||
infographic: infographicBodySchema,
|
||||
});
|
||||
|
||||
const quizDifficultyEnum = z.enum(['easy', 'medium', 'hard']);
|
||||
|
||||
const quizQuestionSchema = z.object({
|
||||
id: z.string().min(1),
|
||||
question: z.string().min(1),
|
||||
@@ -129,6 +131,7 @@ const quizQuestionSchema = z.object({
|
||||
options: z.array(z.string().min(1)).length(4),
|
||||
correctIndex: z.number().int().min(0).max(3),
|
||||
explanation: z.string().min(1),
|
||||
difficulty: quizDifficultyEnum,
|
||||
});
|
||||
|
||||
export const quizQuestionsSchema = z.object({
|
||||
|
||||
Reference in New Issue
Block a user