Ссылка на youtube версию: https://youtu.be/S-Me-MhUUiw

Что это

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

Технически это цикл: агент вызывает инструмент → получает результат → решает, нужен ли следующий вызов, или уже можно отвечать. На нетривиальный запрос типа "напиши функцию, которая проверяет задолженность контрагента перед проведением" уходит от 3 до 10+ вызовов инструментов за один ответ — семантический поиск по векторной базе, чтение найденной функции целиком, построение графа вызовов от неё вверх и вниз, при необходимости SQL-запрос к таблицам анализа. Это не RAG в классическом понимании (достал релевантный чанк — вставил в промпт) — агент сам решает, какой инструмент вызвать на каждом шаге, и может вернуться на предыдущий шаг, если результат его не устроил.

Почему обычный ассистент облажается на 1С

Возьмите любой generic-инструмент — ChatGPT, Copilot, что угодно с общей моделью без доступа к вашей базе — и попросите написать запрос: "выбери контрагентов с задолженностью больше 30 дней". Получите что-то в духе:

Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
|    Контрагенты.Ссылка КАК Контрагент,
|    Контрагенты.ЗадолженностьКонтрагента КАК Задолженность
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|ГДЕ
|    Контрагенты.ДнейПросрочки > 30";

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

В лучшем случае ассистент честно припишет "проверьте наличие реквизита в вашей конфигурации". В худшем — вы это заметите только на этапе синтаксической проверки в конфигураторе, а если совсем не повезёт — код соберётся (потому что где-то в базе случайно оказалось похожее по названию поле) и будет тихо считать неправильно.

Это не вопрос качества модели — GPT-5 или Claude здесь принципиально не решают проблему лучше друг друга. Вопрос в том, что задача в принципе нерешаема без доступа к конкретной конфигурации: 1С — это не язык с фиксированной стандартной библиотекой, как условный Python, а платформа, где 90% сущностей, с которыми вы работаете (справочники, регистры, документы, их реквизиты) — генерируется индивидуально под каждую конфигурацию. Универсальной "правильной" структуры данных для "задолженности контрагента" не существует — есть только то, что реально реализовано в вашей конкретной базе.

Второй пример — злее первого, потому что тут промахивается не только generic-ассистент, но и обычный статический анализ без доступа к расширениям. Допустим, в типовой конфигурации у документа "ЗаказПокупателя" в табличной части "Товары" стандартный набор полей: Номенклатура, Количество, Цена, Сумма. Но конкретно у вас накатано расширение, которое через &После("ОбработкаЗаполнения") добавляет в эту табличную часть реквизит ДополнительнаяСкидка и правит расчёт суммы с её учётом. Спросите generic-ассистента "напиши запрос, который выберет товары в заказе с итоговой суммой" — получите:

ВЫБРАТЬ
    ЗаказПокупателяТовары.Номенклатура,
    ЗаказПокупателяТовары.Количество,
    ЗаказПокупателяТовары.Цена,
    ЗаказПокупателяТовары.Сумма
ИЗ
    Документ.ЗаказПокупателя.Товары КАК ЗаказПокупателяТовары

Синтаксически рабочий запрос — и полностью бесполезный, потому что игнорирует ровно ту скидку, ради которой вы вообще писали расширение. Ассистент не мог поступить иначе: он видел только "стандартную 1С", а не то, что реально накатано у вас поверх. Мой агент сначала накладывает расширения на основную конфигурацию в порядке приоритета, с учётом аннотаций &Вместо/&После, и видит итоговую картину — ту, что реально работает у заказчика. На тот же вопрос он добавит в запрос ЗаказПокупателяТовары.ДополнительнаяСкидка и учтёт её в расчёте суммы, потому что знает: это поле физически существует в объекте, которым вы пользуетесь каждый день, даже если в "чистой" типовой конфигурации его никогда не было.

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

Архитектура: единый агент поверх готовой аналитической модели

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

Это цикл tool_use → tool_result → снова tool_use или уже финальный текстовый ответ, с лимитом на число шагов на один вопрос (у меня — 15 вызовов инструментов максимум, дальше агент обязан ответить на том, что успел собрать). Набор инструментов покрывает несколько уровней: резолвинг нечёткого имени объекта в точный адрес в метаданных, чтение кода функции целиком по адресу, построение графа вызовов вверх/вниз от узла, SQL-запрос к аналитическим таблицам (объекты, реквизиты, типы), полнотекстовый и семантический поиск, и отдельно — интерфейсные действия (открыть найденную функцию, переключить вкладку, подсветить узел в дереве конфигурации).

Цепочка функций через модули — не то, что агент ищет, а то, что он уже знает

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

У агента эта связка не строится на лету по запросу — она уже собрана на этапе загрузки и разбора конфигурации, вместе со всей остальной аналитической моделью. Когда агент вызывает построение графа вызовов, он не парсит заново текст четырёх модулей — он читает уже готовые рёбра графа, вычисленные один раз при загрузке (и пересчитанные инкрементально после правок, по той же логике, что и остальная аналитика). Это разница между "найти" и "уже знать, где искать": агенту не нужно тратить шаги tool-calling на banальный обход текста в поисках связей — эти шаги уходят на реальную работу с найденным.

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

Из той же готовой базы агент получает доступ к остальному, что накоплено статическим анализом задолго до появления ИИ-части: результаты девяти сканеров (безопасность, производительность, транзакции, блокировки, фоновые задания, плохие имена переменных, рекурсия), роли и права доступа к объектам, реквизиты форм и макетов. Всё это — не то, что агент "ищет" по вашему запросу, а то, к чему он уже имеет прямой доступ через SQL-запрос к готовым таблицам.

Что агент реально делает с кодом

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

  • Дорабатывает существующую. Читает текущий код и контекст — какие объекты и реквизиты уже используются — и правки вписываются в сложившуюся логику, а не торчат чужеродной вставкой.

  • Разбивает и переписывает. Громоздкую функцию — на несколько, участок кода — другим способом, с опорой на то, как аналогичные задачи уже решены в этой же конфигурации.

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

  • Собирает и дорабатывает запросы по реальным объектам — с учётом расширений, как в примере выше, а не по абстрактной "стандартной" схеме.

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

Векторный поиск: без эмбеддингов в облаке

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

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

Ключевое архитектурное решение здесь — эмбеддинг-модель считается локально, отдельным Python-процессом (sidecar), который держится в памяти постоянно, а не поднимается заново на каждый вызов — иначе стоимость холодного старта модели убила бы всю практическую пользу от локального счёта. Индексация не отправляет код в облако вообще: весь массовый прогон по конфигурации — потенциально десятки тысяч функций — происходит на диске пользователя. В облако при работе уже подключённого агента уходит не индекс и не база целиком, а точечный контекст под конкретный вопрос: код той функции, которую агент решил прочитать, результат конкретного поискового запроса.

Практический эффект: семантический и полнотекстовый поиск работают в связке — гибридный поиск, где агент сам решает (или комбинирует), какой из двух методов дать по конкретному вопросу, потому что у них взаимно компенсирующиеся слабые места. Точное совпадение по редкому идентификатору — забирает FTS5. Вопрос, сформулированный своими словами без единого точного термина из кода — забирает векторный поиск.

Переиндексация — инкрементальная и фоновая: при изменении конфигурации не нужно пересчитывать эмбеддинги для всего проекта заново, только для объектов, которые реально изменились (та же логика, что уже была в базовом аналайзере для основной загрузки — сверка по ConfigDumpInfo.xml), и фоновый процесс синхронизации отделён от основного потока загрузки, чтобы не блокировать интерфейс на время переиндексации.

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

Прямой вызов Функция() в тексте — самый простой случай для построения графа. В 1С хватает мест, где реальная связь между кодом спрятана иначе:

  • Выполнить() с динамически собранной строкой — вызов, которого в статическом тексте функции просто нет, потому что имя вызываемого метода формируется в рантайме;

  • Оповещения (ОповеститьОВыполнении → обработчик ПриОповещении) — связь между тем, что оповестило, и тем, что среагировало, не выражена прямым вызовом функции;

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

  • Фоновые задания — асинхронная точка входа, где что запускает и что происходит внутри задания — две разные вещи с точки зрения обычного построения графа "кто кого вызывает".

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

Деньги

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

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

Риски

Как у любого инструмента, который подключает LLM к вашему коду — Cursor, Copilot, что угодно ещё, не только у меня:

Часть кода уходит в облако. Чтобы модель ответила на вопрос про вашу функцию, ей нужно эту функцию увидеть. Так работает tool-calling в принципе, это не обходится никаким инженерным трюком. Если в конфигурации есть код, который вы ни при каких условиях не готовы показывать третьей стороне — на такие участки любой ИИ-инструмент лучше не натравливать, работайте по старинке.

Модель может уверенно ошибаться. Ни один такой инструмент не гарантирует корректность сгенерированного кода. Там, где агенту не хватило контекста, он может дорисовать деталь — и звучать при этом убедительно. Код от ИИ — черновик для code review, а не готовое решение для прод-базы без проверки. Чем рутиннее задача, тем проще перестать перепроверять — и именно там ошибка чаще всего проскакивает.

Зависимость от внешнего сервиса. Доступность и лимиты — не полностью в ваших руках. На этот случай в продукте ничего не сломается критично: статический анализ (графы, сканеры, поиск) работает полностью локально и от облака не зависит в принципе — если завтра upstream-провайдер модели изменится или станет недоступен, вы теряете только AI-надстройку, а не весь инструмент.

Куда дальше

Сейчас агент работает на одной модели с поддержкой tool-calling и справляется с этим уверенно — сама архитектура не завязана на конкретную модель, она заменяемый компонент, а не то, вокруг чего написана вся логика. Дальше буду добавлять модели в качестве выбора, в том числе российские — не для галочки про импортозамещение, а потому что для части 1С-инсталляций (бюджетные организации, компании с требованиями по локализации данных) вопрос "какая модель и где физически стоит инфраструктура" не абстрактный, а рабочий.

Параллельно — дальнейшая прокачка ответов на многослойных запросах и расширение покрытия косвенных связей в графе.

Ссылка на youtube версию:https://youtu.be/j_G6PCK5SuU

Итог

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

Отличие от "просто прикрутить ChatGPT" — не в маркетинге, а в том, что он в принципе не может писать код по вашей конфигурации, если её не видит. Я решил это архитектурой: агент с tool-calling, который сначала читает вашу реальную базу — граф вызовов, реквизиты, типы, расширения — и только потом пишет код. Не "код в стиле 1С", а код, который сразу встаёт в вашу архитектуру, потому что построен на данных о том, что там реально есть.

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

Попробовать можно с бесплатным стартовым бонусом на балансе, без обязательств: lycurg.com/page_soft_MetaVisionAI.htm.

Комментарии (1)


  1. CrushBy
    29.08.2026 16:23

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

    Мы в lsFusion сделали MCP прямо в сервере приложений: внешний агент читает реально загруженные исходники и может выполнять lsFusion-скрипты под правами пользователя. Например, на демо MyCompany Claude по одному запросу разбирает бизнес-логику, проверяет данные и замечает ограничения, о которых его прямо не спрашивали.

    Вот пример : https://claude.ai/share/bd0b0d12-75e5-4d6f-ade3-8e78f55984f3

    Планируете добавить такой execution/verification loop и, возможно, открыть вашу аналитическую модель через MCP для любых клиентов — Claude, Codex и т. п.?