วิธีใช้ OpenAI WebSocket Mode API

Ashley Innocent

Ashley Innocent

24 February 2026

วิธีใช้ OpenAI WebSocket Mode API

Apidog สำหรับองค์กร

การติดตั้งแบบ On-Premises

SSO & RBAC

รองรับมาตรฐาน SOC 2

สำรวจ Apidog Enterprise

TL;DR

OpenAI มีโหมด WebSocket API สองโหมดสำหรับกรณีการใช้งานที่แตกต่างกัน: โหมด Responses API WebSocket สำหรับเวิร์กโฟลว์แบบ agentic ที่มีการเรียกใช้เครื่องมือจำนวนมาก (เร็วขึ้นสูงสุด 40% สำหรับการเรียกใช้เครื่องมือ 20+ ครั้ง) และ Realtime API สำหรับแอปพลิเคชันเสียงและวิดีโอที่มีความหน่วงต่ำ ทั้งสองโหมดใช้การเชื่อมต่อ WebSocket แบบถาวรแทนการร้องขอ HTTP แบบไร้สถานะ ซึ่งช่วยลดความหน่วงโดยการกำจัดค่าใช้จ่ายในการเชื่อมต่อซ้ำๆ และเปิดใช้งานการโต้ตอบแบบมีสถานะที่ขับเคลื่อนด้วยเหตุการณ์

บทนำ

API ของ OpenAI ได้พัฒนาไปไกลกว่ารูปแบบการร้องขอ-ตอบกลับแบบง่ายๆ สำหรับแอปพลิเคชันที่ต้องการการเรียกใช้เครื่องมืออย่างรวดเร็วหรือการสตรีมเสียงแบบเรียลไทม์ โมเดล HTTP แบบดั้งเดิม จะสร้างค่าใช้จ่ายที่ไม่จำเป็น การร้องขอใหม่ทุกครั้งต้องมีการตั้งค่าการเชื่อมต่อ การยืนยันตัวตน และการส่งสถานะ แม้ว่าคุณจะกำลังสนทนาต่อเนื่องในบทสนทนาเดียวกันก็ตาม

WebSocket API ของ OpenAI แก้ปัญหานี้โดยการรักษาการเชื่อมต่อแบบสองทิศทางที่ถาวร สำหรับเวิร์กโฟลว์แบบ agentic ที่มีการเรียกใช้เครื่องมือต่อเนื่อง 20+ ครั้ง สิ่งนี้หมายถึงการดำเนินการแบบ end-to-end ที่เร็วขึ้นประมาณ 40% สำหรับแอปพลิเคชันเสียง ช่วยให้สามารถสนทนาได้อย่างเป็นธรรมชาติ สามารถขัดจังหวะได้ และมีความหน่วงต่ำกว่า 500ms

💡
การทดสอบการเชื่อมต่อ WebSocket ตามปกติแล้วต้องใช้เครื่องมือดีบักที่ซับซ้อน อินเทอร์เฟซการทดสอบ WebSocket ของ Apidog ช่วยให้คุณสามารถสร้างการเชื่อมต่อ ส่งเหตุการณ์ และตรวจสอบการตอบกลับแบบเรียลไทม์ ซึ่งจำเป็นสำหรับการตรวจสอบการผสานรวม OpenAI WebSocket ก่อนการนำไปใช้งานจริง
button

คู่มือนี้ครอบคลุมโหมด WebSocket ทั้งสองของ OpenAI: Responses API สำหรับเวิร์กโฟลว์ตัวแทนที่เน้นเครื่องมือ และ Realtime API สำหรับการสตรีมเสียง คุณจะได้เรียนรู้ว่าจะใช้แต่ละโหมดเมื่อใด วิธีนำไปใช้งาน และวิธีทดสอบอย่างมีประสิทธิภาพ

OpenAI WebSocket API คืออะไร?

OpenAI WebSocket API มีกลไกการขนส่งทางเลือกแทน HTTP สำหรับการโต้ตอบกับโมเดลภาษาของ OpenAI แทนที่จะสร้างการเชื่อมต่อใหม่สำหรับการเรียก API แต่ละครั้ง WebSocket จะสร้างการเชื่อมต่อเดียวที่ใช้งานได้ยาวนาน ซึ่งยังคงเปิดอยู่ตลอดระยะเวลาเซสชันของคุณ

คุณสมบัติหลัก

การเชื่อมต่อแบบถาวร: เมื่อสร้างแล้ว การเชื่อมต่อ WebSocket จะยังคงเปิดอยู่จนกว่าจะปิดอย่างชัดเจน ซึ่งช่วยลดค่าใช้จ่ายในการเชื่อมต่อต่อคำขอ

การสื่อสารแบบสองทิศทาง: ทั้งไคลเอนต์และเซิร์ฟเวอร์สามารถส่งข้อความได้ตลอดเวลา ทำให้สถาปัตยกรรมที่ขับเคลื่อนด้วยเหตุการณ์เป็นจริงได้

เซสชันที่มีสถานะ: เซิร์ฟเวอร์จะรักษาสถานะบริบทสำหรับการเชื่อมต่อปัจจุบัน ทำให้คุณสามารถอ้างอิงการตอบกลับก่อนหน้าได้โดยไม่ต้องส่งประวัติการสนทนาทั้งหมดซ้ำ

โมเดลที่ขับเคลื่อนด้วยเหตุการณ์: การสื่อสารเกิดขึ้นผ่านเหตุการณ์ที่แยกจากกัน (ข้อความ JSON) แทนที่จะเป็นคู่การร้องขอ-ตอบกลับ

พื้นฐานโปรโตคอล WebSocket

การเชื่อมต่อ WebSocket เริ่มต้นด้วย คำขออัปเกรด HTTP จากนั้นจึงเปลี่ยนไปใช้โปรโตคอล WebSocket สำหรับ OpenAI คุณจะเชื่อมต่อกับปลายทางต่างๆ เช่น:

รูปแบบ wss:// แสดงถึงการเชื่อมต่อ WebSocket ที่ปลอดภัย (คล้ายกับ HTTPS สำหรับ HTTP)

คำอธิบายสองโหมด WebSocket

OpenAI มี โหมด WebSocket สองแบบที่แตกต่างกัน ซึ่งแต่ละโหมดได้รับการปรับให้เหมาะสมกับกรณีการใช้งานที่แตกต่างกัน

โหมด Responses API WebSocket

Responses API รองรับการเชื่อมต่อ WebSocket สำหรับ เวิร์กโฟลว์แบบ agentic ที่คุณต้องทำการเรียกใช้เครื่องมือตามลำดับจำนวนมาก โหมดนี้ออกแบบมาสำหรับผู้ช่วยเขียนโค้ด ระบบจัดการ และตัวแทนอิสระที่เรียกใช้เครื่องมือซ้ำๆ เพื่อทำงานที่ซับซ้อนให้สำเร็จ

วิธีการทำงาน:

ในการเชื่อมต่อ WebSocket ที่ทำงานอยู่ บริการจะรักษาสถานะการตอบกลับก่อนหน้าหนึ่งรายการไว้ในแคชในหน่วยความจำเฉพาะการเชื่อมต่อ (การตอบกลับล่าสุด) เมื่อคุณดำเนินการต่อ คุณจะส่งเพียง:

เซิร์ฟเวอร์จะนำสถานะที่แคชไว้กลับมาใช้ใหม่ แทนที่จะประมวลผลประวัติการสนทนาทั้งหมดซ้ำ

ประโยชน์ด้านประสิทธิภาพ:

สำหรับเวิร์กโฟลว์ที่มีการเรียกใช้เครื่องมือ 20+ ครั้ง OpenAI รายงานว่าการดำเนินการแบบ end-to-end เร็วขึ้นสูงสุด 40% เมื่อเทียบกับ HTTP ซึ่งมาจากการ:

ความเข้ากันได้:

โหมด WebSocket ใช้งานได้ทั้งกับ Zero Data Retention (ZDR) และตัวเลือก store=false ทำให้เหมาะสำหรับแอปพลิเคชันที่คำนึงถึงความเป็นส่วนตัว

โหมด Realtime API WebSocket

Realtime API ให้ความสามารถในการสตรีมเสียงที่มีความหน่วงต่ำสำหรับ แอปพลิเคชันที่ขับเคลื่อนด้วยเสียง ช่วยให้สามารถโต้ตอบแบบพูด-ต่อ-พูดที่โมเดลสามารถตอบกลับอินพุตเสียงด้วยเอาต์พุตเสียง จัดการการขัดจังหวะได้อย่างเป็นธรรมชาติ

วิธีการทำงาน:

Realtime API ใช้ WebSocket เพื่อสร้างเซสชันที่มีสถานะและขับเคลื่อนด้วยเหตุการณ์ คุณสตรีมส่วนข้อมูลเสียงไปยัง API และ API จะสตรีมกลับมาทั้งการถอดความและเสียงที่สร้างขึ้น การเชื่อมต่อรองรับ:

คุณสมบัติหลัก:

การตรวจจับกิจกรรมเสียง (VAD): API มี VAD เชิงความหมายที่เข้าใจว่าผู้ใช้พูดจบแล้วกับการหยุดชั่วคราว สิ่งนี้สร้างการสนทนาที่เป็นธรรมชาติมากขึ้น

ความสามารถแบบ Multimodal: เข้าถึงความสามารถแบบ multimodal ดั้งเดิมของ GPT-4o ได้โดยตรง ประมวลผลทั้งเสียงและข้อความในโมเดลแบบรวม

ความหน่วงต่ำ: ออกแบบมาสำหรับความหน่วงต่ำกว่า 500ms สำหรับการโต้ตอบด้วยเสียง เหมาะสำหรับการสนทนาแบบเรียลไทม์

WebSocket เทียบกับ HTTP: การเปรียบเทียบประสิทธิภาพ

การเลือกระหว่าง WebSocket และ HTTP ขึ้นอยู่กับลักษณะของแอปพลิเคชันของคุณ นี่คือเมื่อแต่ละโปรโตคอลทำงานได้ดีที่สุด

WebSocket vs HTTP
WebSocket เทียบกับ HTTP

เมื่อ WebSocket ทำงานได้ดีกว่า HTTP

ปริมาณการเรียกใช้เครื่องมือสูง:
หากเวิร์กโฟลว์ของคุณมีการเรียกใช้เครื่องมือตามลำดับ 10+ ครั้งขึ้นไป การเชื่อมต่อแบบถาวรของ WebSocket จะช่วยขจัดค่าใช้จ่ายในการตั้งค่าซ้ำๆ การร้องขอ HTTP แต่ละครั้งต้องมี:

WebSocket ทำสิ่งนี้เพียงครั้งเดียว จากนั้นจึงนำการเชื่อมต่อกลับมาใช้ใหม่

แอปพลิเคชันที่คำนึงถึงความหน่วง:
สำหรับแอปพลิเคชันเสียงหรือแชทแบบเรียลไทม์ที่ทุกมิลลิวินาทีมีความสำคัญ การเชื่อมต่อแบบถาวรของ WebSocket และความสามารถในการสตรีมจะช่วยลดความหน่วงที่รับรู้ได้อย่างมาก

การอัปเดตที่เริ่มต้นโดยเซิร์ฟเวอร์:
WebSocket ช่วยให้เซิร์ฟเวอร์สามารถส่งข้อมูลไปยังไคลเอนต์ได้โดยไม่ต้องมีการพอลลิง สำหรับงานตัวแทนที่ใช้เวลานาน เซิร์ฟเวอร์สามารถส่งการอัปเดตความคืบหน้าเมื่อเกิดเหตุการณ์ขึ้น

เมื่อ HTTP เพียงพอ

การร้องขอ-ตอบกลับแบบง่าย:
สำหรับความสามารถในการเรียก API แบบครั้งเดียว หรือเวิร์กโฟลว์ที่มีการเรียกใช้เครื่องมือ 1-2 ครั้ง HTTP นั้นง่ายต่อการนำไปใช้งานและดีบัก นักพัฒนาส่วนใหญ่คุ้นเคยกับไคลเอนต์ HTTP และโครงสร้างพื้นฐาน (โหลดบาลานเซอร์, พร็อกซี) ก็จัดการ HTTP ได้ดี

การดำเนินการแบบไร้สถานะ:
หากคุณไม่จำเป็นต้องรักษาสถานะเซสชันระหว่างการร้องขอ ลักษณะไร้สถานะของ HTTP ก็เป็นข้อดี — ไม่จำเป็นต้องมีการจัดการการเชื่อมต่อ

ข้อจำกัดของโครงสร้างพื้นฐาน:
สภาพแวดล้อมการปรับใช้บางอย่าง (ฟังก์ชันไร้เซิร์ฟเวอร์, พร็อกซีบางประเภท) ไม่รองรับการเชื่อมต่อ WebSocket ที่ใช้งานได้ยาวนาน HTTP ใช้งานได้ทั่วไป

เมตริกประสิทธิภาพ

จากเอกสารประกอบของ OpenAI และการทดสอบของชุมชน:

เมตริกHTTPWebSocket (Responses API)WebSocket (Realtime API)
การตั้งค่าการเชื่อมต่อทุกคำขอ (~100-300ms)ครั้งเดียว (~100-300ms)ครั้งเดียว (~100-300ms)
เวิร์กโฟลว์การเรียกใช้เครื่องมือ 20+ ครั้งพื้นฐานเร็วขึ้น ~40%ไม่มี
ความหน่วงไปกลับของเสียงไม่มี (ไม่ได้ออกแบบมาเพื่อสิ่งนี้)ไม่มีน้อยกว่า 500ms
ค่าใช้จ่ายหน่วยความจำต่ำ (ไร้สถานะ)ปานกลาง (สถานะแคช)ปานกลาง-สูง (สถานะเซสชัน)
ความซับซ้อนในการนำไปใช้งานต่ำปานกลางปานกลาง-สูง

วิธีใช้โหมด Responses API WebSocket

มานำการเชื่อมต่อ WebSocket ไปใช้กับ Responses API สำหรับเวิร์กโฟลว์แบบ agentic กัน

ข้อกำหนดเบื้องต้น

การตั้งค่าการเชื่อมต่อ

ตัวอย่าง Node.js:

const WebSocket = require('ws');

// Connect to Responses API WebSocket endpoint
const ws = new WebSocket('wss://api.openai.com/v1/responses', {
  headers: {
    'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
    'OpenAI-Beta': 'responses-api=v1'
  }
});

ws.on('open', () => {
  console.log('Connected to OpenAI Responses API');

  // Send initial request
  const initialMessage = {
    model: 'gpt-4o',
    messages: [
      { role: 'user', content: 'Help me analyze this codebase and suggest improvements.' }
    ],
    tools: [
      {
        type: 'function',
        function: {
          name: 'read_file',
          description: 'Read contents of a file',
          parameters: {
            type: 'object',
            properties: {
              path: { type: 'string', description: 'File path to read' }
            },
            required: ['path']
          }
        }
      },
      {
        type: 'function',
        function: {
          name: 'search_code',
          description: 'Search for code patterns',
          parameters: {
            type: 'object',
            properties: {
              pattern: { type: 'string', description: 'Regex pattern to search' }
            },
            required: ['pattern']
          }
        }
      }
    ]
  };

  ws.send(JSON.stringify(initialMessage));
});

ws.on('message', (data) => {
  const response = JSON.parse(data);
  console.log('Received:', response);

  // Check if model wants to call tools
  if (response.choices[0].finish_reason === 'tool_calls') {
    const toolCalls = response.choices[0].message.tool_calls;

    // Execute tools (simplified)
    const toolResults = toolCalls.map(call => ({
      tool_call_id: call.id,
      output: executeToolLocally(call.function.name, call.function.arguments)
    }));

    // Continue the conversation with tool results
    const continuation = {
      previous_response_id: response.id, // Reference previous response
      input: toolResults
    };

    ws.send(JSON.stringify(continuation));
  }
});

ws.on('error', (error) => {
  console.error('WebSocket error:', error);
});

ws.on('close', () => {
  console.log('Connection closed');
});

function executeToolLocally(name, args) {
  // Your tool execution logic
  if (name === 'read_file') {
    const { path } = JSON.parse(args);
    return fs.readFileSync(path, 'utf-8');
  }
  // ... other tools
}

ตัวอย่าง Python:

import websocket
import json
import os

def on_message(ws, message):
    response = json.loads(message)
    print(f"Received: {response}")

    # Handle tool calls
    if response['choices'][0]['finish_reason'] == 'tool_calls':
        tool_calls = response['choices'][0]['message']['tool_calls']

        # Execute tools
        tool_results = []
        for call in tool_calls:
            result = execute_tool(call['function']['name'],
                                 json.loads(call['function']['arguments']))
            tool_results.append({
                'tool_call_id': call['id'],
                'output': result
            })

        # Send continuation with only new input + previous_response_id
        continuation = {
            'previous_response_id': response['id'],
            'input': tool_results
        }
        ws.send(json.dumps(continuation))

def on_error(ws, error):
    print(f"Error: {error}")

def on_close(ws, close_status_code, close_msg):
    print("Connection closed")

def on_open(ws):
    print("Connected to OpenAI Responses API")

    # Send initial request
    initial_message = {
        'model': 'gpt-4o',
        'messages': [
            {'role': 'user', 'content': 'Analyze this codebase and suggest improvements.'}
        ],
        'tools': [
            {
                'type': 'function',
                'function': {
                    'name': 'read_file',
                    'description': 'Read file contents',
                    'parameters': {
                        'type': 'object',
                        'properties': {
                            'path': {'type': 'string'}
                        },
                        'required': ['path']
                    }
                }
            }
        ]
    }
    ws.send(json.dumps(initial_message))

def execute_tool(name, args):
    if name == 'read_file':
        with open(args['path'], 'r') as f:
            return f.read()
    # ... other tools

# Create WebSocket connection
ws = websocket.WebSocketApp(
    "wss://api.openai.com/v1/responses",
    header={
        "Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}",
        "OpenAI-Beta": "responses-api=v1"
    },
    on_open=on_open,
    on_message=on_message,
    on_error=on_error,
    on_close=on_close
)

ws.run_forever()

รายละเอียดการนำไปใช้งานที่สำคัญ

การจัดการสถานะ:
ความแตกต่างที่สำคัญจาก HTTP คือการใช้ previous_response_id ในการดำเนินการต่อ สิ่งนี้จะบอก API ให้ใช้สถานะที่แคชไว้จากการตอบกลับล่าสุดซ้ำ

การดำเนินการต่อเฉพาะอินพุต:
เมื่อดำเนินการต่อในเทิร์น ให้ส่งเพียง:

อย่าส่งอาร์เรย์ messages ทั้งหมดซ้ำ — เซิร์ฟเวอร์มีบริบทนั้นอยู่แล้ว

การเก็บรักษาข้อมูลเป็นศูนย์:
หากต้องการใช้ ZDR กับโหมด WebSocket ให้ใส่ store: false ในคำขอเริ่มต้นของคุณ

วิธีใช้โหมด Realtime API WebSocket

Realtime API เปิดใช้งานการโต้ตอบด้วยเสียงที่มีความหน่วงต่ำ นี่คือวิธีนำไปใช้งาน

ข้อกำหนดเบื้องต้น

การตั้งค่าการเชื่อมต่อ

ตัวอย่าง JavaScript (เบราว์เซอร์):

// เชื่อมต่อกับ Realtime API
const ws = new WebSocket(
  `wss://api.openai.com/v1/realtime?model=gpt-realtime`,
  ['realtime', 'openai-insecure-api-key.' + process.env.OPENAI_API_KEY]
);

ws.addEventListener('open', () => {
  console.log('Connected to Realtime API');

  // กำหนดค่าเซสชัน
  ws.send(JSON.stringify({
    type: 'session.update',
    session: {
      modalities: ['text', 'audio'],
      voice: 'alloy',
      input_audio_format: 'pcm16',
      output_audio_format: 'pcm16',
      turn_detection: {
        type: 'server_vad', // or 'semantic_vad' for smarter detection
        threshold: 0.5,
        prefix_padding_ms: 300,
        silence_duration_ms: 500
      }
    }
  }));
});

ws.addEventListener('message', (event) => {
  const message = JSON.parse(event.data);

  switch (message.type) {
    case 'session.created':
      console.log('Session created:', message.session);
      break;

    case 'conversation.item.created':
      console.log('New item:', message.item);
      break;

    case 'response.audio.delta':
      // ได้รับส่วนข้อมูลเสียง - เล่น
      const audioChunk = base64ToArrayBuffer(message.delta);
      playAudioChunk(audioChunk);
      break;

    case 'response.audio_transcript.delta':
      // ได้รับส่วนข้อมูลถอดความ
      console.log('Transcript:', message.delta);
      break;

    case 'input_audio_buffer.speech_started':
      console.log('User started speaking');
      break;

    case 'input_audio_buffer.speech_stopped':
      console.log('User stopped speaking');
      break;

    case 'error':
      console.error('API error:', message.error);
      break;
  }
});

// Send audio from microphone
async function streamMicrophoneToAPI() {
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  const audioContext = new AudioContext({ sampleRate: 24000 });
  const source = audioContext.createMediaStreamSource(stream);
  const processor = audioContext.createScriptProcessor(4096, 1, 1);

  processor.onaudioprocess = (e) => {
    const inputData = e.inputBuffer.getChannelData(0);

    // แปลง Float32 เป็น Int16 PCM
    const pcmData = new Int16Array(inputData.length);
    for (let i = 0; i < inputData.length; i++) {
      pcmData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32768));
    }

    // ส่งไปยัง API
    ws.send(JSON.stringify({
      type: 'input_audio_buffer.append',
      audio: arrayBufferToBase64(pcmData.buffer)
    }));
  };

  source.connect(processor);
  processor.connect(audioContext.destination);
}

// ส่งอินพุตข้อความ
function sendTextMessage(text) {
  ws.send(JSON.stringify({
    type: 'conversation.item.create',
    item: {
      type: 'message',
      role: 'user',
      content: [
        { type: 'input_text', text: text }
      ]
    }
  }));

  // ร้องขอการสร้างการตอบกลับ
  ws.send(JSON.stringify({
    type: 'response.create'
  }));
}

function playAudioChunk(arrayBuffer) {
  const audioContext = new AudioContext({ sampleRate: 24000 });
  audioContext.decodeAudioData(arrayBuffer, (buffer) => {
    const source = audioContext.createBufferSource();
    source.buffer = buffer;
    source.connect(audioContext.destination);
    source.start();
  });
}

ตัวอย่าง Python:

import websocket
import json
import base64
import pyaudio

# การกำหนดค่าเสียง
RATE = 24000
CHUNK = 4096
FORMAT = pyaudio.paInt16
CHANNELS = 1

audio = pyaudio.PyAudio()

def on_open(ws):
    print("Connected to Realtime API")

    # กำหนดค่าเซสชัน
    ws.send(json.dumps({
        'type': 'session.update',
        'session': {
            'modalities': ['text', 'audio'],
            'voice': 'alloy',
            'input_audio_format': 'pcm16',
            'output_audio_format': 'pcm16',
            'turn_detection': {
                'type': 'server_vad',
                'threshold': 0.5,
                'silence_duration_ms': 500
            }
        }
    }))

    # เริ่มสตรีมไมโครโฟน
    stream_microphone(ws)

def on_message(ws, message):
    data = json.loads(message)

    if data['type'] == 'response.audio.delta':
        # ถอดรหัสและเล่นเสียง
        audio_chunk = base64.b64decode(data['delta'])
        play_audio(audio_chunk)

    elif data['type'] == 'response.audio_transcript.delta':
        print(f"Transcript: {data['delta']}", end='', flush=True)

    elif data['type'] == 'input_audio_buffer.speech_started':
        print("\n[User speaking...]")

    elif data['type'] == 'error':
        print(f"Error: {data['error']}")

def stream_microphone(ws):
    stream = audio.open(
        format=FORMAT,
        channels=CHANNELS,
        rate=RATE,
        input=True,
        frames_per_buffer=CHUNK
    )

    def audio_thread():
        while True:
            audio_data = stream.read(CHUNK)
            ws.send(json.dumps({
                'type': 'input_audio_buffer.append',
                'audio': base64.b64encode(audio_data).decode('utf-8')
            }))

    import threading
    threading.Thread(target=audio_thread, daemon=True).start()

def play_audio(audio_chunk):
    stream = audio.open(
        format=FORMAT,
        channels=CHANNELS,
        rate=RATE,
        output=True
    )
    stream.write(audio_chunk)
    stream.stop_stream()
    stream.close()

# สร้างการเชื่อมต่อ WebSocket
ws = websocket.WebSocketApp(
    f"wss://api.openai.com/v1/realtime?model=gpt-realtime",
    header={
        "Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}"
    },
    on_open=on_open,
    on_message=on_message
)

ws.run_forever()

รายละเอียดการนำไปใช้งานที่สำคัญ

ประเภทเหตุการณ์:

Realtime API ใช้การสื่อสารแบบขับเคลื่อนด้วยเหตุการณ์ เหตุการณ์ทั่วไป:

ไคลเอนต์ → เซิร์ฟเวอร์:

เซิร์ฟเวอร์ → ไคลเอนต์:

การตรวจจับกิจกรรมเสียง:

เลือกระหว่างโหมด VAD สองโหมด:

server_vad: การตรวจจับกิจกรรมเสียงพื้นฐานโดยอิงจากระดับเสียงและระยะเวลาความเงียบ

semantic_vad: การตรวจจับที่ชาญฉลาดกว่าที่เข้าใจการหยุดชั่วคราวตามธรรมชาติกับการสิ้นสุดเทิร์น ใช้สิ่งนี้สำหรับการสนทนาที่เป็นธรรมชาติมากขึ้นที่ผู้ใช้อาจหยุดชั่วคราวระหว่างความคิด

การทดสอบการเชื่อมต่อ WebSocket ด้วย Apidog

การทดสอบ WebSocket API แตกต่างจากการทดสอบ HTTP — คุณต้องรักษาการเชื่อมต่อ ส่งเหตุการณ์ และตรวจสอบการไหลของข้อความแบบสองทิศทาง Apidog มีความสามารถในการทดสอบ WebSocket ที่เชี่ยวชาญ

Apidog Web Design Interface
อินเทอร์เฟซการออกแบบเว็บ Apidog

การตั้งค่าการทดสอบ WebSocket ใน Apidog

ขั้นตอนที่ 1: สร้างคำขอ WebSocket

ใน Apidog สร้างคำขอใหม่และเลือก "WebSocket" เป็นโปรโตคอล ป้อน URL การเชื่อมต่อของคุณ:

Create WebSocket Request In Apidog
สร้างคำขอ WebSocket ใน Apidog
wss://api.openai.com/v1/responses

ขั้นตอนที่ 2: กำหนดค่าส่วนหัว

เพิ่มส่วนหัวการยืนยันตัวตน:

Authorization: Bearer YOUR_OPENAI_API_KEY
OpenAI-Beta: responses-api=v1

สำหรับ Realtime API คุณยังสามารถใช้การยืนยันตัวตนแบบ URL ได้:

wss://api.openai.com/v1/realtime?model=gpt-realtime

พร้อมคีย์ API ในส่วนหัว subprotocol

ขั้นตอนที่ 3: สร้างการเชื่อมต่อ

คลิก "Connect" เพื่อสร้างการเชื่อมต่อ WebSocket Apidog จะแสดง:

ขั้นตอนที่ 4: ส่งเหตุการณ์

ใช้ตัวสร้างข้อความของ Apidog เพื่อส่งเหตุการณ์ JSON สำหรับ Responses API:

{
  "model": "gpt-4o",
  "messages": [
    {
      "role": "user",
      "content": "What's the weather in San Francisco?"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get current weather",
        "parameters": {
          "type": "object",
          "properties": {
            "location": { "type": "string" }
          }
        }
      }
    }
  ]
}

ขั้นตอนที่ 5: ตรวจสอบการตอบกลับ

Apidog จะแสดง:

การทดสอบการดำเนินการต่อ

หากต้องการทดสอบรูปแบบการดำเนินการต่อด้วย previous_response_id:

  1. ส่งข้อความเริ่มต้น สังเกต response.id ในการตอบกลับ
  2. ส่งการดำเนินการต่อพร้อมอินพุตใหม่เท่านั้น:
{
  "previous_response_id": "resp_abc123",
  "input": [
    {
      "tool_call_id": "call_xyz789",
      "output": "{\"temperature\": 72, \"conditions\": \"sunny\"}"
    }
  ]
}
  1. สังเกตความหน่วงที่ลดลงเมื่อเทียบกับการส่งบริบททั้งหมดซ้ำ

การทดสอบ Realtime API

สำหรับ Realtime API, Apidog ช่วยให้คุณสามารถ:

สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับการดีบักว่าทำไมผู้ช่วยเสียงของคุณถึงตัดคำพูดของผู้ใช้ หรือไม่ตรวจจับคำพูดอย่างถูกต้อง

ตัวแปรสภาพแวดล้อม

จัดเก็บคีย์ API อย่างปลอดภัยโดยใช้ตัวแปรสภาพแวดล้อมของ Apidog:

{{OPENAI_API_KEY}}

สิ่งนี้ช่วยให้คุณสามารถสลับไปมาระหว่างคีย์สำหรับพัฒนาและคีย์สำหรับใช้งานจริงได้โดยไม่ต้องแก้ไขคำขอ

กรณีศึกษาในโลกแห่งความเป็นจริง

มาสำรวจสถานการณ์จริงที่โหมด WebSocket ของ OpenAI มีความเป็นเลิศกัน

กรณีศึกษาที่ 1: ตัวแทนเขียนโค้ดอัตโนมัติ

สถานการณ์: ผู้ช่วยเขียนโค้ดที่วิเคราะห์โค้ดเบส ระบุปัญหา และทำการปรับปรุงโดยอัตโนมัติ

ทำไมต้อง Responses API WebSocket:

รูปแบบการนำไปใช้งาน:

// งานเริ่มต้น
ws.send({ messages: [{ role: 'user', content: 'Audit security vulnerabilities' }], tools: [...] })

// การตอบกลับครั้งแรก: โมเดลเรียก read_file
ws.on('message', (resp1) => {
  ws.send({ previous_response_id: resp1.id, input: [tool_result_1] })
})

// การตอบกลับครั้งที่สอง: โมเดลเรียก search_code
ws.on('message', (resp2) => {
  ws.send({ previous_response_id: resp2.id, input: [tool_result_2] })
})

// ดำเนินการต่ออีก 20+ ครั้ง...

กรณีศึกษาที่ 2: บอทบริการลูกค้าด้วยเสียง

สถานการณ์: บอทสนับสนุนทางโทรศัพท์ที่จัดการคำถามของลูกค้าด้วยการสนทนาที่เป็นธรรมชาติ

ทำไมต้อง Realtime API WebSocket:

รูปแบบการนำไปใช้งาน:

// สตรีมเสียงโทรศัพท์ไปยัง API
phoneSystem.on('audio', (chunk) => {
  ws.send({
    type: 'input_audio_buffer.append',
    audio: base64Encode(chunk)
  })
})

// เล่นการตอบกลับของ AI ทันที
ws.on('message', (event) => {
  if (event.type === 'response.audio.delta') {
    phoneSystem.playAudio(base64Decode(event.delta))
  }
})

การแก้ไขปัญหาทั่วไป

การเชื่อมต่อล้มเหลว

อาการ: การเชื่อมต่อ WebSocket ไม่เปิดขึ้นมาเลย, เกิดเหตุการณ์ปิดทันที

สาเหตุทั่วไป:

  1. คีย์ API ไม่ถูกต้อง - ตรวจสอบส่วนหัว Authorization ของคุณอีกครั้ง
  2. ส่วนหัวเบต้าหายไป - Responses API ต้องการ OpenAI-Beta: responses-api=v1
  3. ข้อจำกัดของเครือข่าย - เครือข่ายองค์กรบางแห่งบล็อก WebSocket
  4. URL ไม่ถูกต้อง - ตรวจสอบ wss:// (ไม่ใช่ ws://) และเส้นทางปลายทาง

วิธีแก้ปัญหา:
ใช้ Apidog เพื่อทดสอบการเชื่อมต่อพร้อมข้อความแสดงข้อผิดพลาดโดยละเอียด ตัวตรวจสอบคำขอจะแสดงส่วนหัวที่ถูกส่งไปอย่างถูกต้อง ทำให้ง่ายต่อการระบุคีย์ API ที่ขาดหายไปหรือไม่ถูกต้อง

โค้ดดีบัก:

ws.on('error', (error) => {
  console.error('Connection error:', error);
});

ws.on('close', (code, reason) => {
  console.log(`Closed with code ${code}: ${reason}`);
  // รหัสทั่วไป:
  // 1006: การปิดที่ผิดปกติ (มักเกิดจากปัญหาการตรวจสอบสิทธิ์)
  // 1008: การละเมิดนโยบาย (ส่วนหัวไม่ถูกต้อง)
});

ความหน่วงสูงแม้ใช้ WebSocket

อาการ: การเชื่อมต่อ WebSocket ใช้งานได้ แต่ไม่เร็วกว่า HTTP

สาเหตุทั่วไป:

  1. ไม่ได้ใช้ previous_response_id - คุณกำลังส่งบริบททั้งหมดซ้ำ
  2. การเริ่มต้นแบบ Cold start - คำขอแรกในการเชื่อมต่อใหม่จะช้าลง
  3. ความหน่วงของเครือข่าย - ระยะทางทางภูมิศาสตร์ไปยังเซิร์ฟเวอร์ API
  4. เพย์โหลดขนาดใหญ่ - ส่งข้อมูลที่ไม่จำเป็นในการดำเนินการต่อ

วิธีแก้ปัญหา:
ตรวจสอบว่าคุณกำลังส่งเฉพาะอินพุตใหม่ในการดำเนินการต่อ:

// ผิด - ส่งบริบททั้งหมดทุกครั้ง
ws.send({
  messages: [...allPreviousMessages, newMessage],
  tools: [...]
})

// ถูก - อ้างอิงสถานะที่แคชไว้
ws.send({
  previous_response_id: lastResponse.id,
  input: [newMessage]
})

หน่วยความจำรั่วไหลในการเชื่อมต่อที่ใช้งานได้ยาวนาน

อาการ: หน่วยความจำของแอปพลิเคชันเพิ่มขึ้นเมื่อเวลาผ่านไปกับการเชื่อมต่อแบบถาวร

สาเหตุทั่วไป:

  1. ตัวฟังเหตุการณ์ไม่ได้ถูกลบออก - สะสมตัวฟังเมื่อมีการเชื่อมต่อใหม่
  2. บัฟเฟอร์เสียงไม่ได้ถูกปล่อย - เก็บการอ้างอิงถึงเสียงที่เล่นไปแล้ว
  3. ประวัติข้อความเพิ่มขึ้น - จัดเก็บข้อความที่ได้รับทั้งหมด

วิธีแก้ปัญหา:

// ล้างตัวฟังเหตุการณ์เมื่อเชื่อมต่อใหม่
function cleanupAndReconnect(ws) {
  ws.removeAllListeners();
  ws.close();

  const newWs = createConnection();
  return newWs;
}

// Release audio buffers after playing
function playAndRelease(audioBuffer) {
  const audioContext = new AudioContext({ sampleRate: 24000 });
  audioContext.decodeAudioData(audioBuffer, (buffer) => {
    const source = audioContext.createBufferSource();
    source.buffer = buffer;
    source.connect(audioContext.destination);
    source.start();

    source.onended = () => {
      source.disconnect();
      // บัฟเฟอร์จะถูกเก็บขยะ
    };
  });
}

// จำกัดประวัติข้อความ
const messageHistory = [];
const MAX_HISTORY = 100;

ws.on('message', (data) => {
  messageHistory.push(data);
  if (messageHistory.length > MAX_HISTORY) {
    messageHistory.shift(); // ลบรายการที่เก่าที่สุด
  }
});

สรุป

โหมด WebSocket API ของ OpenAI ปลดล็อกความเป็นไปได้ใหม่ๆ สำหรับแอปพลิเคชัน AI โหมด Responses API WebSocket ให้การดำเนินการที่เร็วขึ้นสูงสุด 40% สำหรับเวิร์กโฟลว์แบบ agentic ที่มีการเรียกใช้เครื่องมือจำนวนมาก ทำให้เหมาะสำหรับผู้ช่วยเขียนโค้ดอัตโนมัติและระบบจัดการ Realtime API ให้ความหน่วงต่ำกว่า 500ms สำหรับแอปพลิเคชันเสียง ทำให้สามารถสนทนาได้อย่างเป็นธรรมชาติและสามารถขัดจังหวะได้

การเลือกโหมดที่เหมาะสมขึ้นอยู่กับกรณีการใช้งานของคุณ:

ลักษณะการเชื่อมต่อแบบถาวรและขับเคลื่อนด้วยเหตุการณ์ของ WebSocket ต้องการวิธีการทดสอบที่แตกต่างจาก HTTP ทดสอบ OpenAI WebSocket API ของคุณด้วยไคลเอนต์ WebSocket แบบเรียลไทม์ของ Apidog — นำเข้าคีย์ API ของคุณ, สร้างการเชื่อมต่อ, ส่งเหตุการณ์ และตรวจสอบการตอบกลับด้วยการบันทึกรายละเอียด ลองใช้ฟรีเพื่อตรวจสอบการผสานรวมของคุณก่อนการนำไปใช้งานจริง

button

ฝึกการออกแบบ API แบบ Design-first ใน Apidog

ค้นพบวิธีที่ง่ายขึ้นในการสร้างและใช้ API