Gerçek zamanlı sesli asistan — 280 ms'lik gecikme bütçesinin bize öğrettikleri
WebRTC, gerçek zamanlı konuşma motoru, yedek ses sağlayıcısı ve bota lafı kesen Macar bir büyükanne. Uçtan uca gecikmeyi 300 ms'nin altında nasıl tuttuk?
Sesli asistan hızlı yanıt verdiğinde iyi değildir. Cümlesinin ortasında sözünü kesebildiğinizde — ve kafası karışmadığında iyidir.
Mart 2026'da Nortinia Voice'u 16 sitemizde devreye aldığımızda, canlı ortamdaki ilk olayımız bir büyükanneydi. Siteye geldi, mikrofon düğmesine bastı ve şunu söyledi: "Alo, alo, alo canım, bunu istemiyorum, sadece…". Bot o bitirene kadar kibarca bekledi, ardından 2,8 saniye sonra yanıt verdi — büyükanne çoktan kapatmıştı. Söz kesme (barge-in) yönetimi, gecikme bütçesi ve bağlantı değiştirme stratejisi bir hafta boyunca ana gündemimiz oldu; işte 8 haftalık canlı kullanımda öğrendiklerimiz.
Aşama başına gecikme bütçesi
Hedefimiz uçtan uca 300 ms ilk token gecikmesiydi; çünkü bu sınırın ötesinde konuşma canlılığını yitirir. Bu süreyi ağ atlamaları arasında paylaştırmamız gerekiyordu. Bütçe canlı ortamda şöyle görünüyor.
- Mikrofon → tarayıcı yakalama: 8–12 ms (Opus kodlayıcı, 20 ms'lik kareler)
- Tarayıcı → gerçek zamanlı konuşma motoru (WebRTC): 35–80 ms (AB bölgesi, yapışkan oturum)
- OpenAI VAD + first token: 120–180 ms (gpt-4o-realtime-preview)
- TTS ilk parça → tarayıcı: 25–45 ms (sunucu tarafı akış)
- Tarayıcı → hoparlör: 8–15 ms (AudioWorklet, 40 ms titreşim tamponu)
Yedekleme: ana konuşma motoru kesildiğinde yedek sağlayıcı
Gerçek zamanlı konuşma motorumuz AB bölgesinde ayda 1–2 kez 5–15 dakikalığına kesiliyor. Kullanıcıların bunu görmesini istemedik; bu yüzden motorun VoiceSessionMintService bileşeninde oturum oluşturma anında çalışan bir sağlayıcı yedekleme mekanizması kurduk: oturum token'ı verilirken backend, kiracıya özel bir öncelik listesini sırayla dener (ana motor → yedek ses sağlayıcısı → WebSpeech) ve son 60 saniyede hata veren sağlayıcıyı atlayan bir devre kesici kullanır. Panel tarafındaki kod `session.kind` alanını zaten ayrımlı birleşim (discriminated union) olarak işlediği için ön yüzde hiçbir şey değişmedi. Yedek sağlayıcının gecikmesi ~420 ms — belirgin şekilde daha yavaş, ama "çalışıyor" ile "çalışmıyor" arasındaki fark bu.
Söz kesme (barge-in): en zor mühendislik problemi
Kullanıcı, bot konuşurken konuşmak ister. Basit görünüyor ama üç alt sistem gerektiriyor: giriş akışında konuşmayı algılayan sunucu tarafı VAD (gerçek zamanlı konuşma motoru bunu yerleşik olarak sağlıyor); botun kendi sesinin VAD'ı tetiklememesi için istemci tarafında ses yankı engelleme (AudioWorklet içinde AEC); ve devam eden `response.create` çağrısını kesip TTS kuyruğunu boşaltan temiz bir iptal sinyali. Panel v2.97.43'ten bu yana bu 110 ms'nin altında çalışıyor — büyükannenin artık sözümüzü kesebilmesinin sebebi de tam olarak bu.
0 ile 300 ms arasında gecikme bir mühendislik problemidir. 300 ile 1000 ms arasında bir kullanıcı deneyimi problemi. 1000 ms'nin üzerinde ise bir iş problemi.