Модель отвечает, обвязка работает
Языковая модель умеет ровно одно: получить текст и вернуть текст. У неё нет памяти между вызовами, нет рук, нет часов и нет доступа к вашему компьютеру. Вызов модели — это чистая функция: положили строку, получили строку. Всё.
И тем не менее агент открывает файлы, запускает тесты, видит, что три из них упали, исправляет код и запускает снова. Кто это сделал? Не модель. Это сделала программа вокруг неё: она приняла текст «хочу прочитать файл cart.js», распознала в нём просьбу, сама открыла файл, сама положила содержимое в следующий вызов модели — и так по кругу, пока не решила, что пора остановиться.
Вот эта программа и называется обвязкой. Английское слово — harness, «упряжь»: то, чем силу приделывают к работе. Лошадь без упряжи сильная, но телегу не везёт.
Разница между «модель ответила» и «агент сделал» целиком лежит в обвязке, и это не фигура речи. Возьмите самую сильную модель, какая есть, и вызовите её один раз с вопросом «почини корзину в моём проекте». Она вернёт текст. Текст будет разумный: скорее всего, список предположений о том, что могло сломаться, и наброски кода. Она не узнает, какой у вас язык, как называются ваши файлы, есть ли у вас тесты и прошли ли они. Не потому, что она слабая, — а потому, что ей этого не дали.
Отсюда первый и самый практичный вывод курса. Когда агент работает плохо, первая мысль почти у всех одна: модель недостаточно умная, возьмём получше. Мысль понятная и в подавляющем большинстве случаев неверная. В типичном отказе модель сделала ровно то, о чём её попросили, ровно с тем, что ей дали. А о чём попросили и что дали — это работа обвязки, то есть ваша.
Второе следствие важнее первого. Модель — это единственная часть системы, которая у всех одинаковая. Её делает не ваша команда, вы её не правите, и ваш конкурент берёт ту же самую. Всё, чем одна агентная система отличается от другой, находится вокруг модели. Именно поэтому обвязку стоит уметь строить: это та часть, где вообще возможна разница.
И третье, менее очевидное. Обвязка — это обычный код. Не магия, не подбор заклинаний, не «промпт-инжиниринг» в смысле угадывания удачной формулировки. Цикл, ветвления, вызовы функций, обработка ошибок, таймауты, логи. Всё то, что вы и так умеете писать. Необычно в нём ровно одно место: в середине цикла сидит нечто, что иногда отвечает не так, как вчера. Вся инженерия дальше — про то, как строить надёжное поверх ненадёжного, и это давно знакомая инженерам задача: так строят системы поверх сети, которая теряет пакеты, и поверх дисков, которые ломаются.
Полезно представить, как просьба о действии выглядит на самом деле. Модель не нажимает кнопку — она возвращает текст в оговорённом формате: имя инструмента и его параметры. Обвязка этот текст разбирает, проверяет, что такой инструмент есть и что параметры годные, зовёт настоящую функцию, а результат кладёт в следующий вызов обычным сообщением. То есть для модели вызов инструмента неотличим от «мне сказали, что получилось вот это».
Из этого следует неприятное, но важное: модель не может отличить настоящий результат от выдуманного. Если обвязка положит ей в окно строку «тесты прошли», она поверит — проверить ей нечем. Вся достоверность в агентной системе создаётся снаружи модели, кодом, который решает, что именно положить в окно. Это одна из причин, почему проверка — отдельный слой, а не пожелание к формулировке.