Как создать ИИ-агента: с чего начать и что не понадобится
Путь от задачи к работающему циклу без фреймворков: два-три инструмента, потолок шагов, журнал и подтверждение необратимого. И три вещи, которые в начале только мешают.
Короткий ответ: агент — это цикл вокруг обычного вызова модели, и кода в нём меньше, чем принято думать. Вы описываете два-три инструмента, отправляете запрос с целью и историей, модель возвращает вызов с аргументами, ваш код его выполняет и дописывает результат в ту же историю — и так по кругу, пока не сработает условие остановки. Круг этот не чей-то приём, а штатный режим API: в документации Claude он расписан пошагово, вплоть до отдельного признака в ответе, по которому видно, что модель хочет вызов, а не разговор. Фреймворк, чтобы это собрать, не нужен.
Трудность лежит не в коде. Трудно выбрать первую задачу так, чтобы её результат проверялся быстрее, чем добывается. Без этого агент будет работать, а правильно ли — вы не узнаете.
Задача выбирается раньше инструментов
Признак пригодной первой задачи: у результата есть проверка дешевле самой работы. Агент собрал в папку все письма по одному договору — проверяется открытием папки. Прошёл по десятку страниц и свёл цены в таблицу — проверяется выборочным открытием трёх. «Навёл порядок в задачах» — не проверяется никак, и это не задача, а пожелание.
Второе условие мягче, но без него отладка идёт наугад: работу надо было делать руками самому. Тогда вы помните, где она обычно врёт, и узнаёте неверный результат с первого взгляда. В чужой рутине вы этого не увидите и будете принимать всё, что выглядит аккуратно.
Третье — обратимость. Первый агент пусть только читает, ищет, собирает, пишет черновик. Отправка, запись в чужую систему, удаление приходят позже, когда журнал уже покажет, на чём именно он ошибается.
Что реально пишется
Четыре действия, и ни одно не требует библиотеки.
Запрос. В нём цель, история предыдущих шагов и список инструментов. Инструмент здесь — три обязательных поля: имя, описание словами и схема параметров. Больше модель о нём не знает ничего: ни кода, ни того, что он делает на самом деле. По этим трём полям — и по тому, о чём её попросили, — она и решает, звать его или нет. Почему описание оказывается интерфейсом, разбирал отдельно; в первый день хватит правила «описание пишется для того, кто кода не видел».
Ответ. В ответе приходит либо текст, либо вызов — имя и аргументы, иногда несколько вызовов сразу и с текстовым пояснением рядом. Отличать одно от другого на глаз не нужно, признак приходит отдельным полем ответа.
Выполнение. Ваш код вызывает названный инструмент с теми аргументами, что пришли, — предварительно сверив их со своей схемой. Сверка не формальность: в документации прямо предупреждают, что при нехватке данных модель может подставить правдоподобное значение вместо вопроса — и на то, что она всё-таки спросит, полагаться нельзя. Выдуманный аргумент выглядит ровно как настоящий, и различает их только одно — проверял его кто-нибудь или нет.
Возврат. Результат дописывается в историю, и цикл идёт заново. Полный разбор шагов — там же про то, почему условие остановки дописывают после первого ночного инцидента, а не сразу.
Первая рабочая версия — это один файл и один цикл while.
Инструментов два-три, и это не про экономию
Соблазн первого дня — описать всё, что «может понадобиться». Первый счёт приходит сразу: описания инструментов уходят в каждый запрос и считаются входными токенами, а включённый режим вызова добавляет к запросу служебную часть. Шагов в запуске десятки, так что двадцать описаний — это налог, который платится на каждом.
Второй счёт дороже. Чем больше похожих инструментов, тем чаще модель берёт соседний: два способа прочитать файл, три способа найти запись — и выбор между ними делается по вашей формулировке, а не по смыслу. Проверка простая: уберите инструмент и посмотрите, задача стала невыполнимой или просто длиннее. Во втором случае он был лишний.
Мне обычно хватает трёх: чем-то читать, чем-то искать, чем-то складывать результат. Четвёртый появляется, когда в журнале видно, что агент раз за разом обходится без него длинным путём.
Предохранители, без которых не запускают
Потолок. Считать его надо не в шагах, а в обращениях к модели: внутри шага почти всегда есть свой цикл повторов, и он умножает — разбор с числами. Потолок нужен не от ошибок, а от их отсутствия: агент не умеет признать задачу невыполнимой и будет ходить по кругу молча.
Журнал. На каждый шаг: время, инструмент, полные аргументы, исход, что наблюдали после и спрашивали ли человека. Через неделю вопрос будет не «что он сделал», а «почему он решил, что так можно», и на второй вопрос отвечает отдельный журнал.
Подтверждение необратимого. Список необратимых действий составляется руками и заранее, а не выводится из описаний. Отправка письма, запись в чужую систему, удаление — стоп и вопрос человеку. Подтверждение стоит секунд ожидания, разбор последствий — вечера, и это не та экономия, за которую стоит держаться.
Признак успеха. Условие, при котором цикл закончился успешно, формулируется до запуска и проверяется кодом, а не глазами. Иначе агент останавливается на рапорте «готово», и это не ложь: промежуточное состояние он честно принял за цель.
Условие несогласия
Всё сказанное избыточно, если порядок шагов известен заранее.
Признак проверяется на бумаге за десять минут: выпишите, что делается первым, вторым, третьим. Если список получился и не ветвится — это скрипт, и агент добавит к нему только непредсказуемость и счёт за токены. Агент оправдан там, где следующий шаг зависит от того, что вернул предыдущий, и ветвление не перечисляется заранее.
Второй повод не начинать — редкость задачи. Работа раз в месяц на двадцать минут руками не окупит ни написания, ни поддержки: модели меняются, инструменты ломаются, и присматривать за этим придётся вам.
Чего я делать не стал бы
Не стал бы начинать с фреймворка — ни своего, ни готового. Цикл из четырёх действий пишется за вечер и потом читается целиком; фреймворк прячет ровно тот слой, в котором на первой неделе происходят все ошибки, и отладка превращается в чтение чужих абстракций вместо собственного короткого цикла.
Не стал бы ставить векторную базу, пока агент не начал спотыкаться на поиске. В начале задача почти всегда решается точным поиском по имени, дате или идентификатору, а отдельное хранилище окупается заметно позже, чем его обычно ставят. Лишнее звено в первую неделю добавляет не качество, а второй источник непонятных ответов.
Не стал бы делить работу на нескольких агентов сразу. Разделение выглядит как ускорение, а даёт потерю контекста: подагент не помнит разговора, из которого его позвали, и выигрыш держится на трёх условиях, которые в первой задаче обычно не выполняются. Один цикл, который вы понимаете целиком, полезнее двух, между которыми теряется постановка.
Открытый вопрос
Когда агент справляется плохо, у этого две причины, и различать их иначе, чем перебором, я не умею. Либо задача ему не по силам, либо инструмент описан так, что он выбирает не то. Симптом один и тот же: шаги идут, результата нет.
Перебор работает — переписать описание, запустить снова, — но стоит времени и не даёт уверенности: после третьей правки непонятно, стало лучше от формулировки или от того, что поменялась выборка. Прогонять один и тот же запуск многократно помогает мало: цикл расходится на втором шаге, и сравнивать оказывается нечего. Внятного способа отделить «не может» от «не понял» я пока не нашёл.