chat-agent: результат переработки · 06.10.2026
Чат перешёл на одну генерацию для обычного разговора, ограниченные очереди и
потоковый ответ. WebRTC и PCM через WSS вынесены в отдельные ingress. Работающий
стэк называется chat-agent; Git-репозиторий по-прежнему webrtc-komaroff.
Voice, H100, Ollama, TURN, OAuth и платформу наблюдаемости эта поставка не меняла.
Главный выигрыш получен в исполнении диалога: убраны лишняя генерация router и последовательное ожидание независимых сессий в Agent. Сама модель по-прежнему выполняет одну генерацию за раз. Точность распознавания этой работой не улучшалась.
Что подтверждено отдельно
| Уровень | Доказательство |
|---|---|
| Исходники и проверки C3 | e9122e017baaeab26bea2fd2603214fe473077ee, pipeline 4930 |
| Опубликованные приложения C3 | Все восемь собственных OCI revisions совпали с e9122e0; build 9886 и consumers 9887 — success |
| Конфигурация и переключение | Preflight 9888 и deploy 9889 — success; точные 15 прежних сервисов заменены 13 новыми |
| Фактический runtime C3 | Insight подтвердил running/health/image identity, сети и mounts всех 13 сервисов; inventory |
| Реальные сценарии | 33/33 контрольных хода, 12 WebRTC и 5 WSS; voice-файлы, stages, семь benchmark-конфигураций, summary и диагностика |
| Найденное исправление Core | a479e520f4e8416d52afe8658757ed0fb400b526, pipeline 4932: четыре checks и выборочная сборка Core/RTC/WSS 9897 — success; Core и оба ingress обновлены listener, healthy, revision a479e52; postcheck |
Повторный HTTP-запрос без явного turn_id раньше получал новый turn UUID и
ложный request_id_conflict. Core теперь использует request_id как стабильный
turn, если клиент его не передал. Явный turn и редактирование сохраняют свой
контракт. Два одновременных POST и повтор после завершения дали 200/DONE: одна
генерация в Tempo, две строки истории, повтор завершился за 127 мс.
Evidence идемпотентности.
Исправление и две HTTP-регрессии:
diff a479e52.
Один запрос проходит ограниченный путь
Исходный Mermaid
flowchart LR
U[Текст или ASR final] --> C[Core: request_id и срок]
C --> A[Agent: порядок в сессии, 3 исполнителя]
A --> R[Ruby: dialog_step либо прежний граф]
R --> L[LLM: одна генерация]
L -->|текст по частям| A
L -->|native tool calls| T[Проверка схемы → tools]
T --> R
A --> P[(История и итог PostgreSQL)]
A -->|session / request / generation / sequence| F[Свой интерфейс]Agent сохраняет порядок внутри одного чата и выбирает независимые сессии
справедливо. Для нового обычного разговора Ruby сразу вызывает модель; при
необходимости она запрашивает инструменты. Сервер проверяет имя и все аргументы
до исполнения. Активные и pending-сценарии продолжают использовать свои графы.
Проверенное новое сочетание search_airports_nearby + get_weather использовало
два инструмента и две генерации в одном связанном trace. Погода и другие
демонстрационные авиационные данные остаются fixtures, а не живым внешним API.
Evidence инструментов.
Общий deadline — 120 с. Agent: 3 работающих / 9 ожидающих / до 2 ожидающих на сессию; Ruby: 3 / 3; LLM: 1 / 3. Бюджет tools — 10 действий. Отмена и успешное завершение согласуются одним владельцем; микрофон останавливается отдельным действием. Контракт выполнения.
До и после на одинаковой контрольной серии
Использованы cases.json, одна модель
qwen3:30b, ASR streaming и WAV 3,025 с. SHA256 WAV:
bbdc8147226297b2a56f177b2b70a750dcfc44bbf57498e7ef2befe9c921a42a.
После речи источник продолжал silent PCM. Квантили R7; наблюдаемые загрузки
модели прогретые. Холодная серия и разрешение физического микрофона не измерялись.
| Показатель | C0 p50 / p95, с | C3 p50 / p95, с | Образцы до / после |
|---|---|---|---|
| Обычный полный текстовый ответ | 14,969 / 20,951 | 3,112 / 3,978 | 12 / 12 |
| Первый видимый фрагмент обычного ответа | В C0 не измерен | 3,025 / 3,890 | — / 12 |
| ASR final → полный ответ, нагрузка 1/2/3 | 46,007 / 89,399 | 14,103 / 23,225 | 11 / 12 |
| Готовое локальное SDP → connected | 1,394 / 1,559 | 1,629 / 1,880 | 12 / 12 |
| Начало WAV → ASR final | 3,803 / 3,993 | 3,815 / 4,020 | 11 / 12 |
| Номинальный конец WAV → ASR final | 0,778 / 0,968 | 0,790 / 0,995 | 11 / 12 |
Медиана обычного ответа снизилась на 79%, p95 — на 81%. У голосового ответа после ASR выигрыш составил 69% / 74%. Это короткая контрольная серия, не SLO и не прогноз ёмкости production. До переработки один из 33 ходов завершился ошибкой аудиотранспорта; после — 33/33 DONE. Обычные 12 ответов требуют 12 генераций вместо 26; весь corpus — 36 генераций на 33 ответа вместо 62 на 32.
Подключение WebRTC остаётся ниже цели 3 с по медиане, но в этой серии стало немного медленнее C0, где Trickle уже работал. Снижение с примерно 16 с до 1,25 с относится к отдельной поставке Trickle. Рост ASR p95 после номинального конца WAV — 2,8%, ниже принятого порога 10%. Речь иногда распознана неверно: содержательно «4» получено в 5/12 RTC и 4/5 WSS. Это ограничивает оценку полезного ответа и не скрывается за transport DONE.
У пяти WSS-подключений ready p50 / p95 — 0,357 / 0,381 с; WAV → final — 3,586 / 3,603 с; final → ответ — 5,618 / 16,005 с. Эта отдельная серия имеет пять одиночных ходов: сравнивать её напрямую с RTC нагрузкой 1/2/3 нельзя.
Исходные числа: C0, C3 browser measurements, C3 Tempo spans.
Аудио, отмена, история и разделение чатов
Все 12 RTC-прогонов подтвердили ICE/DTLS connected, растущие RTP counters, серверный TURN relay и декодирование PCM. Один Core принимает ASR final; два ingress используют общий PCM FIFO. Проверка четвёртого WSS-подключения при трёх активных RTC дала явный отказ до передачи PCM: ноль chunks и байт. Максимальная частота периодического flush по метрике — 3,997/с на connection. End/abort flush считаются отдельно. Контракт аудио.
Legacy offer без Trickle тоже проверен: прежний 10-секундный snapshot сбора,
затем 5,234 с на answer и 6,502 с от POST до connected. Путь prflx → relay,
DTLS connected, 59 RTP packets и span первого PCM. Ожидание полного gathering
не завершилось за 15 с; вариант без клиентского STUN не установил media.
Неверный ICE-токен закрыл WS с 1008 за 471 мс без выдачи кандидатов; удаление
своего соединения действующим токеном вернуло 204.
ICE compatibility evidence.
После hotfix a479e52 отдельно повторены современные RTC и WSS: connected
за 1,581 / ready за 0,404 с, настоящий PCM, partial → final → фрагменты → DONE,
по две записи истории. Оба потока остановлены, временная оснастка удалена.
Оба новых распознавания были неточными и привели к уточнению; они не добавлены
в сопоставимый corpus. Postcheck.
Живая отмена длинного ответа завершилась за 1,179 с, отмена редактирования — за 0,786 с. После reload отменённые черновики помечены; исходные две записи редактируемого диалога имеют прежние SHA256. Snapshot своей сессии доступен, чужой session UUID получает 404. Завершённые контрольные сессии восстанавливают историю. Фактическая остановка вычисления на внешнем GPU не доказана. Evidence отмены и истории.
Два настоящих интерфейса проверены одновременно: пока первый выполнял два
инструмента и отображал карту, второй сохранил свой текст и статусы.
Проверка команд карты дополнительно покрыта frontend-тестами; отдельного
live-измерения позиции камеры второго интерфейса нет. Общий user123 сохранён.
Фильтрация событий по session/request не заменяет отдельные NATS ACL для каждого
пользователя: транспортная изоляция пользователей остаётся отдельной работой.
Voice продолжает работать на прежней поставке
Неизменённый voice 5d1d9591 проверен настоящим файлом и NATS progress/result:
обычная transcription, combined diarization, staged Transcribe → Diarize →
Combine, benchmark и summary. Завершены четыре H100-конфигурации и три явно
выбранных CPU sidecar. Короткий WAV дал одного говорящего; WER/DER не измерялись.
CPU не включался как автоматический fallback. Свежий Insight подтвердил все
16 работающих сервисов, прежние image identities, один live bridge и общий
том bench/summary: runtime postcheck.
Все 55 прежних benchmark-записей совпали по агрегированному SHA256 полных строк; после семи тестов summary содержит 62 записи. В описании старого метода исправлена только неточная запись separator: использовался newline U+000A, не буквальные символы backslash-n. Исходный checksum сохранён.
Diagnostics Run smoke: 31 рабочая проверка OK, включая ASR, model requests,
workflow, tools, PG и browser /ws. Прямой HTTP ingress H100 недоступен в
информационной группе; рабочие NATS requester-пути прошли. Это ограничение
соседнего контура сохраняется. Voice evidence.
Размеры и цена изменения
Для образов сравнивается весь состав из 13 сервисов, включая новые ingress и tokenizer. Manifest config IDs сверены с фактическими контейнерами; неизменённые платформенные images используют прежние проверенные manifests.
| Показатель всего стэка | C0 | C3 e9122e0 | Изменение |
|---|---|---|---|
| Сумма rootfs, общие layers повторяются | 3 685,21 МБ | 3 251,97 МБ | −11,8% |
| Сумма compressed layers + configs с повторами | 1 459,41 МБ | 1 230,68 МБ | −15,7% |
| Уникальные compressed layers | 1 217,10 МБ | 978,72 МБ | −19,6% |
| Production LOC, альтернативные исходники включены | 21 230 | 22 358 | +5,3% |
| Активный production LOC | 14 762 | 15 890 | +7,6% |
| Tests LOC | 2 510 | 4 637 | +84,7% |
| Operations LOC | 641 | 1 223 | +90,8% |
| Весь считаемый Git-код, включая tests/operations | 24 381 | 28 218 | +15,7% |
МБ десятичные. Это размеры образов, а не место на диске: тома, внешние модели,
registry attestations и повторное размещение layers на nodes не входят.
Core сократился с 2 893 до 1 321 строк, LLM — с 1 489 до 1 086, но ingress,
контракты, отмена, UI и тесты увеличили общий код. «Кода стало меньше» для всего
проекта было бы неверным выводом. Подсчёт использует tracked physical lines;
YAML, JSON, Dockerfiles и inline-код HTML не включены. Снимок образов относится к corpus release e9122e0;
последующий hotfix увеличил rootfs Core на 56 байт, размеры ingress сохранились.
Image evidence,
точные SHA и LOC.
В одинаковых трёхминутных idle-окнах непосредственно перед и после миграции C2 → C3 working set всего стэка: 700,95 → 570,12 МБ (−18,7%), CPU: 0,120 → 0,177 ядра (+48%). C2 содержал 15 сервисов, C3 — 13. Это сравнение последнего промежуточного состава, а не всей переработки относительно C0. Единственная idle-точка C0 была 476,79 МБ; она не равнозначна среднему окна C3. Сравнимого idle CPU-окна C0 нет.
Во время corpus C3: mean/max working set 555,50 / 579,31 МБ, CPU 0,299 / 0,642 ядра. Шаг metrics 15 с, CPU rate 60 с. В основных Python process CPU заметно меньше container CPU; измерение healthcheck-child показало около 0,49 CPU-с на пробу раз в 10 с. Этот снимок снят до последующей оптимизации healthcheck C4: в двух свежих idle-окнах CPU снизился с 0,197 до 0,049 ядра; RAM не сократилась. Числа C2/C3 выше сохранены как история. Сокращение RAM не означает сокращения CPU. Resources, idle до миграции.
Проверки, доступ и оставшиеся границы
Pipeline 4932: Python 85 passed + 28 subtests, frontend 21 passed, Ruby 38 examples / 0 failures, отдельный Ruby/NATS/PostgreSQL integration job прошёл. Пятнадцать Python skips не считаются выполненными проверками: реальные NATS/PG и media entrypoints проверяются дополнительно integration job и живыми сценариями. Тесты точных aiortc 1.14.0 / aioice 0.10.2 подтверждают DTLS/RTP/PCM при зависшем STUN, поздние кандидаты и cleanup; private adapter остаётся нашим.
Без OAuth новые защищённые HTTP/WS возвращают 302 на вход, не UI/101. Четыре прежних application/admin hosts с путями UI/API/WS дали 404 поверх доверенного TLS нового host. Это проверка маршрутов, а не удаления wildcard DNS. Access evidence.
Исходники альтернативных runtimes сохранены, но в production их нет. GPU scheduling, decoder hang и длинная фраза (№25/26/30) остаются у voice. Несколько владельцев media, ICE restart и автоматическая смена транспорта не реализованы. Thinking-модель скрывает рассуждение до видимого текста, поэтому streaming не гарантирует немедленного первого слова.
Project/agent documentation обновлена через source codex-workspace и штатный
sync; active project py-faster-whisper сохранён. OpenWiki пропущен по явному
решению пользователя. Его прежние generated страницы не подтверждают C3;
актуальные источники — код, этот отчёт,
архитектура и deployment runbook.
Проверены 325 относительных targets и 311 Git permalinks без потерянных файлов.
Оба HTML deck прошли standalone validator. Семь файлов project overlay совпали
с runtime; validate, sync --company monitorsoft и doctor прошли.
Links,
workspace parity.