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