AI-инжиниринг
Realtime AI: WebSocket + LLM, voice assistants, live collaboration
Цели урока
- Реализовать WebSocket gateway для streaming AI-чата с поддержкой прерывания
- Спроектировать voice assistant pipeline со streaming для минимальной латентности
- Разобрать OpenAI Realtime API - natively audio-to-audio без промежуточного текста
- Понять архитектуру AI collaboration: CRDT + AI agent + human-in-the-loop
Realtime AI - это когда latency измеряется в миллисекундах, а не секундах. GPT-4o Realtime API: 300ms end-to-end для голоса. Это граница восприятия - ниже кажется мгновенным. Выше - 'тормозит'. Два пользователя используют одну модель: один ждёт 5 секунд пустого экрана, другой видит ответ через 200ms. Разница не в модели - в архитектуре. WebSocket вместо HTTP, VAD для голоса, interruption handling, stateful соединения - это не оптимизация, это другая профессия.
- ChatGPT показывает токены по мере генерации - streaming через SSE, ~200ms time-to-first-token
- Google Duplex совершает звонки с latency 300ms - streaming STT + LLM + TTS pipeline с VAD
- Notion AI - collaborative AI editing в Google Docs-стиле, AI предложения через ghost text и CRDT
- Cursor IDE - real-time AI code editing через CRDT + LLM agent, Tab для принятия suggestions, 40ms debounce
От стриминга токенов к Realtime API
Первым шагом к realtime-ощущению стал стриминг токенов: ChatGPT и затем Chat Completions API в 2023 году отдавали ответ по мере генерации через server-sent events, и пользователь видел текст сразу, а не ждал несколько секунд полный ответ. Это убрало главную боль восприятия, но всё ещё работало по схеме запрос-ответ. Настоящий сдвиг произошёл 1 октября 2024 года, когда OpenAI на своей конференции DevDay представила Realtime API в публичной бете. Она держит постоянное WebSocket-соединение с GPT-4o и работает speech-to-speech: аудио идёт в модель и из модели напрямую, без промежуточной связки speech-to-text плюс LLM плюс text-to-speech. Это убирает накопленную задержку всей цепочки и позволяет вести голосовой диалог с латентностью около границы человеческого восприятия, поддерживая прерывания посреди фразы. На старте API предлагал шесть предустановленных голосов. Realtime API закрепил архитектуру голосовых ассистентов на постоянном соединении вместо серии отдельных HTTP-запросов.
Предварительные знания
WebSocket + LLM Streaming: real-time чат с AI
SSE (Server-Sent Events) - однополосная дорога: данные едут только в одну сторону. Для простого чата хватает. Но как только нужно прервать генерацию на середине, отправить параллельный запрос или получить push-уведомление от сервера - SSE упирается в стену. Здесь начинается WebSocket.
WebSocket - это постоянное соединение с двусторонней связью. Клиент отправляет `stop` прямо во время генерации - сервер получает, вызывает `AbortController.abort()`, LLM-стрим обрывается. Именно так работает кнопка «Стоп» в ChatGPT. Не магия - stateful соединение и правильная архитектура.
**Масштабирование WebSocket:** Socket.IO с Redis adapter позволяет распределить connections между несколькими Node.js instances. Sticky sessions не нужны - Redis pub/sub синхронизирует events между серверами.
Зачем использовать WebSocket вместо SSE для AI-чата?
Voice Assistant Architecture: speech-to-speech через LLM
Голосовой ассистент - это гонка со временем. Pipeline: **Речь → Текст (STT) → LLM → Текст → Речь (TTS)**. При последовательном выполнении сумма латентностей убивает UX: Whisper даёт 1.5с, Claude - ещё 2-5с, ElevenLabs - ещё 1-3с. Итого 4-9 секунд молчания перед каждым ответом. Диалог превращается в переписку.
Решение - параллельный стриминг. Не ждать полного ответа LLM. Как только появляется первое законченное предложение - сразу отдавать его в TTS и воспроизводить. Пока играет первое предложение, LLM генерирует второе, TTS рендерит его. Time to first audio падает с 9 секунд до ~1.1 секунды. Разница между роботом и живым собеседником.
**Voice Activity Detection (VAD)** - критический компонент. Нужно определять, когда пользователь начал и закончил говорить. Silero VAD (open-source, 100KB модель) работает в браузере через WebAssembly. Без VAD система будет обрабатывать тишину и фоновый шум.
Как минимизировать time-to-first-audio в voice assistant?
OpenAI Realtime API: speech-to-speech без промежуточного текста
300 миллисекунд. Это граница восприятия: ниже - кажется мгновенным, выше - «тормозит». Traditional voice pipeline с STT + LLM + TTS даёт 1-3 секунды. OpenAI Realtime API (2024) пробивает барьер напрямую: GPT-4o принимает аудио и генерирует аудио нативно, без текстового промежуточного слоя. End-to-end ~300ms. Как настоящий телефонный разговор.
Протокол - WebSocket на `wss://api.openai.com/v1/realtime`. Клиент стримит PCM16 аудио-чанки, сервер возвращает аудио-чанки обратно. Server-side VAD (voice activity detection) определяет паузы и автоматически триггерит turn detection. Прерывание встроено: как только VAD фиксирует что пользователь заговорил, можно отправить `response.cancel` - модель остановится мгновенно.
| Характеристика | Traditional Pipeline (STT→LLM→TTS) | OpenAI Realtime API |
|---|---|---|
| Латентность | 1-3 секунды | ~300ms |
| Эмоции в голосе | TTS пытается угадать | Нативное понимание тона |
| Interruption | Сложная реализация | Встроенное (server VAD) |
| Стоимость | 0.006-0.02 per 15s | USD 0.06 per 15s input + USD 0.24 output |
| Гибкость моделей | Любая LLM + любой TTS | Только GPT-4o |
| Контроль голоса | Полный (ElevenLabs клоны) | 6 preset голосов |
| Offline/Edge | Возможно (Whisper+local LLM) | Только online |
**Цена Realtime API в 10x выше** traditional pipeline. Оправдано там, где каждая секунда задержки стоит денег: live customer support, real-time translation, accessibility tools. Для асинхронных задач (голосовые заметки, транскрипция) - traditional pipeline выгоднее в 10 раз.
Главное преимущество OpenAI Realtime API над traditional STT→LLM→TTS pipeline?
Live Collaboration с AI: совместное редактирование в реальном времени
Cursor IDE - это не просто автодополнение. Это AI-агент как полноправный участник совместного редактирования: видит каждую правку, понимает намерение, предлагает изменения через ghost text. Нажал Tab - применил. Нажал Esc - отклонил. Под капотом - CRDT (Conflict-free Replicated Data Type): алгоритм, который позволяет мержить правки от любого числа участников без конфликтов. AI - просто ещё один участник.
Ключевой инсайт: AI не должен менять документ автоматически. Это разрушает trust мгновенно. Архитектура строится вокруг принципа human-in-the-loop: AI генерирует pending-операции, они отображаются как ghost text, человек подтверждает (Tab) или отклоняет (Esc). Только после этого CRDT-движок мержит правку в документ.
- **AI - соавтор, не автор.** Предложения показываются как ghost text, не применяются автоматически
- **Debounce обязателен.** AI анализирует после паузы в редактировании (2-3 секунды), не на каждый keystroke
- **Быстрая модель для suggestions.** claude-haiku или GPT-4o-mini - латентность < 500ms для inline suggestions
- **CRDT для conflict resolution.** AI-операции мержатся через тот же движок, что и пользовательские
- **Graceful degradation.** Если AI-сервис недоступен - collaboration продолжает работать без него
**Yjs** - наиболее популярная CRDT-библиотека для JavaScript. Поддерживает WebSocket sync, offline-first, и легко интегрируется с AI-агентом. Cursor IDE использует похожую архитектуру для AI-powered editing.
Почему AI-предложения в real-time collaboration показываются как ghost text, а не применяются сразу?
Realtime AI - это просто быстрый HTTP-запрос к LLM
Realtime AI требует принципиально другой архитектуры: WebSocket или WebRTC для постоянного соединения, VAD для голоса, interruption handling, stateful сессий и специального протокола обмена событиями
HTTP-запрос завершается - соединение закрывается. Для realtime нужно соединение, которое живёт минуты и часы, где обе стороны могут отправлять данные в любой момент. Добавьте VAD (детекцию голоса), turn detection (кто сейчас говорит), interruption (прервать AI на середине фразы) - и окажется, что это совсем другая архитектурная задача. OpenAI Realtime API работает через WebSocket именно по этой причине: HTTP для него просто не подходит.
Итоги
- WebSocket = bidirectional: прерывание генерации, параллельные запросы, push от сервера - SSE этого не умеет
- Voice pipeline: streaming STT → sentence-by-sentence TTS сокращает time-to-first-audio с 9с до ~1.1с
- OpenAI Realtime API: audio→audio нативно, 300ms vs 1-3s у traditional pipeline, но 10x дороже
- AI collaboration через CRDT: AI как ещё один participant с pending-операциями через ghost text
- Human-in-the-loop не опционален - автоматические AI-правки разрушают trust мгновенно
Что дальше
Real-time архитектура понятна. Пора собрать все эти паттерны в конкретную реализацию - AI backend на NestJS с modules, queues, caching и error handling.
- AI Backend на NestJS — Конкретная реализация AI backend: module structure, queues, caching, patterns
- AI System Design — Полная архитектура production AI-приложения
Связанные уроки
- aie-08-streaming — Real-time AI строится на token streaming
- aie-23-speech-to-text — Голосовые pipeline требуют низколатентного STT
- aie-44-ai-backend-node — Backend хостит real-time AI-сервис
- aie-42-ai-system-design — Real-time-ограничения формируют архитектуру
- net-36-websocket — Дуплекс-транспорт для живых двунаправленных потоков
- sd-03-scalability