21 KiB
21 KiB
AI分析API技術實現規格
📋 文件資訊
- 文件名稱: AI分析API技術實現規格
- 版本: v2.0
- 建立日期: 2025-01-25
- 最後更新: 2025-01-25
- 負責團隊: DramaLing後端技術團隊
- 對應產品需求: 《AI句子分析功能產品需求規格》
🛠 技術架構概述
系統架構設計
分層架構:
- 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
功能: 智能英文句子分析
請求格式:
{
"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
}
}
回應格式:
{
"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
功能: 服務健康檢查
回應格式:
{
"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模板
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配置
模型配置:
- 模型: gemini-1.5-flash
- 溫度: 0.7 (平衡創造性和準確性)
- 最大輸出: 2000 tokens
- 超時: 30秒
重試策略:
- 最大重試: 3次
- 退避策略: 指數退避 (1s, 2s, 4s)
- 重試條件: 網路錯誤、超時、5xx錯誤
- 熔斷條件: 連續失敗 > 5次
降級策略:
- 備用回應: 基礎翻譯和詞性分析
- 快取回退: 相似句子的歷史分析結果
- 服務狀態: 實時監控和告警
🔧 數據模型設計
請求模型
SentenceAnalysisRequest
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;
}
回應模型
核心資料模型
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<string, VocabularyAnalysisDto> VocabularyAnalysis { get; set; } = new();
public List<IdiomDto> Idioms { get; set; } = new();
public AnalysisMetadata Metadata { get; set; } = new();
}
詳細模型定義
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<string> 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<string> 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<GrammarErrorDto> 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介面
public interface IGeminiService
{
Task<SentenceAnalysisData> AnalyzeSentenceAsync(string inputText, AnalysisOptions options);
Task<bool> HealthCheckAsync();
Task<string> GetModelVersionAsync();
}
服務實現重點
public class GeminiService : IGeminiService
{
private readonly HttpClient _httpClient;
private readonly IOptions<GeminiOptions> _options;
private readonly ILogger<GeminiService> _logger;
// ✅ 強型別配置注入
public GeminiService(HttpClient httpClient, IOptions<GeminiOptions> options, ILogger<GeminiService> logger)
{
_httpClient = httpClient;
_options = options;
_logger = logger;
ConfigureHttpClient();
}
// ✅ 結構化錯誤處理
public async Task<SentenceAnalysisData> 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);
}
}
}
配置管理架構
強型別配置
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<GeminiOptions>
{
public ValidateOptionsResult Validate(string name, GeminiOptions options)
{
var failures = new List<string>();
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;
}
}
🛡️ 錯誤處理與穩定性
異常層次結構
public abstract class DramaLingException : Exception
{
public string ErrorCode { get; }
public Dictionary<string, object> Context { get; }
protected DramaLingException(string errorCode, string message) : base(message)
{
ErrorCode = errorCode;
Context = new Dictionary<string, object>();
}
}
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;
}
}
錯誤回應標準
{
"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"
}
重試與熔斷機制
// 使用Polly實現重試策略
services.AddHttpClient<IGeminiService, GeminiService>()
.AddPolicyHandler(GetRetryPolicy())
.AddPolicyHandler(GetCircuitBreakerPolicy());
private static IAsyncPolicy<HttpResponseMessage> 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);
});
}
📊 性能優化設計
快取策略
多層快取架構:
L1: 應用程序記憶體快取 (5分鐘)
L2: Redis分散式快取 (1小時)
L3: 資料庫持久快取 (24小時)
快取鍵設計:
- 格式: "analysis:{hash(inputText)}"
- 過期: 基於內容複雜度動態調整
- 清理: 背景服務定期清理過期快取
快取命中率目標: > 70%
資料庫優化
// 查詢優化範例
public async Task<AnalysisCache> 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安全
認證機制:
- JWT Bearer Token認證
- Token過期時間: 24小時
- 刷新機制: Refresh Token
授權控制:
- 角色基礎存取控制 (RBAC)
- 資源級別權限
- API速率限制
輸入驗證:
- 參數類型檢查
- 字符長度限制
- XSS防護過濾
- SQL注入防護
資料安全
傳輸安全:
- TLS 1.3強制加密
- HSTS標頭
- 安全標頭 (CSP, X-Frame-Options)
存儲安全:
- 敏感資料加密
- API金鑰安全管理
- 個人資料匿名化
- 定期安全掃描
🧪 測試策略
測試金字塔
單元測試 (70%):
- 服務邏輯測試
- 配置驗證測試
- 錯誤處理測試
- Mock外部依賴
整合測試 (20%):
- API端點測試
- 資料庫整合測試
- 快取系統測試
- 健康檢查測試
E2E測試 (10%):
- 完整分析流程測試
- 真實AI API測試
- 性能基準測試
- 安全滲透測試
測試案例設計
[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服務故障時的錯誤處理
}
}
📈 監控與可觀測性
日誌標準
// 結構化日誌擴展
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);
}
}
健康檢查
public class AIServiceHealthCheck : IHealthCheck
{
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context,
CancellationToken cancellationToken = default)
{
var checks = new Dictionary<string, bool>
{
["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");
}
}
性能指標
關鍵指標:
- API回應時間分佈 (P50, P95, P99)
- AI API調用成功率
- 快取命中率
- 記憶體和CPU使用率
- 錯誤率和異常分佈
告警閾值:
- 回應時間P95 > 5秒
- 錯誤率 > 5%
- AI API失敗率 > 10%
- 記憶體使用 > 80%
🚀 部署與配置
環境配置
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配置
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"]
📋 開發指導
程式碼規範
命名規範:
- 類別: PascalCase (UserService)
- 方法: PascalCase (AnalyzeAsync)
- 參數: camelCase (inputText)
- 常數: UPPER_CASE (MAX_LENGTH)
註釋規範:
- 公開API: 完整XML註釋
- 複雜邏輯: 行內註釋解釋
- 業務邏輯: 意圖說明註釋
- TODO: 使用標準格式
錯誤處理:
- 自訂異常類型
- 結構化錯誤回應
- 日誌記錄完整
- 用戶友善訊息
API設計原則
RESTful設計:
- 使用標準HTTP動詞
- 資源導向URL設計
- 狀態碼語義明確
- 一致的回應格式
版本管理:
- URL版本控制 (/api/v1/)
- 向下相容保證
- 淘汰策略明確
- 版本變更文檔
安全實踐:
- 最小權限原則
- 輸入驗證完整
- 輸出編碼安全
- 審計日誌記錄
🔄 變更管理
API版本演進
- v1.0: 基礎分析功能 (2025-01-20)
- v1.1: 移除userLevel,簡化API (2025-01-25)
- v2.0: 重構技術規格,標準化設計 (2025-01-25)
技術債務管理
已解決:
- 硬編碼配置移除
- 強型別配置實施
- API規格標準化
待解決:
- 重試機制實施
- 健康檢查完善
- 監控指標實施
- 性能優化
文件版本: v2.0 技術負責人: DramaLing後端技術團隊 最後更新: 2025-01-25 下次審查: 2025-02-25
關聯文件:
- 《AI句子分析功能產品需求規格》- 業務需求和用戶故事
- 《系統整合與部署規格》- 整合和部署細節
- 《AI驅動產品後端技術架構指南》- 架構設計指導原則