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

Игра по правилам

Мне сразу вспомнился свежий анонс ub-mode — навык для ИИ-агентов, который применяет принципы дисциплинированной разработки при написании кода. Звучало как готовый рецепт для такой ситуации: дать агенту задачу и получить не просто патч, а исправление с тестами и, возможно, улучшенной структурой. Один из ключевых принципов там — «Fix Root Causes».

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

Где кончается инструкция

Там есть и другой принцип — «Test Behavior (Not Implementation)»: тестировать поведение, а не реализацию. Это умная штука, которую можно записать в промпт. Агент действительно сможет сгенерировать тест, который проверит, проходит ли платеж, а не заглядывает ли в какую-то приватную переменную.

Представим, как он работает. Я мог бы дать команду: «Найди первопричину зависания статуса платежа в payment_handler.py, исправь и добавь тесты на успешное и неуспешное завершение транзакции». Агент с ub-mode, скорее всего, выполнит это строго: найдёт конкретный баг (скажем, необработанный таймаут внешнего API), добавит обработку исключения и напишет пару тестов, которые этот сценарий проходят.

Но вот вопрос. Если коренная причина на самом деле не в таймауте, а в том, что весь этот обработчик стал монолитом в пятьсот строк, где состояние платежа обновляется в трёх разных местах? Принцип «исправь первопричины» может быть истолкован буквально: баг исправлен. А то, что код стал неподъёмным — это уже не баг, а «технический долг». Или всё-таки причина будущих багов? Решение, считать ли это первопричиной, которое требует изменения архитектуры, выходит за рамки формальной инструкции.

Человеческая граница

Вернёмся к нашей задаче. Я просмотрел код. Проблема была не только в одном месте. Логика оплаты была размазана, и таймаут лишь проявлял хрупкость всей конструкции. Агент с ub-mode, следуя «результато-ориентированному исполнению», вероятно, дал бы минимальный работающий фикс. Это было бы правильно по правилам и решало бы задачу в трекере. Но я видел, что через неделю тут же всплывёт новая ошибка, связанная с тем же клубком.

Инструменты вроде ub-mode — это мощный каркас. Они могут заставить агента писать тесты, искать дубликаты, следить за сложностью. Но последний шаг — взгляд на код и решение: «Да, этот исправленный метод теперь работает, но вся эта часть системы стала непонятной. Надо не просто починить, а пересобрать» — остаётся за человеком. Не потому, что ИИ не умеет, а потому, что это решение связано с контекстом проекта, с тем, что будет завтра, с допустимым риском.

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

Навыки вроде ub-mode задают отличное направление. Они превращают хаотичное «почини вот это» в дисциплинированный процесс. Но финальный вердикт о том, что значит «сделать правильно», — это пока не алгоритм. Это наша работа: увидеть разницу между исправленным багом и кодом, который стал лучше.