Tool schema — это API, а не подсказка модели

Описание инструмента видит модель, но контракт используют ещё validator, policy engine, worker, аудит и replay. Сохранённый вызов может быть выполнен после деплоя новой версии. Если поле исчезло или поменяло смысл, ошибка возникнет не в момент релиза, а внутри старого долгого workflow.

Что именно версионировать

Версия относится к bundle: имя и назначение tool, input schema, output schema, error taxonomy, side-effect semantics, permission scope и idempotency contract. Обновить JSON Schema без обновления фактического worker так же опасно, как поменять endpoint без клиента.

Стабильная идентичность

Используйте внутренний tool_id и отдельную schema_version. Человекочитаемое display name и description могут меняться. Каждый tool request сохраняет обе величины, hash schema и версию policy, чтобы результат можно было объяснить и воспроизвести.

tool_id: crm.customer.update
schema_version: 2.1.0
schema_hash: sha256:...
worker_contract: crm-tools@2027.04

Backward и forward compatibility

СовместимостьВопросПример
Backwardновый consumer читает староепонимает отсутствующее optional поле
Forwardстарый consumer читает новоеигнорирует неизвестное output поле
Fullоба направленияаддитивное изменение без нового смысла

Совместимость нужно формулировать отдельно для input, output, stored event и side effect.

Обычно безопасные изменения

Добавление optional input с безопасным default, добавление output-поля, расширение description без смены семантики и новый terminal error часто совместимы — но только если старые consumers действительно игнорируют неизвестное. additionalProperties: false делает новый output несовместимым для строгого validator.

Ломающие изменения

  • новое обязательное поле;
  • переименование или удаление поля;
  • string превращается в number;
  • сужается enum или диапазон;
  • default начинает внешний эффект;
  • read-only tool становится write;
  • ошибка меняется с retryable на terminal;
  • тот же аргумент выбирает другой resource scope.

Изменение смысла опаснее синтаксиса и требует новой major version.

Presence, null и default — разные состояния

Отсутствующее поле может означать «оставить как есть», null — «очистить», а пустая строка — реальное значение. Не смешивайте их. Для обновления ресурсов полезен явный patch contract и список изменяемых полей. Default применяется runtime, а не додумывается моделью.

Enum должен переживать будущее

Consumer обязан иметь ветку UNKNOWN/UNRECOGNIZED. Новый enum value не должен автоматически попадать в опасный fallback. Если policy не знает новое значение действия, безопасный режим — deny или ручная обработка. Удалённые числовые tags в Protobuf резервируют и не используют повторно.

Новая major version как отдельный tool

Для несовместимого контракта публикуйте customer_update_v2 или внутренний route с явной major version. Старый tool продолжает обслуживать активные workflows. Prompt bundle выбирает одну версию; не показывайте модели пять почти одинаковых вариантов без routing policy.

Adapter на границе

Adapter преобразует старый request в новый только при доказанной однозначности. Он добавляет defaults из доверенной конфигурации, переводит ошибки и сохраняет обе версии в trace. Если значение нельзя вывести без бизнес-решения, adapter обязан отказать, а не угадывать.

Сохранённые tool results и events

Результат храните как envelope: type, schema version, occurred_at, producer, payload reference и checksum. Reducer должен читать исторические версии или предварительно мигрировать snapshot. Не переписывайте прошлое событие без provenance: это ломает аудит и replay.

Долгие workflows и determinism

Workflow, ожидающий approval неделю, возобновится после нескольких релизов. Он должен вызвать ту версию activity, которая была запланирована, либо пройти явный patch transition. Изменение порядка команд, имени activity или типа события может сделать history несовместимой.

Schema registry и CI

Храните schemas в репозитории/registry с владельцем, статусом и сроком поддержки. CI сравнивает новую версию с последней published: required, types, enums, bounds, additionalProperties и semantics annotations. Ломающий diff требует major bump, migration plan и одобрение owners consumers.

Contract и replay tests

Golden fixtures включают старые inputs, новые inputs, старые outputs, неизвестные поля, null/default и все ошибки. Затем проигрывайте обезличенные production traces через новый validator и reducer. Отдельно проверяйте, что модель по обновлённому description выбирает правильный tool и заполняет поля семантически верно.

Rollout без флага «всем сразу»

  1. Опубликовать новую schema как draft.
  2. Прогнать compatibility и replay.
  3. Развернуть worker, понимающий обе версии.
  4. Включить shadow translation.
  5. Перевести малый canary prompt bundle.
  6. Сравнить invalid calls, outcomes и side effects.
  7. Расширить traffic.
  8. Дождаться завершения старых workflows.
  9. Отключить producer старой версии.
  10. Удалить consumer только после окна retention.

Метрики и аудит миграции

Считайте долю calls по version, schema rejection, adapter failures, unknown enums, semantic validation errors, retries и business outcomes. Trace связывает model/prompt/tool schema/worker. Дата удаления старой версии основывается на отсутствии активных workflows и сообщений, а не только на календаре.

Главная проверка

Спросите: сможет ли новый код безопасно обработать вызов, созданный вчера, а старый код — ответ, созданный новым producer? Если нет, нужен version boundary. И отдельно проверьте смысл: синтаксически совместимое поле может расширить полномочия и стать самым опасным изменением релиза.

Нужно ли менять версию при добавлении optional-поля?
Не всегда major, но версию и schema hash всё равно фиксируют. Проверьте strict consumers, additionalProperties, default и влияние поля на права.
Можно ли просто переименовать tool?
Для активных workflows имя может быть частью сохранённой команды. Без alias или новой версии replay и поздние задачи сломаются.
Что делать с новым enum value?
Новые consumers поддерживают его явно, старые должны безопасно обработать UNKNOWN. Для действий неизвестное значение не должно вести к разрешающему fallback.
Нужно ли хранить старые schemas?
Да, пока существуют события, traces, queued messages и workflow histories этой версии, а также в течение требуемого audit retention.
Чем schema validation отличается от semantic validation?
Schema проверяет форму и типы. Semantic validation проверяет права, существование resource, допустимость перехода, бизнес-лимиты и согласованность полей.
Как удалить старую версию?
Остановить старых producers, дождаться/мигрировать активные executions и queues, подтвердить нулевое использование метриками, сохранить reader для audit или мигрировать данные, затем удалить consumer.
← Все статьи блога