The Jerusalem PostANU adds three new artworks to 'October 7' exhibit as Israel marks third anniversary of massacrePunchOne dead, many injured as bus catches fire on Kwara expresswayESPNTransfer rumors, news: Bayern brace for tough contract talks with OliseBollywood HungamaRakul Preet Singh BREAKS silence on Income Tax searches, DENIES involvement in illegal foreign remittances: "Have been paying my due taxes since the age of 20"InquirerFoul odor prompts shoreline inspection in MamburaoInvesting.comGoldman Sachs anticipe des gains pour le real brésilien après les électionsInvesting.comGoldman Sachs prevé ganancias del real brasileño tras eleccionesNumeramaL’IA a tué (pour l’instant) l’un des programmes de sécurité de GoogleBBC NewsScott out of England squad and faces injury lay-off7sur7Trump dévoile le numéro de portable d’un collègue de son parti opposé à l’heure d’été permanente: “Appelez-le!”Times of India EntertainmentSRK's net worth is Rs 12,000 crore which is 4x times more than Salman, Aamir, Akshay, says analystGMA NewsSara Duterte had over P10M in withdrawals, check encashment in Dec. 2024 -- AMLC witness
The Daily Newsstand · Free, Always
Monday, October 5, 2026

Вайбкодинг и DevOps.Не просите AI чинить: научите его расследовать

Translate

AI отвечает мгновенно и предлагает очистить кэш, перезапустить сервис, переустановить пакет, отключить файрвол и добавить запись в /etc/hosts, причём какое-нибудь из этих действий иногда даже помогает. После этого система снова работает, причина остаётся неизвестной, а в инфраструктуре появляется ещё одно временное решение с прекрасными шансами пережить автора.

Так рождаются технические легенды. «Этот сервис по вторникам надо рестартовать два раза». «DNS здесь особенный». «Строку не трогай, без неё всё падает». Никто уже не помнит, откуда взялась строка, зато она заботливо переносится из одного поколения конфигурации в другое, как фамильное проклятие, и через три года, когда вы будете мигрировать на новый кластер, кто-нибудь обязательно спросит: «А мы перенесли эту магическую строку?» - и ответить не сможет никто. Но перенесут. На всякий случай.

AI особенно опасен в таком режиме вовсе не оттого, что плохо ищет ошибки; беда ровно в обратном - он очень быстро находит правдоподобные объяснения, и когда контекста мало, правдоподобие начинает подменять доказательство. Модель узнаёт знакомый симптом и достраивает остальную историю по наиболее вероятному шаблону, иногда угадывая. Вот здесь и важно понять, что в production слово «иногда» перестаёт быть статистической погрешностью и становится бомбой с часовым механизмом, которая просто ждёт своего часа.

Задача этой главы - не устанавливать софт: мы снова ничего не будем ставить. Да, опять. Да, так надо. Научиться нужно другому - расследовать сбой вместе с AI: собрать свидетельства, отделить факт от гипотезы, проверить версии по одной, найти не только непосредственную причину, но и системную, а затем сохранить знание в проекте. Это ещё не Linux-диагностика, ею займёмся позже; сейчас мы строим сам процесс мышления, которым потом будем разбирать Linux, сеть, Terraform, Kubernetes и всё остальное, что умеет ломаться с гораздо большим размахом. А начинать придётся с терминов, потому что слово «ошибка» обычно используют сразу для пяти разных вещей.

Симптом - то, что заметил человек или мониторинг: страница не открывается, команда завершилась неуспешно, файл не появился. Симптом сообщает, где болит, но редко объясняет почему.

Свидетельство - наблюдаемый факт: точная команда, время, код возврата, строка лога, diff, состояние процесса. Свидетельство можно повторно проверить или привязать к источнику.

Гипотеза - возможное объяснение свидетельств: «имя не резолвится из-за отсутствующей DNS-записи» - гипотеза, которая становится полезной только вместе с проверкой, способной её опровергнуть.

Непосредственная причина - конкретное условие, из-за которого операция не выполнилась именно сейчас: например, в конфигурации остался «enter_your_ip_here».

Системная причина - объяснение того, почему неправильное условие прошло через процесс незамеченным: скрипт не проверил заглушку, проигнорировал ошибку curl, напечатал сообщение об успехе и вернул код 0. Исправить только имя узла - значит убрать непосредственную причину и сохранить фабрику следующих инцидентов.

Исправление (fix) восстанавливает правильное поведение, тогда как предохранитель (guardrail) меняет код или процесс так, чтобы тот же класс ошибки не проходил бесшумно. Перезапустить сервис можно считать исправлением; добавить проверку конфигурации до запуска и функциональный health check после - предохранитель.

AI должен работать именно с этой цепочкой, и если агент перескакивает от симптома прямо к исправлению, он не расследует. Он участвует в лотерее с очень убедительными комментариями.

В будущем нам понадобится stage-zero bootstrap - минимальный ручной этап, который подготовит вход в инфраструктуру до появления полноценной автоматизации; поскольку никакой инфраструктуры пока нет, проверим только локальную механику будущей предстартовой проверки. Представим, что агент предложил такой черновик:

#!/usr/bin/env bash

MANAGEMENT_HOST="${MANAGEMENT_HOST:-control.example.invalid}"

echo "Checking management endpoint..."
curl -s "https://${MANAGEMENT_HOST}/health" || true
echo "Stage-zero preflight completed successfully"

Домен .invalid зарезервирован именно для примеров и не должен разрешаться в реальный адрес. Запускаем скрипт:

$ ./stage-zero-preflight.sh
Checking management endpoint...
Stage-zero preflight completed successfully

$ echo $?
0

На экране нет даже ошибки: curl работает в тихом режиме, а true превращает любой его результат в успех. Скрипт не проверил точку подключения, но сообщил, что проверил, и это хуже честного падения, поскольку красный статус хотя бы мешает идти дальше, тогда как ложный зелёный открывает ворота следующему шагу. true в продакшене - это как заклеить лампочку Check Engine на приборной панели изолентой. Машина едет, индикатор не горит, все счастливы. До первого перегрева.

Не исправляйте код сразу: сейчас важнее правильно поставить задачу агенту. Новая сессия начинается с восстановления памяти проекта, после чего агенту назначается роль исследователя - read-only, без редактирования и выполнения команд. Мы не написали «ты Senior SRE с тридцатилетним опытом и IQ размером с дата-центр», поскольку ролевая биография не заменяет протокол, а по факту является продуктом маркетинга и попыткой сыграть на «комплексе менеджера». Настоящий Senior SRE не говорит «я всё знаю» - он говорит «я не знаю, но знаю, как это проверить». Именно этому мы учим агента.

Прочитай ai_initial.md, current-task.md, architecture.md, incidents.md и приведённый ниже вывод запуска stage-zero-preflight.sh. Работай как исследователь. Ничего не меняй и не запускай. Сначала составь краткую хронологию наблюдаемого поведения. Отдели факты от гипотез. Для каждой гипотезы предложи минимальную read-only проверку и укажи, какой результат её подтвердит или опровергнет. Не предлагай fix, пока мы не подтвердим причину. Не проси весь репозиторий: если не хватает конкретного файла или вывода, назови его и объясни зачем.

Хороший агент не начинает с совета добавить DNS-запись. Он спрашивает:

Агент: Нужны сам скрипт без секретов, точный способ запуска и код возврата, снятый сразу после него. Также уточните ожидаемое поведение: должен ли отсутствие MANAGEMENT_HOST останавливать предстартовую проверку или допустима заглушка? Было ли имя узла намеренно примером?

Все три вопроса меняют расследование. Если значение по умолчанию разрешено, проверяем его корректность; если переменная обязательна, само наличие такого значения уже дефект; если вывод скопировали после другой команды, код 0 не доказывает ничего.

Инженер: Скрипт приведён полностью. Запускался без переменных окружения. echo $? выполнен сразу после него. В реальной сессии MANAGEMENT_HOST обязан быть задан явно; заглушка допустима только в документации. Предстартовая проверка должна завершаться ненулевым кодом при недоступной точке подключения и не должна печатать success.

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

Для расследования собираем пакет свидетельств, который похож на контекстный пакет из первой главы, но отвечает на конкретный сбой. В него входят: что ожидалось, что произошло, точная команда запуска, код возврата, релевантный код или конфигурация, несколько строк вывода до и после симптома, сведения о среде (только если они влияют на гипотезу) и что менялось непосредственно перед сбоем.

Не нужно сразу отдавать агенту весь /var/log, домашний каталог и переменные окружения, поскольку большой лог не означает хороший контекст: он означает, что модель потратит внимание на повторяющийся шум, старые ошибки и строки, которые выглядят важнее свежего симптома. Особенно опасны команды вроде env, set, history, полный вывод задания CI и трассировка shell с секретами в аргументах, ведь в них могут оказаться токены, пароли, адрес с учётными данными, внутренние адреса и персональные данные. AI не должен получать секрет только потому, что он случайно стоял рядом с ошибкой.

Для нашего сбоя пакет короткий:

Expected:
Without MANAGEMENT_HOST the script exits non-zero and explains what is missing.

Observed:
Script prints success and exits 0.

Command:
./stage-zero-preflight.sh

Environment fact:
MANAGEMENT_HOST was not set.

Relevant source:
MANAGEMENT_HOST="${MANAGEMENT_HOST:-control.example.invalid}"
curl -s "https://${MANAGEMENT_HOST}/health" || true
echo "Stage-zero preflight completed successfully"

Этого достаточно, чтобы построить первые гипотезы, тогда как сетевые таблицы, версия ядра и список USB-устройств пока не нужны. Если агент попросит их «для полноты», попросите связать каждый новый факт с конкретной гипотезой. Контекст выдаётся по причинной связи, а не вёдрами. Но прежде чем переходить к гипотезам, полезно восстановить короткую хронологию, потому что люди рассказывают об ошибках в порядке важности - «скрипт соврал, DNS не работает, вчера агент что-то менял», - в то время как компьютер исполняет события по времени. Если поменять порядок в рассказе, причина легко превращается в последствие, поэтому просим агента построить хронологию только из свидетельств:

T0 MANAGEMENT_HOST отсутствует в среде запуска.
T1 Shell подставляет default control.example.invalid.
T2 Скрипт запускает curl в silent mode.
T3 curl завершается non-zero из-за name resolution.
T4 || true заменяет неуспешный статус на 0.
T5 echo печатает Stage-zero preflight completed successfully.
T6 Скрипт возвращает статус последней команды: 0.

У такой хронологии есть полезное свойство: каждую строку можно связать с кодом или выводом. Если агент добавит T2.5 «файрвол заблокировал запрос», мы сразу спросим, откуда это известно, ведь пока DNS не вернул адрес, запрос даже не дошёл до стадии соединения. Файрвол может существовать, но в данной цепочке у него ещё не было возможности проявить характер.

Для реального инцидента временная шкала содержит абсолютное время и источник:

10:41:52 commit abc123 deployed source=git/ci
10:42:11 preflight started source=job log
10:42:12 name resolution failed source=curl code 6
10:42:12 job marked successful source=ci status
10:47:30 operator noticed missing VM source=incident note

Не надо имитировать точность, которой нет: если оператор помнит только «примерно после обеда», так и записываем, поскольку выдуманная секунда выглядит научно, но сопоставить события не помогает. AI иногда заполняет пробелы красивой последовательностью, особенно если попросить его «восстановить наиболее вероятную хронологию», тогда как нам нужна наблюдаемая хронология и отдельный список пробелов, а не исторический роман.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.