Dosya

Medical Transcription Orchestration

Klinik toplantılar için gerçek zamanlı altyazı — başsız botlar + WebSocket fan-out.

Rol
Kıdemli Yazılım Mühendisi
Şirket
Ceiba
Tarihler
2025–2026
Yığın
Node.js / TypeScript / Express / Docker / WebSockets / Redis / FFmpeg / JWT / Zoom Meeting SDK / Zoom RTMS / C++

Öne Çıkanlar

  • Başsız toplantı botlarını, ses akışlarını ve bir transkripsiyon servisini koordine eden Node.js orkestrasyon backend'ini tasarladım ve inşa ettim
  • Her katılımcı için ayrı ses yakalayıp orkestratöre katılımcı başına bir TCP akışı açan bir C++ başsız toplantı botu (konteynerlenmiş) dağıttım
  • Zoom'un Realtime Media Streams SDK'sı üzerinde alternatif bir TypeScript bot yazdım — tam Meeting SDK yolundaki aynı toplantı-başına konteyner modelini korur, ama Linux Meeting SDK'sının sessiz hatalarını ve bir kat tutkal kodu karmaşıklığını ortadan kaldırır
  • İki TypeScript SDK yayımladım: biri bot yazarları için (3 aşamalı el sıkışma, stream API, backpressure, otomatik yeniden bağlanma) ve biri altyazı tüketicileri için (tipli olaylar, çoklu oturum abone olma, otomatik yeniden bağlanma)
  • Katılımcı başına ses yakalama, FFmpeg normalleştirme, gerçek zamanlı transkripsiyon ve WebSocket altyazı yayınını tek bir uçtan uca pipeline olarak bağladım
  • Yeniden başlatmada kurtarma ile Redis destekli oturum kalıcılığı; toplantı başına dockerode ile sürülen izole bot konteyner oluşturma

Sorun

Klinik toplantılardaki canlı altyazıların doğrudan mevcut klinik arayüze iletilmesi gerekiyordu; Zoom’un kendi altyazılama özelliği iki koşulu da karşılamıyordu: tıbbi terim doğruluğu ve AV-sağlayıcı bağımsızlığı. Zoom’un yerleşik altyazıları tıbbi terimleri klinik dokümantasyon için kullanılamayacak sıklıkta yanlış üretiyordu; altyazı boru hattını tek bir sağlayıcıya kilitlemek ise diğer AV platformlarına planlanan genişlemeyi tıkardı.

Yaklaşım

Üç bağımsız değiştirilebilir servise ayırdık. Başsız bir toplantı botu çağrıya katılır ve katılımcı başına sesi ortaya çıkarır — iki kez inşa edildi: bir kez C++ ile tam Meeting SDK üzerinde, bir kez TypeScript ile Zoom’un yeni Realtime Media Streams ile. Orkestratör; oturum yaşam döngüsünü, dockerode tabanlı bot spawn’ını, FFmpeg ses normalleştirmeyi ve transkripsiyon teslimini sahiplenir. Bir WebSocket fan-out servisi, abone olan klinik arayüzlere altyazıları yayınlar. Sözleşme yüzeylerinde iki TypeScript SDK durur — bot tarafı (3 aşamalı el sıkışma, stream API, backpressure, otomatik yeniden bağlanma) ve tüketici tarafı (tipli olaylar, çoklu oturum abone olma, otomatik yeniden bağlanma). Oturumlar Redis’te kalıcılaşır, böylece orkestratör yeniden başlatması aktif toplantıları düşürmez. Bot/orkestratör sınırı açıkça AV-sağlayıcı bağımsızdır: Zoom dışı bir platform, orkestratörü veya tüketici SDK’sını yeniden yazmadan yeni bir bot yazılarak eklenebilir.

Sonuç

Uçtan uca altyazı gecikmesi, gayri resmi üretim gözlemine göre ~200 ms aralığında (program nedeniyle formal bir ölçüm yapılmadı). Orkestratör üretimde 10–50 eş zamanlı toplantıyı yönetiyor; beş klinik sağlayıcıya ABD’deki 50+ hastane genelinde gerçek zamanlı hizmet veriyor.

Ne kırıldı

İlk yaklaşım başsız bot için Zoom’un Linux Meeting SDK’sını kullanıyordu — ve üretimde bizi ısırmaya devam etti: aralıklı toplantı katılım hataları, SDK’nın toplantı içinde gösterdiği kayıt-izin uyarısı (hastalar ve klinisyenler bunu gözle görülür biçimde rahatsız edici buldular), küçük bir ek gecikme ve zamanla azalmayan bir bakım yükü. Botu RTMS yoluna çevirmek bu hata modlarını kaldırdı: ham AV akışları için özel olarak inşa edilmiş bir gerçek zamanlı medya sunucusu, gösterilecek izin uyarısı yok, başarısız olabilecek bir katılım el sıkışması da yok — bizim taraftaki tutkal kodu sadeleşti, bakım maliyeti düştü.