15 KiB
15 KiB
對話練習 API
📋 概述
Drama Ling 的核心功能 - 情境對話練習系統,包含場景對話、AI分析、回覆輔助等功能。
🎭 核心功能
對話系統特色
- 情境化對話: 真實場景模擬(餐廳、機場、購物等)
- AI智能回應: OpenAI GPT-4o-mini 驅動的自然對話
- 即時分析: 語法、語義、流暢度多維度評分
- 學習輔助: 智能提示和回覆建議
- 進度追蹤: 對話目標和完成度監控
📌 API 端點
1. 開始對話練習
POST /api/v1/dialogues/start
Authorization: Bearer <access_token>
Content-Type: application/json
{
"scenario_id": "SC_Restaurant_01",
"difficulty_override": "A2",
"target_vocabulary": ["reservation", "menu", "order"],
"practice_mode": "guided" // guided, free_form, challenge
}
回應範例
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. 發送對話訊息
POST /api/v1/dialogues/{dialogue_id}/message
Authorization: Bearer <access_token>
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
}
}
回應範例
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. 請求回覆輔助
POST /api/v1/dialogues/{dialogue_id}/assistance
Authorization: Bearer <access_token>
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
}
}
回應範例
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. 中翻英翻譯輔助
POST /api/v1/dialogues/{dialogue_id}/translation
Authorization: Bearer <access_token>
Content-Type: application/json
{
"chinese_text": "我想要一個靠窗的座位",
"context": {
"scenario": "restaurant_dining",
"formality_level": "formal",
"target_level": "A2"
}
}
回應範例
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. 獲取詳細分析
GET /api/v1/dialogues/{dialogue_id}/analysis
Authorization: Bearer <access_token>
查詢參數
turn_id: 特定對話輪次ID (可選)analysis_type:summary|detailed|vocabulary(預設summary)
回應範例
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. 結束對話
POST /api/v1/dialogues/{dialogue_id}/complete
Authorization: Bearer <access_token>
Content-Type: application/json
{
"completion_type": "natural", // natural, forced, timeout
"user_rating": 4, // 1-5, user satisfaction
"feedback": "Great practice session!"
}
回應範例
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. 暫停/恢復對話
POST /api/v1/dialogues/{dialogue_id}/pause
Authorization: Bearer <access_token>
POST /api/v1/dialogues/{dialogue_id}/resume
Authorization: Bearer <access_token>
8. 獲取對話歷史
GET /api/v1/dialogues/history
Authorization: Bearer <access_token>
查詢參數
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 | 提示使用次數超限 | 購買更多提示或明日重置 |
🧪 測試範例
開始對話
curl -X POST "https://api.dramaling.com/api/v1/dialogues/start" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"scenario_id": "SC_Restaurant_01", "practice_mode": "guided"}'
發送訊息
curl -X POST "https://api.dramaling.com/api/v1/dialogues/DLG_123/message" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"message": "I have a reservation under Smith.", "message_type": "text"}'