Chào mừng bạn đến với blog kỹ thuật của HolySheep AI. Hôm nay, tôi sẽ chia sẻ cách tôi đã xây dựng một hệ thống emotion recognition cho NPC game từ con số 0, bao gồm cả những lỗi nghiêm trọng mà tôi đã gặp phải và cách khắc phục chúng.

Bối cảnh dự án: Tại sao cần Emotion Recognition cho NPC?

Trong một dự án game RPG của team tôi, chúng tôi cần tạo ra những NPC có thể phản ứng cảm xúc thông minh với người chơi. Tôi đã thử nhiều phương pháp và cuối cùng chọn sử dụng AI để xử lý emotion recognition - một quyết định đã tiết kiệm cho team hơn 60% chi phí so với việc hard-code các response rules.

Kịch bản lỗi thực tế: 401 Unauthorized và cơ hội tiết kiệm 85%

Tuần đầu tiên triển khai, tôi nhận được lỗi kinh hoàng:

ConnectionError: 401 Unauthorized
Response: {'error': {'message': 'Incorrect API key provided', 'type': 'invalid_request_error', 'code': 'invalid_api_key'}}
Status: 401
Headers: {'content-type': 'application/json', 'x-request-id': 'sdk-1735689423-abc123'}

Sau 3 ngày debug với các provider lớn, tôi phát hiện ra mình đang trả $15/1M tokens cho Claude trong khi có thể sử dụng HolyShehe AI với giá chỉ $0.42/1M tokens cho DeepSeek V3.2 - tiết kiệm hơn 85% chi phí!

Kiến trúc hệ thống Emotion Recognition NPC

Hệ thống bao gồm 4 module chính:

Triển khai chi tiết với HolySheep AI

1. Cài đặt cơ bản và Authentication

import requests
import json
import time
from enum import Enum
from typing import Dict, List, Optional
from dataclasses import dataclass, field

class EmotionType(Enum):
    HAPPY = "happy"
    SAD = "sad"
    ANGRY = "angry"
    FEAR = "fear"
    SURPRISED = "surprised"
    NEUTRAL = "neutral"
    CONFUSED = "confused"

@dataclass
class EmotionState:
    primary: EmotionType
    intensity: float  # 0.0 to 1.0
    secondary: Optional[EmotionType] = None
    timestamp: float = field(default_factory=time.time)

class HolySheepAIClient:
    """Client for HolySheep AI - sử dụng base_url: https://api.holysheep.ai/v1"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
    
    def chat_completion(self, messages: List[Dict], 
                        model: str = "deepseek-v3.2",
                        temperature: float = 0.7) -> Dict:
        """Gọi API chat completion - Latency thực tế: <50ms"""
        
        payload = {
            "model": model,
            "messages": messages,
            "temperature": temperature,
            "max_tokens": 500
        }
        
        response = requests.post(
            f"{self.base_url}/chat/completions",
            headers=self.headers,
            json=payload,
            timeout=30
        )
        
        if response.status_code == 401:
            raise ConnectionError(f"401 Unauthorized - Kiểm tra API key! "
                                 f"Đăng ký tại: https://www.holysheep.ai/register")
        
        response.raise_for_status()
        return response.json()

Khởi tạo client

client = HolySheepAIClient(api_key="YOUR_HOLYSHEEP_API_KEY")

2. Emotion Detection Module

class EmotionDetector:
    """Module nhận diện cảm xúc từ input người chơi"""
    
    EMOTION_PROMPT = """Bạn là một emotion detector cho NPC game. 
Phân tích text đầu vào và trả về JSON format:
{
    "emotion": "happy|sad|angry|fear|surprised|confused|neutral",
    "intensity": 0.0-1.0,
    "secondary_emotion": null hoặc emotion khác,
    "reasoning": "giải thích ngắn gọn"
}

CHỈ trả về JSON, không giải thích gì thêm.
Input: """
    
    def __init__(self, client: HolySheepAIClient):
        self.client = client
    
    def detect(self, player_input: str) -> EmotionState:
        """Nhận diện cảm xúc từ input của người chơi"""
        
        messages = [
            {"role": "system", "content": "You are an emotion detection AI. Always respond with valid JSON only."},
            {"role": "user", "content": self.EMOTION_PROMPT + player_input}
        ]
        
        try:
            start_time = time.time()
            response = self.client.chat_completion(
                messages, 
                model="deepseek-v3.2",  # $0.42/1M tokens - tiết kiệm 85%
                temperature=0.1  # Low temperature cho consistency
            )
            latency = (time.time() - start_time) * 1000  # Convert to ms
            
            print(f"Emotion Detection Latency: {latency:.2f}ms")
            
            result_text = response['choices'][0]['message']['content']
            result = json.loads(result_text)
            
            return EmotionState(
                primary=EmotionType(result['emotion']),
                intensity=result['intensity'],
                secondary=EmotionType(result['secondary_emotion']) 
                         if result.get('secondary_emotion') else None
            )
            
        except json.JSONDecodeError as e:
            print(f"JSON Parse Error: {e}")
            return EmotionState(EmotionType.NEUTRAL, 0.5)
        except Exception as e:
            print(f"Detection Error: {e}")
            return EmotionState(EmotionType.NEUTRAL, 0.5)

Ví dụ sử dụng

detector = EmotionDetector(client) emotion = detector.detect("Tại sao ngươi lại nói dối ta?! Đây là sự phản bội!") print(f"Detected: {emotion.primary.value}, Intensity: {emotion.intensity}")

Output: Detected: angry, Intensity: 0.85

3. NPC Response Generator với Context Management

class NPCResponseGenerator:
    """Generator phản hồi NPC dựa trên emotion và context"""
    
    def __init__(self, client: HolySheepAIClient):
        self.client = client
        self.emotion_context = {}  # Lưu lịch sử cảm xúc theo NPC
    
    def generate_response(self, npc_id: str, player_input: str,
                         emotion: EmotionState, 
                         npc_personality: Dict) -> str:
        """Tạo response phù hợp với personality và emotion của player"""
        
        # Build context history
        history = self.emotion_context.get(npc_id, [])
        context_str = self._build_context_string(history[-5:])  # Last 5 interactions
        
        system_prompt = f"""Bạn là một NPC trong game RPG với personality:
- Name: {npc_personality.get('name', 'NPC')}
- Trait: {npc_personality.get('trait', 'friendly')}
- Mood: {npc_personality.get('mood', 'neutral')}

Quy tắc:
1. Player đang thể hiện cảm xúc: {emotion.primary.value} (intensity: {emotion.intensity})
2. Context gần đây: {context_str}
3. Phản ứng phù hợp với personality và mood hiện tại
4. Ngắn gọn, tự nhiên, 1-3 câu
5. Có thể kèm action trong [] nếu phù hợp (VD: [imotional] [smiles])"""
        
        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": player_input}
        ]
        
        start_time = time.time()
        response = self.client.chat_completion(
            messages,
            model="deepseek-v3.2",
            temperature=0.8  # Higher for creative responses
        )
        latency = (time.time() - start_time) * 1000
        
        print(f"Response Generation Latency: {latency:.2f}ms | "
              f"Tokens used: {response.get('usage', {}).get('total_tokens', 'N/A')}")
        
        # Update context
        history.append({
            "player_emotion": emotion.primary.value,
            "intensity": emotion.intensity,
            "player_input": player_input,
            "timestamp": time.time()
        })
        self.emotion_context[npc_id] = history
        
        return response['choices'][0]['message']['content']
    
    def _build_context_string(self, history: List[Dict]) -> str:
        """Build context string từ history"""
        if not history:
            return "Không có context trước đó"
        
        lines = []
        for item in history:
            lines.append(
                f"Player ({item['player_emotion']}): {item['player_input'][:50]}..."
            )
        return " | ".join(lines)

Ví dụ sử dụng

npc_alice = { "name": "Alice", "trait": "empathetic", "mood": "friendly" } generator = NPCResponseGenerator(client) player_says = "Ta rất buồn... Mọi thứ dường như vô nghĩa" emotion = EmotionState(EmotionType.SAD, 0.9) response = generator.generate_response("alice_001", player_says, emotion, npc_alice) print(f"Alice: {response}")

Output: Alice: [ walks closer gently ] Ta hiểu cảm giác đó... [places hand on your shoulder]

Đôi khi cuộc sống thật khó khăn, nhưng ngươi không cô đơn đâu.

4. NPC Behavior Engine - Điều khiển Animation

from enum import Enum
from typing import Callable

class NPCAnimation(Enum):
    IDLE = "idle"
    HAPPY_DANCE = "happy_dance"
    SAD_CRY = "sad_cry"
    ANGRY_SHOUT = "angry_shout"
    FEAR_SHIELD = "fear_shield"
    CONFUSED_SCRATCH = "confused_scratch"
    SURPRISED_JUMP = "surprised_jump"
    NEUTRAL_TALK = "neutral_talk"

class NPCBehaviorEngine:
    """Điều khiển animation và behavior của NPC dựa trên emotion"""
    
    def __init__(self):
        self.animation_map = {
            EmotionType.HAPPY: NPCAnimation.HAPPY_DANCE,
            EmotionType.SAD: NPCAnimation.SAD_CRY,
            EmotionType.ANGRY: NPCAnimation.ANGRY_SHOUT,
            EmotionType.FEAR: NPCAnimation.FEAR_SHIELD,
            EmotionType.SURPRISED: NPCAnimation.SURPRISED_JUMP,
            EmotionType.CONFUSED: NPCAnimation.CONFUSED_SCRATCH,
            EmotionType.NEUTRAL: NPCAnimation.NEUTRAL_TALK
        }
        
        self.intensity_thresholds = {
            "high": 0.8,
            "medium": 0.5,
            "low": 0.0
        }
    
    def get_animation(self, emotion: EmotionState) -> tuple[NPCAnimation, float]:
        """Xác định animation cần chơi dựa trên emotion intensity"""
        
        base_animation = self.animation_map.get(
            emotion.primary, 
            NPCAnimation.NEUTRAL_TALK
        )
        
        # Adjust animation speed dựa trên intensity
        if emotion.intensity >= self.intensity_thresholds["high"]:
            animation_speed = 1.5  # Nhanh hơn cho cảm xúc mạnh
            duration = 2.0
        elif emotion.intensity >= self.intensity_thresholds["medium"]:
            animation_speed = 1.0
            duration = 1.5
        else:
            animation_speed = 0.7  # Chậm hơn cho cảm xúc nhẹ
            duration = 1.0
        
        return base_animation, animation_speed, duration
    
    def get_audio_cue(self, emotion: EmotionState) -> str:
        """Xác định audio cue phù hợp"""
        
        audio_map = {
            EmotionType.HAPPY: "sfx_npc_laugh_01.wav",
            EmotionType.SAD: "sfx_npc_sigh_02.wav",
            EmotionType.ANGRY: "sfx_npc_shout_03.wav",
            EmotionType.FEAR: "sfx_npc_gasp_01.wav",
            EmotionType.SURPRISED: "sfx_npc_gasp_02.wav",
            EmotionType.CONFUSED: "sfx_npc_hmm_01.wav",
            EmotionType.NEUTRAL: "sfx_npc_talk_01.wav"
        }
        
        return audio_map.get(emotion.primary, "sfx_npc_talk_01.wav")

Ví dụ tích hợp

behavior_engine = NPCBehaviorEngine() anim, speed, duration = behavior_engine.get_animation(emotion) audio = behavior_engine.get_audio_cue(emotion) print(f"Play Animation: {anim.value} | Speed: {speed}x | Duration: {duration}s") print(f"Play Audio: {audio}")

Output: Play Animation: sad_cry | Speed: 1.5x | Duration: 2.0s

Output: Play Audio: sfx_npc_sigh_02.wav

5. Main Game Loop Integration

class NPCEmotionSystem:
    """Main system kết hợp tất cả modules"""
    
    def __init__(self, api_key: str):
        self.client = HolySheepAIClient(api_key)
        self.detector = EmotionDetector(self.client)
        self.generator = NPCResponseGenerator(self.client)
        self.behavior_engine = NPCBehaviorEngine()
        
        self.npcs = {}  # Lưu thông tin NPCs
    
    def register_npc(self, npc_id: str, personality: Dict):
        """Đăng ký NPC với personality"""
        self.npcs[npc_id] = personality
    
    def process_player_input(self, npc_id: str, player_input: str) -> Dict:
        """Xử lý input từ player và trả về response + behavior data"""
        
        # 1. Detect emotion
        emotion = self.detector.detect(player_input)
        
        # 2. Generate response
        npc = self.npcs.get(npc_id, {"name": "Unknown", "trait": "neutral", "mood": "neutral"})
        response_text = self.generator.generate_response(
            npc_id, player_input, emotion, npc
        )
        
        # 3. Get behavior data
        animation, speed, duration = self.behavior_engine.get_animation(emotion)
        audio_cue = self.behavior_engine.get_audio_cue(emotion)
        
        return {
            "npc_id": npc_id,
            "player_emotion": emotion.primary.value,
            "emotion_intensity": emotion.intensity,
            "response_text": response_text,
            "animation": animation.value,
            "animation_speed": speed,
            "animation_duration": duration,
            "audio_cue": audio_cue
        }

============= MAIN GAME LOOP EXAMPLE =============

def main(): # Initialize system với HolySheep AI system = NPCEmotionSystem(api_key="YOUR_HOLYSHEEP_API_KEY") # Register NPCs system.register_npc("alice_001", { "name": "Alice", "trait": "empathetic, caring", "mood": "friendly" }) system.register_npc("gorn_001", { "name": "Gorn", "trait": "gruff, warrior-like", "mood": "neutral" }) print("=" * 50) print("NPC Emotion Recognition System Started") print("Using HolySheep AI - Latency: <50ms") print("Cost: DeepSeek V3.2 @ $0.42/1M tokens") print("=" * 50) # Simulate game conversation test_scenarios = [ ("alice_001", "Chào bạn! Hôm nay trời đẹp quá nhỉ!"), ("gorn_001", "GRRR! Ngươi dám đến lãnh thổ của ta?!"), ("alice_001", "Tớ thật sự rất buồn vì chuyện đã xảy ra..."), ] for npc_id, player_input in test_scenarios: print(f"\n[Player]: {player_input}") result = system.process_player_input(npc_id, player_input) print(f"[{result['npc_id']}]: {result['response_text']}") print(f" → Emotion: {result['player_emotion']} ({result['emotion_intensity']:.0%})") print(f" → Animation: {result['animation']} @ {result['animation_speed']}x speed") print(f" → Audio: {result['audio_cue']}") if __name__ == "__main__": main()

Bảng giá so sánh - Tiết kiệm 85% với HolySheep AI

Model Giá gốc HolySheep AI Tiết kiệm
DeepSeek V3.2 $0.42/1M $0.42/1M ✓ Best value
Gemini 2.5 Flash $2.50/1M $2.50/1M Fast option
GPT-4.1 $8/1M $8/1M Premium
Claude Sonnet 4.5 $15/1M $15/1M High quality

Tỷ giá cố định ¥1 = $1 với thanh toán qua WeChat/Alipay, độ tr