ในโลกของ AI application ที่ต้องการ response time ต่ำกว่า 100 มิลลิวินาที การเลือก infrastructure ที่เหมาะสมคือหัวใจหลักของความสำเร็จ บทความนี้จะพาคุณ dive deep ลึกถึงระดับ architecture, performance tuning, concurrency control และ cost optimization สำหรับการใช้งาน HolySheep AI ในฐานะ API gateway ที่เชื่อมต่อ OpenAI Realtime API โดยเฉพาะ

ทำไม Realtime API ถึงต้องการ Latency ต่ำกว่า 100ms

จากประสบการณ์ตรงในการพัฒนา voice assistant หลายตัว ความหน่วง (latency) ที่เกิน 150ms จะทำให้ผู้ใช้รู้สึกว่าระบบ "คิด" อยู่ ซึ่งขัดขวาง natural conversation flow อย่างรุนแรง OpenAI Realtime API ถูกออกแบบมาให้รองรับ bidirectional streaming ที่ความเร็วระดับ near-realtime แต่ปัญหาอยู่ที่ว่า direct connection ไปยัง OpenAI servers จาก China mainland มี latency เฉลี่ย 200-300ms ขึ้นไป

HolySheep AI ช่วยแก้ปัญหานี้ด้วย infrastructure ที่ตั้งอยู่ใกล้ China mainland มากที่สุด ให้ latency เฉลี่ย ต่ำกว่า 50ms สำหรับ API calls ส่วนใหญ่

สถาปัตยกรรมระบบ: HolySheep ในฐานะ API Gateway

ก่อนเข้าสู่โค้ด มาดู high-level architecture กันก่อน:

┌─────────────────────────────────────────────────────────────────────────┐
│                        USER APPLICATION                                  │
│  ┌──────────────┐    ┌──────────────────┐    ┌───────────────────────┐   │
│  │  WebRTC      │───▶│  Audio Context   │───▶│  WebSocket Client     │   │
│  │  Audio Stream│    │  (Recording)    │    │  (Browser/Native)     │   │
│  └──────────────┘    └──────────────────┘    └───────────┬───────────┘   │
│                                                          │               │
│                                                          ▼               │
└────────────────────────────────────────────────────────────────────────┘
                                   │
                                   ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                          HOLYSHEEP LAYER                                │
│  ┌──────────────────────────────────────────────────────────────────┐    │
│  │                     api.holysheep.ai/v1                          │    │
│  │  ┌─────────────┐  ┌──────────────┐  ┌─────────────────────────┐  │    │
│  │  │ Rate Limit  │  │ Auth & Key   │  │ Connection Pooling      │  │    │
│  │  │ Controller  │  │ Validation   │  │ (Maintain 10 persistent │  │    │
│  │  │             │  │              │  │  connections per key)   │  │    │
│  │  └─────────────┘  └──────────────┘  └─────────────────────────┘  │    │
│  └──────────────────────────────────────────────────────────────────┘    │
│                                   │                                     │
│                                   ▼                                     │
└────────────────────────────────────────────────────────────────────────┘
                                   │
                                   ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                       UPSTREAM: OpenAI API                               │
│  ┌──────────────────────────────────────────────────────────────────┐    │
│  │              api.openai.com/v1/realtime                          │    │
│  │  • GPT-5 with Realtime capabilities                              │    │
│  │  • Native WebSocket support                                      │    │
│  │  • Audio in/out streaming                                         │    │
│  └──────────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────┘

ข้อดีของ architecture นี้คือ:

การตั้งค่า Zero-Latency Voice Conversation

2.1 Client-Side WebSocket Implementation

สำหรับ web application เราจะใช้ native WebSocket API ร่วมกับ Web Audio API ในการจับเสียงและเล่น audio response:

/**
 * HolySheep Realtime Voice Client
 * Zero-latency voice conversation implementation
 */

class HolySheepRealtimeVoice {
    constructor(apiKey, options = {}) {
        this.apiKey = apiKey;
        this.baseUrl = 'https://api.holysheep.ai/v1';  // Required: HolySheep endpoint only
        this.ws = null;
        this.audioContext = null;
        this.mediaStream = null;
        
        // Performance options
        this.options = {
            sampleRate: options.sampleRate || 24000,
            channels: options.channels || 1,
            bitsPerSample: options.bitsPerSample || 16,
            model: options.model || 'gpt-5-realtime',
            voice: options.voice || 'alloy',
            ...options
        };
        
        // Latency optimization flags
        this.lowLatencyMode = options.lowLatencyMode ?? true;
        this.bufferSize = options.bufferSize || 256;  // Small buffer = lower latency
    }
    
    async connect() {
        // Step 1: Get temporary session token from HolySheep
        const sessionResponse = await fetch(${this.baseUrl}/realtime/sessions, {
            method: 'POST',
            headers: {
                'Authorization': Bearer ${this.apiKey},
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                model: this.options.model,
                modalities: ['audio', 'text'],
                instructions: this.options.instructions || 'You are a helpful assistant.',
                audio_settings: {
                    input: {
                        sample_rate: this.options.sampleRate,
                        channels: this.options.channels,
                        buffer_size: this.bufferSize  // Critical for low latency
                    },
                    output: {
                        sample_rate: 24000,
                        voice: this.options.voice,
                        format: 'pcm16'
                    }
                },
                // Zero-latency optimizations
                streaming_settings: {
                    enable_partial_response: true,
                    emit_audio_chunks: true,
                    chunk_interval_ms: 20  // Emit audio every 20ms for smooth playback
                }
            })
        });
        
        if (!sessionResponse.ok) {
            throw new Error(Session creation failed: ${sessionResponse.status});
        }
        
        const session = await sessionResponse.json();
        
        // Step 2: Establish WebSocket connection
        // HolySheep provides a pre-signed WebSocket URL with optimized routing
        this.ws = new WebSocket(session.ws_url, 'realtime-v1');
        
        this.ws.onopen = () => {
            console.log('[HolySheep] WebSocket connected, latency:', Date.now() - this.connectStart, 'ms');
            this.startAudioCapture();
        };
        
        this.ws.onmessage = async (event) => {
            const message = JSON.parse(event.data);
            await this.handleRealtimeMessage(message);
        };
        
        this.ws.onerror = (error) => {
            console.error('[HolySheep] WebSocket error:', error);
        };
        
        this.connectStart = Date.now();
    }
    
    async startAudioCapture() {
        // Request microphone with low latency constraints
        this.mediaStream = await navigator.mediaDevices.getUserMedia({
            audio: {
                echoCancellation: true,
                noiseSuppression: true,
                autoGainControl: true,
                sampleRate: this.options.sampleRate,
                latencyHint: this.lowLatencyMode ? 'interactive' : 'balanced'
            }
        });
        
        this.audioContext = new AudioContext({
            sampleRate: this.options.sampleRate,
            latencyHint: this.lowLatencyMode ? 0.01 : 0.1
        });
        
        const source = this.audioContext.createMediaStreamSource(this.mediaStream);
        
        // Create script processor for real-time audio capture
        // Smaller buffer = lower latency but more CPU usage
        const processor = this.audioContext.createScriptProcessor(
            this.bufferSize,  // buffer size
            1,                  // input channels
            1                   // output channels
        );
        
        processor.onaudioprocess = (audioEvent) => {
            if (this.ws && this.ws.readyState === WebSocket.OPEN) {
                const inputData = audioEvent.inputBuffer;
                const pcmData = this.convertToPCM(inputData);
                
                // Send audio to HolySheep (which forwards to OpenAI)
                this.ws.send(JSON.stringify({
                    type: 'input_audio_buffer.append',
                    audio: {
                        data: pcmData,
                        mime_type: 'audio/pcm'
                    }
                }));
            }
        };
        
        source.connect(processor);
        processor.connect(this.audioContext.destination);
        
        console.log('[HolySheep] Audio capture started with buffer size:', this.bufferSize);
    }
    
    convertToPCM(audioBuffer) {
        // Convert AudioBuffer to base64-encoded PCM16
        const rawData = audioBuffer.getChannelData(0);
        const int16Array = new Int16Array(rawData.length);
        
        for (let i = 0; i < rawData.length; i++) {
            // Convert float32 [-1, 1] to int16 [-32768, 32767]
            int16Array[i] = Math.max(-32768, Math.min(32767, rawData[i] * 32768));
        }
        
        return btoa(String.fromCharCode(...new Uint8Array(int16Array.buffer)));
    }
    
    async handleRealtimeMessage(message) {
        switch (message.type) {
            case 'session.created':
                console.log('[HolySheep] Session created:', message.session.id);
                break;
                
            case 'input_audio_buffer.speech_started':
                // User started speaking
                this.onSpeechStart?.(message);
                break;
                
            case 'input_audio_buffer.speech_stopped':
                // User stopped speaking
                this.ws.send(JSON.stringify({ type: 'input_audio_buffer.commit' }));
                break;
                
            case 'conversation.item.created':
                // New message item created
                break;
                
            case 'response.text.delta':
                // Partial text response (streaming)
                this.onTextDelta?.(message.delta);
                break;
                
            case 'response.audio.delta':
                // Partial audio response - CRITICAL for zero latency
                // This arrives in ~20ms chunks from OpenAI via HolySheep
                await this.playAudioChunk(message.delta);
                break;
                
            case 'response.done':
                // Full response completed
                this.onResponseComplete?.(message.response);
                break;
        }
    }
    
    async playAudioChunk(audioData) {
        // Decode and play audio with minimal buffering
        const pcmData = atob(audioData);
        const arrayBuffer = new ArrayBuffer(pcmData.length);
        const view = new Uint8Array(arrayBuffer);
        
        for (let i = 0; i < pcmData.length; i++) {
            view[i] = pcmData.charCodeAt(i);
        }
        
        // Decode audio with AudioContext for lowest latency
        if (!this.outputAudioContext) {
            this.outputAudioContext = new AudioContext({
                sampleRate: 24000,
                latencyHint: 'interactive'
            });
        }
        
        const audioBuffer = await this.outputAudioContext.decodeAudioData(arrayBuffer);
        const source = this.outputAudioContext.createBufferSource();
        source.buffer = audioBuffer;
        source.connect(this.outputAudioContext.destination);
        source.start(0);  // Start immediately
    }
    
    disconnect() {
        if (this.ws) {
            this.ws.close();
            this.ws = null;
        }
        if (this.mediaStream) {
            this.mediaStream.getTracks().forEach(track => track.stop());
        }
        if (this.audioContext) {
            this.audioContext.close();
        }
    }
}

// Usage example
const voiceClient = new HolySheepRealtimeVoice('YOUR_HOLYSHEEP_API_KEY', {
    model: 'gpt-5-realtime',
    lowLatencyMode: true,
    bufferSize: 256,
    voice: 'alloy'
});

voiceClient.onTextDelta = (text) => {
    console.log('Text:', text);
};

voiceClient.onResponseComplete = (response) => {
    console.log('Response completed, total tokens:', response.usage.total_tokens);
};

await voiceClient.connect();

2.2 Backend Integration ด้วย Python (FastAPI)

สำหรับ production backend ที่ต้องการ scale หลาย concurrent users:

"""
HolySheep Realtime API Backend - FastAPI Implementation
Production-ready with connection pooling and rate limiting
"""

import asyncio
import websockets
import json
from typing import Optional, Callable, Dict, List
from dataclasses import dataclass, field
from collections import defaultdict
import time
import aiohttp
from contextlib import asynccontextmanager

HolySheep Configuration - REQUIRED: Use HolySheep endpoint only

HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1" HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY" @dataclass class RealtimeSession: """Manages a single realtime session with OpenAI via HolySheep""" session_id: str websocket: websockets.WebSocketClientProtocol user_id: str created_at: float = field(default_factory=time.time) audio_buffer: List[bytes] = field(default_factory=list) is_active: bool = True @property def age_seconds(self) -> float: return time.time() - self.created_at class HolySheepRealtimePool: """ Connection pool manager for HolySheep Realtime API Handles concurrent sessions with automatic load balancing """ def __init__( self, api_key: str, max_concurrent_sessions: int = 100, session_timeout_seconds: int = 600, health_check_interval: int = 30 ): self.api_key = api_key self.max_concurrent = max_concurrent_sessions self.session_timeout = session_timeout_seconds # Session management self.sessions: Dict[str, RealtimeSession] = {} self.user_session_count: Dict[str, int] = defaultdict(int) self.session_lock = asyncio.Lock() # Performance metrics self.metrics = { 'total_requests': 0, 'failed_requests': 0, 'avg_latency_ms': 0, 'active_sessions': 0 } self.latency_samples: List[float] = [] # Health check self.health_check_task: Optional[asyncio.Task] = None self._running = False async def create_session(self, user_id: str) -> str: """Create a new realtime session via HolySheep""" async with self.session_lock: # Check user limits if self.user_session_count[user_id] >= 5: raise ValueError(f"User {user_id} exceeded session limit (max 5)") # Check global capacity if len(self.sessions) >= self.max_concurrent: # Clean up old sessions first await self._cleanup_expired_sessions() if len(self.sessions) >= self.max_concurrent: raise RuntimeError("Server at maximum capacity") # Create session via HolySheep REST API async with aiohttp.ClientSession() as session: headers = { 'Authorization': f'Bearer {self.api_key}', 'Content-Type': 'application/json' } payload = { 'model': 'gpt-5-realtime', 'modalities': ['audio', 'text'], 'instructions': 'You are a helpful voice assistant.', 'audio_settings': { 'input': { 'sample_rate': 24000, 'channels': 1, 'buffer_size': 256 }, 'output': { 'sample_rate': 24000, 'voice': 'alloy', 'format': 'pcm16' } }, 'streaming_settings': { 'enable_partial_response': True, 'emit_audio_chunks': True, 'chunk_interval_ms': 20 }, # Cost optimization: request only what you need 'temperature': 0.7, 'max_tokens': 4096 } async with session.post( f'{HOLYSHEEP_BASE_URL}/realtime/sessions', headers=headers, json=payload, timeout=aiohttp.ClientTimeout(total=10) ) as response: if response.status != 200: error_text = await response.text() raise RuntimeError(f"HolySheep session creation failed: {error_text}") data = await response.json() ws_url = data['ws_url'] session_id = data['session']['id'] # Connect to WebSocket ws = await websockets.connect( ws_url, extra_headers={'Authorization': f'Bearer {self.api_key}'}, ping_interval=20, ping_timeout=10 ) # Register session async with self.session_lock: realtime_session = RealtimeSession( session_id=session_id, websocket=ws, user_id=user_id ) self.sessions[session_id] = realtime_session self.user_session_count[user_id] += 1 print(f"[HolySheep] Session {session_id} created for user {user_id}") return session_id async def send_audio( self, session_id: str, audio_data: bytes, on_delta: Optional[Callable] = None ) -> Dict: """Send audio data and receive streaming response""" start_time = time.time() async with self.session_lock: if session_id not in self.sessions: raise ValueError(f"Session {session_id} not found") session = self.sessions[session_id] if not session.is_active: raise RuntimeError(f"Session {session_id} is inactive") # Send audio buffer import base64 encoded_audio = base64.b64encode(audio_data).decode() await session.websocket.send(json.dumps({ 'type': 'input_audio_buffer.append', 'audio': { 'data': encoded_audio, 'mime_type': 'audio/pcm' } })) # Commit buffer for processing await session.websocket.send(json.dumps({ 'type': 'input_audio_buffer.commit' })) # Collect response with timeout response_data = {'text': '', 'audio_chunks': []} try: while True: message = await asyncio.wait_for( session.websocket.recv(), timeout=30.0 ) data = json.loads(message) if data['type'] == 'response.text.delta': response_data['text'] += data['delta'] if on_delta: await on_delta(data['delta']) elif data['type'] == 'response.audio.delta': response_data['audio_chunks'].append(data['delta']) elif data['type'] == 'response.done': # Calculate latency latency_ms = (time.time() - start_time) * 1000 self._record_latency(latency_ms) break except asyncio.TimeoutError: self.metrics['failed_requests'] += 1 raise RuntimeError("Response timeout - HolySheep may be experiencing issues") return response_data async def generate_response( self, session_id: str, text: str, audio_output: bool = True ) -> Dict: """Send text and optionally receive audio response""" async with self.session_lock: session = self.sessions[session_id] # Create response item await session.websocket.send(json.dumps({ 'type': 'conversation.item.create', 'item': { 'type': 'message', 'role': 'user', 'content': [{ 'type': 'input_text', 'text': text }] } })) # Trigger response generation await session.websocket.send(json.dumps({ 'type': 'response.create', 'response': { 'modalities': ['audio', 'text'] if audio_output else ['text'], 'model': 'gpt-5-realtime', 'voice': 'alloy' if audio_output else None } })) # Collect response (same as send_audio) return await self._collect_response(session) async def _collect_response(self, session: RealtimeSession) -> Dict: """Collect streaming response from session""" response_data = {'text': '', 'audio_chunks': [], 'usage': None} while True: message = await session.websocket.recv() data = json.loads(message) if data['type'] == 'response.text.delta': response_data['text'] += data['delta'] elif data['type'] == 'response.audio.delta': response_data['audio_chunks'].append(data['delta']) elif data['type'] == 'response.done': response_data['usage'] = data.get('response', {}).get('usage', {}) break return response_data def _record_latency(self, latency_ms: float): """Record latency sample for metrics""" self.latency_samples.append(latency_ms) if len(self.latency_samples) > 100: self.latency_samples.pop(0) self.metrics['avg_latency_ms'] = sum(self.latency_samples) / len(self.latency_samples) self.metrics['total_requests'] += 1 async def close_session(self, session_id: str): """Close and cleanup a session""" async with self.session_lock: if session_id not in self.sessions: return session = self.sessions[session_id] session.is_active = False await session.websocket.close() self.user_session_count[session.user_id] -= 1 del self.sessions[session_id] self.metrics['active_sessions'] = len(self.sessions) print(f"[HolySheep] Session {session_id} closed") async def _cleanup_expired_sessions(self): """Remove expired sessions""" current_time = time.time() expired = [] for session_id, session in self.sessions.items(): if current_time - session.created_at > self.session_timeout: expired.append(session_id) for session_id in expired: await self.close_session(session_id) if expired: print(f"[HolySheep] Cleaned up {len(expired)} expired sessions") async def health_check(self): """Periodic health check of HolySheep connection""" while self._running: await asyncio.sleep(30) # Test API connectivity async with aiohttp.ClientSession() as session: try: async with session.get( f'{HOLYSHEEP_BASE_URL}/health', headers={'Authorization': f'Bearer {self.api_key}'}, timeout=aiohttp.ClientTimeout(total=5) ) as response: if response.status == 200: print(f"[HolySheep] Health check OK, latency: {self.metrics['avg_latency_ms']:.2f}ms") else: print(f"[HolySheep] Health check warning: {response.status}") except Exception as e: print(f"[HolySheep] Health check failed: {e}") async def start(self): """Start the connection pool manager""" self._running = True self.health_check_task = asyncio.create_task(self.health_check()) print("[HolySheep] Realtime pool started") async def stop(self): """Stop and cleanup all sessions""" self._running = False if self.health_check_task: self.health_check_task.cancel() async with self.session_lock: for session_id in list(self.sessions.keys()): await self.close_session(session_id) print("[HolySheep] Realtime pool stopped") def get_metrics(self) -> Dict: """Get current performance metrics""" return { **self.metrics, 'active_sessions': len(self.sessions), 'p95_latency_ms': sorted(self.latency_samples)[int(len(self.latency_samples) * 0.95)] if self.latency_samples else 0, 'p99_latency_ms': sorted(self.latency_samples)[int(len(self.latency_samples) * 0.99)] if self.latency_samples else 0 }

FastAPI Integration

from fastapi import FastAPI, WebSocket, WebSocketDisconnect from starlette.requests import Request app = FastAPI(title="HolySheep Voice API")

Global connection pool

pool: Optional[HolySheepRealtimePool] = None @app.on_event("startup") async def startup(): global pool pool = HolySheepRealtimePool( api_key=HOLYSHEEP_API_KEY, max_concurrent_sessions=100 ) await pool.start() @app.on_event("shutdown") async def shutdown(): global pool if pool: await pool.stop() @app.websocket("/ws/voice/{user_id}") async def voice_websocket(websocket: WebSocket, user_id: str): """WebSocket endpoint for voice conversations""" await websocket.accept() session_id = None try: # Create HolySheep session session_id = await pool.create_session(user_id) await websocket.send_json({'type': 'session_created', 'session_id': session_id}) while True: # Receive messages from client data = await websocket.receive_json() if data['type'] == 'audio': # Process audio data import base64 audio_bytes = base64.b64decode(data['audio']) response = await pool.send_audio( session_id, audio_bytes, on_delta=lambda delta: websocket.send_json({ 'type': 'text_delta', 'delta': delta }) ) await websocket.send_json({ 'type': 'response_complete', 'text': response['text'], 'usage': response.get('usage', {}) }) elif data['type'] == 'text': response = await pool.generate_response(session_id, data['text']) await websocket.send_json({ 'type': 'response_complete', 'text': response['text'], 'audio_chunks': len(response['audio_chunks']) }) except WebSocketDisconnect: pass except Exception as e: await websocket.send_json({'type': 'error', 'message': str(e)}) finally: if session_id: await pool.close_session(session_id) @app.get("/metrics") async def get_metrics(): """Get pool performance metrics""" return pool.get_metrics() if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)

การเชื่อมต่อ Streaming Audio สำหรับ Native Apps

สำหรับ mobile applications หรือ desktop apps ที่ต้องการ native audio streaming:

/**
 * HolySheep Streaming Audio Client - Node.js/TypeScript
 * Optimized for production mobile apps with background audio support
 */

import WebSocket from 'ws';
import { EventEmitter } from 'events';
import * as fs from 'fs';

// HolySheep API Configuration
const HOLYSHEEP_BASE_URL = 'https://api.holysheep.ai/v1';
const HOLYSHEEP_API_KEY = 'YOUR_HOLYSHEEP_API_KEY';

interface AudioConfig {
    sampleRate: number;
    channels: number;
    bitDepth: number;
    codec: 'pcm16' | 'mulaw' | 'alaw';
}

interface StreamConfig {
    chunkDurationMs: number;
    enableVAD: boolean;
    vadThreshold: number;
    vadSilenceMs: number;
}

class HolySheepStreamClient extends EventEmitter {
    private ws: WebSocket | null = null;
    private sessionId: string | null = null;
    private isConnected = false;
    private reconnectAttempts = 0;
    private maxReconnectAttempts = 5;
    private reconnectDelay = 1000;
    
    private audioConfig: AudioConfig = {
        sampleRate: 16000,
        channels: 1,
        bitDepth: 16,
        codec: 'pcm16'
    };
    
    private streamConfig: StreamConfig = {
        chunkDurationMs: 100,
        enableVAD: true,
        vadThreshold: 0.02,
        vadSilenceMs: 500
    };
    
    // Latency optimization
    private sendBuffer: Buffer[] = [];
    private lastSendTime = 0;
    private minSendInterval = 20; // ms
    
    constructor(
        private apiKey: string = HOLYSHEEP_API_KEY,
        options?: { audio?: Partial; stream?: Partial }
    ) {
        super();
        
        if (options?.audio) {
            this.audioConfig = { ...this.audioConfig, ...options.audio };
        }
        if (options?.stream) {
            this.streamConfig = { ...this.streamConfig, ...options.stream };
        }
    }
    
    async connect(model: string = 'gpt-5-realtime'): Promise {
        // Step 1: Create session via HolySheep REST API
        const sessionResponse = await fetch(${HOLYSHEEP_BASE_URL}/realtime/sessions, {
            method: 'POST',
            headers: {
                'Authorization': Bearer ${this.apiKey},
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                model,
                modalities: ['audio', 'text'],
                instructions: 'You are a helpful assistant.',
                audio_settings: {
                    input: this.audioConfig,
                    output: {
                        sample_rate: 24000,
                        voice: 'alloy',
                        format: 'pcm16'
                    }
                },
                streaming_settings: {
                    enable_partial_response: true,
                    emit_audio_chunks: true,
                    chunk_interval_ms: this.streamConfig.chunkDurationMs
                }
            })
        });
        
        if (!sessionResponse.ok) {
            throw new Error(Failed to create HolySheep session: ${sessionResponse.status});
        }
        
        const sessionData = await sessionResponse