Трендовые github проекты в нашем телеграм канале. Подпишись → Инфраструктурные расследования, где факт важнее правдоподобного ответа
Инженерский вопрос часто звучит просто: «Почему сервис отдавал 502?», «Кто выкатывал эту версию?» или «Что изменилось перед инцидентом?». Для ответа нужно соединить Kubernetes, access- и error-логи, метрики, CI/CD, инвентарь и историю изменений. LLM хорошо понимает формулировку вопроса и умеет объяснять результаты. Но если дать ей прямой доступ к набору инструментов, она легко построит убедительную версию без достаточных оснований.
Рабочая модель инфраструктурного агента начинается с более строгой цели: он должен собирать проверяемые наблюдения, показывать пробелы в данных и разделять факт, гипотезу и рекомендацию. Агент остаётся read-only; изменения в production принимает человек.
Начинайте с точного контекста запроса
Свободный текст нельзя считать готовым запросом к инфраструктуре. Из него нужно выделять отдельное типизированное состояние: площадку, namespace, объект, subject, временной диапазон и режим данных — live или historical.
environment: dc-a
namespace: payments
object: service-a
subject: request_trace
request_id: 7f9...c21
time: 2026-07-20 14:11 MSK ±15m
mode: historical
Это защищает follow-up вопросы от опасного наследования контекста. Если пользователь просит «проверь то же самое в dc-b», новая площадка обязана заменить старую. Слово «сейчас» сбрасывает прежнюю историческую точку времени. Явно заданные значения в текущем сообщении должны быть сильнее памяти треда.
Такое разделение также не позволяет выдать историческое наблюдение за текущее состояние. Успешный rollout вчера и работающий workload прямо сейчас — разные утверждения, которым нужны разные источники и семантика времени.
Контракт источника шире JSON Schema
JSON Schema полезна для проверки типов, обязательных полей и допустимых значений. Для корректного расследования этого недостаточно. У инструмента должны быть эксплуатационные свойства:
- read-only статус и требования к роли пользователя;
- тип данных: live-состояние или исторический источник;
- время наблюдения;
- evidence objectives, которые способен закрыть источник;
- правила для пустого результата;
- полнота покрытия и предупреждения.
Критичнее всего семантика отрицательного результата. Пустой ответ из логов не означает, что события не было. Он может говорить о неверном индексе, неподдерживаемой площадке, неполном окне, лимите выдачи или ошибке, которую workflow превратил в пустой массив.
Нормализованный ответ инструмента должен сохранять scope, observed_at, coverage, факты и warnings. Тогда фраза «ничего не найдено» появляется только при доказанной полноте поиска для нужного контекста. Во всех остальных случаях агент сообщает, какой источник не подтвердил результат и почему вывод ограничен.
Планируйте доказательства, а не вызовы tools
Обычный ReAct-цикл выглядит привлекательно: модель выбирает инструмент, читает ответ и решает, что делать дальше. На реальных инцидентах такой подход даёт разные цепочки для одинаковых вопросов и способен завершить расследование после первого удобного ответа.
Надёжнее начать с перечня целей. Для вопроса о 502 это могут быть симптом, маршрут edge → ingress → service, готовность endpoints, состояние backend и изменения перед инцидентом. У каждой цели есть несколько допустимых источников и условие завершения: цель либо подтверждена, либо явно отмечена недоступной.
Отдельный guard не должен разрешать финальный ответ, пока обязательные evidence objectives не закрыты. Он не заставляет бесконечно повторять неработающий запрос: после подтверждённой ошибки источник помечается как unavailable, а ограничение попадает в итоговый отчёт.
Для известных рискованных сценариев полезны детерминированные маршруты. Точный request_id следует вести через access-log, корреляцию соединения, host и узкое временное окно к error-log и логу приложения. Массовый одновременный всплеск 502 у независимых сервисов требует сравнить failure domains, ноды и сетевые сигналы. Один HTTP-код не является диагнозом.
Почему 302 в приложении и 502 на edge не противоречат друг другу
Такое расхождение — хороший тест качества расследования. Лог приложения с 302 подтверждает, что handler сформировал redirect. Он не подтверждает, что proxy смог прочитать и передать клиенту весь набор response headers.
Корреляция access-log и error-log может показать сообщение upstream sent too big header while reading response header from upstream. В этом случае proxy установил соединение с upstream, но не смог разместить заголовки в настроенном буфере. Длинный Location, Set-Cookie, Content-Security-Policy и повторяющиеся заголовки складываются в общий размер блока.
Корректный вывод здесь конкретен: приложение завершило обработку с 302, edge отдал клиенту 502, причина подтверждена на чтении response headers. Состояние endpoints или ноды не нужно объявлять причиной без отдельных данных. Следующий шаг — измерить полный набор заголовков и устранить избыточные значения; изменение proxy buffers требует оценки влияния на весь поток.
Храните raw-данные вне prompt
Логи и таблицы инфраструктуры быстро занимают десятки килобайт. Полная передача всех результатов в контекст модели ухудшает способность следовать текущей цели. Простая обрезка head/tail ещё опаснее: из середины пакета может исчезнуть важный источник или площадка.
Практичная схема состоит из двух уровней. Workspace текущего turn хранит полный результат. Evidence packet содержит компактные структурированные наблюдения: источник, scope, время, факты, coverage и ссылку на артефакт. При необходимости модель запрашивает конкретный временной фрагмент, строки по request_id или определённую таблицу.
Полный raw не должен становиться вечной памятью. Это сокращает утечки чувствительных данных и не превращает старые результаты инструментов в якобы актуальное знание.
Память не является evidence
Контекст переписки, короткая рабочая память и подтверждённое операционное знание решают разные задачи. История треда полезна для понимания вопроса, но прежний ответ ассистента нельзя использовать как live-доказательство. Короткая память должна иметь TTL, ограничение размера, scope и признак historical. Подтверждённые правила или ссылки на runbook стоит сохранять отдельно с автором, временем, происхождением и явным подтверждением.
Эта граница особенно важна для инцидентов: старая метрика или вывод из другого окружения могут звучать правдоподобно и быть полностью нерелевантными текущему запросу.
Оценивайте агента на воспроизводимых сценариях
Unit-тесты проверяют код, но не отвечают на вопрос: выберет ли модель нужный источник, удержит ли смену окружения и не объявит ли timeout чистым результатом. Каждое неприятное расследование стоит превращать в scenario fixture: диалог, replay ответов инструментов, обязательные вызовы, ожидаемые факты и запрещённые ложные выводы.
Сценарии нужно запускать реальной моделью несколько раз. Полезны проверки на смену scope, различение live и historical, корректную обработку пустого результата, сохранение ручного audit-действия в истории релиза и полноту evidence перед финальным ответом.
Инфраструктурный агент становится полезным не после первого успешного tool call. Его ценность появляется там, где система знает границы своих данных: сохраняет контекст, исполняет policy кодом, планирует доказательства и честно показывает, чего ей не удалось проверить.