# 對話練習 API ## 📋 概述 Drama Ling 的核心功能 - 情境對話練習系統,包含場景對話、AI分析、回覆輔助等功能。 ## 🎭 核心功能 ### 對話系統特色 - **情境化對話**: 真實場景模擬(餐廳、機場、購物等) - **AI智能回應**: OpenAI GPT-4o-mini 驅動的自然對話 - **即時分析**: 語法、語義、流暢度多維度評分 - **學習輔助**: 智能提示和回覆建議 - **進度追蹤**: 對話目標和完成度監控 ## 📌 API 端點 ### 1. 開始對話練習 ```http POST /api/v1/dialogues/start Authorization: Bearer Content-Type: application/json { "scenario_id": "SC_Restaurant_01", "difficulty_override": "A2", "target_vocabulary": ["reservation", "menu", "order"], "practice_mode": "guided" // guided, free_form, challenge } ``` #### 回應範例 ```http Response 201 Created { "success": true, "data": { "dialogue_id": "DLG_20240907_001", "scenario_id": "SC_Restaurant_01", "session_token": "session_eyJhbGciOiJIUzI1NiIs...", "dialogue_config": { "max_turns": 12, "time_limit": 600, // seconds "difficulty_level": "A2", "practice_mode": "guided" }, "scenario_context": { "setting": "高級義大利餐廳內部,晚上8點", "location": "Milano Restaurant, 市中心", "your_role": "顧客", "ai_role": "餐廳服務員", "objective": "成功預約座位並完成點餐", "background_info": "這是一家需要預約的高檔餐廳,服務正式" }, "initial_state": { "life_points_cost": 1, "remaining_life_points": 4, "objectives": [ "確認預約", "選擇餐桌", "點餐主菜", "完成付款" ] }, "ai_opening": { "message": "Good evening! Welcome to Milano Restaurant. Do you have a reservation with us tonight?", "audio_url": "https://cdn.dramaling.com/audio/dialogues/DLG_20240907_001_001.mp3", "audio_duration": 4.2, "emotion": "polite_welcoming", "formality_level": "formal", "suggestions": [ "Yes, I have a reservation under Chen.", "No, but could we get a table for two?", "I'd like to check if you have any available tables." ] } }, "message": "Dialogue session started successfully" } ``` #### 場景類型 - `SC_Restaurant_*`: 餐廳相關場景 - `SC_Airport_*`: 機場/旅行場景 - `SC_Shopping_*`: 購物場景 - `SC_Business_*`: 商務場景 - `SC_Medical_*`: 醫療場景 - `SC_Education_*`: 教育場景 ### 2. 發送對話訊息 ```http POST /api/v1/dialogues/{dialogue_id}/message Authorization: Bearer Content-Type: application/json { "message": "Yes, I have a reservation under Chen for 8 PM for two people.", "message_type": "text", "audio_data": { "audio_url": "https://cdn.dramaling.com/user_audio/msg001.mp3", "duration": 3.5 }, "metadata": { "input_method": "voice", // voice, keyboard "confidence_level": 4, // 1-5, user's confidence "time_taken": 15.2 // seconds to compose } } ``` #### 回應範例 ```http Response 200 OK { "success": true, "data": { "turn_id": "TURN_002", "dialogue_status": "active", "ai_response": { "message": "Excellent! Mr. Chen, party of two at 8 PM. Your table is ready. Would you prefer a window seat or would you like to sit in our main dining area?", "audio_url": "https://cdn.dramaling.com/audio/dialogues/DLG_20240907_001_002.mp3", "audio_duration": 6.8, "emotion": "friendly_professional", "formality_level": "formal", "context_hints": { "next_expected": "table_preference", "vocabulary_focus": ["window seat", "dining area", "prefer"] } }, "user_analysis": { "grammar_score": 90, "semantic_score": 95, "fluency_score": 85, "pronunciation_score": 88, "overall_score": 90, "detailed_feedback": { "strengths": [ "Perfect use of formal language", "Appropriate information included", "Natural sentence structure" ], "improvements": [ "Consider adding 'please' for extra politeness" ], "vocabulary_analysis": [ { "word": "reservation", "usage": "perfect", "level": "A2", "context_appropriateness": 5 } ] } }, "dialogue_progress": { "turns_completed": 2, "estimated_turns_remaining": 6, "progress_percentage": 25, "objectives_status": { "confirmed_reservation": true, "selected_table": false, "ordered_food": false, "completed_payment": false }, "current_phase": "table_selection" }, "suggestions": [ "I'd love a window seat if available.", "The main dining area sounds great.", "Could we see both options first?" ] } } ``` ### 3. 請求回覆輔助 ```http POST /api/v1/dialogues/{dialogue_id}/assistance Authorization: Bearer Content-Type: application/json { "assistance_type": "reply_guidance", "context": { "partner_message": "Would you prefer a window seat or would you like to sit in our main dining area?", "scenario_context": "choosing table at restaurant", "user_language_level": "A2", "stuck_reason": "vocabulary", // vocabulary, grammar, context "partial_response": "I would like..." // user's partial input } } ``` #### 回應範例 ```http Response 200 OK { "success": true, "data": { "assistance_id": "AST_20240907_001", "assistance_type": "reply_guidance", "guidance": { "intent_analysis": "對方在詢問你的座位偏好,這是餐廳服務的常見情況", "response_strategy": "表達你的偏好並保持禮貌", "key_phrases": [ { "phrase": "I'd prefer...", "meaning": "我比較喜歡...", "usage": "表達偏好的禮貌方式" }, { "phrase": "window seat", "meaning": "靠窗座位", "usage": "餐廳座位類型" } ], "sample_responses": [ { "response": "I'd prefer a window seat, please.", "level": "A2", "politeness": "appropriate", "explanation": "簡單直接地表達偏好" }, { "response": "A window seat would be lovely if you have one available.", "level": "B1", "politeness": "very_polite", "explanation": "更加禮貌和委婉的表達方式" } ] }, "usage_cost": { "hints_used": 1, "remaining_hints": 4, "hint_type": "free" // free, premium } } } ``` ### 4. 中翻英翻譯輔助 ```http POST /api/v1/dialogues/{dialogue_id}/translation Authorization: Bearer Content-Type: application/json { "chinese_text": "我想要一個靠窗的座位", "context": { "scenario": "restaurant_dining", "formality_level": "formal", "target_level": "A2" } } ``` #### 回應範例 ```http Response 200 OK { "success": true, "data": { "translation_id": "TRANS_20240907_001", "translations": [ { "english_text": "I'd like a window seat.", "level": "A2", "formality": "polite", "naturalness": 5, "explanation": "最直接和常用的表達方式" }, { "english_text": "Could I have a window seat, please?", "level": "A2", "formality": "very_polite", "naturalness": 5, "explanation": "更加禮貌的請求方式" }, { "english_text": "I would prefer a seat by the window.", "level": "B1", "formality": "formal", "naturalness": 4, "explanation": "較正式的表達方式" } ], "grammar_notes": [ "使用 'I'd like' 比 'I want' 更禮貌", "'window seat' 是固定搭配,不需要冠詞" ], "usage_cost": { "translations_used": 1, "remaining_translations": 9 } } } ``` ### 5. 獲取詳細分析 ```http GET /api/v1/dialogues/{dialogue_id}/analysis Authorization: Bearer ``` #### 查詢參數 - `turn_id`: 特定對話輪次ID (可選) - `analysis_type`: `summary` | `detailed` | `vocabulary` (預設 `summary`) #### 回應範例 ```http Response 200 OK { "success": true, "data": { "dialogue_id": "DLG_20240907_001", "analysis_summary": { "overall_performance": { "grammar_score": 88, "semantic_score": 92, "fluency_score": 85, "pronunciation_score": 87, "total_score": 88, "completion_percentage": 100, "is_perfect_score": false }, "interaction_quality": { "appropriateness": 95, "naturalness": 88, "engagement": 90, "cultural_sensitivity": 92 } }, "turn_by_turn_analysis": [ { "turn_number": 1, "user_message": "Yes, I have a reservation under Chen for 8 PM for two people.", "analysis": { "scores": { "grammar": 90, "semantic": 95, "fluency": 85, "pronunciation": 88 }, "feedback": { "positive_aspects": [ "Perfect use of formal register", "All necessary information included", "Natural sentence structure" ], "areas_for_improvement": [ "Consider using 'please' for extra politeness" ], "grammar_analysis": { "errors": [], "complexity_level": "A2", "sentence_patterns": ["declarative_affirmative"] } }, "vocabulary_usage": [ { "word": "reservation", "correctness": "perfect", "level": "A2", "context_score": 5, "frequency": "high" } ] } } ], "learning_outcomes": { "vocabulary_progress": { "words_practiced": 12, "words_used_correctly": 11, "new_words_encountered": 4, "words_to_review": ["appetizer", "dessert"] }, "skill_development": { "improved_areas": ["formal_requests", "restaurant_vocabulary"], "mastery_achieved": ["basic_reservation_language"], "next_focus": ["ordering_specific_dishes"] }, "achievement_progress": { "dialogue_completion": true, "perfect_turns": 3, "vocabulary_milestone": false, "fluency_improvement": true } }, "personalized_recommendations": [ "Practice pronunciation of 'th' sounds in words like 'thank you'", "Learn more specific food vocabulary for ordering", "Try more complex sentence structures for B1 level" ] } } ``` ### 6. 結束對話 ```http POST /api/v1/dialogues/{dialogue_id}/complete Authorization: Bearer Content-Type: application/json { "completion_type": "natural", // natural, forced, timeout "user_rating": 4, // 1-5, user satisfaction "feedback": "Great practice session!" } ``` #### 回應範例 ```http Response 200 OK { "success": true, "data": { "completion_summary": { "dialogue_id": "DLG_20240907_001", "scenario_name": "餐廳預約與點餐", "duration_seconds": 420, "turns_completed": 8, "all_objectives_met": true, "completion_type": "natural" }, "performance_summary": { "final_score": 88, "grade": "B+", "is_perfect_dialogue": false, "best_turn_score": 95, "average_response_time": 12.5, "vocabulary_accuracy": 0.92 }, "rewards_earned": { "experience_points": 150, "score_points": 88, "diamonds": 10, "achievements_unlocked": [ { "achievement_id": "restaurant_master", "name": "餐廳對話專家", "description": "完成餐廳場景對話" } ] }, "learning_progress": { "vocabulary_advances": [ { "word": "reservation", "old_level": "learning", "new_level": "familiar" } ], "skill_improvements": [ "formal_conversation", "restaurant_etiquette" ] }, "next_recommendations": { "suggested_scenarios": [ "SC_Restaurant_02", // 更高級餐廳場景 "SC_Shopping_01" // 購物場景 ], "focus_areas": [ "complex_sentence_structures", "polite_expressions" ] } } } ``` ### 7. 暫停/恢復對話 ```http POST /api/v1/dialogues/{dialogue_id}/pause Authorization: Bearer ``` ```http POST /api/v1/dialogues/{dialogue_id}/resume Authorization: Bearer ``` ### 8. 獲取對話歷史 ```http GET /api/v1/dialogues/history Authorization: Bearer ``` #### 查詢參數 - `scenario_id`: 特定場景ID (可選) - `date_from`: 開始日期 (可選) - `date_to`: 結束日期 (可選) - `min_score`: 最低分數 (可選) - `page`: 頁碼 (預設 1) - `limit`: 每頁筆數 (預設 20) ## 🎯 對話評分系統 ### 評分維度 | 維度 | 權重 | 評分標準 | |------|------|----------| | **Grammar** | 25% | 語法正確性和複雜度 | | **Semantic** | 30% | 語義適切性和理解度 | | **Fluency** | 25% | 流暢度和自然性 | | **Pronunciation** | 20% | 發音準確度 (語音輸入) | ### 分數等級 - **90-100**: A+ (完美) - 滿星對話 - **80-89**: B+ (優秀) - **70-79**: B (良好) - **60-69**: C (及格) - **<60**: D (需改進) ## 🔧 錯誤處理 ### 對話相關錯誤 | 錯誤碼 | HTTP狀態 | 描述 | 處理建議 | |--------|----------|------|----------| | `DIALOGUE_NOT_FOUND` | 404 | 對話記錄不存在 | 檢查對話ID或重新開始 | | `SCENARIO_NOT_FOUND` | 404 | 場景不存在 | 檢查場景ID | | `DIALOGUE_EXPIRED` | 410 | 對話已過期 | 重新開始對話 | | `INSUFFICIENT_LIFE_POINTS` | 403 | 命條不足 | 購買命條或等待恢復 | | `AI_SERVICE_UNAVAILABLE` | 503 | AI服務暫時無法使用 | 稍後重試 | | `RESPONSE_GENERATION_FAILED` | 500 | 回應生成失敗 | 重新發送訊息 | | `HINT_LIMIT_EXCEEDED` | 429 | 提示使用次數超限 | 購買更多提示或明日重置 | ## 🧪 測試範例 ### 開始對話 ```bash curl -X POST "https://api.dramaling.com/api/v1/dialogues/start" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"scenario_id": "SC_Restaurant_01", "practice_mode": "guided"}' ``` ### 發送訊息 ```bash curl -X POST "https://api.dramaling.com/api/v1/dialogues/DLG_123/message" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"message": "I have a reservation under Smith.", "message_type": "text"}' ``` --- **模組負責人**: AI團隊 + 後端團隊 **最後更新**: 2024年9月7日 **相關文檔**: [用戶管理API](./user-management.md), [遊戲化系統API](./gamification.md)