# Gemini AI API 整合文檔 ## 概述 本文檔說明如何整合 Google Gemini API 來實現 AI 詞卡生成功能。 ## API 設置 ### 1. 取得 API Key 1. 訪問 [Google AI Studio](https://makersuite.google.com/app/apikey) 2. 點擊 "Create API Key" 3. 選擇專案或建立新專案 4. 複製生成的 API Key ### 2. 安裝 SDK ```bash npm install @google/generative-ai ``` ### 3. 環境變數配置 ```env GEMINI_API_KEY=your_api_key_here ``` ## API 實作 ### 基礎設置 ```typescript // lib/gemini.ts import { GoogleGenerativeAI } from '@google/generative-ai'; const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!); export const geminiModel = genAI.getGenerativeModel({ model: "gemini-pro" }); ``` ### 詞卡生成功能 ```typescript // app/api/ai/generate-flashcard/route.ts import { NextRequest, NextResponse } from 'next/server'; import { geminiModel } from '@/lib/gemini'; export async function POST(request: NextRequest) { try { const { text, type } = await request.json(); const prompt = createPrompt(text, type); const result = await geminiModel.generateContent(prompt); const response = await result.response; const generatedText = response.text(); const flashcards = parseFlashcards(generatedText); return NextResponse.json({ flashcards }); } catch (error) { console.error('Gemini API error:', error); return NextResponse.json( { error: 'Failed to generate flashcards' }, { status: 500 } ); } } ``` ## Prompt 工程 ### 基礎 Prompt 模板 ```typescript const FLASHCARD_PROMPT = ` 你是一個專業的英語教學助手,專門幫助台灣學生透過美劇學習英文。 請根據以下內容生成詞卡: 輸入文本:{input_text} 請生成5個最重要的詞彙學習卡片,每個卡片包含: 1. 英文單字或片語 2. 中文翻譯 3. 詞性和用法說明 4. 原文例句(從輸入文本中提取) 5. 額外例句(創造一個相似情境的例句) 6. 使用情境說明(什麼場合使用) 7. 難度等級(1-5,1最簡單) 請以 JSON 格式回覆,格式如下: { "flashcards": [ { "word": "英文單字或片語", "translation": "中文翻譯", "partOfSpeech": "詞性", "usage": "用法說明", "originalExample": "原文例句", "additionalExample": "額外例句", "context": "使用情境", "difficulty": 難度數字 } ] } `; ``` ### 不同類型的 Prompt #### 1. 美劇對話分析 ```typescript const DRAMA_DIALOGUE_PROMPT = ` 分析以下美劇對話,提取日常對話中的重要表達: - 重點關注俚語、慣用語、口語表達 - 解釋文化背景和使用場合 - 標註正式程度(非常口語/口語/中性/正式) `; ``` #### 2. 主題學習 ```typescript const TOPIC_LEARNING_PROMPT = ` 生成關於「{topic}」主題的詞彙卡片: - 包含該主題最常用的詞彙 - 提供實用的搭配詞和片語 - 給出真實對話場景的例句 `; ``` #### 3. 語法重點 ```typescript const GRAMMAR_FOCUS_PROMPT = ` 分析文本中的語法結構: - 識別重要的語法模式 - 解釋語法規則和例外 - 提供類似結構的變化練習 `; ``` ## 回應解析 ### JSON 解析函數 ```typescript function parseFlashcards(responseText: string) { try { // 清理回應文本(移除可能的 markdown 標記) const cleanedText = responseText .replace(/```json\n?/g, '') .replace(/```\n?/g, '') .trim(); const parsed = JSON.parse(cleanedText); return parsed.flashcards; } catch (error) { console.error('Parse error:', error); // 備用解析邏輯 return extractFlashcardsManually(responseText); } } ``` ### 錯誤處理與重試 ```typescript async function generateWithRetry(prompt: string, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { const result = await geminiModel.generateContent(prompt); return result; } catch (error) { if (i === maxRetries - 1) throw error; await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); } } } ``` ## Rate Limiting 與配額管理 ### 請求限制 ```typescript import { RateLimiter } from '@/lib/rate-limiter'; const limiter = new RateLimiter({ tokensPerInterval: 60, // Gemini Free: 60 QPM interval: 'minute', }); export async function checkRateLimit(userId: string) { const isAllowed = await limiter.check(userId); if (!isAllowed) { throw new Error('Rate limit exceeded'); } } ``` ### 配額追蹤 ```typescript // 記錄用戶使用量 async function trackUsage(userId: string, tokensUsed: number) { await supabase .from('user_usage') .upsert({ user_id: userId, date: new Date().toISOString().split('T')[0], gemini_tokens: tokensUsed, }); } ``` ## 最佳實踐 ### 1. Prompt 優化 - 使用具體、清晰的指示 - 提供輸出格式範例 - 設定合適的 temperature (0.7-0.9) ### 2. 成本控制 - 限制每個請求的 token 數量 - 實施用戶配額系統 - 快取常見請求結果 ### 3. 錯誤處理 - 實施重試機制 - 提供降級方案 - 記錄錯誤日誌 ### 4. 安全考量 - 不在前端暴露 API Key - 實施內容過濾 - 驗證用戶輸入 ## 測試範例 ### 單元測試 ```typescript describe('Gemini Integration', () => { it('should generate flashcards from text', async () => { const input = "I'm gonna grab a coffee, wanna come?"; const result = await generateFlashcards(input); expect(result).toHaveLength(5); expect(result[0]).toHaveProperty('word'); expect(result[0]).toHaveProperty('translation'); }); it('should handle rate limiting', async () => { // 測試超過限制的請求 }); }); ``` ### 整合測試 ```typescript describe('API Endpoint', () => { it('should return flashcards via API', async () => { const response = await fetch('/api/ai/generate-flashcard', { method: 'POST', body: JSON.stringify({ text: 'test input' }), }); expect(response.status).toBe(200); const data = await response.json(); expect(data.flashcards).toBeDefined(); }); }); ``` ## 監控與日誌 ### 關鍵指標 - API 回應時間 - 成功/失敗率 - Token 使用量 - 用戶滿意度 ### 日誌記錄 ```typescript import { logger } from '@/lib/logger'; logger.info('Gemini API called', { userId, promptLength: prompt.length, responseTime: Date.now() - startTime, }); ``` ## 故障排除 ### 常見問題 1. **API Key 無效** - 確認環境變數設置正確 - 檢查 API Key 是否啟用 2. **Rate Limit 錯誤** - 實施請求隊列 - 升級到付費方案 3. **回應解析失敗** - 改進 prompt 明確性 - 實施備用解析邏輯 4. **生成品質不佳** - 調整 temperature 參數 - 優化 prompt 內容 - 提供更多範例