OpenAI Realtime API完全チュートリアル:リアルタイム音声AIアシスタントの構築
OpenAI Realtime APIとWebSocketストリーミングを使用した低遅延音声AIアプリケーションの構築を徹底解説
OpenAI Realtime API完全チュートリアル:リアルタイム音声AIアシスタントの構築
OpenAIのRealtime APIは、AI インタラクションのパラダイムシフトを表しています—自然でレスポンシブな1秒未満の音声会話を可能にします。この包括的なチュートリアルでは、初めてのリアルタイム音声アシスタントの構築をガイドします。
Realtime APIとは?
Realtime APIが提供するもの:
- WebSocketベースのストリーミング 双方向通信用
- 200ミリ秒未満の遅延 ほぼ即時の応答
- ネイティブ音声から音声へ 中間テキスト変換なし
- マルチモーダル入力 テキスト、オーディオ、ファンクションコールをサポート
Chat Completions APIとの主な違い
| 機能 | Chat Completions | Realtime API |
|---|---|---|
| プロトコル | HTTP REST | WebSocket |
| 遅延 | 500ms-2s | <200ms |
| 音声サポート | Whisper + TTS経由 | ネイティブS2S |
| ストリーミング | トークン単位 | 連続 |
| 最適用途 | チャットボット、非同期タスク | 音声アシスタント、ライブインタラクション |
前提条件
開始前に以下を確認:
- Realtime APIアクセス権限のあるOpenAI APIキー
- Node.js 18+ または Python 3.10+
- WebSocketの基本的な理解
- テスト用のマイク
クイックスタート:Node.js実装
ステップ1:プロジェクトセットアップ
mkdir realtime-voice-assistant
cd realtime-voice-assistant
npm init -y
npm install ws dotenv openai
ステップ2:環境設定
.envファイルを作成:
OPENAI_API_KEY=sk-your-api-key-here
OPENAI_REALTIME_MODEL=gpt-4o-realtime-preview-2024-12
ステップ3:基本的なWebSocket接続
// index.js
import WebSocket from 'ws';
import dotenv from 'dotenv';
dotenv.config();
const REALTIME_URL = 'wss://api.openai.com/v1/realtime';
class RealtimeClient {
constructor() {
this.ws = null;
this.sessionId = null;
}
async connect() {
return new Promise((resolve, reject) => {
this.ws = new WebSocket(REALTIME_URL, {
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
'OpenAI-Beta': 'realtime=v1'
}
});
this.ws.on('open', () => {
console.log('✅ Realtime APIに接続しました');
this.initializeSession();
resolve();
});
this.ws.on('message', (data) => {
this.handleMessage(JSON.parse(data));
});
this.ws.on('error', reject);
});
}
initializeSession() {
// セッションを設定
this.send({
type: 'session.update',
session: {
modalities: ['text', 'audio'],
instructions: 'あなたは親切な音声アシスタントです。簡潔でフレンドリーに対応してください。',
voice: 'alloy',
input_audio_format: 'pcm16',
output_audio_format: 'pcm16',
turn_detection: {
type: 'server_vad',
threshold: 0.5,
prefix_padding_ms: 300,
silence_duration_ms: 500
}
}
});
}
send(message) {
if (this.ws?.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(message));
}
}
handleMessage(message) {
switch (message.type) {
case 'session.created':
console.log('📍 セッション作成:', message.session.id);
this.sessionId = message.session.id;
break;
case 'response.audio.delta':
// オーディオチャンクを処理
this.processAudioChunk(message.delta);
break;
case 'response.text.delta':
process.stdout.write(message.delta);
break;
case 'error':
console.error('❌ エラー:', message.error);
break;
}
}
processAudioChunk(base64Audio) {
// オーディオを変換して再生
const audioBuffer = Buffer.from(base64Audio, 'base64');
// オーディオ出力デバイスに送信
}
sendText(text) {
this.send({
type: 'conversation.item.create',
item: {
type: 'message',
role: 'user',
content: [{ type: 'input_text', text }]
}
});
this.send({ type: 'response.create' });
}
sendAudio(audioBuffer) {
const base64Audio = audioBuffer.toString('base64');
this.send({
type: 'input_audio_buffer.append',
audio: base64Audio
});
}
disconnect() {
this.ws?.close();
}
}
// 使用例
const client = new RealtimeClient();
await client.connect();
client.sendText('こんにちは!今日は何かお手伝いできますか?');
高度な機能
1. 音声アクティビティ検出(VAD)
Realtime APIは自動ターン検出のためのサーバーサイドVADをサポート:
session: {
turn_detection: {
type: 'server_vad',
threshold: 0.5, // 感度(0-1)
prefix_padding_ms: 300, // 発話前のオーディオ
silence_duration_ms: 500 // ターン終了の無音時間
}
}
2. ファンクションコール
会話中にAIがアクションを実行できるように:
session: {
tools: [
{
type: 'function',
name: 'get_weather',
description: '指定された場所の現在の天気を取得',
parameters: {
type: 'object',
properties: {
location: { type: 'string', description: '都市名' }
},
required: ['location']
}
}
]
}
// ファンクションコールを処理
handleMessage(message) {
if (message.type === 'response.function_call_arguments.done') {
const result = await executeFunction(
message.name,
JSON.parse(message.arguments)
);
// 関数結果を返送
this.send({
type: 'conversation.item.create',
item: {
type: 'function_call_output',
call_id: message.call_id,
output: JSON.stringify(result)
}
});
}
}
3. 割り込み処理
ユーザーがAIの応答中に割り込めるように:
handleMessage(message) {
if (message.type === 'input_audio_buffer.speech_started') {
// ユーザーが話し始めた - 現在の応答をキャンセル
this.send({ type: 'response.cancel' });
console.log('🛑 応答キャンセル - ユーザー割り込み');
}
}
Python実装
Python開発者向けの同等の実装:
import asyncio
import websockets
import json
import os
from dotenv import load_dotenv
load_dotenv()
class RealtimeClient:
def __init__(self):
self.ws = None
self.session_id = None
async def connect(self):
headers = {
'Authorization': f'Bearer {os.getenv("OPENAI_API_KEY")}',
'OpenAI-Beta': 'realtime=v1'
}
self.ws = await websockets.connect(
'wss://api.openai.com/v1/realtime',
extra_headers=headers
)
print('✅ Realtime APIに接続しました')
await self.initialize_session()
async def initialize_session(self):
await self.send({
'type': 'session.update',
'session': {
'modalities': ['text', 'audio'],
'instructions': 'あなたは親切なアシスタントです。',
'voice': 'alloy',
'turn_detection': {
'type': 'server_vad',
'threshold': 0.5
}
}
})
async def send(self, message):
await self.ws.send(json.dumps(message))
async def listen(self):
async for message in self.ws:
data = json.loads(message)
await self.handle_message(data)
async def handle_message(self, message):
msg_type = message.get('type')
if msg_type == 'session.created':
print(f'📍 セッション: {message["session"]["id"]}')
elif msg_type == 'response.text.delta':
print(message['delta'], end='', flush=True)
elif msg_type == 'error':
print(f'❌ エラー: {message["error"]}')
# 実行
async def main():
client = RealtimeClient()
await client.connect()
await client.listen()
asyncio.run(main())
ベストプラクティス
1. オーディオ最適化
// 推奨オーディオ設定
const audioConfig = {
sampleRate: 24000, // 品質のため24kHz
channels: 1, // モノラルで十分
bitDepth: 16, // PCM16フォーマット
bufferSize: 4096 // 遅延/品質のバランス
};
2. エラー処理
ws.on('close', (code, reason) => {
if (code === 1006) {
// 異常終了 - 再接続を試行
setTimeout(() => this.connect(), 1000);
}
});
ws.on('error', (error) => {
console.error('WebSocketエラー:', error);
// 指数バックオフを実装
});
3. コスト最適化
| 戦略 | 節約率 |
|---|---|
| 非音声部分はテキストを使用 | 60-70% |
| クライアントサイドVADを実装 | 30-40% |
| 一般的な応答をキャッシュ | 20-30% |
| ファンクションコールをバッチ処理 | 10-20% |
価格(2026年1月)
| コンポーネント | コスト |
|---|---|
| 音声入力 | $0.06/分 |
| 音声出力 | $0.24/分 |
| テキスト入力 | $5.00/100万トークン |
| テキスト出力 | $15.00/100万トークン |
典型的な5分間の音声会話: 約$1.50
まとめ
OpenAI Realtime APIは自然なAIインタラクションの新しい可能性を開きます。重要なポイント:
- WebSocketアーキテクチャ が真のリアルタイム通信を可能に
- サーバーサイドVAD でターン管理を簡素化
- ファンクションコール でAI機能をアクションに拡張
- コスト管理 は本番デプロイメントに不可欠
今すぐ音声アシスタントの構築を始めましょう—AIインタラクションの未来は会話型です!
FAQ
Q:達成可能な最小遅延は? A:最適な条件下では、エンドツーエンドで150-200ミリ秒の遅延が可能。
Q:カスタム音声は使える? A:現在は組み込み音声のみ(alloy、echo、fable、onyx、nova、shimmer)。
Q:無料プランはある? A:無料プランはありませんが、新規アカウントには$5のクレジットが付与。
Q:複数の同時ユーザーをどう処理する? A:各ユーザーに独自のWebSocket接続が必要;コネクションプールパターンを使用。
Q:電話通話に使える? A:はい、Twilioなどのテレフォニープロバイダーと統合可能。
Realtime APIで何か作りましたか?コメントでプロジェクトを共有してください!