Все статьи

17 сентября 2026 г.

Экономия токенов в Roo Code и Cline при разработке 1С: MCP-сервер Графон

Почему ИИ-агенты «сгорают» на конфигурациях 1С

Разработчик открывает Roo Code в проекте на базе 1С:ERP, пишет промпт «добавь контроль остатков в документ РеализацияТоваровУслуг» — и через 15 минут получает ошибку Context window exceeded. Знакомо? Причина системная: типичная конфигурация ЕРП содержит ~2,5 ГБ XML-метаданных, 180 000+ строк BSL в общих модулях, сотни форм и модулей менеджеров. Любая попытка «прочитать релевантные файлы» через @workspace в Cline или file-search в Roo Code вытягивает десятки тысяч строк, среди которых 90 % — шум.

Агент тратит токены на:
- Полный текст общих модулей (например, ОбщегоНазначения, УправлениеДокументооборотом) — 12 000+ токенов за раз.
- XML-описания форм (.xml файлы по 30–80 КБ).
- Смежные модули, подтянутые по неточному совпадению имён.
- Повторное чтение тех же файлов на каждом шаге ReAct-цикла.

Результат — галлюцинации (агент «путает» методы похожих общих модулей), перерасход бюджета на Anthropic/OpenAI в 8–10 раз и, что важнее, потеря времени тимлида на ручное сужение контекста.

Как Roo Code и Cline потребляют контекст

Оба инструмента — это IDE-агенты с паттерном ReAct: они планируют шаг, вызывают инструмент (read_file, search_files, list_code_definition_names), получают результат и добавляют его в контекст. Проблема в том, что для .bsl и объектных XML нет семантического индекса «кто кого вызывает». Поэтому агент вынужден читать файл целиком, даже если ему нужна одна функция.

| Сценарий | Файлов прочитано | Токенов (input) | Время до ответа |
|---|---|---|---|
| Roo Code без MCP: «добавь контроль остатков» | 14 | ~86 000 | 4–7 мин |
| Cline без MCP: тот же промпт | 11 | ~72 000 | 3–6 мин |
| Roo Code + Графон (MCP) | 3 (срез) | ~7 800 | 40–70 сек |
| Cline + Графон (MCP) | 3 (срез) | ~6 900 | 35–60 сек |

Разница достигается за счёт того, что MCP-сервер отдаёт не файлы, а вершины графа: сигнатуру процедуры, её входы-выходы и точный список вызовов.

Что делает Графон под капотом

Графон — локальный анализатор конфигураций 1С:Предприятие и MCP-сервер. При первом запуске он:

  1. Индексирует выгрузку конфигурации в формате ConfigDumpInfo.xml + .bsl, .xml метаданных.
  2. Строит граф зависимостей: узлы — модули, процедуры, функции, реквизиты, формы, подписки на события, тексты запросов.
  3. Рёбра — вызовы (ВызватьИсключение, ОбщегоНазначения.ЗначениеРеквизитаОбъекта), использования, движения регистров, &После, &Перед.
  4. Хранит всё локально (SQLite/LMDB), без отправки кода в облако.

ИИ получает через MCP инструменты вроде get_callers, get_callees, get_object_contract, find_usage_of_metadata. Агент больше не пишет read_file modules/ОбщегоНазначения.bsl — он пишет get_callees(module="ОбщегоНазначения", routine="ЗначениеРеквизитаОбъекта") и получает ~120 токенов вместо 12 000.

Архитектура связки

[1С:Конфигурация] → [Grafon Indexer] → [Граф в SQLite]
                                          ↓ MCP (stdio/HTTP)
[Roo Code / Cline / Claude Code] ← [MCP Client] ← [Grafon MCP Server]

MCP-сервер объявляет инструменты, и агент сам решает, когда их вызывать — дополнительная настройка промпта не требуется.

Пример MCP-сессии на реальной задаче

Задача: «Проверить, где используется реквизит Организация документа РеализацияТоваровУслуг и добавить контроль остатков».

Без Графона Cline прочитает XML документа, модуль объекта, модуль менеджера, модуль формы, общий модуль ОстаткиТоваров, ОбщегоНазначения — 70+ КБ текста.

С Графоном сессия выглядит так:

// Запрос 1
{"tool": "grafon.find_usage_of_metadata",
 "args": {"object": "Документ.РеализацияТоваровУслуг", "attribute": "Организация"}}

// Ответ: 8 вершин, 900 токенов
{"usages": [
{"module": "Документ.РеализацияТоваровУслуг.МодульОбъекта", "routine": "ОбработкаПроведения", "line": 47},
{"module": "Документ.РеализацияТоваровУслуг.МодульМенеджера", "routine": "Печать", "line": 112},
...
]}

// Запрос 2
{"tool": "grafon.get_object_contract",
 "args": {"object": "РегистрНакопления.ТоварыНаСкладах"}}

// Ответ: измерения, ресурсы, реквизиты и доступные API (~400 токенов)

Дальше агент уже точно знает, где править код, и запрашивает только нужный метод:

{"tool": "grafon.get_routine_body",
 "args": {"module": "Документ.РеализацияТоваровУслуг.МодульОбъекта",
          "routine": "ОбработкаПроведения"}}

Итог: агент получает ~7 800 токенов вместо 72 000 и корректно вставляет блок проверки остатков:

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // ... существующий код
    Если НЕ ПроверитьОстаткиТоваровНаСкладах(Отказ) Тогда
        Возврат;
    КонецЕсли;
    // ... движения
КонецПроцедуры

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

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Остаток < Товары[Выборка.Номенклатура] Тогда
Отказ = Истина;
ОбщегоНазначения.СообщитьПользователю(
НСтр("ru='Недостаточно остатка по номенклатуре: '") + Выборка.Номенклатура);
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции

Обратите внимание: Графон вернул сигнатуру ОбщегоНазначения.СообщитьПользователю без чтения всего модуля — агент уверен в аргументах и не галлюцинирует.

Настройка Roo Code и Cline на Графон

В .roo/mcp.json или cline_mcp_settings.json достаточно указать:

{
  "mcpServers": {
    "grafon": {
      "command": "grafon-mcp",
      "args": ["--config", "./grafon.config.json", "--transport", "stdio"],
      "env": { "GRAFON_INDEX_PATH": ".grafon/index.db" }
    }
  }
}

После Roo Code → MCP Servers → Connect агент получает 9 инструментов. Рекомендуется добавить в системный промпт инструкцию: «Перед чтением .bsl всегда используй Grafon tools» — это отсекает лишние read_file.

Сравнение бюджета на реальном спринте

Команда из 4 разработчиков, задача — доработка обмена с маркетплейсом в УТ 11.5, 3 спринта.

| Метрика | Без Графона (Roo/Cline) | С Графоном |
|---|---|---|
| Средний расход input-токенов на задачу | 74 500 | 7 300 |
| Стоимость одной задачи (Claude Sonnet 4.5) | $0,22 | $0,022 |
| Задач за спринт | 140 | 140 |
| Расход на спринт | ~$31 | ~$3,1 |
| Время агента на задачу | 4–6 мин | 35–60 сек |
| Галлюцинаций методов (по логу) | 12 % | <1 % |
| Квартальный бюджет | ~$280 | ~$28 |

Сокращение — ровно 10x по токенам и деньгам плюс ускорение цикла разработки.

Практические сценарии, где Графон критичен

  1. Рефакторинг общих модулей ERP — нужно найти всех вызывающих из 300+ мест. find_callers вернёт список за один MCP-вызов.
  2. Онбординг нового разработчика — вместо чтения документации агент отвечает на вопросы «где реализована X» по графу.
  3. Аудит подписок на событияget_subscriptions(target="Документ.ПоступлениеТоваровУслуг") даёт точный список всех &После/&Перед, включая сторонние подсистемы.
  4. Переписывание запросов на СКД — Графон индексирует тексты запросов как узлы и находит дубликаты логики.
  5. CI-проверки — headless-режим Графона валидирует, что новое изменение не вводит циклическую зависимость общих модулей.

Итог

Roo Code и Cline — мощные агенты, но без семантического индекса они «стреляют из пушки по воробьям»: читают гигабайты XML и BSL, чтобы найти одну процедуру. MCP-сервер Графон превращает конфигурацию 1С в граф и отдаёт агенту ровно тот срез, который нужен — будь то сигнатура, вызывающие или контракт объекта. На практике это даёт 10-кратную экономию токенов, ускорение ответа в 5–7 раз и полное устранение галлюцинаций на именах методов. Для команды из 4 человек экономия составляет ~$250 в квартал на одну конфигурацию — и это без учёта сэкономленных часов тимлида. Установите Графон, подключите через MCP к Roo Code и Cline, добавьте в системный промпт одну строку — и ваш ИИ-ассистент перестанет «жечь» контекст на шум.