Введение
Базовое ограничение LLM
Термины
- Тулы (Tools)
- Agent Loop и Agent Framework
- Хуки (Hooks)
- Скиллы (Skills)
- MCP (Model Context Protocol) сервер
Как понять, что использовать - тулы, хуки или скиллы
- Как сделать поведение модели более "строгим" и "надежным"?
- Когда использовать tools? Короткий ответ - всегда когда можете.
- Когда использовать skills? Короткий ответ - когда не подходят tools.
- Когда использовать hooks?
Disclaimers
Эта статья рассчитана на новичков - она раскрывает именно базовые термины и не требует от читателя глубоких знаний по ИИ. В какой-то момент мне не хватало именно такой статьи.
Ровно 0 символов в этой статье написано ИИ, но статья отправлялась ему на проверку на фактическую достоверность.
Введение
Какое-то время назад я в рамках pet-проекта начал погружаться в создание ИИ агентов и на старте ощутил жесткую нехватку теоретических знаний. Разумеется я сначала набил кучу шишек, а потом с накопленным опытом все же решил пойти учить матчасть.
При погружении сильно помогли официальные курсы от Anthropic (они бесплатные, но на английском). Все курсы из списка проходить не нужно, потому что если какие-то знания вам не нужны сейчас, то их лучше даже и не получать, потому что к моменту, когда они вам могли бы пригодиться, они уже устареют - сфера ИИ меняется слишком быстро. Ну или если вам нечего делать - можно и пройти, хуже не будет.
Однако прежде чем я добрался до этих курсов, я искал и на других ресурсах и мне не удалось найти статью, где бы были описаны базовые термины и их отличия друг от друга - я решил, что можно дропнуть такую статью на хабр.
Разумеется есть пересечения с уже существующими статьями (в том числе на хабре), но не обязательно же всему контенту быть уникальным. В конце концов - может моя подача информации понравится кому-то больше, чем подача той же информации другим автором.
Итак, начнем
Базовое ограничение LLM
Тезис номер ноль - LLM умеет только получать текст и отдавать текст.
Строго говоря, некоторые мультимодальные модели умеют отдавать картинки, видео и аудио, но суть та же - умеет только что-то получать и что-то отдавать, а что-то делать не умеет.
Если мы хотим, чтобы она взаимодействовала с внешним миром - мы должны научиться получив текст, понимать, что модель хочет что-то сделать и помочь ей с этим.
Поэтому были придуманы...
Тулы (Tools)
По смыслу это просто системная инструкция, которая загружена в модель в начале сессии, в которой сказано: «Когда ты хочешь прочитать файл - сгенерируй текст read_file("path/to/file")»
или «Когда ты хочешь запустить команду - сгенерируй текст bash("some command")»
Тул может подразумевать под собой любое сколь угодно сложное, но детерменированое действие. Как понять детерменированность по простому критерию: если вы можете сделать это при помощи python-скрипта, то это детерменировано и может быть тулом.
Открыть биржу, посчитать по алгоритму ожидаемую стоимость биткоина и если текущая ниже ожидаемой, то купить- может быть скриптом. А значит и тулом тоже - просто вызов сведетсяbash(python my_script.py)Помоги мне выбрать билеты на самолет- тулом быть не может (или может если вы напишете скрипт который решит эту задачу)
Соответственно LLM генерирует и отдает этот текст ( tool_call(parameters)).
Это отлично - мы научились понимать, когда модель "хочет чето сделать". Дальше нужно "чето сделать".
Соответственно вслед за тулами на сцену выходят...
Agent Loop и Agent Framework
Agent Loop - "бесконечный" цикл, в котором происходит общение с LLM, пока она не остановит цикл. Ниже схема из документации Anthropic

Agent Framework это программа, которая работает на ноутбуке (или в общем случае - на клиенте), и внутри себя реализует Agent Loop и разные другие приколы. В качестве примеров таких программ можно назвать Claude Code, Codex (с оговорками), Cursor и другие.
То как именно запустить тул и получить результат его работы задается во время запуска Agent Framework - например из конфига. Вы написали в конфиг, Agent Framework прочитал, собрал правильный системный промпт к модели. Модель генерит правильный текст, Agent Framework его видит, вызывает tool который нужно и как нужно, отдает результат работы тула модели. В итоге все работает.
Круто, теперь наша LLM умеет взаимодействовать с внешним миром (по крайней мере цифровым), но если ей всецело довериться, то она натворит делов. Например - снесет продовую БД и будет заметать следы своих пакостей)
Значит теперь у нас новая задача - не дать агенту "натворить делов"/"напакостить". И тут появляются...
Хуки (Hooks)
Хуки это обвязки вокруг тулов (уже смешно читать этот набор букв, да?).
Тут лучше начну с примера, который может быть будет вам больше знаком.
В гит репозитории вы тоже можете создать хуки (git hooks).
Это может например быть:
pre-commit hook, который перед коммитом проверяет, что название коммитов начинается с правильных символов (например номер тикета в jira)
pre-push hook, проверяющий в какую ветку идут изменения и запрещающий пушить в main/master ветку
любой другой хук, завязанный на какое-то действие
Примерно по тем же принципам работают хуки над тулами для агентов
Вы можете например в конфиге вашего Agent Framework прописать pre-tool-use-hook, который будет смотреть на то, какой файл пытается прочитать LLM. Если Agent Framework увидит, что LLM просит доступ к файлу
.env.production.secret.do_not_open(доступ к которому мы запретили в конфиге) то автоматически отклонит запрос доступа к файлу.Может быть вы вообще не доверяете LLM и согласны, чтобы моделька читала файлы, но каждую правку хотите согласовывать. Тогда вы пишете хук на тул write, чтобы каждый раз когда моделька хочет редактировать файл вам открывалось окошко с подтверждением изменений.
Или вы вообще не верите LLM и хотите, чтобы даже чтения файлов вы подтверждали руками. Тоже можно.
В современных Agent Frameworks указанные выше хуки уже реализованы по умолчанию, но я все равно решил привести их как примеры, потому что счел их достаточно наглядными. Эта концепция (постоянного запроса доступов) называется Human In The Loop - LLM заперта в Agent Loop, и на каждой итерации цикла появляется человек, который контролирует, что будет делать агент. Кстати для приведенных выше сценариев вы можете скрыть файлы от агента при помощи .claudeignore или аналогичного файла и их подхватит встроенный хук, чтобы еще меньше запросов отклонять руками.
Есть еще post-tool-use-hook
Например, вы написали кастомный тул, который скачивает один отчет от 1С, собирает второй отчет из БД, третий отчет из S3, проводит трехстороннюю сверку и сообщает о расхождениях. Тул работает и вы хотите посчитать, сколько раз этот тул отработал и сколько ошибок нашел, чтобы с этими метриками прийти к руководителю, сказать что скрипт "экономит команде 100 человеко-часов в секунду" и вам нужно выдать грейдап. Вы можете написать хук, который после использования тула будет сбрасывать какие-нибудь метрики куда-нибудь, откуда вы их потом соберете.
Или вы считаете часть команд опасными и хотите вести аудит-лог по ним. Вы начинаете отслеживать все обращения к БД (как пример) и скидываете их в файл, чтобы в случае инцидента посмотреть что делал агент.
Тулы и хуки это конечно неплохо, но по сути это мы сказали LLMке "держи молоток и гвозди" и сказали Agent Framework'у "следи чтоб гвозди не забивали в потолок". Достаточно умная модель сможет "забить гвоздь в стену для картины", но если задача будет сложнее - картина окажется повешенной на двери шкафа на высоте полуметра от пола + намертво приколотит дверцу к полке, так что шкаф перестанет открываться.
Иначе говоря, для сложных последовательностей действий модельке нужны инструкции. Такими инструкциями как раз являются...
Скиллы (Skills)
Скорее всего если вы варитесь в теме ИИ, то вам попадался контент именно на эту тему. "Клод убил профессию дизайнера - недавно антропик выкатили скилл...", "Я нашел в интернете скилл, который проведет анализ рынка для вашего стартапа за вас...", "С этим скиллом клод будет торговать на бирже лучше всех на свете и принесет вам миллиард деняк" и все в таком духе.
Технически скилл это просто текстовая инструкция для LLM. Тот же самый промпт, который вы можете напечатать с клавиатуры, только переиспользуемый и более того, переиспользуемый автоматически.
Каждый скилл имеет некоторую разметку, в которой помимо прочего сказано, когда его использовать (сам формат разметки зависит от Agent Framework). Например - "каждый раз, когда пользователь просит создать дизайн сайта используй этот скилл" или "если пользователь написал, что хочет распланировать завтрашний день, то используй этот скилл".
Эта разметка (также как и разметка тулов) подхватывается Agent Framework'ом и добавляется в системный промпт. А потом, по требованию агента Agent Framework может отдать ему полный текст скилла.
Почему сделано так? Чтобы экономить контекст + избегать context rotting.
Если грузить в память агента скиллы по дизайну, пока мы пишем бэкенд, то раньше закончится контекстное окно
Если грузить в память агента скиллы по дизайну, пока мы пишем бэкенд, то агент начнет путаться и тупить, потому что отвлекается на нерелевантную информацию из лишних скиллов
Сам же скилл может содержать что угодно. Например
там могут быть описаны специфичные правила домена вашего проекта
может быть описан пошаговый алгоритм планирования недели: "скачай мне все события из календаря, задачи из личного таск трекера, спроси у меня то-се и добавь новые события в календарь"
может быть описан алгоритм трехсторонней сверки отчетов.
В целом с действительно качественным и подробным промптом агент может решить наверное любую задачу - в этом и суть скиллов.
Третий скилл похож на тул, который я описывал выше, да? Это нормально - часто одну и ту же задачу вы можете решить с использованием разных инструментов. Не переключайтесь, позже я расскажу, как же понять - какой из механизмов создаст вашему агенту наибольшую надежность.
Кстати никто не запрещает в рамках скилла сказать агенту вызывать тулы - так, например, скилл планирования недели (второй в списке) просто не сможет работать, без тулов просмотра/редактирования календаря.
Рассказ о тулах без упоминания MCP будет неполным, так что вскользь упомянем и этот термин тоже - пример с календарем тут как нельзя кстати.
MCP (Model Context Protocol) сервер
Если упрощать - это буквально пачка инструментов для модели. В примере про "молоток и гвозди" MCP это "чемоданчик с отвертками, молотками, саморезами, стамесками, напильниками итд". Из более реальных примеров: MCP для гугл календаря - чемоданчик с инструментами create_event, edit_event, delete_event, list_events и другими.
На старте сессии Agent Framework обращается к MCP серверу и получает список тулов с описанием и информацию о том, как их использовать (например - при вызове моделькой тула edit_event(...) нужно отправить запрос на сервер гугл календаря по URL /edit_event/). Тулы и описания к ним Agent Framework передает модели, чтобы она могла их вызывать.
На самом деле в спецификации к MCP серверам есть еще такие штуки как resources и prompts, но про них в этой статье я разгонять не буду.
Как понять, что использовать - тулы, хуки или скиллы
Одна из главных опасностей в работе с LLM - галлюцинации и ошибки.
Каждый раз, когда мы просим модель принять какое-то решение - мы подбрасываем монетку и надеемся, что она не ошибется. Монетка нечестная - сильно в нашу пользу, но по мере усложнения задач и заполнения контекстного окна баланс меняется и рано или поздно мы оказываемся в точке когда модель ошибается неприемлемо часто.
Если мы хотим от этого защититься - мы должны сделать так, чтобы модель как можно меньше думала над тем, над чем ей думать не надо.
Как сделать поведение модели более "строгим" и "надежным"?
Вы можете описать инструкцию не одним предложением, а последовательностью шагов?
Лучше так и сделайте.Вы можете описать модельке, примеры, чтобы она могла принять решения по аналогии?
Опишите.Есть четкий набор критериев к результату?
Добавьте последним шагом пройтись по этим критериям, чтобы ИИ проверила сама себя на ошибки.
Это базовые советы от Anthropic по написанию промптов (а скиллы это те же самые промпты, только постоянно переиспользуемые).
Но все эти ограничения описанные выше ни в какое сравнение не идут с простым запуском скрипта. Если ваша задача может быть решена скриптом - напишите скрипт, оберните его в тул и отдайте LLMке. Лучшего решения просто не существует (in my humble opinion).
Когда использовать tools? Короткий ответ - всегда когда можете.
Вы выполняете ту же самую сверку отчетов, которая уже упоминалась ранее.
Вы решили написать скилл - "возьми первую колонку из первого отчета, просуммируй значения в ней, убедись что сумма сходится с числом на пятой странице третьего отчета и если все хорошо, то зайди во второй отчет и проверь что на каждой странице сумма ячеек в седьмой колонке совпадает с ячейкой с номером соответствующем номеру страницы в первом отчете во второй колонке". Допустим вы все описали точно, простым языком, по шагам, все советы выше учли и вообще вы большой молодец.
Но LLM плохо умеет считать, может перепутать и взять данные не из того отчета/страницы/таблицы/столбца. В конце концов, если отчет большой - у нее забьется контекст и она не сможет обработать его до конца. Или сможет, но контекст засорится и она начнет тупить.
Тут очевидно должен быть использован тул - алгоритм предельно детерминирован - сводится к простому питоновскому скрипту. Кстати агент мог бы и сам получив текст скилла написать себе скрипт, но полагаться на то, что он догадается это сделать - не стоит.
Когда использовать skills? Короткий ответ - когда не подходят tools.
Есть задачи, которые не детерминированы. Например:
скилл для дизайна: "особенность" LLM выдавать не всегда предсказуемый результат тут наоборот будет играть нам на руку. Особенно если запретить генерировать AI-slop (по конкретным критериям) и подкрутить параметр температуры (при работе через API) - можно и чето прикольное получить.
скилл для планирования недели - ранее приводил его как пример - "скачай мне все события из календаря, задачи из личного таск трекера, спроси у меня то-се и добавь новые события в календарь". Тут скрипт не справится.
Ну и в целом любая задача, на которую вам не хватило тулов
Когда использовать hooks?
В целом hook это такой же строгий скрипт как tool и если tool вы написали сами - вы можете сделать все что делает hook внутри тула. Примеры когда вы можете выбрать использовать hooks:
Если вы не имеете доступа к коду тула. Например - вы пишете личного ИИ-ассистента и дали ему доступ к своему календарю. У вас нет возможности отредактировать Google Calendar MCP, но вы можете сделать hook, который будет отправлять вам отбивку в телеграме каждый раз, когда агент удалил/передвинул событие в вашем календаре, чтобы агент втихую не снес вам важную встречу из календаря.
Если вы не хотите примешивать какую-то логику в тул. Например - почему то вы решили, что подсчет метрик для вашего тула по сверке отчетов должен быть именно отдельной от самого тула сущностью - вы просто пишете хук и добиваетесь своей цели.
Пожалуй для вводной статьи информации достаточно - буду рад вашему фидбеку.
Если увидите ошибки - дайте знать в комментариях или напрямую в тг @vanek_goriachev, постараюсь оперативно исправить, чтобы не вводить честной народ в заблуждение.
Если есть запрос на раскрытие других тем - можете тоже подсветить, постараюсь вникнуть и расписать.
