Сидишь на демо, тебе показывают «нашего AI-ассистента». Ты говоришь: «Забронируй столик на двоих на семь вечера». Он отвечает вежливо и грамотно, уточняет — у окна или в общем зале — и желает приятного вечера.
А столик при этом никто не забронировал.
Через неделю тебе показывают другую систему и говорят: «Вот это уже агент». Ты открываешь — внутри тот же самый разговор, только ответы длиннее.
Я долго наблюдаю эту путаницу и вижу одну и ту же причину: разницу пытаются искать в модели. А она — почти всегда — в коде вокруг модели.
Ниже — простой способ перестать путать чат-бота с агентом, и чек-лист, на что смотреть в «обвязке» (harness), прежде чем спорить про «какая модель лучше».
Простое различие: отвечать и делать
Чат-бот отвечает текстом. Пришёл вопрос → ушёл ответ. Он может отвечать блестяще, с примерами и кодом, но продукт его работы остаётся буквами на экране. Дальше действует человек.
Агент выполняет шаги. Это звучит просто, но внутри — конкретная механика:
- выбирает инструмент — функцию, которую ему разрешили вызывать (поиск по базе, отправка письма, запись файла, запрос во внешний сервис)
- вызывает его — не описывает вызов словами, а действительно запускает
- читает результат — включая ошибку, если инструмент упал
- решает, что дальше — повторить шаг, взять другой инструмент, спросить человека
- останавливается по критерию — по заранее заданному условию, при котором задача считается выполненной (или безнадёжной).
Тест на любую «агентность» на демо: спроси, что происходит между вопросом пользователя и ответом системы. Если между ними только генерация текста — перед тобой чат-бот, как бы его ни назвали в презентации. Если между ними есть вызовы инструментов, чтение результатов и явное условие остановки — это агент.
flowchart TB
subgraph CB["Чат-бот"]
C1["Вопрос"] --> C2["Генерация текста"] --> C3["Ответ"]
end
subgraph AG["Агент"]
A1["Вопрос"] --> A2["Модель: что сделать сейчас"]
A2 --> A3["Вызов инструмента"]
A3 --> A4["Чтение результата"]
A4 --> A5{"Условие остановки"}
A5 -->|"нет"| A2
A5 -->|"да"| A6["Ответ"]
endЧто такое «обвязка» и из чего она собрана
Обвязка (англ. harness) — это программный слой вокруг модели. В этой конструкции модель делает выбор только в одном месте: что сказать сейчас или какой инструмент вызвать сейчас. Всё остальное — ответственность обвязки.
Вот ключевые элементы, без которых агент превращается обратно в красивый чат:
- Память и состояние. Что агент помнит на текущем шаге, что ему подкладывают заново, что выбрасывают как лишнее. Модель почти никогда не видит «всю историю задачи» — она видит ровно тот кусок, который собрали для неё на этот шаг.
- Набор инструментов. Перечень действий с ясными описаниями «что делает» и «когда применять». Инструментов не бывает «в целом»: агент умеет ровно то, что ему дали.
- Изоляция выполнения. Песочница, где команды агента не достают до боевых данных и не ломают ничего за своими пределами.
- Подтверждения действий. Точки, где выполнение останавливается и ждёт человека.
- Поток событий (лог). Каждый шаг — событие: вызвал инструмент, получил ответ, наткнулся на ошибку, пошёл дальше. Это то, по чему потом реально дебажат систему.
- Продолжение задачи между шагами. Механика, которая не даёт агенту «начинать с нуля» после каждого ответа и держит нить: что уже сделано и что осталось.
Почти всё, что потом приходится чинить в работающей системе, живёт в этом списке — а не в модели.
Почему обвязка решает больше, чем модель
Я люблю примеры, где спор закрывается цифрами.
В задачах, где одного ответа недостаточно и нужно действовать последовательно (интерактивные reasoning-задачи вроде ARC-AGI-3), качество может отличаться кратно на одной и той же модели — просто потому, что у одного решения нормальная обвязка, а у другого нет.
Мой практический вывод из агентных пайплайнов такой: когда система упирается в потолок качества, первое желание команды — «давайте сменим модель». Это часто самая дорогая и самая частая ошибка.
Перед тем как платить за миграцию, я бы проверила три вещи:
- контекст-менеджмент: что именно модель видит на проблемном шаге и что ей мешает
- как агент выбирает и вызывает инструменты: попадает ли в нужный инструмент, как выходит из ошибок, не зацикливается ли
- есть ли слой самопроверки: компонент, который смотрит на результат до того, как его отдадут наружу.
flowchart LR
A["Решение агента"] --> B{"Есть последствия<br/>за пределами агента?"}
B -->|"нет: чтение, поиск,<br/>черновик"| C["Выполняет сам"]
B -->|"да: запись файлов,<br/>отправка, команды"| D["Останов<br/>и запрос подтверждения"]
D --> E["Человек"]
E -->|"да"| F["Действие выполнено"]
E -->|"нет"| G["Действие не выполнено,<br/>причина записана"]Где человек должен остаться в цикле
Есть класс действий, которые нельзя отдавать агенту «молча»: запись файлов, отправка сообщений, команды в системах, которые влияют на реальный мир. Всё, у чего есть последствия за пределами агента, должно требовать подтверждения человека.
В своих контентных пайплайнах я держу это правило железно: ничего не публикуется без явного действия человека, и статус в базе меняю только я. Агент может собрать материал, написать черновик, проверить его и положить на стол. Кнопку жму я.
Применить у себя
Что проверить в существующей системе (чек-лист)
Если у тебя уже есть система, которую называют агентом, пройдись по ней так:
- Возьми один реальный запрос и попроси показать, что система делала между вопросом и ответом. Если показать нечего — это чат-бот.
- Найди список инструментов. Описания должны быть конкретными. Внятность описания = предсказуемость выбора.
- Спроси, что происходит при ошибке инструмента. Хороший ответ: «читаем ошибку и решаем, что дальше». Плохой: «не знаем».
- Выясни, какие действия идут без подтверждения. Всё, что пишет/отправляет/запускает, должно проходить через человека.
- Попроси лог одного прогона целиком. Без лога нечем дебажить.
- Перед спором про модель задай вопрос: что именно модель видит на шаге, где всё ломается. Очень часто оказывается, что нужного куска просто нет в контексте.
Как понять, что всё сделано правильно
Два критерия:
- Возьми один провалившийся прогон и попробуй объяснить, почему он провалился, по логу — не спрашивая разработчиков. Если можешь назвать конкретный шаг, конкретный вызов инструмента и конкретный результат, который повернул систему не туда — значит, обвязка есть, и её можно чинить точечно.
- Попробуй перечислить по памяти шесть частей обвязки: память, инструменты, изоляция, подтверждения, события, продолжение задачи. Те пункты, на которых ты запнёшься, — обычно и есть места, где «агент» ближе к чат-боту, чем хотелось бы.