refactor: 強化 Quiz Option 生成機制防止重複詞彙
- 加強 AI 生成後的詞彙過濾,確保不包含目標詞彙 - 改進 fallback 選項品質,使用更具挑戰性的詞彙池 - 添加詳細日誌追蹤選項生成過程(✅📚💡🤖) - 修復資料庫重複詞彙問題,確保選項品質 測試驗證:happy -> efficient, essential, fundamental 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
f24f2b0445
commit
1eb28e83c5
|
|
@ -79,7 +79,7 @@ public class OptionsVocabularyService : IOptionsVocabularyService
|
|||
|
||||
if (_cache.TryGetValue(cacheKey, out List<OptionsVocabulary>? cachedOptions) && cachedOptions != null)
|
||||
{
|
||||
_logger.LogInformation("Using cached distractors for '{Word}': {Distractors}",
|
||||
_logger.LogInformation("✅ Using cached distractors for '{Word}': {Distractors}",
|
||||
targetWord, string.Join(", ", cachedOptions.Select(d => d.Word)));
|
||||
return cachedOptions.Take(count).ToList();
|
||||
}
|
||||
|
|
@ -104,11 +104,14 @@ public class OptionsVocabularyService : IOptionsVocabularyService
|
|||
// 快取結果
|
||||
_cache.Set(cacheKey, selectedExisting, TimeSpan.FromHours(1));
|
||||
|
||||
_logger.LogInformation("Using existing distractors for '{Word}': {Distractors}",
|
||||
_logger.LogInformation("📚 Using existing database distractors for '{Word}': {Distractors}",
|
||||
targetWord, string.Join(", ", selectedExisting.Select(d => d.Word)));
|
||||
return selectedExisting;
|
||||
}
|
||||
|
||||
_logger.LogInformation("💡 Insufficient database options ({ExistingCount}/{RequiredCount}), proceeding to AI generation for '{Word}'",
|
||||
existingOptions.Count, count, targetWord);
|
||||
|
||||
// 3. 使用 AI 生成新的混淆選項
|
||||
var aiGeneratedOptions = await GenerateOptionsWithAI(targetWord, cefrLevel, partOfSpeech, count);
|
||||
|
||||
|
|
@ -122,7 +125,7 @@ public class OptionsVocabularyService : IOptionsVocabularyService
|
|||
_cache.Set(cacheKey, aiGeneratedOptions, TimeSpan.FromHours(1));
|
||||
}
|
||||
|
||||
_logger.LogInformation("Successfully generated {Count} AI distractors for '{Word}': {Distractors}",
|
||||
_logger.LogInformation("🤖 Successfully generated {Count} AI distractors for '{Word}': {Distractors}",
|
||||
aiGeneratedOptions.Count, targetWord,
|
||||
string.Join(", ", aiGeneratedOptions.Select(d => d.Word)));
|
||||
|
||||
|
|
@ -247,8 +250,14 @@ Please respond with ONLY a JSON array of strings, like: [""word1"", ""word2"", "
|
|||
return GetFallbackDistractors(targetWord, cefrLevel, partOfSpeech, count);
|
||||
}
|
||||
|
||||
// 轉換為 OptionsVocabulary 實體
|
||||
var options = generatedWords.Take(count).Select(word => new OptionsVocabulary
|
||||
// 轉換為 OptionsVocabulary 實體,並過濾掉與目標詞彙相同的詞彙
|
||||
var targetWordLower = targetWord.ToLower();
|
||||
var filteredWords = generatedWords
|
||||
.Where(word => !string.IsNullOrWhiteSpace(word) &&
|
||||
word.Trim().ToLower() != targetWordLower)
|
||||
.Take(count);
|
||||
|
||||
var options = filteredWords.Select(word => new OptionsVocabulary
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Word = word.Trim(),
|
||||
|
|
@ -259,6 +268,9 @@ Please respond with ONLY a JSON array of strings, like: [""word1"", ""word2"", "
|
|||
UpdatedAt = DateTime.UtcNow
|
||||
}).ToList();
|
||||
|
||||
_logger.LogInformation("Filtered AI generated words from {OriginalCount} to {FilteredCount} options for '{TargetWord}'",
|
||||
generatedWords.Length, options.Count, targetWord);
|
||||
|
||||
// 計算字數長度
|
||||
foreach (var option in options)
|
||||
{
|
||||
|
|
@ -283,20 +295,27 @@ Please respond with ONLY a JSON array of strings, like: [""word1"", ""word2"", "
|
|||
string partOfSpeech,
|
||||
int count)
|
||||
{
|
||||
// 根據詞性提供不同的固定選項
|
||||
// 根據詞性提供不同的固定選項(避免常見目標詞彙)
|
||||
var fallbackWords = partOfSpeech.ToLower() switch
|
||||
{
|
||||
"verb" => new[] { "create", "destroy", "change", "develop", "improve", "reduce" },
|
||||
"noun" => new[] { "example", "result", "problem", "method", "system", "process" },
|
||||
"adjective" => new[] { "important", "different", "special", "general", "common", "simple" },
|
||||
"adverb" => new[] { "quickly", "carefully", "easily", "slowly", "clearly", "directly" },
|
||||
_ => new[] { "option", "choice", "answer", "question", "test", "study" }
|
||||
"verb" => new[] { "accomplish", "construct", "transform", "establish", "generate", "implement", "maintain", "organize", "validate", "coordinate" },
|
||||
"noun" => new[] { "solution", "approach", "framework", "component", "structure", "mechanism", "principle", "strategy", "technique", "procedure" },
|
||||
"adjective" => new[] { "efficient", "comprehensive", "innovative", "sophisticated", "fundamental", "essential", "remarkable", "outstanding", "significant", "substantial" },
|
||||
"adverb" => new[] { "thoroughly", "efficiently", "precisely", "consistently", "systematically", "effectively", "accurately", "appropriately", "specifically", "particularly" },
|
||||
_ => new[] { "element", "aspect", "feature", "component", "factor", "criteria", "parameter", "attribute", "characteristic", "specification" }
|
||||
};
|
||||
|
||||
var targetWordLower = targetWord.ToLower();
|
||||
return fallbackWords
|
||||
var selectedWords = fallbackWords
|
||||
.Where(word => word.ToLower() != targetWordLower)
|
||||
.Take(count)
|
||||
.Take(count * 2) // 取更多選項用於隨機選擇
|
||||
.OrderBy(x => Guid.NewGuid()) // 隨機排序
|
||||
.Take(count);
|
||||
|
||||
_logger.LogInformation("Using fallback distractors for '{TargetWord}': {FallbackWords}",
|
||||
targetWord, string.Join(", ", selectedWords));
|
||||
|
||||
return selectedWords
|
||||
.Select(word => new OptionsVocabulary
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
|
|
|
|||
Loading…
Reference in New Issue