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 без флага «всем сразу»
- Опубликовать новую schema как draft.
- Прогнать compatibility и replay.
- Развернуть worker, понимающий обе версии.
- Включить shadow translation.
- Перевести малый canary prompt bundle.
- Сравнить invalid calls, outcomes и side effects.
- Расширить traffic.
- Дождаться завершения старых workflows.
- Отключить producer старой версии.
- Удалить 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. И отдельно проверьте смысл: синтаксически совместимое поле может расширить полномочия и стать самым опасным изменением релиза.