fix(quiz): use course language instead of UI locale for grading

quiz-view was passing the UI locale to the grading API, causing AI
feedback to follow the student's answer language instead of the course
language. Now reads stage.language from the store.

Also strengthen the grading prompt: explicitly instruct the LLM to
write comments in the course language regardless of the student's
input language.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
yangshen
2026-03-30 17:20:59 +08:00
co-authored by Claude Opus 4.6
parent f7bd6bdb21
commit 5bb5133da7
2 changed files with 9 additions and 5 deletions
+5 -3
View File
@@ -40,13 +40,15 @@ export async function POST(req: NextRequest) {
const isZh = language === 'zh-CN';
const langName = getCourseLanguagePromptName(language || 'en-US');
const langSuffix =
!isZh && language !== 'en-US' ? `\nIMPORTANT: Write your comment in ${langName}.` : '';
const langSuffix = !isZh
? `\nCRITICAL: The "comment" field MUST be written in ${langName}, regardless of what language the student used in their answer.`
: '';
const systemPrompt = isZh
? `你是一位专业的教育评估专家。请根据题目和学生答案进行评分并给出简短评语。
无论学生用什么语言作答,你的评语必须使用中文。
必须以如下 JSON 格式回复(不要包含其他内容):
{"score": <0到${points}的整数>, "comment": "<一两句评语>"}`
{"score": <0到${points}的整数>, "comment": "<一两句中文评语>"}`
: `You are a professional educational assessor. Grade the student's answer and provide brief feedback.
You must reply in the following JSON format only (no other content):
{"score": <integer from 0 to ${points}>, "comment": "<one or two sentences of feedback>"}${langSuffix}`;
+4 -2
View File
@@ -15,6 +15,7 @@ import {
} from 'lucide-react';
import { cn } from '@/lib/utils';
import { useI18n } from '@/lib/hooks/use-i18n';
import { useStageStore } from '@/lib/store';
import { getCurrentModelConfig } from '@/lib/utils/model-config';
import { createLogger } from '@/lib/logger';
@@ -687,6 +688,7 @@ function ScoreBanner({
export function QuizView({ questions, sceneId }: QuizViewProps) {
const { t, locale } = useI18n();
const courseLanguage = useStageStore((s) => s.stage?.language) || locale;
const [phase, setPhase] = useState<Phase>('not_started');
const [answers, setAnswers] = useState<Record<string, string | string[]>>({});
const [results, setResults] = useState<QuestionResult[]>([]);
@@ -753,7 +755,7 @@ export function QuizView({ questions, sceneId }: QuizViewProps) {
const shortAnswerQs = questions.filter(isShortAnswer);
const aiResults = await Promise.all(
shortAnswerQs.map((q) =>
gradeShortAnswerQuestion(q, (answers[q.id] as string) ?? '', locale),
gradeShortAnswerQuestion(q, (answers[q.id] as string) ?? '', courseLanguage),
),
);
@@ -774,7 +776,7 @@ export function QuizView({ questions, sceneId }: QuizViewProps) {
return () => {
cancelled = true;
};
}, [phase, questions, answers, locale]);
}, [phase, questions, answers, courseLanguage]);
const handleRetry = useCallback(() => {
setPhase('not_started');