# chat-agent: стоимость healthcheck · 06.10.2026

После C3 заметную часть CPU в простое тратили три периодические health-пробы.
Каждые 10 секунд они запускали Python для одного локального HTTP-запроса.
Теперь Core, WebRTC ingress и WSS ingress вызывают `curl`. В одинаковых
трёхминутных окнах расход CPU всего стэка снизился примерно на 75%.

Это продолжение [приёмки C3](</experiments/voice-ai/archive/w/DOCS/CHAT_AGENT_ACCEPTANCE_C3.md>). Диалог, ASR,
аудиоконтракты и соседние сервисы не перерабатывались повторно.

## Код, CI и фактические контейнеры

Исходники: [0c403307](<https://git.giscloud.ru/voice-chat/webrtc-komaroff/-/commit/0c403307a506f03c6e77833fd5f1cbb36743c028>).
[Pipeline 4934](<https://git.giscloud.ru/voice-chat/webrtc-komaroff/-/pipelines/4934>):
Python 9910, frontend 9911, Ruby 9912, integration 9913 и
[выборочная сборка 9915](<https://git.giscloud.ru/voice-chat/webrtc-komaroff/-/jobs/9915>)
завершились успешно. Опубликованы только Core и два ingress.

Registry listener обновил эти три контейнера. Insight подтвердил у каждого
revision `0c403307`, healthy и update completed. Повторный Insight U и полный
deploy не запускались. Остальные десять container IDs сохранились; все 13
сервисов running, OOM/restart count — ноль. Frontend и Ruby имеют revision
документирующей поставки `27432de7`; Agent, API и LLM — `e9122e0`.
Image ID ниже — config identity Docker, а не registry manifest digest.

| Сервис | Actual image config ID | Rootfs до → после, байт |
|---|---|---:|
| Core | `sha256:c4c3906c6310f29f34b05ed4d2d93c5f0661b6ba94f1d8c4427a4b1c55ea5629` | 325 268 232 → 318 527 416 |
| WebRTC ingress | `sha256:10a3a8ed2d259aa20614ac84afb408bbe603b833ce0b286e623cff426c7c8a88` | 380 131 574 → 385 635 305 |
| WSS ingress | `sha256:f4b6c1eafd91e76604184fde803d5139e7dda65690ddebef7c3acf11e7a15e84` | 351 291 258 → 356 794 989 |

## Проверка осталась строгой

Успех означает полностью полученный HTTP 200 от локального `/healthz`.
503, redirect, отказ соединения, зависшие headers и зависший body после headers
200 дают отказ. Proxy environment игнорируется; тело ответа не выводится.
Core учитывает `CORE_PORT`, ingress используют порт 8000. NATS readiness в
обработчиках `/healthz` сохранена. Docker interval/timeout/start-period/retries:
10 с / 3 с / 20 с / 3; HTTP deadline — 2 с.

Исходники: [Core Dockerfile](#archive-availability),
[ingress Dockerfile](#archive-availability),
[проверка точной команды](</experiments/voice-ai/archive/w/docker/check_healthcheck.py>).
Fixture выполняется при сборке каждого образа через временный bind mount и
не остаётся в runtime layer. В обеих Compose-конфигурациях добавлен этот
build context; удалён повторный ключ имени dev PostgreSQL-тома, который мешал
`docker compose config`. Production DRS и тома этой правкой не менялись.

В каждом реальном образе выполнено 30 CPU-проб. `RUSAGE_CHILDREN` учитывает
полное дерево shell/curl, а не только родительский shell. Порог 50 мс выдержан
во всех 90 измерениях. Дополнительно прошли перечисленные случаи отказов,
проверка порта и игнорирования proxy.

| Образ | CPU mean / p95 / max одной пробы, мс | n |
|---|---:|---:|
| Core | 19,145 / 23,590 / 27,292 | 30 |
| WebRTC ingress | 18,710 / 23,812 / 25,443 | 30 |
| WSS ingress | 21,146 / 26,112 / 28,948 | 30 |

Прежний диагностический mean Core — 490,520 мс CPU. Число образцов старого
замера не сохранено в этом отчёте; это ориентир причины, а не симметричная
статистическая серия. Основное сравнение результата — container CPU ниже.

## Замеры до и после

Источник — VictoriaMetrics через [Grafana gis-master](<https://tempo.gis-master.ru/map/grafana/>).
Оба окна по 180 с, 13 точек с шагом 15 с, CPU rate 60 с. Namespace `chat-agent`,
13 сервисов; active и pending во всех точках равны нулю. После тестов выдержана
минута перед началом нового окна. Данные и точные запросы:
[числовой evidence](</experiments/voice-ai/archive/w/DOCS/evidence/chat-agent-c4-healthcheck.json>).

| Показатель всего стэка в простое | До, 12:22:16–12:25:16 UTC | После, 12:43:27–12:46:27 UTC | Изменение |
|---|---:|---:|---:|
| CPU mean, ядра | 0,19718 | 0,04930 | −75,0% |
| CPU max, ядра | 0,22213 | 0,06691 | −69,9% |
| Working set mean, МБ | 547,57 | 553,41 | +1,1% |
| Working set max, МБ | 547,59 | 558,32 | +2,0% |
| Сумма rootfs 13 образов, МБ | 3 251,98 | 3 256,25 | +4,27 МБ / +0,13% |

МБ десятичные. RAM этой правкой не сократилась. Rootfs — весь результат
пересборки, включая слои зависимостей; это не изолированный вес пакета curl.
Общие layers в сумме повторяются, тома и внешние модели не входят.

Свежий compressed delta не подтверждён: Registry Explorer `/index` возвращал
`ERR_CONNECTION_CLOSED`, чтение `/json` завершалось timeout. Доступ не обходился.
Точное сравнение compressed/unique layers C0 → corpus C3 остаётся в
[датированном отчёте C3](</experiments/voice-ai/archive/w/DOCS/CHAT_AGENT_ACCEPTANCE_C3.md>); его нельзя выдавать за
размеры новых C4 images. Rootfs текущего полного состава подтверждён Insight.

Сопоставление CPU относится к двум окнам простоя перед/после C4. Это не
load SLO и не сравнение с C0, у которого равнозначного CPU-окна не было.
Производственный код сохранил 22 358 строк, активный — 15 890. Fixture добавил
124 строки operations: 1 223 → 1 347; весь считаемый Git-код — 28 218 → 28 342.
Правила подсчёта прежние: physical tracked lines; YAML, JSON, Dockerfiles и
inline HTML не входят. Итоговый rootfs C0 → C4: 3 685,21 → 3 256,25 МБ (−11,6%).

## Короткая проверка пользовательского пути

После обновления выполнены один текстовый запрос, один RTC и один WSS с тем же
WAV 3,025 с, что в C3. После речи продолжался silent PCM. Это smoke, n=1 на
сценарий; полную контрольную серию и приёмку неизменённого voice повторно не
запускали. Их результаты сохраняются в C3.

- Текст: HTTP 200/DONE, верный ответ «4», 4,180 с, две записи истории.
- RTC: SDP → connected 1,583 с; srflx → relay, DTLS connected, 1 948 наблюдённых
  RTP packets, decoded first PCM, пять partial spans, final, одна LLM generation,
  DONE и две записи истории.
- WSS: ready 0,343 с, без RTC peer; 3 577 наблюдённых chunks / 7 325 696 PCM bytes,
  first PCM, четыре partial spans, final, одна generation, DONE и две записи истории.
- UI показал ответы и отключение обоих потоков. Временные media/fetch hooks
  восстановлены; в idle-окне активных работ не осталось.

Связанные traces: RTC `81d480d14214b77989b7d9bd908702f7`, WSS
`db8dbf9011741f21fb067b9cb26ec2ae`. Browser event cursor WSS был усечён;
partial/final подтверждены свежими Tempo spans и итогом в UI/history, а не
заявлением о полном replay браузерных событий.

Оба аудиораспознавания были неточными и привели к уточнению. Исправление
healthcheck не улучшает WER/DER; физический микрофон этой синтетической пробой
не проверен. Voice/H100/Ollama/TURN/OAuth/platform не менялись. Отложенные
проблемы voice, per-user NATS ACL, ICE restart и несколько media owners
остаются указанными в C3. OpenWiki пропущен по явному решению пользователя.
