# AI分析API技術實現規格 ## 📋 **文件資訊** - **文件名稱**: AI分析API技術實現規格 - **版本**: v2.0 - **建立日期**: 2025-01-25 - **最後更新**: 2025-01-25 - **負責團隊**: DramaLing後端技術團隊 - **對應產品需求**: 《AI句子分析功能產品需求規格》 --- ## 🛠 **技術架構概述** ### **系統架構設計** ```yaml 分層架構: - API Gateway: 認證、限流、路由 - Controllers: HTTP請求處理、參數驗證 - Services: 業務邏輯、AI整合 - Data Access: 資料庫操作、快取管理 - External APIs: AI服務、第三方整合 技術棧: - 語言: C# / .NET 8 - 框架: ASP.NET Core Web API - AI服務: Google Gemini 1.5 Flash - 資料庫: SQLite (開發) / PostgreSQL (生產) - 快取: Redis (生產) / In-Memory (開發) - 監控: Application Insights ``` ### **核心設計原則** - **單一職責**: 每個服務類別職責明確 - **依賴注入**: 基於介面的鬆耦合設計 - **配置外部化**: 強型別配置管理 - **錯誤恢復**: 重試機制和降級策略 - **可觀測性**: 結構化日誌和健康檢查 --- ## 📡 **API端點設計** ### **核心分析端點** #### **POST /api/ai/analyze-sentence** **功能**: 智能英文句子分析 **請求格式**: ```json { "inputText": "She just join the team, so let's cut her some slack until she get used to the workflow.", "analysisMode": "full", "options": { "includeGrammarCheck": true, "includeVocabularyAnalysis": true, "includeTranslation": true, "includeIdiomDetection": true, "includeExamples": true } } ``` **回應格式**: ```json { "success": true, "processingTime": 2.34, "data": { "analysisId": "uuid-string", "originalText": "原始輸入文本", "grammarCorrection": { "hasErrors": true, "correctedText": "修正後文本", "corrections": [ { "position": { "start": 9, "end": 13 }, "error": "join", "correction": "joined", "type": "時態錯誤", "explanation": "第三人稱單數過去式應使用 'joined'", "severity": "high" } ] }, "sentenceMeaning": "中文翻譯", "vocabularyAnalysis": { "word": { "word": "詞彙", "translation": "中文翻譯", "definition": "英文定義", "partOfSpeech": "詞性", "pronunciation": "/IPA發音/", "difficultyLevel": "A1-C2", "frequency": "high/medium/low", "synonyms": ["同義詞陣列"], "example": "例句", "exampleTranslation": "例句翻譯" } }, "idioms": [ { "idiom": "cut someone some slack", "translation": "對某人寬容一點", "definition": "to be more lenient or forgiving", "pronunciation": "/發音/", "difficultyLevel": "B2", "frequency": "medium", "synonyms": ["be lenient", "give leeway"], "example": "例句", "exampleTranslation": "例句翻譯" } ], "metadata": { "analysisModel": "gemini-1.5-flash", "analysisVersion": "2.0", "processingDate": "2025-01-25T10:30:00Z" } } } ``` #### **GET /api/ai/health** **功能**: 服務健康檢查 **回應格式**: ```json { "status": "Healthy", "service": "AI Analysis Service", "timestamp": "2025-01-25T10:30:00Z", "version": "2.0", "dependencies": { "geminiApi": "healthy", "database": "healthy", "cache": "healthy" } } ``` --- ## 🤖 **AI集成架構** ### **Prompt工程設計** #### **核心Prompt模板** ```text You are an English learning assistant. Analyze this sentence 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" } ] } **Analysis Guidelines:** 1. **Grammar Check**: Detect tense errors, subject-verb agreement, preposition usage, word order 2. **Vocabulary Analysis**: Include ALL significant words (exclude articles: a, an, the) 3. **CEFR Levels**: Assign accurate A1-C2 levels for each word 4. **Idioms**: Identify any idiomatic expressions or phrasal verbs 5. **Translations**: Use Traditional Chinese (Taiwan standard) **IMPORTANT**: Return ONLY the JSON object, no additional text or explanation. ``` ### **AI服務配置** #### **Gemini API配置** ```yaml 模型配置: - 模型: gemini-1.5-flash - 溫度: 0.7 (平衡創造性和準確性) - 最大輸出: 2000 tokens - 超時: 30秒 重試策略: - 最大重試: 3次 - 退避策略: 指數退避 (1s, 2s, 4s) - 重試條件: 網路錯誤、超時、5xx錯誤 - 熔斷條件: 連續失敗 > 5次 降級策略: - 備用回應: 基礎翻譯和詞性分析 - 快取回退: 相似句子的歷史分析結果 - 服務狀態: 實時監控和告警 ``` --- ## 🔧 **數據模型設計** ### **請求模型** #### **SentenceAnalysisRequest** ```csharp public class SentenceAnalysisRequest { [Required] [StringLength(300, MinimumLength = 1)] public string InputText { get; set; } = string.Empty; public string AnalysisMode { get; set; } = "full"; public AnalysisOptions? Options { get; set; } } public class AnalysisOptions { public bool IncludeGrammarCheck { get; set; } = true; public bool IncludeVocabularyAnalysis { get; set; } = true; public bool IncludeTranslation { get; set; } = true; public bool IncludeIdiomDetection { get; set; } = true; public bool IncludeExamples { get; set; } = true; } ``` ### **回應模型** #### **核心資料模型** ```csharp public class SentenceAnalysisResponse { public bool Success { get; set; } = true; public double ProcessingTime { get; set; } public SentenceAnalysisData? Data { get; set; } public string? Message { get; set; } } public class SentenceAnalysisData { public string AnalysisId { get; set; } = Guid.NewGuid().ToString(); public string OriginalText { get; set; } = string.Empty; public GrammarCorrectionDto? GrammarCorrection { get; set; } public string SentenceMeaning { get; set; } = string.Empty; public Dictionary VocabularyAnalysis { get; set; } = new(); public List Idioms { get; set; } = new(); public AnalysisMetadata Metadata { get; set; } = new(); } ``` #### **詳細模型定義** ```csharp public class VocabularyAnalysisDto { public string Word { get; set; } = string.Empty; public string Translation { get; set; } = string.Empty; public string Definition { get; set; } = string.Empty; public string PartOfSpeech { get; set; } = string.Empty; public string Pronunciation { get; set; } = string.Empty; public string DifficultyLevel { get; set; } = string.Empty; public string Frequency { get; set; } = string.Empty; public List Synonyms { get; set; } = new(); public string? Example { get; set; } public string? ExampleTranslation { get; set; } } public class IdiomDto { public string Idiom { get; set; } = string.Empty; public string Translation { get; set; } = string.Empty; public string Definition { get; set; } = string.Empty; public string Pronunciation { get; set; } = string.Empty; public string DifficultyLevel { get; set; } = string.Empty; public string Frequency { get; set; } = string.Empty; public List Synonyms { get; set; } = new(); public string? Example { get; set; } public string? ExampleTranslation { get; set; } } public class GrammarCorrectionDto { public bool HasErrors { get; set; } public string CorrectedText { get; set; } = string.Empty; public List Corrections { get; set; } = new(); } public class GrammarErrorDto { public ErrorPosition Position { get; set; } = new(); public string Error { get; set; } = string.Empty; public string Correction { get; set; } = string.Empty; public string Type { get; set; } = string.Empty; public string Explanation { get; set; } = string.Empty; public string Severity { get; set; } = "medium"; } ``` --- ## 🔧 **服務層架構** ### **核心服務設計** #### **IGeminiService介面** ```csharp public interface IGeminiService { Task AnalyzeSentenceAsync(string inputText, AnalysisOptions options); Task HealthCheckAsync(); Task GetModelVersionAsync(); } ``` #### **服務實現重點** ```csharp public class GeminiService : IGeminiService { private readonly HttpClient _httpClient; private readonly IOptions _options; private readonly ILogger _logger; // ✅ 強型別配置注入 public GeminiService(HttpClient httpClient, IOptions options, ILogger logger) { _httpClient = httpClient; _options = options; _logger = logger; ConfigureHttpClient(); } // ✅ 結構化錯誤處理 public async Task AnalyzeSentenceAsync(string inputText, AnalysisOptions options) { try { var prompt = BuildPrompt(inputText, options); var aiResponse = await CallGeminiAPIWithRetry(prompt); return ParseResponse(inputText, aiResponse); } catch (HttpRequestException ex) { throw new AIServiceException("Gemini", "Network error", ex); } catch (JsonException ex) { throw new AIServiceException("Gemini", "Invalid response format", ex); } } } ``` ### **配置管理架構** #### **強型別配置** ```csharp public class GeminiOptions { public const string SectionName = "Gemini"; [Required] public string ApiKey { get; set; } = string.Empty; [Range(1, 120)] public int TimeoutSeconds { get; set; } = 30; [Range(1, 10)] public int MaxRetries { get; set; } = 3; public string Model { get; set; } = "gemini-1.5-flash"; public double Temperature { get; set; } = 0.7; public int MaxOutputTokens { get; set; } = 2000; } // 配置驗證器 public class GeminiOptionsValidator : IValidateOptions { public ValidateOptionsResult Validate(string name, GeminiOptions options) { var failures = new List(); if (string.IsNullOrWhiteSpace(options.ApiKey)) failures.Add("Gemini API key is required"); if (!IsValidApiKey(options.ApiKey)) failures.Add("Invalid Gemini API key format"); return failures.Any() ? ValidateOptionsResult.Fail(failures) : ValidateOptionsResult.Success; } } ``` --- ## 🛡️ **錯誤處理與穩定性** ### **異常層次結構** ```csharp public abstract class DramaLingException : Exception { public string ErrorCode { get; } public Dictionary Context { get; } protected DramaLingException(string errorCode, string message) : base(message) { ErrorCode = errorCode; Context = new Dictionary(); } } public class AIServiceException : DramaLingException { public AIServiceException(string provider, string details) : base("AI_SERVICE_ERROR", $"AI service '{provider}' failed: {details}") { Context["Provider"] = provider; Context["Details"] = details; } } public class ValidationException : DramaLingException { public ValidationException(string field, string message) : base("VALIDATION_ERROR", $"Validation failed for {field}: {message}") { Context["Field"] = field; } } ``` ### **錯誤回應標準** ```json { "success": false, "error": { "code": "AI_SERVICE_ERROR", "message": "AI服務暫時不可用", "details": { "provider": "gemini", "originalError": "Network timeout" }, "suggestions": [ "請稍後重試", "如果問題持續,請聯繫客服" ] }, "timestamp": "2025-01-25T10:30:00Z", "requestId": "uuid-string" } ``` ### **重試與熔斷機制** ```csharp // 使用Polly實現重試策略 services.AddHttpClient() .AddPolicyHandler(GetRetryPolicy()) .AddPolicyHandler(GetCircuitBreakerPolicy()); private static IAsyncPolicy GetRetryPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() .WaitAndRetryAsync( retryCount: 3, sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), onRetry: (outcome, timespan, retryCount, context) => { logger.LogWarning("Retry {RetryCount} after {Delay}ms", retryCount, timespan.TotalMilliseconds); }); } ``` --- ## 📊 **性能優化設計** ### **快取策略** ```yaml 多層快取架構: L1: 應用程序記憶體快取 (5分鐘) L2: Redis分散式快取 (1小時) L3: 資料庫持久快取 (24小時) 快取鍵設計: - 格式: "analysis:{hash(inputText)}" - 過期: 基於內容複雜度動態調整 - 清理: 背景服務定期清理過期快取 快取命中率目標: > 70% ``` ### **資料庫優化** ```csharp // 查詢優化範例 public async Task GetCachedAnalysisAsync(string inputText) { var textHash = ComputeHash(inputText); return await _context.AnalysisCache .AsNoTracking() // 只讀查詢優化 .Where(c => c.InputTextHash == textHash && c.ExpiresAt > DateTime.UtcNow) .Select(c => new AnalysisCache // 投影查詢,只選需要的欄位 { Id = c.Id, CachedData = c.CachedData, CreatedAt = c.CreatedAt }) .FirstOrDefaultAsync(); } ``` --- ## 🔒 **安全架構設計** ### **API安全** ```yaml 認證機制: - JWT Bearer Token認證 - Token過期時間: 24小時 - 刷新機制: Refresh Token 授權控制: - 角色基礎存取控制 (RBAC) - 資源級別權限 - API速率限制 輸入驗證: - 參數類型檢查 - 字符長度限制 - XSS防護過濾 - SQL注入防護 ``` ### **資料安全** ```yaml 傳輸安全: - TLS 1.3強制加密 - HSTS標頭 - 安全標頭 (CSP, X-Frame-Options) 存儲安全: - 敏感資料加密 - API金鑰安全管理 - 個人資料匿名化 - 定期安全掃描 ``` --- ## 🧪 **測試策略** ### **測試金字塔** ```yaml 單元測試 (70%): - 服務邏輯測試 - 配置驗證測試 - 錯誤處理測試 - Mock外部依賴 整合測試 (20%): - API端點測試 - 資料庫整合測試 - 快取系統測試 - 健康檢查測試 E2E測試 (10%): - 完整分析流程測試 - 真實AI API測試 - 性能基準測試 - 安全滲透測試 ``` ### **測試案例設計** ```csharp [TestFixture] public class AIAnalysisServiceTests { [Test] public async Task AnalyzeAsync_WithValidInput_ReturnsAnalysisResult() { // Arrange var request = new AnalysisRequest { InputText = "She just joined the team." }; // Act var result = await _service.AnalyzeAsync(request); // Assert Assert.That(result.VocabularyAnalysis.Count, Is.GreaterThan(0)); Assert.That(result.SentenceMeaning, Is.Not.Empty); } [Test] public async Task AnalyzeAsync_WhenAIServiceFails_ThrowsAIServiceException() { // 測試AI服務故障時的錯誤處理 } } ``` --- ## 📈 **監控與可觀測性** ### **日誌標準** ```csharp // 結構化日誌擴展 public static class LoggerExtensions { public static void LogAIRequest(this ILogger logger, string requestId, string inputText, string provider, double processingTime) { logger.LogInformation("AI Request: {RequestId} Provider: {Provider} " + "Length: {Length} Time: {Time}ms", requestId, provider, inputText.Length, processingTime); } } ``` ### **健康檢查** ```csharp public class AIServiceHealthCheck : IHealthCheck { public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { var checks = new Dictionary { ["gemini_api"] = await CheckGeminiHealthAsync(), ["database"] = await CheckDatabaseHealthAsync(), ["cache"] = await CheckCacheHealthAsync() }; var failedChecks = checks.Where(c => !c.Value).Select(c => c.Key).ToList(); return failedChecks.Any() ? HealthCheckResult.Unhealthy($"Failed: {string.Join(", ", failedChecks)}") : HealthCheckResult.Healthy("All systems operational"); } } ``` ### **性能指標** ```yaml 關鍵指標: - API回應時間分佈 (P50, P95, P99) - AI API調用成功率 - 快取命中率 - 記憶體和CPU使用率 - 錯誤率和異常分佈 告警閾值: - 回應時間P95 > 5秒 - 錯誤率 > 5% - AI API失敗率 > 10% - 記憶體使用 > 80% ``` --- ## 🚀 **部署與配置** ### **環境配置** ```yaml Development: - Database: SQLite - Cache: In-Memory - AI Provider: Gemini (測試Key) - Logging: Debug Level Production: - Database: PostgreSQL (HA) - Cache: Redis Cluster - AI Provider: Gemini (生產Key) - Logging: Information Level - Monitoring: Application Insights ``` ### **Docker配置** ```dockerfile FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base WORKDIR /app EXPOSE 5008 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["DramaLing.Api.csproj", "."] RUN dotnet restore COPY . . RUN dotnet publish -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=build /app/publish . HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:5008/health || exit 1 ENTRYPOINT ["dotnet", "DramaLing.Api.dll"] ``` --- ## 📋 **開發指導** ### **程式碼規範** ```yaml 命名規範: - 類別: PascalCase (UserService) - 方法: PascalCase (AnalyzeAsync) - 參數: camelCase (inputText) - 常數: UPPER_CASE (MAX_LENGTH) 註釋規範: - 公開API: 完整XML註釋 - 複雜邏輯: 行內註釋解釋 - 業務邏輯: 意圖說明註釋 - TODO: 使用標準格式 錯誤處理: - 自訂異常類型 - 結構化錯誤回應 - 日誌記錄完整 - 用戶友善訊息 ``` ### **API設計原則** ```yaml RESTful設計: - 使用標準HTTP動詞 - 資源導向URL設計 - 狀態碼語義明確 - 一致的回應格式 版本管理: - URL版本控制 (/api/v1/) - 向下相容保證 - 淘汰策略明確 - 版本變更文檔 安全實踐: - 最小權限原則 - 輸入驗證完整 - 輸出編碼安全 - 審計日誌記錄 ``` --- ## 🔄 **變更管理** ### **API版本演進** - **v1.0**: 基礎分析功能 (2025-01-20) - **v1.1**: 移除userLevel,簡化API (2025-01-25) - **v2.0**: 重構技術規格,標準化設計 (2025-01-25) ### **技術債務管理** ```yaml 已解決: - 硬編碼配置移除 - 強型別配置實施 - API規格標準化 待解決: - 重試機制實施 - 健康檢查完善 - 監控指標實施 - 性能優化 ``` --- **文件版本**: v2.0 **技術負責人**: DramaLing後端技術團隊 **最後更新**: 2025-01-25 **下次審查**: 2025-02-25 **關聯文件**: - 《AI句子分析功能產品需求規格》- 業務需求和用戶故事 - 《系統整合與部署規格》- 整合和部署細節 - 《AI驅動產品後端技術架構指南》- 架構設計指導原則