api-server/src/modules/ai-job/quiz-generation-executor.ts
wangdl d368f1a97f
Some checks failed
Deploy API Server / build-and-unit (push) Successful in 37s
Deploy API Server / backward-compat (push) Has been cancelled
Deploy API Server / deploy (push) Has been cancelled
Deploy API Server / current-integration (push) Has been cancelled
feat(M-AI-07-03): quiz generation Executor + Validator + prompt/schema
Resolves A1/A2: bring quiz prompt + output schema in-house from Runtime.
- quiz-generation.prompt.ts: system prompt with question design principles
- quiz-generation.schema.ts: Zod schema (choice/fill/judge types)
- Registered in PromptTemplateService with key 'quiz-generation' v1.0.0
- Executor: AiGateway call with knowledge items + generation params
- Validator: per-type validation (choice options/index, judge true/false)
- Engine dispatch for quiz_generation job type

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-22 20:40:12 +08:00

73 lines
2.5 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { AiGatewayService } from '../ai/gateway/ai-gateway.service';
import { QuizGenerationResultSchema } from '../ai/prompts/schemas/quiz-generation.schema';
import type { QuizGenerationSnapshot } from './quiz-generation-snapshot-builder';
/**
* M-AI-07-03: Quiz Generation Executor
*
* 将 Quiz 生成输入快照适配到统一 Job Engine 的 EXECUTE 阶段。
*
* 职责:从 Snapshot 构造模型输入、通过 AiGateway 调用、返回结构化输出。
* 不负责:写数据库、写 Job 状态、重试、Artifact、Credential。
*/
@Injectable()
export class QuizGenerationExecutor {
private readonly logger = new Logger(QuizGenerationExecutor.name);
constructor(private readonly aiGateway: AiGatewayService) {}
async execute(snapshot: QuizGenerationSnapshot, timeoutMs: number) {
const s = snapshot.snapshot;
// 构造知识点列表文本
const itemsText = s.knowledgeItems
.map((item, i) =>
`【知识点${i + 1}${item.title}\n${item.content}`,
)
.join('\n\n');
const typeDesc = s.questionTypes.join('、');
const userMessage = [
`【知识库】${s.knowledgeBaseTitle}`,
s.knowledgeBaseDescription ? `描述:${s.knowledgeBaseDescription}` : '',
'',
itemsText,
'',
`请为以上知识点生成 ${s.questionCount} 道测验题目。`,
`题型:${typeDesc}`,
`难度:${s.difficultyLevel}`,
].filter(Boolean).join('\n');
this.logger.log(
`Quiz Generation Executor calling AI: userId=${s.userId} ` +
`kb=${s.targetId} items=${s.knowledgeItems.length} ` +
`questionCount=${s.questionCount} types=${s.questionTypes.join(',')} ` +
`difficulty=${s.difficultyLevel} modelTier=${s.modelTier} timeoutMs=${timeoutMs}`,
);
const response = await this.aiGateway.generate(
{
feature: 'quiz-generation',
userId: s.userId,
tier: s.modelTier as any,
promptKey: s.promptKey,
promptVersion: s.promptVersion,
messages: [{ role: 'user' as const, content: userMessage }],
outputSchema: QuizGenerationResultSchema,
maxTokens: 4096,
},
timeoutMs,
);
this.logger.log(
`Quiz Generation Executor completed: userId=${s.userId} ` +
`kb=${s.targetId} questions=${(response.parsed as any)?.questions?.length} ` +
`tokens=${response.usage.inputTokens}/${response.usage.outputTokens}`,
);
return response;
}
}