Все статьи

13 октября 2026 г.

Работа ИИ-агента с формами и клиент-серверными вызовами 1С через MCP-сервер Графон

Почему формы 1С — это худший контекст для ИИ-агента

Модуль управляемой формы в 1С — не файл, а распределённый контекст. Директивы компиляции разбивают его на клиентскую и серверную части, между ними ходят сериализуемые данные, а сам модуль ссылается на реквизиты формы, команды, общие модули, модули менеджеров, подписки на события и запросы к регистрам. Чтобы сгенерировать корректный код, агенту нужно одновременно «видеть» минимум пять сущностей метаданных.

Без графа зависимостей ИИ-агент делает единственное, что умеет: читает файлы целиком. Форма ФормаДокумента из УТ 11 вместе с модулем объекта, менеджера и общими модулями — это 150–250 тысяч токенов на одну правку. При 40 формах в задаче контекстное окно переполняется, а поведение агента деградирует до галлюцинаций: он придумывает реквизиты, вызывает серверные методы из &НаКлиенте, путает &НаСервере с &НаСервереБезКонтекста и предлагает код, который не проходит проверку синтаксиса.

Что именно должен знать агент про клиент-серверное взаимодействие

Ключевые сущности, которые обязана учитывать генерация кода:

  • Директивы компиляции: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста, &НаКлиентеНаСервереБезКонтекста. Агент должен понимать, что &НаСервереБезКонтекста не имеет доступа к данным формы, а значит не может читать Объект.Товары напрямую.
  • Сериализация через границу: структуры, массивы, соответствия, ссылки и примитивы. Таблицы значений передаются, но передача больших коллекций — скрытый расход трафика.
  • Временное хранилище: ПоместитьВоВременноеХранилище / ПолучитьИзВременногоХранилища с адресом УникальныйИдентификатор().
  • Асинхронность: ОписаниеОповещения, Ждать, Асинх — агент обязан не смешивать синхронную и асинхронную модели.
  • Подписки на события: обработчики ПередЗаписью, ПриЗаписи, ОбработкаПроверкиЗаполнения живут в общих модулях и подключаются в метаданных, а не в форме.

Все эти связи лежат в XML метаданных, разбросанных по тысячам файлов. Читать их вслепую — путь к 10-кратному перерасходу токенов.

Графон: граф зависимостей вместо чтения файлов

Графон — локальный инструмент и MCP-сервер для конфигураций 1С. Он индексирует выгрузку конфигурации, строит граф метаданных, функций, процедур, подписок и запросов, а затем отдаёт ИИ-агенту точный срез: только те файлы, сигнатуры и участки кода, которые нужны для конкретной задачи. Агент не грузит модуль формы целиком — он получает контракт формы.

Типовые MCP-инструменты, к которым обращается агент:

| Инструмент | Назначение | Что возвращает |
|---|---|---|
| grafon_get_form_context | Контекст управляемой формы | реквизиты, команды, обработчики с директивами |
| grafon_get_call_graph | Граф вызовов | цепочки клиент → сервер → менеджер/общий модуль |
| grafon_get_subscriptions | Подписки на события | обработчики, модули, состав объектов |
| grafon_get_symbol | Точный срез кода | сигнатура + тело процедуры, без лишних модулей |
| grafon_search_metadata | Поиск по метаданным | объекты, регистры, реквизиты с типами |

Пример MCP-запроса на получение контекста формы вместе с графом вызовов:

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "tools/call",
  "params": {
    "name": "grafon_get_form_context",
    "arguments": {
      "object": "Документ.РеализацияТоваровУслуг",
      "form": "ФормаДокумента",
      "symbols": ["ПриОткрытии", "ЗаполнитьЦеныНаСервере"],
      "includeCallGraph": true,
      "depth": 2
    }
  }
}

В ответ агент получает список реквизитов с типами, директивы компиляции каждого обработчика и цепочку вызовов до общих модулей — обычно 8–15 КБ вместо 2 МБ.

Сценарий 1: добавление серверного вызова без «чата» запросов

Классический антипаттерн, который генерирует агент без графа зависимостей:

&НаКлиенте
Процедура ЗаполнитьЦены(Команда)
    Для Каждого Строка Из Объект.Товары Цикл
        // N обращений к серверу — деградация на больших таблицах
        Строка.Цена = ЦенаНаСервере(Строка.Номенклатура);
    КонецЦикла;
КонецПроцедуры

&НаСервере
Функция ЦенаНаСервере(Номенклатура)
Возврат РегистрыСведений.ЦеныНоменклатуры.ПолучитьПоследнее(ТекущаяДатаСеанса(), Новый Структура("Номенклатура", Номенклатура)).Цена;
КонецФункции

С Графоном агент видит граф вызовов, знает типы реквизитов формы и состав измерений регистра — и строит один round-trip:

&НаКлиенте
Процедура ЗаполнитьЦены(Команда)
    ЗаполнитьЦеныНаСервере(); // один серверный вызов
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьЦеныНаСервере()
Список = Новый Массив;
Для Каждого Строка Из Объект.Товары Цикл
Список.Добавить(Строка.Номенклатура);
КонецЦикла;
Если Список.Количество() = 0 Тогда
Возврат;
КонецЕсли;

Цены = ЦеныНоменклатурыПоСписку(Список);
Для Каждого Строка Из Объект.Товары Цикл
Найденные = Цены.НайтиСтроки(Новый Структура("Номенклатура", Строка.Номенклатура));
Если Найденные.Количество() > 0 Тогда
Строка.Цена = Найденные[0].Цена;
КонецЕсли;
КонецЦикла;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ЦеныНоменклатурыПоСписку(Список)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Цены.Номенклатура КАК Номенклатура,
| Цены.Цена КАК Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, Номенклатура В (&Список)) КАК Цены";
Запрос.УстановитьПараметр("Дата", ТекущаяДатаСеанса());
Запрос.УстановитьПараметр("Список", Список);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции

Здесь важны три вещи, которые даёт граф: тип реквизита Товары.Номенклатура (иначе запрос по В (&Список) может упасть по типам), существование измерения Номенклатура в регистре и отсутствие конфликтующей одноимённой функции в общих модулях.

Сценарий 2: правка подписок на события

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

{"name": "grafon_get_subscriptions",
 "arguments": {"object": "Документ.РеализацияТоваровУслуг", "events": ["ПередЗаписью", "ПриЗаписи"]}}

Сравнение: с Графоном и без

| Сценарий | Без Графона | С Графоном | Экономия |
|---|---|---|---|
| Правка ПриОткрытии в форме документа УТ | ~180 000 токенов / 6 мин | ~12 000 / 40 с | 15× |
| Команда формы с клиент-серверным вызовом | ~250 000 / 9 мин | ~18 000 / 55 с | 14× |
| Аудит серверных вызовов в 40 формах | не влезает в контекст | ~35 000 / 2 мин | 28× |
| Разбор подписок при записи объекта | ~90 000 / 4 мин | ~9 000 / 35 с | 10× |
| Поиск «где вызывается общий модуль» | полный перебор XML | точечный запрос к графу | 20–50× |

Чек-лист внедрения в команде

  1. Выгрузить конфигурацию в XML и проиндексировать её Графоном (инкрементально при каждой сборке).
  2. Подключить MCP-сервер к агенту: claude mcp add grafon -- ... для Claude Code, аналогично — в настройках Cursor или Windsurf.
  3. Зафиксировать в правилах проекта требование: перед любой правкой формы агент вызывает grafon_get_form_context.
  4. Запретить агенту читать модули форм целиком через файловые инструменты.
  5. Добавить в CI проверку синтаксиса и запуск 1С:Конфигуратор /CheckModules после изменений агента.

Итог

Формы и клиент-серверные вызовы — та часть платформы 1С, где цена ошибки максимальна, а объём контекста избыточен. Граф зависимостей превращает работу ИИ-агента из «прочитать всё и надеяться» в точную навигацию: 10–30× меньше токенов, предсказуемое время отклика и код, который компилируется с первого раза. Локальный MCP-сервер Графон снимает главный барьер на пути реального использования Claude Code, Cursor и Windsurf в проектах на ERP, УТ, ЗУП и КА.