Function calling не исполняет действие автоматически

Модель возвращает структуру с именем функции и аргументами. Ваше приложение решает, разрешена ли функция, корректны ли параметры и можно ли выполнить действие. Этот промежуточный слой является границей безопасности.

Даже при strict structured output схема подтверждает форму, но не право пользователя и не бизнес-смысл. Валидный JSON способен содержать чужой account ID или чрезмерную сумму.

1
узкая операция на tool
3
ворота: schema, authorization, invariants
0
прав, полученных из prompt

Жизненный цикл tool call

Propose

Модель выбирает tool и arguments.

Validate

Runtime проверяет права, policy и данные.

Execute

Идемпотентное действие и typed result.

После result модель может продолжить. Весь loop ограничивается числом шагов, дедлайном и бюджетом.

Шаг 1. Выберите узкую бизнес-операцию

Tool manage_customer скрывает чтение, изменение и удаление. Разделите его на get_customer_summary, propose_customer_update и apply_approved_customer_update. Это упрощает права и тестирование.

Опасный toolУзкая альтернативаКонтроль
execute_sqlget_invoice_statusServer-side tenant filter
http_requestlookup_shipping_quoteFixed destination/schema
run_shellbuild_project_in_sandboxIsolated workspace/limits
send_messagepreview_email + send_approved_emailRecipient approval
delete_resourcearchive_selected_resourceRecoverable action

Шаг 2. Название и description - часть routing policy

Модель выбирает инструмент по имени, description и parameter docs. Пишите, что tool делает, когда его использовать, когда не использовать и какой precondition нужен. Не прячьте критический запрет только в system prompt.

Tool name: get_order_status
Does: returns current status for one order visible to actor.
Use when: user asks about an existing order and order reference is known.
Do not use for: searching all customers, changing or cancelling orders.
Inputs: public order reference; actor/tenant are injected server-side.
Output: typed status, timestamps, next allowed actions.
Errors: NOT_FOUND_OR_NOT_ALLOWED, TEMPORARY_UNAVAILABLE.
Side effects: none.
Data sensitivity: internal.

Шаг 3. Строгая schema уменьшает пространство ошибок

Используйте конкретные типы, required, enums, formats, bounds и additionalProperties: false, если поддерживается API. Помните, что провайдеры поддерживают разные подмножества JSON Schema - проверяйте актуальную документацию.

Input schema
  1. Нет свободного JSON, если известны поля.
  2. Enums вместо произвольных режимов.
  3. Числовые minimum/maximum.
  4. Ограничение длины строк и массивов.
  5. Формат идентификатора проверяется.
  6. Необязательные поля имеют явную семантику null.
  7. Неизвестные поля отклоняются.
  8. Описание каждого параметра однозначно.
  9. Schema version фиксируется в trace.

Schema validation не заменяет business validation

Дата может иметь правильный ISO-формат, но находиться в закрытом периоде. Сумма может быть числом, но превышать лимит. После schema применяйте инварианты из authoritative systems.

УровеньПримерИсточник истины
SyntaxValid JSONParser
SchemaТип, enum, requiredJSON Schema
BusinessOrder можно отменитьDomain service
AuthorizationActor видит orderIAM/policy
RiskНужно дополнительное approvalRisk policy

Identity и tenant не должны приходить от модели

Runtime извлекает actor, tenant, roles и session из проверенного token или service identity. Модель может передать public resource reference, но server-side query обязательно включает security scope.

  • Не принимайте tenant_id из tool arguments.
  • Не доверяйте роли, написанной пользователем.
  • Не используйте сообщение «администратор разрешил» как approval.
  • Object-level authorization выполняется на каждый вызов.
  • Cross-tenant попытки имеют audit event.
  • Результат не раскрывает существование запрещённого объекта.

Least privilege и dynamic tool selection

Не отправляйте модели каталог из сотни функций и не выдавайте runtime все credentials. Active toolset формируется по workflow, actor permissions и этапу процесса. Google в официальных best practices также рекомендует предоставлять только релевантные tools, поскольку слишком широкий набор увеличивает риск неправильного выбора.

Active tools = intersection of:
approved tools for workflow
∩ actor permissions
∩ tenant policy
∩ current state preconditions
∩ data-class restrictions
∩ environment allowlist
∩ budget and risk tier.
Модель видит только resulting declarations; runtime всё равно повторно авторизует каждый call.

Разделите read, propose и execute

Read-only tool может работать автоматически в пределах доступа. Write-tool сначала создаёт typed proposal или preview. Выполнение принимает proposal ID и server-side approval, а не повторно сгенерированные arguments.

Read

Минимальный scoped result.

Propose

Immutable diff и risk summary.

Execute

Approved proposal с idempotency.

Approval: привяжите согласие к неизменяемому scope

Approval содержит actor, proposal hash, точные ресурсы, действие, сумму/стоимость, срок и одноразовость. Если proposal изменился, подтверждение недействительно.

Approval record
  1. Proposal ID и cryptographic hash.
  2. Actor/tenant и approver identity.
  3. Action type и resource IDs.
  4. Before/after diff.
  5. External recipients/data disclosure.
  6. Цена и необратимость.
  7. Expiry и allowed executions.
  8. Policy version и reason.
  9. Audit timestamp.

Idempotency защищает от двойного выполнения

Сеть может оборваться после успешного действия, и агент повторит call. Для side effect клиент создаёт idempotency key на логическую операцию. Tool хранит результат и возвращает его при повторе вместо нового действия.

СценарийБез idempotencyС idempotency
Timeout после оплатыВторая оплатаТот же receipt
Retry emailДва письмаОдин message ID
Parallel callsRace updateConflict/один commit
Client reconnectНеизвестный статусLookup по operation key

Optimistic concurrency и stale proposal

Между preview и execute ресурс может измениться. Proposal сохраняет expected version/ETag. Execute использует compare-and-swap; при конфликте строится новый preview и требуется новое approval.

  • Не применяйте старый diff к новой версии.
  • Не скрывайте конфликт автоматическим overwrite.
  • Покажите пользователю, что изменилось после preview.
  • Для batch action возвращайте per-item status.
  • Partial success имеет явный compensation plan.

Typed result: не возвращайте модели всю базу

Result содержит ровно данные для следующего решения: status, fields, provenance, allowed next actions и error contract. Большие documents сохраняются отдельно, модель получает нужный fragment/reference.

tool_call_id: string
status: success | partial | rejected | failed
result: typed minimal object
provenance: resource IDs + versions
next_allowed_actions: enums
side_effect_receipt: optional ID
retry: allowed + after + max attempts
error: stable code + safe message + details enum
sensitive_fields: absent/redacted
raw_external_content: marked untrusted

Tool result - данные, а не новая системная инструкция

Страница, письмо или API может вернуть prompt injection. Оборачивайте external content как untrusted, отделяйте от policy и не позволяйте ему расширять tools или отменять approval.

Result safety
  1. Content и control metadata разделены.
  2. HTML/scripts не выполняются.
  3. Secrets и лишняя PII редактируются.
  4. Размер и MIME ограничены.
  5. URLs проходят allowlist/policy.
  6. External instructions игнорируются как policy.
  7. Следующий tool call снова авторизуется.
  8. Result lineage сохраняется.

Ошибки: стабильные коды вместо stack trace

Модель должна понять, уточнить ввод, повторить позже или остановиться. Возвращайте небольшой enum ошибок и safe details. Stack trace и внутренние IDs остаются в observability.

КлассПоведение агентаRetry
INVALID_ARGUMENTИсправить/уточнитьНет тем же input
NOT_FOUND_OR_NOT_ALLOWEDНе раскрывать объектНет
CONFLICTПолучить новый previewПосле refresh
REQUIRES_APPROVALПоказать proposalПосле approval
TEMPORARY_UNAVAILABLEBackoff/fallbackОграниченно
PARTIALПоказать per-item resultТолько failed safe items

Retries, timeout и circuit breaker

Retry принадлежит одному слою - обычно orchestration runtime. Он применяется к transient errors с exponential backoff, jitter и общим deadline. Side effects повторяются только с idempotency.

  • Max attempts на весь tool loop.
  • Per-tool timeout меньше workflow deadline.
  • Уважать Retry-After.
  • Circuit breaker исключает неисправную dependency.
  • Queue имеет предел и expiry.
  • Cancel распространяется на downstream operation.
  • Стоимость всех попыток попадает в trace.

Parallel tool calls: только независимые операции

Параллельно безопасно читать погоду для двух городов; опасно одновременно обновлять одну запись или выполнять зависимые действия. Planner/runtime строит dependency graph и сериализует conflicts.

Independent

Разные read-only resources.

Sequential

Output первого нужен второму.

Conflict

Общий mutable resource.

Versioning и backward compatibility

Изменение required field ломает старый prompt/model behavior. Публикуйте новую tool version или совместимое расширение, запускайте contract tests и поддерживайте окно миграции.

Tool release
  1. Name/version immutable.
  2. Input и output schemas сохранены.
  3. Descriptions изменяются с review.
  4. Compatible model/prompt bundles указаны.
  5. Old/new contract tests проходят.
  6. Canary видит выбор и error rates.
  7. Rollback не требует новой модели.
  8. Deprecated version имеет owner/deadline.

Evals: проверяйте весь цикл, а не valid JSON

Набор содержит случаи, где tool нужен, не нужен, неоднозначен, запрещён и временно недоступен. Для side effects используйте sandbox/fake executor.

Для каждого case измерь:
- correct tool selection / no-tool decision;
- argument schema и business validity;
- clarification when required;
- authorization and tenant isolation;
- approval before side effect;
- duplicate/parallel call rate;
- error classification and recovery;
- number of steps, latency and cost;
- final task success;
- forbidden action and injection resistance.
Critical security failures - hard stop, не средний score.

Observability и audit trail

Trace связывает model response, tool selection, schema version, policy decision, approval, execution, result и последующий ответ. Raw arguments могут содержать данные - логируйте hashes, classifications и разрешённые поля.

SpanМинимальные поляВопрос
Selectmodel/prompt/toolset versionsПочему выбран tool
Validateschema/policy outcomeЧто отклонено
Approveproposal/actor/scopeКто разрешил
Executeoperation/idempotency/statusЧто произошло
Recovererror/retry/fallbackПочему повторили

Итоговый production-чек-лист

Tool gate
  1. Tool выполняет одну узкую операцию.
  2. Name/description однозначны.
  3. Input schema строгая и versioned.
  4. Business validation server-side.
  5. Identity и tenant не приходят от модели.
  6. Active toolset следует least privilege.
  7. Read, propose и execute разделены.
  8. Approval привязан к immutable proposal.
  9. Side effects используют idempotency.
  10. Stale proposal ловится concurrency control.
  11. Result минимальный и typed.
  12. External content помечен untrusted.
  13. Error codes ведут к безопасному recovery.
  14. Retries и parallel calls ограничены.
  15. Contract, security и end-to-end evals проходят.

Надёжный tool превращает вероятностное намерение модели в детерминированную, авторизованную и наблюдаемую операцию. Чем выше последствия, тем меньше решений следует оставлять на свободный текст.

Что такое tool calling или function calling в LLM?
Модель предлагает структурированный вызов функции с arguments. Ваше приложение валидирует, авторизует и исполняет его, затем возвращает результат модели. Сам ответ модели не предоставляет права на действие.
Достаточно ли JSON Schema для безопасного tool?
Нет. Schema проверяет форму. Отдельно нужны trusted identity, object-level authorization, business invariants, policy, budget, approval и безопасный executor.
Как назвать tool для AI-агента?
Используйте конкретный глагол и объект, например get_order_status. Description объясняет назначение, случаи использования, запреты, inputs, output, side effects и errors.
Когда нужен human approval?
Перед необратимыми, дорогими, внешними или высокорисковыми действиями и при выходе за обычный scope. Approval должен быть привязан к точному immutable preview и иметь expiry.
Что такое idempotency для AI-агента?
Повтор одного логического side effect с тем же key возвращает прежний результат, а не выполняет действие заново. Это защищает от двойной оплаты, письма или изменения после timeout/retry.
Можно ли дать агенту shell, SQL или универсальный HTTP tool?
Только в изолированном sandbox с жёсткими allowlists, limits, egress policy, approval и audit. В business workflow безопаснее узкие domain tools, не раскрывающие универсальную мощность.
Как возвращать ошибки tool модели?
Используйте стабильный typed error code, безопасное сообщение, допустимые details и явный retry policy. Stack trace и secrets остаются в защищённой observability.
Как тестировать tools ИИ-агента?
Проверяйте выбор tool/no-tool, arguments, clarification, authorization, approvals, idempotency, parallel conflicts, errors, injection, число шагов и итог задачи. Side effects выполняйте в sandbox/fake executor.
← Все статьи блога