Просмотр исходного кода

docs: define speaking practice rounds

jimmylee 2 недель назад
Родитель
Сommit
b3d67f9c8a

+ 26 - 7
docs/superpowers/specs/2026-04-25-english-speaking-report-pipeline-design.md

@@ -6,11 +6,30 @@ This design covers the runtime report pipeline for `src/views/Editor/EnglishSpea
 
 The goal is to separate per-round sentence evaluation from whole-session overall evaluation while keeping `/report` as the single frontend entry point for the final report page.
 
+## Round Model
+
+A practice round is:
+
+```text
+AI prompt/question for round N + student answer for round N
+```
+
+The AI message generated after the student answers round N is the prompt/question for round N+1, unless the practice is complete and the AI is only closing the conversation.
+
+This means report grouping should not treat `AI prompt N + student answer N + AI follow-up` as one round. The follow-up belongs to the next round when it asks the next question.
+
+For persistence:
+
+- The opening greeting/question is stored as an AI message for `round = 1`.
+- The student's first answer is stored as a student message for `round = 1`.
+- The AI reply after that answer is stored as an AI message for `round = 2` when another round remains.
+- On the final student answer, the AI closing response may be stored with the final round or a separate non-report role/metadata in a later design; it should not create another expected student evaluation.
+
 ## Problem
 
 The current backend stores Azure pronunciation scores in `pronunciation_evaluation` and has a `content_feedback` JSON field, but the existing feedback shape uses `highlights / corrections / suggestions`. That shape is not correct for `DetailedReport` because those fields describe whole-session conclusions, not one student turn.
 
-`DetailedReport` needs one feedback object per student round:
+`DetailedReport` needs one feedback object per completed student answer:
 
 ```json
 {
@@ -19,13 +38,13 @@ The current backend stores Azure pronunciation scores in `pronunciation_evaluati
 }
 ```
 
-`OverallReport` needs whole-session fields only after all student rounds have completed sentence evaluation.
+`OverallReport` needs whole-session fields only after all expected student answers have completed sentence evaluation.
 
 ## Architecture
 
 The report flow has three layers:
 
-1. Sentence evaluation: one record per student round.
+1. Sentence evaluation: one record per completed student answer.
 2. Overall evaluation: one cached summary per completed session.
 3. Report API: one `/report` response that returns both detailed and overall report data with a readiness status.
 
@@ -33,7 +52,7 @@ The report flow has three layers:
 
 ## Sentence Evaluation
 
-Each student round is evaluated asynchronously after `/speak-stream` writes the student message and AI response.
+Each student answer is evaluated asynchronously after `/speak-stream` writes the student message. The sentence feedback context includes the AI prompt for that same round and earlier dialogue text.
 
 The sentence evaluation job runs in this order:
 
@@ -83,7 +102,7 @@ Both keys are required. Values may be empty strings only if the evaluator fails
 
 ## Overall Evaluation
 
-Overall evaluation is generated only when every student round has a completed pronunciation evaluation.
+Overall evaluation is generated only when every expected student answer has a completed pronunciation evaluation.
 
 The ready condition is:
 
@@ -104,7 +123,7 @@ When all sentence evaluations are completed, the backend generates and caches th
 - `overallScore`
 - statistics such as average score, highest score, grammar error count, and excellent expression count
 
-These fields must be based on all student rounds, all Azure scores, all available sentence feedback objects, and the full dialogue transcript. If a sentence feedback LLM call failed but Azure succeeded, that round still has completed pronunciation scores and `contentFeedback = null`; overall generation should tolerate that missing feedback instead of blocking forever.
+These fields must be based on all expected student answers, all Azure scores, all available sentence feedback objects, and the full dialogue transcript. If a sentence feedback LLM call failed but Azure succeeded, that answer still has completed pronunciation scores and `contentFeedback = null`; overall generation should tolerate that missing feedback instead of blocking forever.
 
 ## API Contract
 
@@ -200,7 +219,7 @@ feedback?: {
 }
 ```
 
-`DetailedReport.vue` should display, for student rounds:
+`DetailedReport.vue` should display, for completed student answers:
 
 - score badge derived from the four Azure scores
 - four pronunciation rows