Logo Craft Homelab Docs Контакты Telegram
Доказательный инфраструктурный агент: как строить расследования без выдуманных выводов Трендовые github проекты в нашем телеграм канале. Подпишись →
27 июля 2026 г.

Инфраструктурные расследования, где факт важнее правдоподобного ответа

Инженерский вопрос часто звучит просто: «Почему сервис отдавал 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 кодом, планирует доказательства и честно показывает, чего ей не удалось проверить.