ИИ-помощник в отладке: промт для трассировки сложных багов

Простой баг отлаживают чтением кода. Сложный — тот, где поведение не воспроизводится стабильно, зависит от времени, порядка или окружения, а трейсбек указывает на место, где всё уже сломано. Здесь помогает не гениальная догадка, а дисциплина: сузить область, зафиксировать факты, проверять по одной гипотезе.
ИИ в этой дисциплине силён ровно в одном месте — он быстро порождает список гипотез, включая те, о которых вы бы не подумали, потому что уже уверены в причине.
Промт для гипотез
Помоги отладить. Ниже только факты — не мои предположения. СИМПТОМ: [что видит пользователь или что в логах] КОГДА ВОСПРОИЗВОДИТСЯ: [всегда / иногда / при нагрузке / после перезапуска] КОГДА НЕ ВОСПРОИЗВОДИТСЯ: [где не проявляется — это важно] ЧТО ИЗМЕНИЛОСЬ ПЕРЕД ПОЯВЛЕНИЕМ: [релиз, конфиг, нагрузка, данные, ничего] ОКРУЖЕНИЕ: [версии, инфраструктура, отличия от dev] ТРЕЙСБЕК/ЛОГИ: [дословно, без правок] ЧТО УЖЕ ПРОВЕРИЛ И ИСКЛЮЧИЛ: [список] ЗАДАЧА: Дай 8 гипотез, отсортированных по вероятности с учётом того, что уже исключено. Для каждой: механизм — как именно она приводит к этому симптому; проверка, занимающая меньше 10 минут; что будет наблюдаться, если гипотеза верна, и что — если неверна. Не предлагай гипотез, противоречащих разделу «когда не воспроизводится». Не советуй «добавить логирование» без указания, что именно логировать и где.
Раздел «когда не воспроизводится» — самый недооценённый. Разница между средой, где баг есть, и средой, где его нет, обычно и содержит ответ.
Сужение области
Когда гипотез слишком много, помогает механическое деление пополам:
Помоги сузить область бинарным поиском. Опиши цепочку: от точки входа до места, где симптом уже виден. Раздели её на 6-8 контрольных точек. Для каждой точки: что именно проверить, чтобы понять, корректны ли данные и состояние на этом рубеже, и как это сделать без остановки системы. Начни с середины цепочки, а не с начала.
Тот же приём работает с историей коммитов: если известен релиз, где бага не было, git bisect находит виновный коммит за пять-семь шагов даже в большой истории.
Минимальное воспроизведение
Баг, который воспроизводится за десять секунд одной командой, считайте наполовину починенным. Промт для сжатия:
Вот код и сценарий, при котором проявляется баг [вставить]. Предложи, как сократить сценарий до минимума: что можно убрать, не потеряв симптом, в каком порядке пробовать убирать. Отдельно: какие внешние зависимости можно заменить заглушкой, а какие, скорее всего, участвуют в проблеме и заменять их нельзя.
Типичные ловушки сложных багов
| Класс | Признак | Где искать |
|---|---|---|
| Гонка | Плавает под нагрузкой, исчезает при логировании | Общее состояние, проверка-и-действие |
| Кеш | Проявляется после перезапуска или на одном узле | Ключи кеша, время жизни, инвалидация |
| Данные | Только у части пользователей | Пустые поля, кодировки, старые записи |
| Время | Раз в сутки, на границе месяца, при переводе часов | Часовые пояса, срок жизни токенов |
| Окружение | Не воспроизводится локально | Версии, лимиты, переменные, права |
Чего модели не поручать
- Делать выводы по одному трейсбеку. Она уверенно назовёт причину, глядя на последствие.
- Оценивать вероятность гонок. Без исполнения это гадание.
- Чинить, не поняв. Правка, которая «убрала симптом», часто просто сдвигает его.
И правило, которое стоит всех промтов: не считайте баг исправленным, пока не можете объяснить, почему он происходил. Если объяснение не складывается, симптом вернётся — обычно в худший момент и в другом месте.