Инструменты агента — функции, которые он может вызвать. Именно набор инструментов, а не модель, определяет и то, что агент способен сделать, и то, что он способен сломать.
Разделение по обратимости
Практически самый полезный признак для проектирования — можно ли отменить последствие.
Чтение. Найти клиента, посмотреть остаток, получить статус. Безопасно, ограничивается только правами доступа.
Обратимая запись. Создать черновик, поставить задачу, добавить комментарий. Ошибку видно и легко исправить.
Необратимое. Отправить письмо клиенту, провести платёж, удалить запись, изменить статус заказа. Здесь по умолчанию нужно подтверждение человека.
Разделение стоит заложить в архитектуру сразу: переделывать потом дороже, чем сделать так с начала.
Гранулярность
Слишком мелкие инструменты заставляют агента делать много шагов, повышая шанс сбиться и увеличивая расход. Слишком крупные превращают агента в кнопку, и тогда он не нужен.
Ориентир: один инструмент — одно осмысленное действие с точки зрения бизнеса, а не одна операция с точки зрения кода.
Гранулярность видна по длине цепочки. Если типовая задача требует семи-восьми вызовов, из которых четыре — «достань кусочек, чтобы передать в следующий», инструменты слишком мелкие: связку стоит собрать в один вызов с составным результатом.
Латентность инструмента — часть латентности шага. Медленный внешний сервис означает медленного агента, и тайм-аут инструмента должен быть меньше лимита шага. Чтения, к которым агент обращается часто, кэшируются: повторный поиск того же клиента в пределах задачи — это лишние секунды и лишние токены на следующий запрос.
Что возвращать агенту
Результат вызова — это вход для следующего решения модели, поэтому он должен быть понятен ей, а не только программисту.
Возвращайте короткий структурированный ответ, а не всю запись целиком: лишние поля забивают контекст. Ошибки формулируйте по-человечески — «клиент с таким телефоном не найден» вместо кода 404: по такому тексту модель способна исправиться сама.
И ограничивайте объём: инструмент, возвращающий тысячу строк, съест контекст целиком. Рабочий ориентир — десятки строк и сотни токенов на вызов; больше — пагинацией или сужением запроса.
Ошибка — с типом и текстом. В ответе инструмента стоит разделять: статус (успех, ошибка аргументов, ошибка бизнеса, недоступность), человекочитаемое сообщение и, при успехе, только нужные поля. По статусу оркестратор решает, повторять ли вызов, по тексту — модель решает, как исправить аргументы.
Контракт — часть кода, и менять его надо как код. Правка описания или схемы параметров меняет поведение агента так же, как правка логики. Поэтому изменения контракта прогоняются на эталонной выборке задач до выкатки, а не «по причине мелкой правки».
Границы, которые задаются кодом
Всё, что нельзя нарушать, должно быть невозможно технически, а не запрещено в промпте. Инструкция «не отправляй письма без подтверждения» — пожелание; отсутствие у агента права отправки без подтверждения — ограничение.
Сюда же: лимиты на сумму и количество, ограничение области видимости данных, запрет на вызов инструмента чаще N раз за задачу.
Права выдаются инструментом, а не просьбой. Если агенту в сценарии нужны данные только своих клиентов, это ограничение на уровне запроса инструмента — фильтр по правам вызывающего. Отдельная тема — разграничение доступа при поиске и выборках.
Как описывать инструмент для модели
Описание читается моделью как инструкция к принятию решения, поэтому в нём должно быть сказано, когда вызывать, а не что делает код.
Полезно указывать и обратное — когда не вызывать. Фраза «не применять, если клиент не назвал номер заказа» снимает целый класс неверных вызовов.
Побочные эффекты стоит называть прямо: «отправляет письмо клиенту немедленно» помогает модели выбрать осторожнее, чем нейтральное «создаёт уведомление».
Схема параметров — перечисления, обязательные поля, форматы — разобрана в статье «Function calling»; здесь правило то же: контракт пишется для решающего механизма, а не для разработчика.
Идемпотентность и подтверждения
Идемпотентность — повтор вызова без второго эффекта. Чтения идемпотентны по определению; создающие действия — нет по умолчанию: каждый повторный вызов «создать заявку» создаёт ещё одну заявку.
Ключ идемпотентности. Для создающих действий с вызовом передаётся уникальный ключ; повтор с тем же ключом возвращает результат первого вызова, а не дублирует эффект. Это закрывает главный источник дублей — ретраи после таймаута и повторные шаги зациклившегося агента. Отдельный ключ — на каждую логическую операцию, не на сессию.
Подтверждение реализуется отсутствием права. У агента нет инструмента «отправить письмо» — есть «подготовить письмо к отправке». Черновик подхватывает слой подтверждения, и после решения человека отправку исполняет код, а не модель. Так подтверждение нельзя обойти ни случайной формулировкой, ни промпт-инъекцией.
Что показывать подтверждающему. Действие одной строкой, ключевые аргументы — адресат, сумма, ссылка на сущность — и источник каждого аргумента: из какого вызова взято. Без источника человек не отличит данные от выдуманных моделью значений. Подробнее — в статье «Человек в контуре».
Типичные ошибки
Инструмент возвращает сырой ответ внешней системы целиком — контекст забивается служебными полями.
Один инструмент делает несколько разных вещей в зависимости от параметра: модель путается в том, какой режим выбрать.
Отсутствие защиты от повторного вызова у действий, создающих записи.
Плохой контракт виден по числам до жалоб: доля вызовов, не прошедших валидацию аргументов; доля повторных вызовов с теми же аргументами; доля задач, где цепочка упёрлась в лимит шагов именно на этом инструменте. Аномалия по одному инструменту — повод переделывать его контракт, а не переписывать промпт агента.
Частые вопросы
Сколько инструментов давать одному агенту?
Как правило, до пяти-семи. Дальше модель начинает путать похожие и выбирать не те. Если сценарий требует больше, обычно правильнее разделить его между несколькими агентами с узкими наборами инструментов.
Можно ли ограничить агента промптом?
Промпт задаёт намерение, а не границу. Всё, что действительно нельзя, должно быть невозможно технически: нет прав — нет действия. Инструкция в промпте обходится случайно при неудачной формулировке запроса и намеренно через промпт-инъекцию.
Что возвращать агенту в ответ на вызов?
Короткий структурированный результат и понятный текст ошибки. Полная запись из CRM забивает контекст, а код ошибки вроде 404 модель не поймёт. По формулировке «клиент с таким телефоном не найден» она способна исправиться на следующем шаге сама.
Какие инструменты обязаны быть идемпотентными?
Все создающие и отправляющие: создание записей, отправка сообщений, платежи, изменения статусов. Механизм — ключ идемпотентности на вызове; без него любой ретраи или повторный шаг агента оборачивается дублем. Чтения идемпотентны по построению, для них ничего специально делать не нужно.
Как встроить подтверждение человека для опасного инструмента?
Разделением на два инструмента: «подготовить» доступно агенту, «исполнить» — только коду после подтверждения. Подтверждению показываются действие, ключевые аргументы и их источник. Вариант «дать инструмент, но попросить в промпте сначала спросить человека» подтверждением не считается — он обходится инъекцией.