Архитектура интеграций

Граница ответственности между AI-агентом и интеграционным слоем 1С

Продвинутый уровень До 10 минут Практическое руководство

Модель может предложить, что сделать, но не должна самостоятельно определять, допустимо ли это в учётной системе. Надёжная интеграция начинается там, где вероятностный вывод агента превращается в строго описанное намерение, а все проверки и изменения данных остаются в детерминированном контуре 1С.

Почему прямые команды модели опасны

AI-агент работает с неполным контекстом и формирует ответы вероятностно. Даже при низкой температуре генерации нельзя считать гарантированными точное имя операции, состав реквизитов или одинаковый результат рассуждения при каждом запуске.

Если текст модели сразу преобразуется в вызов вроде «создать реализацию и провести», бизнес-система получает команду до того, как проверены организация, договор, склад, валюта, период учёта, права пользователя и повторность запроса. Промпт не заменяет эти проверки: он помогает модели выбрать действие, но не обеспечивает соблюдение конфигурации и учётной политики.

Рабочая граница выглядит так: агент формирует декларативное намерение, интеграционный слой проверяет его по контракту, сопоставляет внешние идентификаторы с объектами 1С, выполняет бизнес-валидацию и только затем вызывает заранее разрешённую операцию.

Что находится по каждую сторону границы

AI-агент Интеграционный слой 1С
Определяет намерение пользователя Разрешает только известные типы намерений
Извлекает значения из естественного языка Проверяет типы, формат, диапазоны и обязательность полей
Может сообщить уверенность и неоднозначности Не использует уверенность как замену бизнес-правилам
Запрашивает недостающие сведения Сопоставляет внешние идентификаторы со ссылками 1С
Предлагает действие или черновик Проверяет права, период, состояние объектов и учётные ограничения
Объясняет результат человеку Обеспечивает идемпотентность, транзакцию, журналирование и возврат статуса

Особенно важно не передавать модели внутренние ссылки объектов как строки, которые она должна воспроизвести. Агенту достаточно устойчивых внешних идентификаторов. Их разрешение в ссылки выполняет только интеграционный слой.

Воспроизводимая схема интеграции

Шаг 1. Опишите закрытый набор намерений

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

Следующий JSON — пример контракта, а не универсальный формат 1С:

{
  "schema_version": "1.0",
  "intent": "sales_order.create_draft",
  "request_id": "req-2026-000184",
  "actor_id": "user-42",
  "payload": {
    "organization_id": "org-main",
    "customer_id": "customer-1042",
    "warehouse_id": "warehouse-01",
    "currency": "RUB",
    "items": [
      {
        "product_id": "product-778",
        "quantity": 2,
        "unit": "pcs"
      }
    ]
  }
}

В контракте намеренно нет полей method, query, script, posted или privileged_mode. Агент не должен выбирать серверный метод, формировать запрос к базе, включать привилегированный режим или обходить этап черновика.

Шаг 2. Выполните структурную проверку до обращения к бизнес-логике

На HTTP-границе проверьте тип содержимого, ограничение размера тела, синтаксис JSON, версию схемы, список допустимых полей и длину строк. Неизвестные поля лучше отклонять: иначе новая или ошибочно сгенерированная моделью семантика будет молча проигнорирована.

Минимальная последовательность проверок:

  1. Запрос аутентифицирован доверенным шлюзом.
  2. request_id соответствует принятому формату и ещё не связан с другим содержимым.
  3. intent присутствует в белом списке.
  4. schema_version поддерживается обработчиком.
  5. payload содержит только разрешённые поля ожидаемых типов.
  6. Количество строк и числовые значения находятся в технических пределах.

Технический лимит не является учётным правилом. Например, проверка quantity > 0 отсеивает некорректное число, но допустимость номенклатуры, единицы измерения и склада должна проверяться отдельно.

Шаг 3. Маршрутизируйте намерения через явный реестр

Ниже приведён упрощённый пример на встроенном языке 1С. Имена общих модулей условны и должны быть адаптированы к конкретной конфигурации.

Функция ВыполнитьНамерение(ЗапросНамерения) Экспорт

    Если ЗапросНамерения.ВерсияСхемы <> "1.0" Тогда
        Возврат ОтветСОшибкой(
            "UNSUPPORTED_SCHEMA",
            "Версия контракта не поддерживается");
    КонецЕсли;

    Если ЗапросНамерения.Намерение = "sales_order.create_draft" Тогда
        Возврат ЗаказыИнтеграция.СоздатьЧерновик(
            ЗапросНамерения);
    ИначеЕсли ЗапросНамерения.Намерение = "sales_order.get_status" Тогда
        Возврат ЗаказыИнтеграция.ПолучитьСтатус(
            ЗапросНамерения);
    Иначе
        Возврат ОтветСОшибкой(
            "INTENT_NOT_ALLOWED",
            "Операция не разрешена");
    КонецЕсли;

КонецФункции

Не заменяйте этот реестр вычислением имени функции из строки и динамическим вызовом. Белый список должен связывать внешний тип намерения с конкретным серверным обработчиком в коде.

Шаг 4. Разрешите идентификаторы и примените бизнес-правила

Обработчик получает внешние идентификаторы, находит соответствующие объекты и отклоняет неоднозначное или отсутствующее сопоставление. Поиск по представлению, наименованию или фразе модели небезопасен: названия могут совпадать и меняться.

Функция ПроверитьКомандуСоздания(Команда) Экспорт

    Результат = Новый Структура;
    Результат.Вставить("Ошибки", Новый Массив);

    Организация = НайтиОрганизациюПоВнешнемуИД(
        Команда.ОрганизацияИД);
    Если Организация = Неопределено Тогда
        Результат.Ошибки.Добавить(
            ОшибкаПоля("organization_id", "REFERENCE_NOT_FOUND"));
    КонецЕсли;

    Контрагент = НайтиКонтрагентаПоВнешнемуИД(
        Команда.КонтрагентИД);
    Если Контрагент = Неопределено Тогда
        Результат.Ошибки.Добавить(
            ОшибкаПоля("customer_id", "REFERENCE_NOT_FOUND"));
    КонецЕсли;

    Если Команда.Товары.Количество() = 0 Тогда
        Результат.Ошибки.Добавить(
            ОшибкаПоля("items", "EMPTY_COLLECTION"));
    КонецЕсли;

    Результат.Вставить("Допустимо",
        Результат.Ошибки.Количество() = 0);
    Результат.Вставить("Организация", Организация);
    Результат.Вставить("Контрагент", Контрагент);

    Возврат Результат;

КонецФункции

Реальная проверка обычно шире: доступность организации пользователю, действующий договор, допустимая валюта, единицы измерения, запрет помеченных на удаление объектов, состояние периода и правила конкретной конфигурации. Эти условия нельзя полностью перечислить без знания внедрения; их следует вызывать из существующих механизмов конфигурации, а не дублировать в промпте.

Шаг 5. Отделите проверку от изменения состояния

Полезно иметь два режима: validate и execute. Первый возвращает нормализованный план и ошибки, не записывая данные. Второй принимает тот же контракт и выполняется только после успешной повторной проверки. Между вызовами данные могли измениться, поэтому результат validate не освобождает execute от проверки.

Для действий с заметными последствиями добавьте подтверждение человеком или отдельный токен согласования. Сам факт, что агент второй раз отправил ту же команду, подтверждением не считается.

Шаг 6. Сделайте запись идемпотентной

request_id должен однозначно обозначать бизнес-попытку. До создания документа интеграционный слой ищет сохранённый результат по этому ключу:

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

Запись ключа и создание объекта следует выполнять в одной транзакции, если архитектура хранения это позволяет. Внешний шлюз может повторить запрос после сетевого тайм-аута, даже если 1С уже завершила операцию.

НачатьТранзакцию();
Попытка
    Повтор = РеестрЗапросов.Найти(
        Команда.ИдентификаторЗапроса);

    Если Повтор <> Неопределено Тогда
        ПроверитьСовпадениеХеша(Повтор, Команда);
        ОтменитьТранзакцию();
        Возврат Повтор.СохраненныйОтвет;
    КонецЕсли;

    ДокументОбъект = СоздатьПроверенныйЧерновик(
        ПровереннаяКоманда);

    РеестрЗапросов.ЗаписатьРезультат(
        Команда.ИдентификаторЗапроса,
        ХешНормализованнойКоманды(Команда),
        ДокументОбъект.Ссылка);

    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ВызватьИсключение;
КонецПопытки;

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

Шаг 7. Возвращайте машинный статус, а не свободный текст

Агенту следует передавать структурированный результат. Человекочитаемое объяснение модель может построить уже по нему:

{
  "request_id": "req-2026-000184",
  "status": "rejected",
  "operation": "sales_order.create_draft",
  "errors": [
    {
      "code": "REFERENCE_NOT_FOUND",
      "field": "warehouse_id",
      "retryable": false
    }
  ]
}

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

Безопасная конфигурация контура

Набор конкретных ролей зависит от прикладного решения, но принцип можно воспроизвести в любой конфигурации:

  • отдельная техническая учётная запись для интеграции;
  • минимальные права только на опубликованные сценарии;
  • запрет интерактивного входа этой учётной записи, если инфраструктура это поддерживает;
  • TLS на транспортном уровне и аутентификация вне содержимого промпта;
  • ограничение размера, частоты и времени обработки запросов на шлюзе;
  • секреты в защищённом хранилище среды, а не в системном сообщении модели и не в JSON-команде;
  • журнал аудита без персональных данных и секретов сверх необходимого;
  • раздельные разрешения на чтение, создание черновика, запись и проведение.

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

Как проверить результат

Проверка должна показывать не «разумность» ответа модели, а соблюдение инвариантов границы. Выполните сценарии на тестовой информационной базе с непроизводственными данными.

  1. Отправьте корректный запрос в режиме проверки. Убедитесь, что объект в 1С не создан, а ответ содержит нормализованный план.
  2. Повторите проверку с неизвестным intent. Ожидаемый результат — INTENT_NOT_ALLOWED, без динамического вызова.
  3. Добавьте неизвестное поле в payload. Контракт должен отклонить запрос, а не проигнорировать поле.
  4. Укажите несуществующий внешний идентификатор. Операция должна завершиться до записи документа.
  5. Выполните разрешённую команду и сохраните её структурированный результат.
  6. Повторите запрос с тем же request_id и тем же содержимым. Должен вернуться прежний результат без второго документа.
  7. Повторите идентификатор с изменённым количеством. Должен возникнуть конфликт идемпотентности.
  8. Имитируйте ошибку после начала транзакции. Проверьте отсутствие частично записанного документа и незавершённой записи реестра.
  9. Убедитесь, что в журнале есть идентификатор запроса, тип операции, итоговый статус и ссылка на созданный объект, но нет токенов и содержимого секретов.

Итоговый критерий прост: изменение данных возможно только через известный обработчик, после повторяемых проверок, с фиксируемым результатом и безопасным повтором запроса.

Типовые ошибки

«Модель вернула валидный JSON — значит, команда безопасна»

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

Универсальный инструмент «выполни метод 1С»

Такой интерфейс превращает строку модели в механизм удалённого исполнения. Вместо него публикуйте узкие операции с фиксированной семантикой.

Проверки только на стороне агента

Агент может предварительно обнаружить пропущенное поле, но авторитетная проверка всегда выполняется в интеграционном слое. Клиентские проверки также нельзя считать доверенными.

Автоматический повтор любой ошибки

Повтор допустим только для явно классифицированных временных сбоев. Ошибки данных, прав и бизнес-ограничений не исправятся от повторного вызова и могут усилить нагрузку.

Идемпотентность только по номеру документа

Номер появляется слишком поздно и может назначаться по правилам конфигурации. Ключ запроса должен существовать до начала изменения состояния.

Передача пользователю сырого текста исключения

Исключение полезно во внутреннем журнале с контролем доступа. Внешнему потребителю нужен стабильный код, безопасное сообщение и признак возможности повтора.

Доверие к «уверенности» модели

Высокая заявленная уверенность не разрешает проведение документа. Порог уверенности можно применять для маршрутизации к человеку, но не вместо учётных правил.

Ограничения подхода

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

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

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

Наконец, универсального набора учётных проверок не существует: он определяется конфигурацией, расширениями, ролями и регламентами организации. Архитектурная граница остаётся общей, а конкретные инварианты должны быть извлечены из действующей бизнес-логики.

Короткий контрольный список

  • Агент отправляет намерение, а не код или имя произвольного метода.
  • Контракт версионируется и отклоняет неизвестные поля.
  • Маршрутизация построена на явном белом списке.
  • Внешние идентификаторы разрешаются внутри доверенного контура.
  • Права и бизнес-правила проверяются непосредственно перед записью.
  • Черновик, запись и проведение разделены по полномочиям.
  • Повтор запроса обрабатывается по ключу идемпотентности.
  • Ответ содержит стабильный статус и безопасные коды ошибок.
  • Журнал позволяет связать запрос, результат и объект 1С.
  • Секреты и внутренние исключения не попадают в контекст модели.