dramaling-app/docs/04_technical/api/dialogue-practice.md

549 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 對話練習 API
## 📋 概述
Drama Ling 的核心功能 - 情境對話練習系統包含場景對話、AI分析、回覆輔助等功能。
## 🎭 核心功能
### 對話系統特色
- **情境化對話**: 真實場景模擬(餐廳、機場、購物等)
- **AI智能回應**: OpenAI GPT-4o-mini 驅動的自然對話
- **即時分析**: 語法、語義、流暢度多維度評分
- **學習輔助**: 智能提示和回覆建議
- **進度追蹤**: 對話目標和完成度監控
## 📌 API 端點
### 1. 開始對話練習
```http
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
}
```
#### 回應範例
```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 <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
}
}
```
#### 回應範例
```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 <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
}
}
```
#### 回應範例
```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 <access_token>
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 <access_token>
```
#### 查詢參數
- `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 <access_token>
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 <access_token>
```
```http
POST /api/v1/dialogues/{dialogue_id}/resume
Authorization: Bearer <access_token>
```
### 8. 獲取對話歷史
```http
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 | 提示使用次數超限 | 購買更多提示或明日重置 |
## 🧪 測試範例
### 開始對話
```bash
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"}'
```
### 發送訊息
```bash
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"}'
```
---
**模組負責人**: AI團隊 + 後端團隊
**最後更新**: 2024年9月7日
**相關文檔**: [用戶管理API](./user-management.md), [遊戲化系統API](./gamification.md)