393 lines
11 KiB
Markdown
393 lines
11 KiB
Markdown
# 對話練習 API
|
||
|
||
## 概述
|
||
對話練習API負責管理AI驅動的互動式對話學習體驗,包括場景式對話、實時AI分析回饋、回覆輔助系統和翻譯支援。
|
||
|
||
## API 端點
|
||
|
||
### 對話系統 (Dialogue System)
|
||
|
||
#### 開始對話練習
|
||
```http
|
||
POST /api/v1/dialogues/start
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"scenario_id": "SC_Restaurant_01",
|
||
"difficulty_override": "A2", // optional
|
||
"target_vocabulary": ["reservation", "menu", "order"], // optional
|
||
"practice_mode": "guided", // guided, free_form, challenge
|
||
"language_focus": ["grammar", "vocabulary", "pronunciation"] // optional
|
||
}
|
||
|
||
Response 201 Created
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"dialogue_id": "DLG_20240905_001",
|
||
"scenario_id": "SC_Restaurant_01",
|
||
"session_token": "session_token_here",
|
||
"practice_mode": "guided",
|
||
"initial_context": {
|
||
"setting": "高級餐廳內部,晚上8點",
|
||
"your_role": "客人",
|
||
"ai_role": "餐廳服務員",
|
||
"objective": "成功預約並點餐",
|
||
"cultural_notes": "西式正式餐廳環境,需要適當的禮貌用語"
|
||
},
|
||
"ai_message": {
|
||
"message": "Good evening! Welcome to Milano Restaurant. Do you have a reservation?",
|
||
"audio_url": "https://cdn.example.com/audio/dlg001_001.mp3",
|
||
"phonetic": "ɡʊd ˈivnɪŋ! ˈwɛlkəm tu mɪˈlɑnoʊ ˈrɛstərɑnt. du ju hæv ə ˌrɛzərˈveɪʃən?",
|
||
"suggestions": [
|
||
{
|
||
"text": "Yes, I have a reservation under Smith.",
|
||
"difficulty": "A2",
|
||
"appropriateness": "formal"
|
||
},
|
||
{
|
||
"text": "No, but could we get a table for two?",
|
||
"difficulty": "A2",
|
||
"appropriateness": "polite"
|
||
},
|
||
{
|
||
"text": "I'd like to make a reservation for tonight.",
|
||
"difficulty": "B1",
|
||
"appropriateness": "formal"
|
||
}
|
||
],
|
||
"vocabulary_hints": [
|
||
{
|
||
"word": "reservation",
|
||
"definition": "預約",
|
||
"usage_note": "正式場合的預約用詞"
|
||
}
|
||
]
|
||
},
|
||
"dialogue_settings": {
|
||
"time_limit": 600, // seconds, null for unlimited
|
||
"assistance_available": true,
|
||
"hints_remaining": 3,
|
||
"auto_feedback": true
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 發送對話訊息
|
||
```http
|
||
POST /api/v1/dialogues/{dialogue_id}/message
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"message": "Yes, I have a reservation under Chen for 8 PM.",
|
||
"message_type": "text", // text, audio
|
||
"audio_url": "https://cdn.example.com/user_audio/msg001.mp3", // if audio
|
||
"request_feedback": true, // optional, default true
|
||
"confidence_level": 4 // 1-5 scale, optional
|
||
}
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"ai_response": {
|
||
"message": "Perfect! Mr. Chen, your table for two is ready. Right this way please.",
|
||
"audio_url": "https://cdn.example.com/audio/dlg001_002.mp3",
|
||
"phonetic": "ˈpɜrfɪkt! ˈmɪstər ʧɛn, jʊr ˈteɪbəl fɔr tu ɪz ˈrɛdi. raɪt ðɪs weɪ pliz.",
|
||
"emotion": "friendly_professional",
|
||
"speaking_pace": "normal",
|
||
"analysis": {
|
||
"grammar_score": 90,
|
||
"semantic_score": 95,
|
||
"fluency_score": 85,
|
||
"pronunciation_score": 88,
|
||
"overall_score": 90,
|
||
"feedback": "Excellent use of formal language for restaurant context!",
|
||
"detailed_analysis": {
|
||
"grammar_issues": [],
|
||
"vocabulary_usage": [
|
||
{
|
||
"word": "reservation",
|
||
"correctness": "perfect",
|
||
"context_appropriateness": "excellent"
|
||
}
|
||
],
|
||
"pronunciation_notes": [
|
||
{
|
||
"word": "reservation",
|
||
"accuracy": 0.92,
|
||
"suggestion": "輕微的r音可以更清晰"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"suggestions": [
|
||
{
|
||
"text": "Thank you. Could we see the menu please?",
|
||
"reason": "自然的下一步動作",
|
||
"difficulty": "A2"
|
||
},
|
||
{
|
||
"text": "Great! What do you recommend today?",
|
||
"reason": "顯示興趣並尋求建議",
|
||
"difficulty": "B1"
|
||
},
|
||
{
|
||
"text": "Thank you. We'd like to start with drinks.",
|
||
"reason": "具體的點餐開始",
|
||
"difficulty": "A2"
|
||
}
|
||
]
|
||
},
|
||
"dialogue_progress": {
|
||
"turns_completed": 2,
|
||
"estimated_turns_remaining": 6,
|
||
"objectives_completed": ["greeting", "reservation_confirmation"],
|
||
"objectives_remaining": ["ordering", "payment"],
|
||
"completion_percentage": 25,
|
||
"current_phase": "seating_and_menu"
|
||
},
|
||
"session_stats": {
|
||
"total_time_elapsed": 45, // seconds
|
||
"average_response_time": 8.5,
|
||
"hints_used": 0,
|
||
"mistakes_count": 0
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 結束對話
|
||
```http
|
||
POST /api/v1/dialogues/{dialogue_id}/complete
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"completion_type": "natural", // natural, forced, timeout
|
||
"user_satisfaction": 4 // 1-5 scale, optional
|
||
}
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"dialogue_summary": {
|
||
"dialogue_id": "DLG_20240905_001",
|
||
"completion_type": "natural",
|
||
"duration": 420, // seconds
|
||
"turns_completed": 8,
|
||
"final_score": 88,
|
||
"grade": "B+",
|
||
"objectives_achieved": 4,
|
||
"objectives_total": 4,
|
||
"vocabulary_practiced": 12,
|
||
"new_vocabulary_learned": 3,
|
||
"mistakes_count": 2,
|
||
"hints_used": 1
|
||
},
|
||
"rewards": {
|
||
"experience_points": 150,
|
||
"score_points": 75,
|
||
"diamonds_earned": 25,
|
||
"achievements_unlocked": ["First Perfect Dialogue", "Restaurant Master"],
|
||
"vocabulary_progress": {
|
||
"words_advanced": 3,
|
||
"words_mastered": 1,
|
||
"review_words_generated": 2
|
||
}
|
||
},
|
||
"performance_analysis": {
|
||
"strongest_areas": ["vocabulary_usage", "cultural_appropriateness"],
|
||
"improvement_areas": ["pronunciation", "sentence_variety"],
|
||
"next_recommended_scenarios": [
|
||
{
|
||
"scenario_id": "SC_Restaurant_02",
|
||
"title": "餐廳點餐進階",
|
||
"reason": "Continue building on restaurant vocabulary"
|
||
}
|
||
]
|
||
},
|
||
"certificate": {
|
||
"available": true,
|
||
"certificate_url": "https://cdn.example.com/certificates/DLG_20240905_001.pdf"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 回覆輔助系統
|
||
|
||
#### 獲取回覆輔助
|
||
```http
|
||
POST /api/v1/dialogues/{dialogue_id}/assistance
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"assistance_type": "reply_guidance", // reply_guidance, translation, vocabulary_help
|
||
"context": {
|
||
"partner_message": "Good morning! How is your day going?",
|
||
"scenario_context": "friendly morning greeting at office",
|
||
"user_language_level": "A2",
|
||
"dialogue_history": [
|
||
{
|
||
"speaker": "partner",
|
||
"message": "Hello! Nice to meet you."
|
||
},
|
||
{
|
||
"speaker": "user",
|
||
"message": "Nice to meet you too."
|
||
}
|
||
]
|
||
}
|
||
}
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"assistance_id": "AST_20240905_001",
|
||
"assistance_type": "reply_guidance",
|
||
"analysis": {
|
||
"partner_intent": {
|
||
"intent": "friendly_greeting_inquiry",
|
||
"emotion": "positive_friendly",
|
||
"expectation": "positive_response_about_day",
|
||
"cultural_context": "Western casual workplace greeting",
|
||
"explanation": "對方是在進行友好的早晨問候,期待你分享今天的狀況或心情"
|
||
},
|
||
"response_guidance": {
|
||
"thinking_process": [
|
||
"對方表現友好,我應該同樣友善回應",
|
||
"這是詢問我今天的狀況,我可以簡單分享",
|
||
"可以考慮反問對方相同的問題表示關心"
|
||
],
|
||
"response_strategies": [
|
||
{
|
||
"strategy": "positive_sharing",
|
||
"description": "積極分享今天的狀況",
|
||
"tone": "upbeat"
|
||
},
|
||
{
|
||
"strategy": "brief_polite",
|
||
"description": "簡潔禮貌的回應",
|
||
"tone": "neutral_friendly"
|
||
},
|
||
{
|
||
"strategy": "reciprocal_inquiry",
|
||
"description": "回應後反問對方",
|
||
"tone": "engaging"
|
||
}
|
||
]
|
||
},
|
||
"reply_examples": [
|
||
{
|
||
"example": "Great, thank you! I'm feeling energetic today. How about you?",
|
||
"level": "A2",
|
||
"style": "friendly_reciprocal",
|
||
"explanation": "表達積極心情並反問對方,展現對話技巧"
|
||
},
|
||
{
|
||
"example": "Pretty good, thanks for asking!",
|
||
"level": "A2",
|
||
"style": "casual_brief",
|
||
"explanation": "簡潔友善的回應,適合快節奏對話"
|
||
},
|
||
{
|
||
"example": "It's going well so far! Just got to the office. What about your day?",
|
||
"level": "B1",
|
||
"style": "detailed_engaging",
|
||
"explanation": "提供更多細節並主動延續對話"
|
||
}
|
||
]
|
||
},
|
||
"cost_deducted": {
|
||
"item_type": "reply_hint",
|
||
"quantity": 1,
|
||
"remaining_quantity": 4
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 翻譯輔助
|
||
```http
|
||
POST /api/v1/translation/assistance
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"source_text": "今天天氣真好,讓我心情很愉快",
|
||
"context": {
|
||
"dialogue_scenario": "casual_conversation",
|
||
"formality_level": "informal",
|
||
"target_language_level": "A2",
|
||
"cultural_adaptation": true
|
||
}
|
||
}
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"translation_result": {
|
||
"primary_translation": "The weather is really nice today, it makes me feel happy.",
|
||
"alternative_translations": [
|
||
{
|
||
"text": "It's such a beautiful day today, I'm in a great mood!",
|
||
"level": "B1",
|
||
"style": "enthusiastic"
|
||
},
|
||
{
|
||
"text": "Today's nice weather is making me cheerful.",
|
||
"level": "A2",
|
||
"style": "simple_clear"
|
||
}
|
||
],
|
||
"grammar_notes": [
|
||
{
|
||
"point": "weather_description",
|
||
"explanation": "英文描述天氣常用 'The weather is + adjective' 句型"
|
||
},
|
||
{
|
||
"point": "causative_structure",
|
||
"explanation": "'makes me feel + adjective' 表達某事讓你產生某種感受"
|
||
}
|
||
],
|
||
"vocabulary_highlights": [
|
||
{
|
||
"chinese": "心情愉快",
|
||
"english": "feel happy / in a good mood",
|
||
"note": "英文有多種表達好心情的方式"
|
||
}
|
||
],
|
||
"cultural_adaptation": {
|
||
"original_style": "direct_emotional_expression",
|
||
"adapted_style": "moderate_positive_expression",
|
||
"explanation": "調整為西方文化中更常見的表達方式"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 錯誤處理
|
||
|
||
### 對話練習相關錯誤
|
||
- `DIALOGUE_NOT_FOUND`: 對話不存在
|
||
- `DIALOGUE_ALREADY_COMPLETED`: 對話已完成
|
||
- `DIALOGUE_EXPIRED`: 對話會話已過期
|
||
- `SCENARIO_NOT_ACCESSIBLE`: 場景不可訪問
|
||
- `INVALID_MESSAGE_FORMAT`: 無效的訊息格式
|
||
- `AUDIO_PROCESSING_FAILED`: 音頻處理失敗
|
||
- `AI_ANALYSIS_UNAVAILABLE`: AI分析服務不可用
|
||
|
||
### 輔助系統相關錯誤
|
||
- `INSUFFICIENT_REPLY_HINTS`: 回覆提示道具不足
|
||
- `ASSISTANCE_NOT_AVAILABLE`: 輔助功能不可用
|
||
- `TRANSLATION_SERVICE_ERROR`: 翻譯服務錯誤
|
||
- `DAILY_HINT_LIMIT_EXCEEDED`: 超過每日提示使用限制
|
||
- `DIALOGUE_HINT_LIMIT_EXCEEDED`: 超過單次對話提示使用限制
|
||
- `INVALID_ASSISTANCE_TYPE`: 無效的輔助類型
|
||
- `CONTEXT_INSUFFICIENT`: 上下文資訊不足
|
||
- `LANGUAGE_PAIR_NOT_SUPPORTED`: 不支援的語言對
|
||
|
||
---
|
||
|
||
**建立日期**: 2025-09-08
|
||
**API版本**: v1
|
||
**負責模組**: 對話練習系統 |