refactor: 簡化API設計,移除statistics計算和userLevel參數
- 移除後端statistics計算邏輯,改由前端處理 - 移除userLevel參數,簡化API接口 - 清理DTO模型中的多餘欄位 (Tags, IsIdiom, UserLevel) - 更新AI模型名稱為gemini-1.5-flash - 新增完整的AI Prompt設計規格 - 建立AI驅動產品後端技術架構指南 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
8568d5e500
commit
96bb9e920e
234
AI生成功能後端API規格.md
234
AI生成功能後端API規格.md
|
|
@ -5,7 +5,7 @@
|
|||
- **文件名稱**: AI生成功能後端API規格
|
||||
- **版本**: v1.0
|
||||
- **建立日期**: 2025-01-25
|
||||
- **最後更新**: 2025-01-25
|
||||
- **最後更新**: 2025-01-25 (修正API規格)
|
||||
- **負責團隊**: DramaLing後端開發團隊
|
||||
- **對應前端**: `/app/generate/page.tsx`
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ External Services:
|
|||
語言: C# / .NET 8
|
||||
框架: ASP.NET Core Web API
|
||||
資料庫: PostgreSQL + Redis (緩存)
|
||||
AI服務: Google Gemini API
|
||||
AI服務: Google Gemini 1.5 Flash API (包含結構化Prompt設計)
|
||||
部署: Docker + Kubernetes
|
||||
監控: Application Insights
|
||||
```
|
||||
|
|
@ -79,7 +79,6 @@ Authorization: Bearer {token}
|
|||
```json
|
||||
{
|
||||
"inputText": "She just join the team, so let's cut her some slack until she get used to the workflow.",
|
||||
"userLevel": "A2",
|
||||
"analysisMode": "full",
|
||||
"options": {
|
||||
"includeGrammarCheck": true,
|
||||
|
|
@ -95,7 +94,6 @@ Authorization: Bearer {token}
|
|||
| 參數 | 類型 | 必需 | 說明 |
|
||||
|------|------|------|------|
|
||||
| inputText | string | 是 | 待分析的英文句子 (最多300字) |
|
||||
| userLevel | string | 是 | 用戶CEFR等級 (A1-C2) |
|
||||
| analysisMode | string | 否 | 分析模式: "basic"\|"full" (預設: "full") |
|
||||
| options | object | 否 | 分析選項配置 |
|
||||
|
||||
|
|
@ -142,7 +140,6 @@ Authorization: Bearer {token}
|
|||
"synonyms": ["her"],
|
||||
"example": "She is a teacher.",
|
||||
"exampleTranslation": "她是一名老師。",
|
||||
"tags": ["basic", "pronoun"]
|
||||
},
|
||||
"just": {
|
||||
"word": "just",
|
||||
|
|
@ -155,7 +152,6 @@ Authorization: Bearer {token}
|
|||
"synonyms": ["recently", "only", "merely"],
|
||||
"example": "I just arrived.",
|
||||
"exampleTranslation": "我剛到。",
|
||||
"tags": ["time", "adverb"]
|
||||
}
|
||||
},
|
||||
"idioms": [
|
||||
|
|
@ -175,20 +171,10 @@ Authorization: Bearer {token}
|
|||
"exampleTranslation": "對他寬容一點,他是新來的。"
|
||||
}
|
||||
],
|
||||
"statistics": {
|
||||
"totalWords": 16,
|
||||
"uniqueWords": 15,
|
||||
"simpleWords": 8,
|
||||
"moderateWords": 4,
|
||||
"difficultWords": 3,
|
||||
"idioms": 1,
|
||||
"averageDifficulty": "A2"
|
||||
},
|
||||
"metadata": {
|
||||
"analysisModel": "gemini-pro",
|
||||
"analysisVersion": "1.0",
|
||||
"analysisModel": "gemini-1.5-flash",
|
||||
"analysisVersion": "2.0",
|
||||
"processingDate": "2025-01-25T10:30:00Z",
|
||||
"userLevel": "A2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -228,7 +214,6 @@ interface VocabularyAnalysis {
|
|||
synonyms: string[] // 同義詞
|
||||
example?: string // 例句
|
||||
exampleTranslation?: string // 例句翻譯
|
||||
tags: string[] // 標籤分類
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -250,6 +235,48 @@ interface GrammarError {
|
|||
}
|
||||
```
|
||||
|
||||
### **IdiomDto 模型**
|
||||
```typescript
|
||||
interface IdiomDto {
|
||||
idiom: string // 慣用語本身
|
||||
translation: string // 中文翻譯
|
||||
definition: string // 英文定義
|
||||
pronunciation: string // 發音 (IPA)
|
||||
difficultyLevel: CEFRLevel // CEFR等級
|
||||
frequency: FrequencyLevel // 使用頻率
|
||||
synonyms: string[] // 同義詞或相似表達
|
||||
example?: string // 例句
|
||||
exampleTranslation?: string // 例句翻譯
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### **AnalysisMetadata 模型**
|
||||
```typescript
|
||||
interface AnalysisMetadata {
|
||||
analysisModel: string // AI模型名稱
|
||||
analysisVersion: string // 分析版本
|
||||
processingDate: string // 處理時間 (ISO 8601)
|
||||
}
|
||||
```
|
||||
|
||||
### **ApiErrorResponse 模型**
|
||||
```typescript
|
||||
interface ApiErrorResponse {
|
||||
success: boolean // 固定為 false
|
||||
error: ApiError // 錯誤詳情
|
||||
timestamp: string // 錯誤時間 (ISO 8601)
|
||||
requestId: string // 請求ID
|
||||
}
|
||||
|
||||
interface ApiError {
|
||||
code: string // 錯誤代碼
|
||||
message: string // 錯誤訊息
|
||||
details?: object // 錯誤詳情
|
||||
suggestions: string[] // 建議解決方案
|
||||
}
|
||||
```
|
||||
|
||||
### **枚舉定義**
|
||||
```typescript
|
||||
type CEFRLevel = "A1" | "A2" | "B1" | "B2" | "C1" | "C2"
|
||||
|
|
@ -259,6 +286,151 @@ type AnalysisMode = "basic" | "full"
|
|||
|
||||
---
|
||||
|
||||
## 🤖 **AI Prompt設計規格**
|
||||
|
||||
### **Prompt架構設計**
|
||||
|
||||
#### **核心Prompt模板**
|
||||
```text
|
||||
You are an English learning assistant. Analyze this sentence for a learner and return ONLY a valid JSON response.
|
||||
|
||||
**Input Sentence**: "{inputText}"
|
||||
|
||||
**Required JSON Structure:**
|
||||
{
|
||||
"sentenceTranslation": "Traditional Chinese translation of the entire sentence",
|
||||
"hasGrammarErrors": true/false,
|
||||
"grammarCorrections": [
|
||||
{
|
||||
"original": "incorrect text",
|
||||
"corrected": "correct text",
|
||||
"type": "error type (tense/subject-verb/preposition/word-order)",
|
||||
"explanation": "brief explanation in Traditional Chinese"
|
||||
}
|
||||
],
|
||||
"vocabularyAnalysis": {
|
||||
"word1": {
|
||||
"word": "the word",
|
||||
"translation": "Traditional Chinese translation",
|
||||
"definition": "English definition",
|
||||
"partOfSpeech": "noun/verb/adjective/etc",
|
||||
"pronunciation": "/phonetic/",
|
||||
"difficultyLevel": "A1/A2/B1/B2/C1/C2",
|
||||
"frequency": "high/medium/low",
|
||||
"synonyms": ["synonym1", "synonym2"],
|
||||
"example": "example sentence",
|
||||
"exampleTranslation": "Traditional Chinese example translation"
|
||||
}
|
||||
},
|
||||
"idioms": [
|
||||
{
|
||||
"idiom": "idiomatic expression",
|
||||
"translation": "Traditional Chinese meaning",
|
||||
"definition": "English explanation",
|
||||
"pronunciation": "/phonetic notation/",
|
||||
"difficultyLevel": "A1/A2/B1/B2/C1/C2",
|
||||
"frequency": "high/medium/low",
|
||||
"synonyms": ["synonym1", "synonym2"],
|
||||
"example": "usage example",
|
||||
"exampleTranslation": "Traditional Chinese example"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### **Prompt指導原則**
|
||||
|
||||
#### **分析指導方針**
|
||||
```yaml
|
||||
語法檢查:
|
||||
- 檢測範圍: 時態錯誤、主謂一致、介詞使用、詞序問題
|
||||
- 修正原則: 提供自然且正確的英語表達
|
||||
- 解釋語言: 使用繁體中文(台灣標準)
|
||||
|
||||
詞彙分析:
|
||||
- 包含範圍: 所有有意義的詞彙(排除冠詞 a, an, the)
|
||||
- CEFR標準: 準確分配A1-C2等級
|
||||
- 發音標記: 使用國際音標(IPA)
|
||||
- 例句品質: 提供實用且常見的例句
|
||||
|
||||
慣用語識別:
|
||||
- 識別目標: 慣用語、片語動詞、固定搭配
|
||||
- 分類原則: 獨立於vocabularyAnalysis處理
|
||||
- 解釋詳度: 提供文化背景和使用場景
|
||||
|
||||
翻譯品質:
|
||||
- 語言標準: 繁體中文(台灣用法)
|
||||
- 自然程度: 符合中文表達習慣
|
||||
- 準確性: 保持原文語義完整
|
||||
```
|
||||
|
||||
### **Prompt優化策略**
|
||||
|
||||
#### **結構化輸出控制**
|
||||
```text
|
||||
**IMPORTANT**: Return ONLY the JSON object, no additional text or explanation.
|
||||
|
||||
**Quality Assurance:**
|
||||
1. Ensure all JSON keys are exactly as specified
|
||||
2. Use Traditional Chinese for all translations
|
||||
3. Assign accurate CEFR levels based on standard guidelines
|
||||
4. Separate idioms from regular vocabulary
|
||||
5. Provide practical examples that learners can use
|
||||
```
|
||||
|
||||
#### **錯誤處理Prompt**
|
||||
```text
|
||||
**Error Handling Guidelines:**
|
||||
- If unable to analyze: Return basic structure with explanatory messages
|
||||
- If safety filtered: Provide alternative analysis approach
|
||||
- If ambiguous input: Make reasonable assumptions and proceed
|
||||
- Always return valid JSON regardless of input complexity
|
||||
```
|
||||
|
||||
### **Prompt版本管理**
|
||||
|
||||
#### **版本演進記錄**
|
||||
```yaml
|
||||
v1.0 (2025-01-20):
|
||||
- 基礎prompt結構
|
||||
- 簡單詞彙分析
|
||||
|
||||
v1.5 (2025-01-22):
|
||||
- 新增慣用語識別
|
||||
- 優化語法檢查
|
||||
|
||||
v2.0 (2025-01-25):
|
||||
- 結構化JSON輸出
|
||||
- 完整資料模型支援
|
||||
- 繁體中文本地化
|
||||
- 錯誤處理機制
|
||||
```
|
||||
|
||||
#### **A/B測試配置**
|
||||
```csharp
|
||||
// Prompt變體測試
|
||||
public enum PromptVariant
|
||||
{
|
||||
Standard, // 標準prompt
|
||||
DetailedExamples, // 強調例句品質
|
||||
StrictGrammar, // 加強語法檢查
|
||||
CulturalContext // 增加文化背景
|
||||
}
|
||||
|
||||
// 動態Prompt選擇
|
||||
private string GetPromptByVariant(PromptVariant variant, string inputText)
|
||||
{
|
||||
return variant switch
|
||||
{
|
||||
PromptVariant.Standard => BuildStandardPrompt(inputText),
|
||||
PromptVariant.DetailedExamples => BuildDetailedPrompt(inputText),
|
||||
_ => BuildStandardPrompt(inputText)
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔒 **認證與授權**
|
||||
|
||||
### **API認證**
|
||||
|
|
@ -343,7 +515,7 @@ Premium用戶:
|
|||
"responseTime": 2340,
|
||||
"inputLength": 89,
|
||||
"analysisMode": "full",
|
||||
"aiModel": "gpt-4",
|
||||
"aiModel": "gemini-1.5-flash",
|
||||
"processingSteps": {
|
||||
"grammarCheck": 450,
|
||||
"vocabularyAnalysis": 1200,
|
||||
|
|
@ -409,18 +581,14 @@ Premium用戶:
|
|||
測試目的: 驗證完整分析功能
|
||||
輸入數據:
|
||||
inputText: "She just join the team, so let's cut her some slack until she get used to the workflow."
|
||||
userLevel: "A2"
|
||||
analysisMode: "full"
|
||||
|
||||
預期結果:
|
||||
statusCode: 200
|
||||
grammarCorrection.hasErrors: true
|
||||
grammarCorrection.corrections.length: 2
|
||||
vocabularyAnalysis keys: 17 (16個詞 + 1個慣用語)
|
||||
statistics.simpleWords: 8
|
||||
statistics.moderateWords: 4
|
||||
statistics.difficultWords: 3
|
||||
statistics.phrases: 1
|
||||
vocabularyAnalysis keys: 16 (不含慣用語)
|
||||
idioms.length: 1
|
||||
```
|
||||
|
||||
#### **TC-002: 輸入驗證測試**
|
||||
|
|
@ -623,7 +791,17 @@ AI升級:
|
|||
|
||||
---
|
||||
|
||||
**文件版本**: v1.0
|
||||
**文件版本**: v1.1 (更新AI模型和模型定義)
|
||||
**API版本**: v1
|
||||
**最後更新**: 2025-01-25
|
||||
**下次審查**: 2025-02-25
|
||||
**下次審查**: 2025-02-25
|
||||
|
||||
**更新記錄**:
|
||||
- v1.1: 修正AI模型名稱為Gemini 1.5 Flash
|
||||
- v1.1: 移除VocabularyAnalysis中tags欄位
|
||||
- v1.1: 新增IdiomDto和ApiErrorResponse模型定義
|
||||
- v1.1: 移除userLevel參數(簡化API)
|
||||
- v1.1: 統一回應格式範例
|
||||
- v1.1: 新增完整的AI Prompt設計規格和版本管理
|
||||
- v1.1: 同步更新後端DTO模型實現(移除Tags、IsIdiom、UserLevel欄位)
|
||||
- v1.1: 移除statistics計算邏輯(前端自行處理統計)
|
||||
|
|
@ -498,7 +498,6 @@ API通信: Fetch API
|
|||
```json
|
||||
{
|
||||
"inputText": "英文句子",
|
||||
"userLevel": "A2",
|
||||
"analysisMode": "full"
|
||||
}
|
||||
```
|
||||
|
|
@ -508,9 +507,12 @@ API通信: Fetch API
|
|||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"WordAnalysis": "詞彙分析對象",
|
||||
"SentenceMeaning": "句子翻譯",
|
||||
"GrammarCorrection": "語法修正資料"
|
||||
"vocabularyAnalysis": "詞彙分析字典對象",
|
||||
"sentenceMeaning": "句子翻譯字串",
|
||||
"grammarCorrection": "語法修正資料對象",
|
||||
"idioms": "慣用語陣列",
|
||||
"statistics": "統計資料對象",
|
||||
"metadata": "分析元資料對象"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -537,7 +539,7 @@ interface WordAnalysisRequired {
|
|||
partOfSpeech: string // 必需:詞性
|
||||
pronunciation: string // 必需:發音
|
||||
difficultyLevel: string // 必需:CEFR等級
|
||||
isIdiom: boolean // 必需:是否為慣用語
|
||||
frequency: string // 必需:使用頻率
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -727,7 +729,13 @@ interface WordAnalysisOptional {
|
|||
|
||||
---
|
||||
|
||||
**文件版本**: v1.0
|
||||
**文件版本**: v1.1 (配合後端API規格更新)
|
||||
**產品負責人**: DramaLing產品團隊
|
||||
**最後更新**: 2025-09-21
|
||||
**下次審查**: 2025-10-21
|
||||
**最後更新**: 2025-01-25
|
||||
**下次審查**: 2025-02-25
|
||||
|
||||
**更新記錄**:
|
||||
- v1.1: 移除API請求中的userLevel參數要求
|
||||
- v1.1: 更新API回應格式為實際實現的格式
|
||||
- v1.1: 修正資料模型,移除isIdiom欄位,新增frequency欄位
|
||||
- v1.1: 保留前端個人化分類邏輯,改為從localStorage獲取用戶等級
|
||||
|
|
@ -53,7 +53,7 @@ public class AIController : ControllerBase
|
|||
// 直接執行 AI 分析,不使用快取
|
||||
var options = request.Options ?? new AnalysisOptions();
|
||||
var analysisData = await _geminiService.AnalyzeSentenceAsync(
|
||||
request.InputText, request.UserLevel, options);
|
||||
request.InputText, options);
|
||||
|
||||
stopwatch.Stop();
|
||||
analysisData.Metadata.ProcessingDate = DateTime.UtcNow;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@ public class SentenceAnalysisRequest
|
|||
[StringLength(300, MinimumLength = 1, ErrorMessage = "輸入文本長度必須在1-300字符之間")]
|
||||
public string InputText { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
[RegularExpression("^(A1|A2|B1|B2|C1|C2)$", ErrorMessage = "無效的CEFR等級")]
|
||||
public string UserLevel { get; set; } = "A2";
|
||||
|
||||
public string AnalysisMode { get; set; } = "full";
|
||||
|
||||
|
|
@ -42,7 +39,6 @@ public class SentenceAnalysisData
|
|||
public string SentenceMeaning { get; set; } = string.Empty;
|
||||
public Dictionary<string, VocabularyAnalysisDto> VocabularyAnalysis { get; set; } = new();
|
||||
public List<IdiomDto> Idioms { get; set; } = new();
|
||||
public AnalysisStatistics Statistics { get; set; } = new();
|
||||
public AnalysisMetadata Metadata { get; set; } = new();
|
||||
}
|
||||
|
||||
|
|
@ -77,12 +73,10 @@ public class VocabularyAnalysisDto
|
|||
public string PartOfSpeech { get; set; } = string.Empty;
|
||||
public string Pronunciation { get; set; } = string.Empty;
|
||||
public string DifficultyLevel { get; set; } = string.Empty;
|
||||
public bool IsIdiom { get; set; }
|
||||
public string Frequency { get; set; } = string.Empty;
|
||||
public List<string> Synonyms { get; set; } = new();
|
||||
public string? Example { get; set; }
|
||||
public string? ExampleTranslation { get; set; }
|
||||
public List<string> Tags { get; set; } = new();
|
||||
}
|
||||
|
||||
public class IdiomDto
|
||||
|
|
@ -98,23 +92,12 @@ public class IdiomDto
|
|||
public string? ExampleTranslation { get; set; }
|
||||
}
|
||||
|
||||
public class AnalysisStatistics
|
||||
{
|
||||
public int TotalWords { get; set; }
|
||||
public int UniqueWords { get; set; }
|
||||
public int SimpleWords { get; set; }
|
||||
public int ModerateWords { get; set; }
|
||||
public int DifficultWords { get; set; }
|
||||
public int Idioms { get; set; }
|
||||
public string AverageDifficulty { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AnalysisMetadata
|
||||
{
|
||||
public string AnalysisModel { get; set; } = "gpt-4";
|
||||
public string AnalysisVersion { get; set; } = "1.0";
|
||||
public string AnalysisModel { get; set; } = "gemini-1.5-flash";
|
||||
public string AnalysisVersion { get; set; } = "2.0";
|
||||
public DateTime ProcessingDate { get; set; } = DateTime.UtcNow;
|
||||
public string UserLevel { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class ApiErrorResponse
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace DramaLing.Api.Services;
|
|||
|
||||
public interface IGeminiService
|
||||
{
|
||||
Task<SentenceAnalysisData> AnalyzeSentenceAsync(string inputText, string userLevel, AnalysisOptions options);
|
||||
Task<SentenceAnalysisData> AnalyzeSentenceAsync(string inputText, AnalysisOptions options);
|
||||
}
|
||||
|
||||
public class GeminiService : IGeminiService
|
||||
|
|
@ -31,20 +31,19 @@ public class GeminiService : IGeminiService
|
|||
_httpClient.DefaultRequestHeaders.Add("User-Agent", "DramaLing/1.0");
|
||||
}
|
||||
|
||||
public async Task<SentenceAnalysisData> AnalyzeSentenceAsync(string inputText, string userLevel, AnalysisOptions options)
|
||||
public async Task<SentenceAnalysisData> AnalyzeSentenceAsync(string inputText, AnalysisOptions options)
|
||||
{
|
||||
var startTime = DateTime.UtcNow;
|
||||
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Starting sentence analysis for text: {Text}, UserLevel: {UserLevel}",
|
||||
inputText.Substring(0, Math.Min(50, inputText.Length)), userLevel);
|
||||
_logger.LogInformation("Starting sentence analysis for text: {Text}",
|
||||
inputText.Substring(0, Math.Min(50, inputText.Length)));
|
||||
|
||||
// 符合產品需求規格的結構化 prompt
|
||||
var prompt = $@"You are an English learning assistant. Analyze this sentence for a {userLevel} CEFR level learner and return ONLY a valid JSON response.
|
||||
var prompt = $@"You are an English learning assistant. Analyze this sentence and return ONLY a valid JSON response.
|
||||
|
||||
**Input Sentence**: ""{inputText}""
|
||||
**Learner Level**: {userLevel}
|
||||
|
||||
**Required JSON Structure:**
|
||||
{{
|
||||
|
|
@ -113,7 +112,7 @@ public class GeminiService : IGeminiService
|
|||
}
|
||||
|
||||
// 直接使用 AI 的回應創建分析數據
|
||||
var analysisData = CreateAnalysisFromAIResponse(inputText, userLevel, aiResponse);
|
||||
var analysisData = CreateAnalysisFromAIResponse(inputText, aiResponse);
|
||||
|
||||
var processingTime = (DateTime.UtcNow - startTime).TotalSeconds;
|
||||
_logger.LogInformation("Sentence analysis completed in {ProcessingTime}s", processingTime);
|
||||
|
|
@ -127,7 +126,7 @@ public class GeminiService : IGeminiService
|
|||
}
|
||||
}
|
||||
|
||||
private SentenceAnalysisData CreateAnalysisFromAIResponse(string inputText, string userLevel, string aiResponse)
|
||||
private SentenceAnalysisData CreateAnalysisFromAIResponse(string inputText, string aiResponse)
|
||||
{
|
||||
_logger.LogInformation("Creating analysis from AI response: {ResponsePreview}...",
|
||||
aiResponse.Substring(0, Math.Min(100, aiResponse.Length)));
|
||||
|
|
@ -166,15 +165,12 @@ public class GeminiService : IGeminiService
|
|||
GrammarCorrection = ConvertGrammarCorrection(aiAnalysis),
|
||||
Metadata = new AnalysisMetadata
|
||||
{
|
||||
UserLevel = userLevel,
|
||||
ProcessingDate = DateTime.UtcNow,
|
||||
AnalysisModel = "gemini-1.5-flash",
|
||||
AnalysisVersion = "2.0"
|
||||
}
|
||||
};
|
||||
|
||||
// 計算統計
|
||||
analysisData.Statistics = CalculateStatistics(analysisData.VocabularyAnalysis, analysisData.Idioms, userLevel);
|
||||
|
||||
return analysisData;
|
||||
}
|
||||
|
|
@ -182,7 +178,7 @@ public class GeminiService : IGeminiService
|
|||
{
|
||||
_logger.LogError(ex, "Failed to parse AI response as JSON: {Response}", aiResponse);
|
||||
// 回退到舊的處理方式
|
||||
return CreateFallbackAnalysis(inputText, userLevel, aiResponse);
|
||||
return CreateFallbackAnalysis(inputText, aiResponse);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +201,6 @@ public class GeminiService : IGeminiService
|
|||
Synonyms = aiWord.Synonyms ?? new List<string>(),
|
||||
Example = aiWord.Example,
|
||||
ExampleTranslation = aiWord.ExampleTranslation,
|
||||
Tags = new List<string> { "ai-analyzed", "gemini" }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -260,7 +255,7 @@ public class GeminiService : IGeminiService
|
|||
};
|
||||
}
|
||||
|
||||
private SentenceAnalysisData CreateFallbackAnalysis(string inputText, string userLevel, string aiResponse)
|
||||
private SentenceAnalysisData CreateFallbackAnalysis(string inputText, string aiResponse)
|
||||
{
|
||||
_logger.LogWarning("Using fallback analysis due to JSON parsing failure");
|
||||
|
||||
|
|
@ -271,12 +266,10 @@ public class GeminiService : IGeminiService
|
|||
VocabularyAnalysis = CreateBasicVocabularyFromText(inputText, aiResponse),
|
||||
Metadata = new AnalysisMetadata
|
||||
{
|
||||
UserLevel = userLevel,
|
||||
ProcessingDate = DateTime.UtcNow,
|
||||
AnalysisModel = "gemini-1.5-flash-fallback",
|
||||
AnalysisVersion = "1.0"
|
||||
AnalysisVersion = "2.0"
|
||||
},
|
||||
Statistics = new AnalysisStatistics()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -303,7 +296,6 @@ public class GeminiService : IGeminiService
|
|||
Synonyms = new List<string>(),
|
||||
Example = null,
|
||||
ExampleTranslation = null,
|
||||
Tags = new List<string> { "fallback-analysis" }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -335,21 +327,6 @@ public class GeminiService : IGeminiService
|
|||
return "B2";
|
||||
}
|
||||
|
||||
private AnalysisStatistics CalculateStatistics(Dictionary<string, VocabularyAnalysisDto> vocabulary, List<IdiomDto> idioms, string userLevel)
|
||||
{
|
||||
var stats = new AnalysisStatistics
|
||||
{
|
||||
TotalWords = vocabulary.Count,
|
||||
UniqueWords = vocabulary.Count,
|
||||
SimpleWords = vocabulary.Count(kvp => kvp.Value.DifficultyLevel == "A1"),
|
||||
ModerateWords = vocabulary.Count(kvp => kvp.Value.DifficultyLevel == "A2"),
|
||||
DifficultWords = vocabulary.Count(kvp => !new[] { "A1", "A2" }.Contains(kvp.Value.DifficultyLevel)),
|
||||
Idioms = idioms.Count, // 基於實際 idioms 陣列計算
|
||||
AverageDifficulty = userLevel
|
||||
};
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
private async Task<string> CallGeminiAPI(string prompt)
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue