# 智能填空題系統設計規格書 ## 概述 將填空題的挖空邏輯從前端移至後端,建立智能的例句處理系統,支援詞彙變形識別和AI輔助挖空。 ## 問題分析 ### 當前問題 - 前端使用簡單正則 `\b${word}\b` 進行挖空 - 無法處理詞彙變形:`eat` vs `ate`、`go` vs `went` - 挖空失敗時無替代方案,導致題目無法正常顯示 ### 影響範圍 - 動詞變形:eat/ate、go/went、run/ran - 名詞複數:cat/cats、child/children - 形容詞比較級:good/better、bad/worse - 過去分詞:break/broken、speak/spoken ## 系統架構設計 ### 資料庫結構調整 #### Flashcard 實體新增欄位 ```csharp [MaxLength(1000)] public string? FilledQuestionText { get; set; } // 挖空後的題目文字 ``` #### 範例資料 ```json { "word": "ate", "example": "She ate an apple yesterday.", "filledQuestionText": "She ____ an apple yesterday." } ``` ### 後端服務架構 #### 1. BlankGenerationService 服務 ```csharp public interface IBlankGenerationService { Task GenerateBlankQuestionAsync(string word, string example); string? TryProgrammaticBlank(string word, string example); Task GenerateAIBlankAsync(string word, string example); } ``` #### 2. 智能挖空處理流程 ##### Step 1: 程式碼挖空 (快速處理) ```csharp // 1. 完全匹配 var regex1 = new Regex($@"\b{Regex.Escape(word)}\b", RegexOptions.IgnoreCase); // 2. 常見變形規則 var variations = GetCommonVariations(word); foreach(var variation in variations) { var regex2 = new Regex($@"\b{Regex.Escape(variation)}\b", RegexOptions.IgnoreCase); // 嘗試替換 } ``` ##### Step 2: AI 輔助挖空 (處理複雜變形) ```csharp var prompt = $@" 請將以下例句中與詞彙「{word}」相關的詞挖空,用____替代: 詞彙: {word} 例句: {example} 規則: 1. 只挖空與目標詞彙相關的詞(包含變形、時態、複數等) 2. 用____替代被挖空的詞 3. 保持句子其他部分不變 4. 直接返回挖空後的句子,不要額外說明 挖空後的句子:"; await _geminiService.GenerateTextAsync(prompt); ``` #### 3. API 端點調整 ##### GET /api/flashcards/due 強化邏輯 ```csharp foreach(var flashcard in dueCards) { if(string.IsNullOrEmpty(flashcard.FilledQuestionText)) { var blankQuestion = await _blankGenerationService.GenerateBlankQuestionAsync( flashcard.Word, flashcard.Example); if(!string.IsNullOrEmpty(blankQuestion)) { flashcard.FilledQuestionText = blankQuestion; // 更新資料庫 } } } ``` ##### 新增重新生成端點 ```csharp [HttpPost("{id}/regenerate-blank")] public async Task RegenerateBlankQuestion(Guid id) ``` ### 前端架構簡化 #### SentenceFillTest 組件調整 ```typescript // 移除複雜的 renderSentenceWithInput() 邏輯 // 改為簡單的模板渲染 interface SentenceFillTestProps { word: string; definition: string; example: string; // 原始例句 filledQuestionText: string; // 挖空後的題目 // ... 其他屬性 } // 簡化的渲染邏輯 const renderFilledSentence = () => { return filledQuestionText.replace('____', `` ); } ``` ## 實施計劃 ### Phase 1: 資料庫結構 1. 創建 Migration 添加 `FilledQuestionText` 欄位 2. 更新 Flashcard 實體模型 ### Phase 2: 後端服務開發 1. 實作 `BlankGenerationService` 2. 建立常見詞彙變形對應表 3. 整合 AI 挖空功能 4. 修改 FlashcardsController ### Phase 3: 前端優化 1. 簡化 SentenceFillTest 組件 2. 更新 Props 介面 3. 測試新的渲染邏輯 ### Phase 4: 測試與優化 1. 測試各種詞彙變形情況 2. 驗證 AI 挖空品質 3. 效能優化和錯誤處理 ## 預期效果 ### 功能提升 - ✅ 支援所有詞彙變形挖空 - ✅ AI 輔助處理複雜情況 - ✅ 一次生成,多次使用 - ✅ 統一的挖空品質 ### 技術優勢 - 🚀 前端邏輯簡化 - 🎯 後端統一處理 - 💾 結果快取提升效能 - 🤖 AI 確保準確性 ### 維護性 - 📦 挖空邏輯集中管理 - 🔧 易於調整和優化 - 📊 可監控挖空成功率 - 🐛 錯誤處理更完善 ## 風險評估 ### 技術風險 - AI 調用可能失敗 → 提供降級策略 - 資料庫遷移 → 確保現有資料相容 - 效能影響 → 批次處理優化 ### 緩解措施 - 多層回退機制 (程式碼 → AI → 手動) - 非同步處理避免阻塞 - 詳細日誌記錄便於除錯