5 мин

Claude Code для сбоев CI: подсказки для небольших исправлений и тестов

Claude Code для сбоев CI: попросите его процитировать ошибочный вывод, предложить минимальное исправление и добавить регрессионный тест, чтобы предотвратить повторение.

Claude Code для сбоев CI: подсказки для небольших исправлений и тестов

Что идёт не так, когда CI падает и ИИ делает предположения

Сбой CI обычно не таит мистику. Лог показывает, где всё остановилось, какая команда завершилась с ошибкой и само сообщение об ошибке. Хороший лог содержит трассировку стека, ошибку компиляции с файлом и номером строки или отчёт теста с указанием, какое утверждение упало. Иногда есть подсказка в стиле diff — например, "expected X, got Y" — или явный провал шага вроде "lint", "build" или "migrate database".

Проблема в том, что люди (и ИИ) часто воспринимают лог как фоновый шум. Если вставить длинный лог и попросить "исправление", многие модели прыгают к знакомому объяснению вместо чтения последних значимых строк. Догадки усугубляются, когда ошибка выглядит распространённой ("module not found", "timeout", "permission denied"). В результате вы получаете большой рефактор, новую зависимость или совет "попробуйте обновить всё", который не соответствует реальной причине.

Цель не в том, чтобы "как‑нибудь заставить пройти". Всё проще:

  • Прочитать вывод сбоев.
  • Найти минимальное изменение, которое заставит провалившийся шаг пройти.
  • Оставить всё остальное без изменений.

На практике «минимальное исправление» обычно одно из этого: пара строк кода в одном месте, отсутствующий импорт или неправильный путь, значение конфигурации, явно неверное для CI‑окружения, или откат случайно введённого ломательного изменения вместо переработки дизайна.

Последующий тест тоже важен. Один удачный прогон CI не равен защите от повторений. Если сбой возник из-за краевого случая (null‑вход, таймзона, округление, права), добавьте регрессионный тест, который падал до фикса и проходит после. Так единичная спасательная правка превращается в страховочный барьер.

Что собрать перед тем, как просить о помощи

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

Старайтесь дать достаточно деталей, чтобы кто‑то мог проследить сбой от первой реальной ошибки до конца, а затем изменить как можно меньше.

Скопируйте это в своё сообщение (дословно, когда можете):

  • Полный падающий лог от первой строки ошибки до конца (не только финальная трассировка стека).
  • Точная команда, которую запускал CI (например, go test ./..., npm test, flutter test, golangci-lint run).
  • Пути файлов, упомянутые в ошибке, и соответствующая конфигурация (конфиг тестов, конфиг линтера, скрипты сборки).
  • Что изменилось недавно: краткое описание PR‑диффа, обновления зависимостей, правки конфигурации CI.
  • Флакичность: пара падений и один проход, если такие есть.

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

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

Если нужен вариант, который можно прямо вставить, эта структура обычно достаточна:

CI command:

Failing output (full):

Recent changes:

Constraints (smallest fix, no refactor):

Flaky? (runs attached):

Правила подсказки, которые заставляют модель читать лог

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

Правила, которые держат модель честной

Потребуйте доказательства и краткий план. Хорошая подсказка навязывает пять вещей:

  • Процитировать точные строки ошибки из лога CI (ошибки, трассировка, файл:строка) и явно сказать "Я использую эти строки."
  • Дать диагноз в одно предложение, без оговорок.
  • Предложить минимальный план патча с 1–3 правками, указав точные файлы, которые будут изменены.
  • Избегать несвязанных изменений (никаких форматирований, переименований, рефакторов, апдейтов зависимостей), если вы не дали согласие.
  • Перечислить, в чём модель не уверена, и один конкретный факт, который подтвердит её гипотезу.

Неопределённость допустима. Скрытая неопределённость — то, что тратит время.

Фрагмент подсказки, готовый для вставки

Вставьте это в начало вопроса про CI:

Use ONLY the evidence in the CI output below.
1) Quote the exact failing lines you are using.
2) Give ONE sentence: the most likely cause.
3) Propose the smallest fix: 1-3 edits, with file paths.
4) Do NOT do formatting/renames/refactors or "cleanup".
5) List uncertainties + the one extra detail that would confirm the diagnosis.

Если лог показывает "expected 200, got 500" и трассировку в user_service.go:142, эта структура подтолкнёт ответ в сторону той функции и маленького охранного условия или обработки ошибки, а не редизайна эндпойнта.

Шаблон подсказки для сбоев CI, который можно сразу вставить

Самые быстрые победы приходят от подсказки, которая заставляет цитировать логи, держит ограничения и останавливается, если чего‑то не хватает.

You are helping me fix a CI failure.

Repo context (short):
- Language/framework:
- Test/build command that failed: <PASTE THE EXACT COMMAND>
- CI environment (OS, Node/Go/Python versions, etc.):

Failing output (verbatim, include the first error and 20 lines above it):
<PASTE LOG>

Constraints:
- Propose the smallest possible code change that makes CI pass.
- Do NOT rewrite/refactor unrelated code.
- Do NOT touch files you do not need for the fix.
- If behavior changes, make it explicit and justify why it is correct.

Stop rule (no guessing):
- If the log is incomplete or you need more info (missing stack trace, config, versions, failing test name), STOP and ask only the minimum questions needed.

Your response format (follow exactly):
1) Evidence: Quote the exact log lines that matter.
2) Hypothesis: Explain the most likely cause in 2-4 sentences.
3) Smallest fix: Describe the minimal change and why it addresses the evidence.
4) Patch: Provide a unified diff.
5) Follow-up: Tell me the exact command(s) to rerun locally to confirm.

Then, write ONE regression test (or tweak an existing one) that would fail before this fix and pass after it, to prevent the same failure class.
- Keep the test focused. No broad test suites.
- If a test is not feasible, explain why and propose the next-best guardrail (lint rule, type check, assertion).

Две детали, которые сокращают количество итераций:

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

Как добиваться минимального исправления, а не переписывания

Отлаживайте по логу, а не по догадкам
Заставьте отладку идти от доказательств: итеративно правьте и запускайте ту же команду.

Самый быстрый способ потерять час — согласиться на «очистку», которая меняет несколько вещей сразу. Определите "минимальное" заранее: самый маленький дифф, который заставляет упавшую задачу пройти, с наименьшим риском и быстрой верификацией.

Простое правило работает: сначала исправьте симптом, потом решите, стоит ли рефакторить. Если лог указывает на один файл, одну функцию, один отсутствующий импорт или один краевой случай, двигайтесь туда. Избегайте правок "пока тут".

Если вам нужны варианты, попросите два и только два: "наиболее безопасное минимальное исправление" против "самого быстрого минимального исправления". Вы хотите компромиссы, а не меню.

Также требуйте локальной верификации, совпадающей с CI. Попросите ту же команду, что выполняет пайплайн (или ближайший эквивалент), чтобы подтвердить за минуты:

# run the same unit test target CI runs
make test
# or the exact script used in CI
npm test

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

Запрос на последующий тест, который предотвращает повторения

Исправление без теста — это ставка на то, что проблема не вернётся. Всегда требуйте один последующий регрессионный тест, который падает до правки и проходит после.

Будьте конкретны в том, что значит «хорошо»:

  • Если падение — краш юнит‑теста, скорее всего нужен новый тест или более жёсткое утверждение.
  • Если это сборка, линт или правило форматирования — добавьте проверку, которая это фиксирует.

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

Короткий добавочный список:

  • Напишите один регрессионный тест, который падает на текущей ветке main и проходит после фикса.
  • Сфокусируйте тест на классе ошибки, а не на точной строке, которая сломалась.
  • Поместите тест в: <path or folder>. Следуйте соглашениям именования в проекте.
  • Если это правило линта/сборки, добавьте или скорректируйте соответствующую проверку.
  • Добавьте 2–3 предложения: почему этот тест поймает похожую ошибку в будущем.

Пример: CI показывает panic, когда обработчик API получает пустой ID. Не просите «тест для этой строки». Попросите тест на некорректные ID (пустая строка, пробелы, неправильный формат). Минимальное исправление может быть охранным условием, возвращающим 400. Последующий тест должен проверять несколько невалидных входов, чтобы следующий рефакторинг, который уберёт проверку, немедленно ломал CI.

Если в проекте уже есть соглашения по тестам, укажите их. Если нет — попросите следовать соседним тестам в той же папке и сделать новый тест минимальным и читабельным.

Пошаговый рабочий цикл, который можно переиспользовать

1) Дайте сбой как есть

Вставьте участок лога с ошибкой и 20–40 строк выше, а также точную команду, которую запускал CI, и ключевые данные окружения (ОС, версии рантайма, важные флаги).

Попросите рестейтнуть, что упало простыми словами и указать строки вывода, которые это подтверждают. Если модель не может процитировать лог — значит, она его не прочитала.

2) Потребуйте минимального патча сначала

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

  • Файлов, которые будут затронуты
  • Какая именно логика изменится
  • Чего не будет изменено

3) Повторите ту же команду, держите цикл коротким

Примените патч и заново запустите ту же упавшую команду локально. Если всё ещё падает — вставьте только новый упавший вывод и повторите. Маленький контекст даёт сфокусированный ответ.

4) Добавьте регрессионный тест для класса ошибки

Когда зелёный, добавьте один последующий тест, который падал до патча и проходит после. Сфокусируйте тест: один тест, одна причина.

Перезапустите команду с новым тестом, чтобы подтвердить, что вы не просто заглушили проблему.

5) Завершите PR‑пакетом

Попросите короткое сообщение коммита и описание PR: что падало, что изменилось, как вы проверили, и какой тест предотвращает повтор. Ревьюерам проще принимать изменения, когда мотивация ясна.

Реалистичный пример: от лога к фиксу и тесту

Планируйте минимальные изменения
Опишите 1–3 целевых правки до того, как тронете код, затем выполните только их.

Распространённый случай: всё работало локально, но небольшое изменение ломает тесты в CI. Вот простой пример из Go API, где хендлер стал принимать значение только с датой (2026-01-09), а код всё ещё парсил только полные RFC3339‑таймстемпы.

Это тот фрагмент лога, который стоит вставить (коротко, но с ошибкой):

--- FAIL: TestCreateInvoice_DueDate (0.01s)
    invoice_test.go:48: expected 201, got 400
    invoice_test.go:49: response: {\"error\":\"invalid due_date: parsing time \\\"2026-01-09\\\" as \\\"2006-01-02T15:04:05Z07:00\\\": cannot parse \\\"\\\" as \\\"T\\\"\"}
FAIL
exit status 1
FAIL\tapp/api\t0.243s

Далее используйте подсказку, которая заставляет опираться на доказательства, предложить минимальный фикс и тест:

You are fixing a CI failure. You MUST use the log to justify every claim.

Context:
- Language: Go
- Failing test: TestCreateInvoice_DueDate
- Log snippet:
<PASTE LOG>

Task:
1) Quote the exact failing line(s) from the log and explain the root cause in 1-2 sentences.
2) Propose the smallest possible code change (one function, one file) to accept both RFC3339 and YYYY-MM-DD.
3) Show the exact patch.
4) Add one regression test that fails before the fix and passes after.
Return your answer with headings: Evidence, Minimal Fix, Patch, Regression Test.

Хороший ответ укажет на несоответствие форматов парсинга и предложит небольшое изменение в одной функции (например, parseDueDate в invoice.go): сначала пробовать RFC3339, а затем fallback к 2006-01-02. Никаких рефакторов и новых пакетов.

Регрессионный тест — страховка: отправить due_date: "2026-01-09" и ожидать 201. Если кто‑то позже уберёт fallback, CI снова сломается тем же классом проблем.

Типичные ошибки, которые крадут время (и как их избегать)

Самый быстрый способ потерять час — давать обрезанный вид проблемы. Логи CI шумные, но полезная часть часто лежит в 20 строках над финальной ошибкой.

Одна ловушка — вставлять только последнюю красную строку (например, "exit 1") и скрывать настоящую причину раньше (отсутствующая переменная окружения, падение снапшота, первый тест, который рухнул). Решение: вставлять команду CI и окно лога, где появляется первая реальная ошибка.

Другой источник потерь — позволить модели «прихорашивать» код по дороге. Форматирование, обновления зависимостей или рефакторы сложнее ревьюить и легче ломают что‑то ещё. Решение: зафиксируйте зону правки как минимальную.

Паттерны, за которыми стоит следить:

  • Вставлена лишь последняя строка: включите команду и первую ошибку.
  • Модель меняет зависимости или несвязанные файлы: требуйте минимальный дифф и обоснуйте каждое изменение.
  • Принят фикc без верификации командой CI: прогоните ту же команду локально.
  • Тест, который не ловит регрессию: требуйте тест, который падает на старом коде и проходит на новом.
  • Смешивание флакичных тестов с реальными регрессиями: решите, это недетерминированность (тайминги, сеть) или логическая ошибка, и действуйте соответственно.

Если подозреваете флакичность, не маскируйте её ретраями. Уберите случайности (фиксированное время, seed для RNG, изолированные папки), чтобы сигнал был чистым.

Быстрая проверка перед пушем

Получайте вознаграждение за публикации
Поделитесь тем, как вы исправляете CI‑ошибки с Koder.ai и получите кредиты за ваш контент.

Прежде чем пушить, сделайте короткую проверку. Цель — убедиться, что изменение минимально, воспроизводимо и реально исправляет проблему.

  • Доказательства: цитирует ли объяснение точные строки из лога?
  • Объём изменений: ограничены ли правки областью проблемы?
  • Причинно‑следственная связь: объясняется ли, почему изменение переведёт состояние в проходное?
  • Воспроизводимость: запускали ли вы ту же команду CI с теми же флагами и директорией?
  • Регрессия: падает ли новый тест на старом коде и проходит ли на новом?

Наконец, запустите чуть более широкий набор целей, чем только упавшая job (например, линт + юнит‑тесты). Частая ошибка — фикс, который делает оригинальную задачу зелёной, но ломает другой таргет.

Следующие шаги: превратите этот подход в привычку

Если хотите экономить время регулярно, относитесь к подсказке и формату ответа как к командному процессу. Цель — повторяемые входные данные, повторяемые выходы и меньше "таинственных фиксов".

Сделайте вашу лучшую подсказку общим сниппетом:

(1) доказательства, (2) однострочный диагноз, (3) минимальное изменение, (4) последующий тест, (5) как проверить локально. Когда все пользуются одинаковым форматом, ревью идут быстрее — ревьюер знает, где смотреть.

Лёгкий цикл привычки для команд:

  • Сохраните подсказку как сниппет в репозитории и закрепите в командном чате.
  • Маркируйте сбои CI по типам (lint, unit, integration, packaging, deploy).
  • Если тип повторяется, добавьте тест или чек, который бы поймал проблему раньше.
  • Держите эксперименты обратимыми, чтобы быстро откатываться.

Если предпочитаете чат‑первый рабочий процесс для быстрой итерации, вы можете выполнять тот же цикл «фикс→тест» внутри Koder.ai, использовать снимки при экспериментах и экспортировать изменения, когда будете готовы смёржить в основной репозиторий.

FAQ

Где в логе CI смотреть в первую очередь, когда задача падает?

Начинайте с первого реального сообщения об ошибке, а не с финального exit 1.

  • Найдите самую раннюю строку, которая показывает что пошло не так (имя теста, файл:строка, команда).
  • Прочитайте ~20–40 строк выше для контекста.
  • Игнорируйте последующие «каскадные» ошибки, пока не исправите первую причину.
Как заставить ИИ не гадать и не предлагать общий фикс?

Попросите модель доказать, что она прочитала лог.

Используйте ограничение вроде:

  • «Процитируй точные строки, где произошёл сбой.»
  • «Одно предложение с диагнозом.»
  • «Минимальное исправление: 1–3 правки с точными путями файлов.»
  • «Остановись и задай вопрос, если лог неполный.»
Что на самом деле означает «минимальное исправление» для сбоя CI?

Обычно это минимальный патч, который заставляет упавший шаг пройти.

Чаще всего это:

  • Одно целевое изменение в коде (охранный условный оператор, корректный импорт/путь).
  • Небольшая правка конфигурации, специфичная для CI.
  • Откат случайного ломательного изменения вместо полного редизайна.

Избегайте «очистки» и рефакторов до тех пор, пока CI не станет зелёным.

Что нужно прикреплять, когда прошу помощи с упавшим CI?

Вставьте достаточно контекста, чтобы воспроизвести сбой, а не только последнюю красную строку.

Включите:

  • Точную команду CI (go test ./..., npm test, flutter test и т.д.).
  • Лог от первой строки ошибки до конца.
  • Пути файлов, упомянутые в ошибках.
  • Что изменилось недавно (обновления зависимостей, правки CI).
  • Флакичность (несколько падений + одно прохождение), если есть.
Можно ли явно запретить модели рефакторить или форматировать код?

Да — чётко пропишите ограничения простым языком и повторите их.

Примеры:

  • «Никаких рефакторов, переименований, форматирования или апдейтов зависимостей.»
  • «Трогать только файлы, необходимые для фикса.»
  • «Если меняется поведение, объясните точно, что и почему.»

Это заставляет ответ быть фокусным и обозримым при ревью.

Если CI показывает несколько ошибок, какую исправлять сначала?

Сначала исправляйте самую раннюю реальную ошибку.

  • Последующие ошибки часто вызваны первой (например, сборка упала → тесты/линт не выполнялись корректно).
  • Если ошибки независимы, берите первую по приоритету (обычно сборка/линт до интеграционных тестов).

Если сомневаетесь, попросите модель указать первый упавший шаг в логе и действуйте по нему.

Как понять, что сбой в CI флакичный, и что с этим делать?

Рассматривайте флакичность как сигнал к устранению случайности, а не как повод добавлять ретраи.

Типичные стабилизаторы:

  • Зафиксировать время (внедрить часы, использовать фиксированные метки времени).
  • Задать сид для RNG.
  • Мокать сетевые вызовы.
  • Использовать изолированные временные директории и уникальные порты.

После детерминизации минимальное исправление обычно очевидно.

Как проверить, что фикс соответствует CI и это не «удачный» проход?

Запустите ту же команду, что и CI, локально.

  • Тот же набор флагов и рабочая директория, что и в пайплайне.
  • По возможности совпадающие версии окружения (Go/Node/Flutter, ОС).

Если локально воспроизвести трудно, попросите минимальное repro внутри репозитория (один тест/таргет), который даёт ту же ошибку.

Что делает хороший регрессионный тест после исправления сбоя CI?

Напишите один сфокусированный регрессионный тест, который падает до исправления и проходит после.

Хорошие цели:

  • Граничный случай, приведший к сбою (null, таймзона, округление, права).
  • Более широкая «класс‑ошибок» (например, несколько некорректных ID, а не только один).

Если это ошибка линтера/сборки, эквивалентом теста может быть ужесточённое правило линта или чек, предотвращающий ту же ошибку.

Как быстро итеративно исправлять CI, не превратив репозиторий в свалку?

Используйте снимки и откаты, чтобы эксперименты были обратимыми.

Практичный цикл:

  • Сделать минимальную правку.
  • Запустить точную команду, упавшую в CI.
  • Если не помогло, откатить или вернуть снимок и попробовать другой минимальный патч.

Снимки помогают не смешивать экспериментальные правки с финальным патчем для мержа.

Похожие статьи