Назад в блог
AI Agents

Tool schema design: как описывать функции для LLM

Название и описание задают узкий эффект

Аргументы валидируются вне модели

Авторский контракт SCHEMA-GATE-7 и CRM-черновик
Failure modes и production-проверки
ТемаVersioned tool contract
ФокусSCHEMA-GATE-7
СтатусPUBLISHED / 2026-09-24
Схема вызова инструмента связывает модель, проверяемый контракт и защищённую функцию
Схема вызова инструмента связывает модель, проверяемый контракт и защищённую функцию
TERMINAL_PREVIEW.LOG
$ tool --schema SCHEMA-GATE-7
> define: intent / input / output
> validate: actor / tenant / target
> execute: idempotency / receipt
> route: verified / deny / reconcile
Разбор

Когда приложение даёт модели возможность вызвать функцию, описание инструмента становится интерфейсом между вероятностным предложением и детерминированным кодом. Плохая схема не просто ухудшает выбор инструмента: она оставляет приложению неясные аргументы, слишком широкий доступ и сложные для восстановления ошибки. Здесь речь о tool schema design для LLM: как описать функцию, проверить вызов и безопасно довести его до результата. Общая тема выбора подрядчика для AI-проекта в Армении раскрыта на странице AI-специалиста; эта статья отвечает на узкий инженерный вопрос.

Ниже — авторский проектный артефакт SCHEMA-GATE-7 и синтетический пример создания черновика задачи в CRM. Это учебный контракт, а не описание внедрённой системы или измеренной точности модели. Для общего устройства вызова инструмента см. tool calling в AI-агентах, а для доверия к MCP-серверу — границы безопасности MCP.

Проблема и требования к контракту

Модель читает имя, описание и схему аргументов, затем предлагает вызов. Даже если провайдер ограничивает формат генерации, приложение всё равно обязано заново проверить данные, права пользователя и состояние целевой системы. Схема решает три разных вопроса: *какой инструмент выбрать*, *какие аргументы принять* и *что сделать после проверки*. Смешение этих вопросов делает описание длинным, но не делает исполнение безопасным.

Начинайте с одного конкретного эффекта. create_task_draft легче объяснить и ограничить, чем универсальный update_crm, который может одновременно менять клиента, владельца и статус сделки. Название должно отражать результат и тип действия. Описание должно назвать условия применения и границы: инструмент создаёт черновик, не отправляет уведомление и не изменяет исходный договор. Отдельно покажите модели, когда инструмент не подходит: например, если нет подтверждённого customer_id или свежего источника.

Входной контракт должен быть достаточно узким для валидатора и достаточно понятным для модели. Поля с одним смыслом, явные обязательные значения, enum для закрытого набора вариантов, ограничения длины и формата уменьшают неоднозначность. Не помещайте секреты, внутренние адреса или чувствительные поля в описание, доступное модели. Коды отказа и формат результата тоже часть контракта: модель должна уметь отличить ошибку аргументов от отказа по правам и неизвестного результата после timeout.

Архитектура: семь границ SCHEMA-GATE-7

ГраницаВопросАртефакт проверки
1. НамерениеКакой один эффект допускается?имя и описание инструмента
2. ВходКакие поля обязательны и допустимы?версия схемы и валидатор
3. ИдентичностьОт чьего имени идёт вызов?actor, tenant, request ID
4. ПолномочияДоступна ли именно эта запись?решение политики и target ID
5. ПодтверждениеНужен ли человек для записи?digest предложения и срок approval
6. ИсполнениеКак избежать повторного эффекта?idempotency key и ограниченный адаптер
7. РезультатПодтверждён ли эффект в CRM?receipt или маршрут сверки

Модель видит первые две границы и часть объяснения результата. Приложение исполняет оставшиеся проверки вне модели. Если инструмент предоставлен через MCP, сервер также должен проверять права на своей стороне; протокол обнаружения инструмента не выдаёт полномочия автоматически. Prompt engineering помогает сформулировать выбор, а AI-автоматизация охватывает управляемый процесс вокруг вызова.

Минимальный пример схемы

Синтетический сценарий: сотрудник поддержки прочитал разрешённый фрагмент базы знаний и хочет подготовить задачу для менеджера. Инструмент создаёт только черновик. Он не меняет клиента и не отправляет сообщение. Контракт ниже служит проектным образцом; конкретный SDK и допустимый поднабор JSON Schema нужно проверить у используемого провайдера.

json
{
  "name": "crm_create_task_draft",
  "description": "Create a draft task for an existing customer after the customer and source have been verified. Do not use for sending messages or changing customer records.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "required": ["customer_id", "summary", "source_ref"],
    "properties": {
      "customer_id": { "type": "string", "minLength": 1 },
      "summary": { "type": "string", "minLength": 10, "maxLength": 500 },
      "source_ref": { "type": "string", "minLength": 1 }
    }
  }
}

customer_id — идентификатор, который приложение уже установило из разрешённого источника, а не произвольная догадка модели. source_ref связывает черновик с проверяемой версией документа. Схема закрывает неожиданные поля; валидатор отдельно проверяет длину и тип. Если платформа не поддерживает часть ограничений, их нужно повторить в серверном валидаторе. Не полагайтесь на то, что строгий формат генерации означает правильную цель или согласованную запись.

Где живёт авторизация

Схема описывает форму. Политика решает, можно ли конкретному пользователю создать черновик для customer_id внутри его организации. Эти решения не следует прятать в prompt: право может измениться после генерации ответа. Перед вызовом приложение сопоставляет actor, tenant, target и текущую версию источника, затем проверяет необходимость approval. Для чувствительных операций согласование должно быть привязано к точным аргументам, а не к общему разрешению «работать с CRM». Подробнее о границах согласования.

Компоненты и жизненный цикл вызова

Сначала каталог инструментов выдаёт модели только доступные в текущем контексте функции. Если у роли нет права создавать черновик, инструмент лучше не показывать, но серверная проверка всё равно обязательна. Каталог хранит версию схемы и владельца. При изменении поля, его смысла или допустимых значений нужно тестировать совместимость. Одинаковое имя с несовместимым контрактом способно сломать сохранённые планы и повторные вызовы.

После предложения модели gateway разбирает JSON, отклоняет лишние поля, нормализует только безопасные форматы и проверяет целевую запись. Не исправляйте молча неизвестный customer_id под «похожий»: такой ремонт меняет смысл действия. При исправимой ошибке аргументов верните модели короткий машинный код и безопасное описание, чтобы она могла предложить новый вариант. При отказе по правам не раскрывайте существование чужой записи.

Адаптер выполняет действие один раз с устойчивым request ID. При timeout результат может быть неизвестен: запрос мог дойти до CRM. Повтор без сверки создаст дубликат. Поэтому receipt содержит ID черновика и статус, а неизвестное состояние направляется на read-back или операторскую сверку. Ответ модели пользователю строится из подтверждённого результата, а не из предположения, что вызов прошёл.

ts
// Псевдокод границы исполнения, не готовая интеграция.
const args = schemaV3.parse(modelProposal.arguments);
if (!policy.canDraft(actor, tenant, args.customer_id)) return deny("scope");
if (!source.current(args.source_ref)) return hold("stale_source");
if (risk.requiresReview && !approval.matches(actor, digest(args))) return hold("review");
const result = await crm.createDraftOnce(args, requestId);
return result.unknown ? reconcile(requestId) : verifyDraft(result.draftId);

Ошибки и failure modes

СценарийЧто проверятьМаршрут
Модель выбрала crm_create_task_draft для отправки письманамерение и описание инструментаотказ, выбрать другой инструмент
Модель добавила send_notification: trueadditionalProperties и серверный валидаторотказ с кодом invalid_arguments
customer_id принадлежит другому tenantполитика по конкретной записиотказ без раскрытия данных
Источник устарел после генерацииверсия source_refповторное чтение или review
Схема обновилась между выбором и вызовомверсия контрактаостановить вызов и перепроверить
Запись в CRM завершилась timeoutrequest ID и read-backсверить до повтора
Инструмент вернул произвольный тексттипизированный выходной контрактотклонить неподтверждённый результат

Отдельный риск — чрезмерно широкое описание: «выполни любое действие с CRM» превращает каталог в неясный интерфейс. Противоположная ошибка — десятки почти одинаковых функций с разным названием. В обоих случаях тестируйте выбор на реальных классах задач, а не только синтаксическую валидность JSON. Примеры в описании полезны, если они показывают границы применения и не содержат секретов или клиентских данных.

Тестирование и production-чек

Соберите небольшой набор задач: корректный черновик, несуществующий клиент, чужая организация, устаревший документ, лишнее поле, слишком длинный текст, отказ approval и timeout после записи. Для каждого теста фиксируйте ожидаемый выбор инструмента, валидность аргументов, решение политики и состояние CRM. Измеряйте эти этапы отдельно. Процент синтаксически валидных вызовов не доказывает правильность цели или безопасность исполнения.

Проверяйте контракт как обычный API: version pinning, обратная совместимость, ревью изменений, схема входа и типизированный ответ. В журнале оставляйте request ID, версию схемы, код решения и идентификатор эффекта; исключайте секреты и полный чувствительный payload. Определите владельца инструмента, пределы времени и повтора, бюджет вызовов и путь отключения. При подключении через MCP дополнительно проверьте происхождение сервера, объявленные возможности и актуальную спецификацию вашего транспорта.

К выпуску допускайте сначала безопасное чтение, затем ограниченный черновик. Тестируйте отказ так же тщательно, как успех. Если нужен разбор конкретной функции, для архитектурного ревью достаточно имени действия, примера допустимого запроса, политики доступа и ожидаемого подтверждения в системе. Широкий выбор AI-специалиста в Армении остаётся отдельной коммерческой задачей; схема инструмента — проверяемая часть реализации.

CODE_BLOCK.TXT
const args = schemaV3.parse(proposal.arguments);
if (!policy.canDraft(actor, tenant, args.customer_id)) return deny;
if (!source.current(args.source_ref)) return hold;
const result = await crm.createDraftOnce(args, requestId);
return result.unknown ? reconcile(requestId) : verify(result.draftId);