บทความทั้งหมด
OpenAIRealtime APIWebSocketAI

ทดสอบ OpenAI Realtime API บนเครื่องโลคัลผ่านทันเนล

OpenAI Realtime API เชื่อมต่อไคลเอนต์ผ่าน WebSocket หรือ WebRTC สำหรับการเชื่อมต่อฝั่งเซิร์ฟเวอร์ คุณเข้าถึง OpenAI ได้โดยตรงจากเครื่องใดก็ตามที่มีอินเทอร์เน็ต สำหรับการเชื่อมต่อฝั่งไคลเอนต์ — ซึ่งคือสิ่งที่คุณอยากสร้างด้วยมันจริงๆ เป็นส่วนใหญ่ — เบราว์เซอร์ต้องการ origin ที่ปลอดภัย และ backend ของคุณต้องสร้างโทเค็นชั่วคราว ทั้งสองทำงานผ่านทันเนล มีรายละเอียดบางอย่างที่ควรรู้

สองวิธีในการเชื่อมต่อ สองเหตุผลในการทันเนล

Realtime API รองรับการเชื่อมต่อฝั่งเซิร์ฟเวอร์ (backend ของคุณเปิด WebSocket ไปยัง OpenAI) และการเชื่อมต่อฝั่งไคลเอนต์ (เบราว์เซอร์เปิดการเชื่อมต่อ peer WebRTC หรือ WebSocket โดยใช้โทเค็นชั่วคราวที่ backend ของคุณสร้าง) เส้นทางฝั่งเซิร์ฟเวอร์ไม่ต้องการทันเนล ฝั่งไคลเอนต์เกือบทุกครั้งต้องการ

ทำไมฝั่งไคลเอนต์จึงต้องการ HTTPS:

  • สิทธิ์ไมโครโฟนของเบราว์เซอร์ต้องการ origin ที่ปลอดภัย
  • getUserMedia และการจัดการ ICE ของ WebRTC ทำงานดีที่สุดบน HTTPS
  • service worker (ถ้ามี) ต้องการมัน
  • หากคุณเรียก endpoint /session ของ backend เพื่อรับโทเค็นชั่วคราว backend นั้นก็ต้องเป็น HTTPS ด้วยหาก frontend ของคุณเป็น

ข้อแรกคุณเลี่ยงได้ด้วย flag ของเบราว์เซอร์ อย่าทำ ใช้ ทันเนล แล้วอยู่ในโลกจริง

รูปร่างของแอป Realtime ในช่วงพัฒนา

แอป realtime ขั้นต่ำมีสามส่วน:

  1. frontend ที่จับอินพุตไมโครโฟนและเล่นเอาต์พุตเสียง
  2. route ของ backend ที่สร้างโทเค็นชั่วคราวโดยเรียก endpoint /v1/realtime/sessions ของ OpenAI ด้วย API key จริงของคุณ
  3. การเชื่อมต่อ WebRTC หรือ WebSocket โดยตรงจากเบราว์เซอร์ไปยัง OpenAI โดยใช้โทเค็นชั่วคราว

ทันเนลของคุณเปิด frontend + backend (โดเมนเดียวกันในการตั้งค่าส่วนใหญ่) ทราฟฟิก realtime จริงไปจากเบราว์เซอร์-ถึง-OpenAI ไม่ผ่านทันเนลของคุณ — การเชื่อมต่อนั้นเป็นแบบตรงผ่าน HTTPS/WSS

ตั้งค่าอย่างรวดเร็วด้วย PortPreview

  1. เริ่ม dev server (Next.js, Vite หรืออะไรก็ตาม) บนพอร์ต 3000 หรือ 5173
  2. รัน npx portpreview 3000
  3. เปิด URL HTTPS ในเบราว์เซอร์ คำขอสิทธิ์ไมโครโฟนทำงานตามปกติ
  4. เรียก endpoint สร้างโทเค็น รับโทเค็นชั่วคราว เปิดการเชื่อมต่อ realtime
  5. พูด รับการตอบกลับแบบสตรีม

หากใช้ Vite คุณจะต้องใช้ config allowedHosts และ HMR จาก Vite + ทันเนล หากใช้ Next.js ที่มี edge runtime ที่ไหนสักแห่ง ระวัง config runtime บน route ที่ต้องใช้ Node crypto

WebSocket upgrade ผ่านทันเนล

การเชื่อมต่อ realtime คือ WebSocket (หรือ WebRTC ซึ่งส่วนใหญ่เลี่ยงทันเนล) ทันเนลใดที่คุณใช้ต้องส่งต่อคำขอ HTTP Upgrade อย่างถูกต้อง ส่วนใหญ่ทำ — PortPreview, Cloudflare quick tunnels, ngrok ล้วนจัดการ WebSocket upgrade หากของคุณไม่ทำ การเชื่อมต่อจะล้มเหลวเงียบๆ ในเบราว์เซอร์ด้วยข้อความทั่วไป WebSocket closed before connected โดยไม่มีรายละเอียดที่มีประโยชน์

ทดสอบ upgrade ด้วย wscat หากไม่แน่ใจ เชื่อมต่อไปยัง wss://your-tunnel.portpreview.dev/anything แล้วดู handshake

เคล็ดลับการพัฒนาที่ช่วยได้

ตรวจคำขอสร้างโทเค็น

frontend ของคุณเรียก route ของ backend ที่เรียก OpenAI บั๊กการพัฒนาที่พบบ่อยที่สุดตรงนี้คือคำขอที่ตั้งค่าผิดไปยัง /v1/realtime/sessions — ชื่อโมเดลผิด voice ผิด modalities ผิด ทันเนลจับคำขอ frontend→backend แต่ไม่จับ hop backend→OpenAI ให้ log คำขอนั้นฝั่งเซิร์ฟเวอร์ หรือ proxy ผ่านทันเนลโดยรันทั้งสองชั้นบนเครื่องโลคัล

รูปแบบเสียงไม่ตรงกัน

Realtime API ใช้ PCM16 โดยค่าเริ่มต้นพร้อม sample rate ที่ตั้งได้ หากคุณป้อนเสียงจากรูปแบบอื่น โมเดลจะปฏิเสธหรือ hallucinate MediaRecorder ของเบราว์เซอร์มักให้ Opus หรือ WebM — คุณต้องจัดการการแปลง หรือใช้เส้นทาง WebRTC ที่จัดการให้คุณ

โทเค็นหมดอายุระหว่างเซสชันยาว

โทเค็นชั่วคราวมีอายุสั้น หากคุณทดสอบเซสชันที่ยาวกว่า TTL ของโทเค็น ให้รีเฟรชตามตาราง SDK ของ Realtime มี helper สำหรับสิ่งนี้ หากทำเอง หมายถึงคอยดูเหตุการณ์ session.expired และสร้างโทเค็นใหม่ก่อนที่ตัวเก่าจะตาย

หน้าตาในโปรดักชัน

การเปลี่ยนแปลงจริงเพียงอย่างเดียวจากพัฒนาสู่โปรดักชันคือ URL: แทนที่ hostname ของทันเนลด้วยโดเมนจริงของคุณ endpoint สร้างโทเค็นอยู่ที่ backend การเชื่อมต่อ WebRTC/WebSocket จากเบราว์เซอร์ไป OpenAI เป็น code path เดียวกัน เราเคยเห็นทีมคิดมากเกินไปแล้วพยายาม proxy ทราฟฟิก realtime ผ่าน backend — อย่าทำ มันเพิ่ม latency และทำลายโมเดลที่ SDK ของ OpenAI สมมติไว้

สำหรับข้อเสนอคู่ขนานของ Anthropic (ซึ่งใกล้กับลูป tool use มากกว่า WebSocket แบบสตรีม) ดู Anthropic tool use และ webhook บนเครื่องโลคัล เข้าร่วม waitlist ของ PortPreview สำหรับทันเนลที่จัดการ WebSocket upgrade โดยค่าเริ่มต้น

คำถามที่พบบ่อย

ทดสอบ OpenAI Realtime API บน localhost ได้ไหม?
การเชื่อมต่อฝั่งเซิร์ฟเวอร์ไม่ต้องการทันเนล การเชื่อมต่อฝั่งไคลเอนต์จากเบราว์เซอร์ต้องการ HTTPS สำหรับสิทธิ์ไมโครโฟนและ endpoint โทเค็นชั่วคราว ใช้ทันเนลเพื่อเปิด dev server ผ่าน HTTPS แล้วเชื่อมเบราว์เซอร์ไป OpenAI โดยตรงด้วยโทเค็นชั่วคราว
ทันเนลต้องรองรับ WebSocket สำหรับ Realtime API ไหม?
หากใช้ทรานสปอร์ต WebSocket ใช่ — ทันเนลต้องส่งต่อคำขอ upgrade HTTP ทันเนลสมัยใหม่ส่วนใหญ่ทำได้ แต่ควรทดสอบด้วย wscat ก่อนไล่ตามบั๊กการเชื่อมต่อลวงตา WebRTC เลี่ยงทันเนลสำหรับทราฟฟิก realtime เอง
ทำไมการเชื่อมต่อ realtime ของเบราว์เซอร์จึงต้องใช้โทเค็นชั่วคราว?
การใส่ API key เต็มในเบราว์เซอร์เป็นหายนะด้านความปลอดภัย backend ของคุณสร้างโทเค็นชั่วคราวอายุสั้นที่ผูกกับเซสชัน realtime หนึ่งเซสชัน เบราว์เซอร์ใช้โทเค็นนั้นเชื่อมต่อ OpenAI โดยตรงโดยไม่เคยเห็น API key จริงของคุณ