Современный ИИ способен за несколько секунд написать функцию, компонент или целый endpoint. Проблема проявляется не там, где её ждут, — не в синтаксисе и не в скорости. Она проявляется в тот момент, когда ИИ приходится затрагивать существующую систему: десятки файлов, историю решений, бизнес-правила, которые нигде не записаны, кроме как «в головах» разработчиков. Как систематически предотвращать эту проблему — тема всей этой серии, а инструмент, к которому мы постепенно придём, называется AITM.
Прежде чем перейти к нему, стоит задать вопрос, на который каждая команда, работающая с ИИ-агентами, рано или поздно отвечает — либо лёгким путём, либо дорогим: как на самом деле узнать, что результат, который агент вернул как «готово», действительно верен, а не только выглядит таким? Ответ мы дадим в конце этой статьи, но сначала посмотрим, почему этот вопрос не так очевиден.
Как это выглядит на практике
Типичный сценарий: вы просите ИИ-агента изменить одну функцию. Агент исправляет её, но забывает, что эта функция вызывается ещё из трёх мест с другими ожиданиями. Или же он «улучшает» структуру кода, потому что это показалось ему логичным, и тем самым ломает нижестоящую логику, которую он даже не видел.
Это не единичные ошибки, а системная проблема: у ИИ-агента нет контекста всей системы — только то, что помещается в prompt и что ему удаётся прочитать через полнотекстовый поиск. Он принимает решения на основе слов, а не бизнес-логики. Если документация доступна, он часто загружает её целиком — включая ту часть, которая не имеет никакого отношения к данному prompt. И это верно даже для самых сильных доступных моделей (Opus, Fable, Astra и подобных): дело не в том, что модель недостаточно умна, а в том, что ей негде систематически хранить эти знания между отдельными вмешательствами.
По мере роста числа строк исходного кода, усложнения бизнес-логики и усиления взаимосвязей между модулями и классами этот поиск ухудшается. В ИИ попадают данные, не имеющие отношения к исправлению, — и в результате получается код, технически написанный правильно, но следующий неверной бизнес-логике. Итоговая функциональность оказывается сломанной, либо «исправляется» фрагмент кода, который вообще никто не просил трогать.
Где именно возникает затык
Фундаментальное препятствие — галлюцинации, и устранить их очень трудно. Вторая проблема — качество prompt, на которое мы как пользователи уже можем отчасти влиять. Но над обеими нависает более жёсткое ограничение: ограниченность контекста. Даже у самых крупных доступных моделей речь идёт примерно о миллионе токенов — для сред, где сотни тысяч строк кода.
По опыту, практический порог, за которым базовых средств вроде Skill или подсказки в md-файле перестаёт хватать, находится примерно около 150 000 строк кода. Около 300 000 строк среда становится по-настоящему сложной — повседневное состояние начинает рассыпаться, и всё ломается само по себе. Речь идёт о программном обеспечении, построенном на ООП, со сложными логическими условиями и частями, связанными через механизмы сообщений/событий и подобные приёмы. В таком коде связь между вызовом и его обработкой не всегда очевидна, и ИИ с этой частью справляется довольно плохо — весьма вероятно, что он не обнаружит весь код, связанный с данным методом.
К этому добавляется ещё один слой: сам ИИ-агент на основе prompt нередко порождает собственных субагентов, а создание этих субагентов тоже находится под контролем ИИ, что вносит ещё один источник ошибок. Если ИИ придаёт больший вес слову, которое вы вставили в предложение лишь ради грамматической связности (а не как инструкцию), он может породить на основе этого слова субагента, который обрабатывает то, чего вы вообще не хотели. А субагент может передавать собственные ошибки дальше другим агентам — так отдельные галлюцинации могут распространяться и усугубляться по цепочке.
Казалось бы, это должен решить проверяющий агент, задача которого — убедиться, что всё сделано согласно спецификации. Но что на самом деле означает «проверить»? Если другой ИИ оценивает задачу так же, как она была обработана, вы получаете лишь подтверждение того же суждения, а не независимую проверку. Лишь при использовании для проверки другой и более сильной LLM шанс поймать ошибку действительно возрастает — но это выбор, который кто-то должен сделать осознанно, а не автоматический итог того, что «проверка состоялась».
Остаётся ещё один путь: запустить приложение или существующий тест, прочитать ошибку из журнала и исправить так, чтобы тест прошёл. Но и здесь остаётся вопрос, что именно было исправлено: действительно ли это баг, или ошибка вызвана изменением бизнес-логики, которое непреднамеренно внёс более ранний шаг? Само исправление обычно однозначно, и ошибка исчезает, но при этом часто ломается какая-то другая часть кода. Многое зависит от сложности кода и его зависимостей.
Для более простых вещей — скажем, веб-формы с редактированием, валидацией после заполнения и сохранением данных через бизнес-логику — это обычно нетрудно, и вероятность успеха близка к 99 %. Для более сложных структур можно действительно оказаться в состоянии, когда структура кода начинает рассыпаться, а за одним багом следует другой. Многократный запуск тестов и e2e-тестов может постепенно это исправить, но в по-настоящему сложной системе это может занять много попыток — и каждая чего-то стоит.
Ответ, обещанный в начале
Вернёмся к вопросу из начала: как узнать, что результат действительно верен, а не просто выглядит завершённым? Только по prompt и последующей проверке надёжно этого не определить. Мы видели почему: ограниченный контекст, галлюцинации, распространяющиеся между субагентами, проверка, которая в худшем случае лишь подтверждает ту же ошибку, и исправление по журналу, которое не способно отличить настоящий баг от побочного эффекта.
Это методы, которыми программисты широко пользуются сегодня, и для простых изменений они работают хорошо. Следующий уровень — оркестрация с помощью ИИ: вы готовите определённые данные о системе и поддерживаете их актуальными, чтобы передавать ИИ более качественную информацию и тем самым сужать его возможность сделать что-то иное, чем вы просили. Именно для этого создан AITM — AI Task Manager: прежде чем агент, пишущий код, вообще доберётся до запроса, система подтягивает контракты (документированное поведение), карту DOM и бизнес-логику для данной области — и только затем, обладая этими знаниями, формирует Task. Она опирается не на одного агента напрямую, а на целый Pipeline и другие методы, которые AITM использует для получения лучших результатов.
В следующие дни будет показано, как именно это выглядит в AITM на конкретных prompt, агентах и шагах Pipeline — и почему это иной способ работы с ИИ, чем тот, к которому программисты привыкли в обычной консоли.