Как я проектирую контрактную карту для разработки с ИИ
Liquid Contract Map: как связать бизнесовый процесс, права, состояния и код, когда над системой работают люди и ИИ агенты.
Почему я начал описывать контракты
В моих проектах рядом живут мобильное приложение, сервер, административный кабинет и несколько внешних интеграций. Одно пользовательское действие проходит через все эти части. Например, житель оформляет пропуск: клиент отправляет запрос, сервер проверяет полномочия, внешняя система принимает разрешение, а интерфейс показывает результат. Изменение в одной части приходится соотносить со всем процессом.
При работе с ИИ агентами эта зависимость становится особенно заметной. Агент может быстро написать обработчик, опираясь на доступный ему фрагмент кода. При этом смысл статуса, граница полномочий или правило повторной отправки могут находиться в другой части проекта. Я стал описывать их как связанную карту, по которой можно определить, что именно разрешено менять и как проверять результат. Этот подход получил название Liquid Contract Map, или LCM.
Сначала определить смысл действия
В начале карты я описываю бизнесовый процесс и его участников. Для пропуска нужно понять, кто разрешает въезд, на какой срок, где хранится разрешение и как оно прекращает действовать. После этого можно выбирать названия сущностей, команды API и структуру хранения. Порядок важен: техническая модель наследует смысл процесса.
Один и тот же термин должен сохранять значение в приложении, на сервере и в документации. В примере с въездом заявка уже может быть сохранена, пока внешняя система ещё обрабатывает разрешение. Это два разных состояния. Если назвать оба объекта просто пропуском, разработчики начнут подразумевать разные вещи, поэтому в карте я фиксирую предметный словарь и связи между сущностями.
Что должно быть в контракте
Контракт функции объясняет, какое действие выполняет система и кому оно доступно. У команды есть более подробное описание: входные данные, предусловия, результат и возможные ошибки. Инварианты задают обязательные правила. Разработчик сверяет с ними изменение состояний и проверку прав, в том числе при отказе одного из компонентов.
В учебном примере оформления временного доступа контракт задаёт проверку полномочий заявителя, срока и идентичности операции. Подробности определяются действующей интеграцией. Её API и принятая модель прав влияют на то, какие данные нужно передать и какой ответ считать завершением операции. Спорное правило можно обсудить на этой стадии, пока оно ещё не оказалось внутри обработчика.
Как агент получает задачу
Для реализации я выделяю функцию или команду и передаю агенту её контракт вместе с прямыми зависимостями. Если задача меняет проверку прав, в контекст входят модель полномочий и соответствующие инварианты. Для изменения только представления достаточно другого набора материалов. Объём контекста определяется зависимостями задачи.
В большой карте используются фрагменты. Каждый фрагмент владеет своей частью модели и публикует границу взаимодействия. Потребитель ссылается на определённую ревизию этой границы. Это позволяет менять внутреннее устройство компонента и одновременно видеть, какое публичное изменение потребует проверки других частей системы.
Изменения проходят через историю решений
Предположим, раньше разрешение на въезд выдавалось на один срок, а теперь появились разные категории. Новое правило затрагивает модель, интерфейс, серверную проверку и обмен с внешней системой. В карте нужно указать, какое прежнее решение оно уточняет или заменяет, что произойдёт с существующими данными и как поведёт себя старый клиент.
Такая работа особенно существенна для мобильных приложений: пользователи обновляются постепенно. Сервер может уже работать по новой модели, пока на телефоне остаётся предыдущая версия. Совместимость и миграция становятся частью контракта изменения.
Как проверяется результат
Для меня приёмка начинается с условий контракта. Я проверяю действие с разрешёнными правами и попытку выполнить его с недостаточными полномочиями. Затем рассматриваю отказ интеграции, повтор запроса и сохранность данных после восстановления. Для каждого сценария выбираю проверку кода или реального взаимодействия компонентов.
В UCG, например, важно различать принятую публикацию, попытку доставки и подтверждённый результат в конкретном канале. Повторная отправка зависит от уже выполненного шага: при неизвестном результате нужно сначала выяснить состояние прежней попытки. Эти условия я фиксирую в контракте. Во время эксплуатации появляются новые случаи, по которым приходится возвращаться к описанию процесса и дополнять проверки.
Что даёт такая организация разработки
LCM я применяю в AYS, UCG, инструментах MAX и других системах. Карта помогает сохранять смысл продукта при росте числа компонентов и участников разработки. Агент получает ограниченную задачу, разработчик видит её зависимости, а при проверке можно вернуться к конкретному принятому правилу.
По мере развития продукта меняются требования и сама карта. В ней остаются решения, причины, зависимости и условия перехода к следующей версии. Для меня это рабочий способ вести сложную систему, в которой скорость написания кода должна сочетаться с ответственностью за последствия изменений.