Колонка

Дашборд соврал дважды за день — в противоположные стороны

Одна коробка, один день: модель, возвращающая пустые ответы под HTTP 200, и два живых контейнера с вердиктом unhealthy от пробы, нацеленной не в тот порт. «Зелёный, но сломанный» и «красный, но здоровый» — одна болезнь, и лечится она одинаково.

мнение 20 августа 2026 г.

Это колонка-мнение, а не результат лаборатории. Цифры здесь — из рабочего журнала автора и цитируемых внешних источников (помечены в тексте), никогда — из реестра клеймов. Измеренные результаты с доказательствами живут в /claims/.

В середине августа мы пошли проверить две свежеразвёрнутые тестовые модели на одной из коробок лаборатории. Рутинный осмотр: docker ps, логи, пара smoke-запросов. За час коробка выдала обе классические лжи мониторинга, по одной в каждую сторону, и пара получилась слишком чистой, чтобы её не записать.

Красный, но здоровый

Оба контейнера показывали unhealthy. Такой unhealthy, за который перезапускают и будят дежурного. Модели за ними всё это время обслуживали запросы.

Причина нашлась за один docker inspect. Образ везёт с собой дефолтный healthcheck, который стучится в localhost:8080/health. Серверы были подняты на портах 8090 и 8091. Проба стучалась в дверь в пустом коридоре, заключала, что в доме никто не живёт, и штамповала вердикт в строку статуса — а настоящие серверы дверью дальше отвечали на каждый живой запрос.

Ничего не болело. Болело измерение. А у строки статуса нет цвета для «проба смотрит не туда» — есть только цвет для «умер».

Зелёный, но сломанный

Та же коробка, тот же день. Одна из моделей — тяжёлая reasoning-модель. Мы задали ей тривиальный вопрос при нулевой температуре и с обычным токен-бюджетом, каким пользовалось бы любое клиентское приложение. Она ответила HTTP 200.

Внутри этой двухсотки — пустое поле content. Модель потратила весь бюджет на размышления: канал reasoning был полон текста, оборванного на полуслове там, где кончился бюджет, — и не выдала ни одного токена ответа. Каждый сигнал транспортного уровня рапортовал успех. Любой клиент, который читает content и верит коду статуса, показал бы пользователю пустое сообщение, записал бы в лог успешный запрос и пошёл дальше.

Ровно этот режим отказа мы измерили на замороженной нагрузке и опубликовали как отчёт про HTTP 200 без ответа. Странно было на той же неделе поздороваться с ним в дикой природе: никем не спровоцированный, не сконструированный — просто сидит себе за зелёным статусом на здоровой коробке.

Одна болезнь

Две лжи смотрят в противоположные стороны, и именно этим пара поучительна. Одна система отрапортовала отказ вместо успеха, другая — успех вместо отказа. Ни один компонент не сломался. Обе пробы точно ответили на вопрос, который им задали в конфиге, — «отвечает ли что-нибудь на 8080?», «завершился ли HTTP-запрос?» — и ни один из этих вопросов не был тем, который мы на самом деле хотели задать: делает ли эта модель свою работу?

Лампочка статуса — это утверждение об измерении. Если конфигурация пробы не совпадает с системой, которую та берётся описывать, — не тот порт, не та метрика, не тот бюджет — вы мониторите другую систему, у которой с вашей общий только hostname. Дашборд врёт не по злобе. Он точно отвечает — в ту сторону, куда его направили.

У обеих лжей общая и стратегия выживания: дальше строки статуса никто не читает. Красное перезапускают, и это ничего не меняет, потому что перезапущенный контейнер наследует ту же пробу. Зелёное игнорируют, и это хуже, потому что игнорировать — и есть предназначение зелёного. В обе стороны отказ невидим ровно там, куда смотрят, и очевиден слоем глубже — в логах, в теле ответа, — куда никто не заглядывает, пока у строки есть цвет.

Что это поменяло в нашей практике

Измерительные правила лаборатории существуют из-за таких вот экземпляров, и эта пара заточила три из них.

Оценивать содержимое, а не транспорт. Наши гейты читают текст ответа — сказано ли хоть что-то, на том ли языке, без зацикливаний, — а метрика первого токена отличает первый токен ответа от первого токена чего угодно, включая размышления. В зазоре между этими двумя определениями и прячется случай «зелёный, но сломанный»; отчёт про TTFA как раз об этом зазоре.

Пробовать то, что обслуживаешь, а не то, что предполагает образ. Healthcheck нашего харнесса целятся в тот эндпоинт и тот порт, на которые ячейка реально настроена, и падают быстро, если ответа нет: мёртвый контейнер должен стоить секунд, а не всего бюджета таймаута.

А когда под подозрением сама телеметрия — на железе, где штатный GPU-стек не отдаёт вообще ничего, — коллектор носит при себе алерт на собственное устаревание. Лекарство должно действовать и на само лекарство, иначе труба мониторинга становится ещё одной системой, которая умеет ломаться, оставаясь зелёной.

Коробка, для протокола, всё это время была здорова. Сломаны были вопросы — и вопросы были нашими. Направьте пробу на то, чем вы реально управляете, и хотя бы раз за деплой прочитайте на один слой глубже цвета. Дашборд ответит на любой вопрос. Задайте правильный.

← Все колонки