- BrainTools - https://www.braintools.ru -
Разбор архитектуры ИИ-агента для статического анализа кода: локальный индекс на SQLite, 71 инструмент, цикл tool-calling на 30 ходов и валидаторы, которые мы написали и сами же сняли, потому что они ложно срабатывали на валидных файлах.
Вайб-кодинг отлично работает там, где весь нужный контекст помещается в промпт: скрипт, лендинг, небольшой сервис. Но возьмите большую legacy-систему — у меня это конфигурации 1С:Предприятие, тысячи объектов метаданных, сотни тысяч строк кода, связи, прописанные не в коде, а в структуре (реквизиты с типами, движения документов, подписки на события, RLS в ролях).
Посчитаем в лоб: даже окно в 128K токенов — это порядка ста тысяч символов кода. То есть модель видит 1–2% базы. Остальные 98% она достраивает из статистики обучения [1] — отсюда и классическая картина: нейросеть для 1С уверенно пишет код с реквизитом, которого в этой конфигурации нет, и вызовом несуществующего метода. Проблема не в том, что модель глупая. Проблема в том, что мы просим её угадывать то, что можно просто прочитать.
Отсюда постановка: не тащить код в модель, а дать модели инструменты, чтобы она сама ходила по базе и доставала нужные факты. Это, по сути, RAG, но не «найти чанк и вставить в промпт», а полноценный агент с циклом tool-calling.
Такой ИИ-агент я построил внутри десктопного анализатора конфигураций 1С (проект опенсорсный, ссылка в конце). Дальше — как он устроен, с цифрами и граблями.
Первое принципиальное решение: индекс живёт локально на машине пользователя, а не в облаке. Кодовая база — это коммерческая тайна, и требование «передай весь репозиторий нашему сервису» убивает продукт на месте.
Как устроен индекс:
Структурированные данные — SQLite: объекты метаданных, реквизиты с типами, формы, движения документов, права и RLS-ограничения, значения перечислений. По этому индексу агент выполняет настоящий SQL — это даёт точные ответы вида «перечисли всех, кто ссылается на этот реквизит».
Полнотекстовый поиск — FTS5. Быстро, точно, но находит только то, что совпадает по словам.
Семантический поиск — локальная мультиязычная модель эмбеддингов (384 измерения) строит векторы для каждой функции и объекта. Индексация считается офлайн, на машине пользователя, один раз при подключении проекта, дальше поддерживается в фоне.
Почему оба поиска, а не только векторный: они компенсируют слабости друг друга. Векторный находит «проверку просрочки задолженности», даже если в коде нет ни одного слова из запроса. FTS находит точное имя переменной, которое эмбеддинги размазали. Решать, какой применить, — обязанность агента.
Отдельно стоило усилий граф вызовов. Обычный статический анализ ловит только прямые вызовы Функция(). Но в 1С полно скрытых связей: Выполнить() со строкой, собранной в рантайме, оповещения (ОповеститьОбИзменении → ОбработкаОповещения), подписки на события, где связь вообще прописана в метаданных, а не в тексте. Все эти каналы граф учитывает — иначе агент на вопрос «что сломается, если я поменяю эту процедуру» отвечает «ничего», а сломается фоновое задание.
Вместо мультиагентного релея (классификатор → поисковик → генератор, где на каждой передаче теряется контекст) — единый агент с нативным tool-calling: модель сама решает, какой инструмент вызвать, получает результат и решает дальше. Цикл — до 30 ходов на вопрос. Это важная цифра: с 8–16 ходами агент на сложных вопросах стабильно не доезжал — и мы это поднимали не один раз (в истории константы так и осталась цепочка 8 → 15 → 12 → 16 → 30).
Арсенал — 71 инструмент, четыре группы:
Поиск и типизация: семантический поиск, литерал-поиск, разрешение сущностей («открой документ проведения» → конкретный модуль), паспорта функций с выведенными типами.
Данные: SQL к локальному индексу (только SELECT), графы вызовов вверх/вниз, полнотекстовый и векторный поиск.
Правки: точечные патчи, вставки, замены строк, разбиение функций — с diff-панелью «оригинал/доработка».
Доменные: правка отчётных схем семантическими операциями («добавь колонку», «сделай вариант», «добавь итог») и веб-поиск по выверенному белому списку сайтов.
Инженерные находки, без которых цикл разваливался:
Журнал проверок. LLM не помнит, что сама же сделала пять ходов назад: агент переспрашивал базу теми же запросами и противоречил собственным выводам. Лечится журналом: каждый вызов инструмента пишет компактный след (инструмент + аргументы + короткий результат), а перед следующим вопросом агенту подкладывается блок «ты это уже проверял: …». Держим последние 40 записей с обрезкой по границе.
Урезание результатов тулов. Сырой SQL-выброс на 500 строк убивает контекст быстрее, чем помогает. У каждого инструмента свой потолок результата, у некоторых — умная обрезка (SQL режется по границе строкового литерала, длинные статьи отдаются с подсказкой «перечитай с фильтром по слову X»).
Фильтрация инструментов по теме. Все 71 схема инструментов — это ~80 КБ текста на каждый запрос. Когда вопрос про код, СКД-инструменты оплачиваются и съедают контекст впустую. Решение: у инструментов есть темы, у вопроса — темы (по словесным триггерам, содержимому открытых файлов и семантическому роутеру по эмбеддингам), на сервер пересылаются только релевантные схемы. Тот же список тем заодно автоматически подгружает модели предметные справочники по платформе.
Маркеры хода. На каждом хопе модель видит «[СИСТЕМА] Ход N из 30, осталось K». За 4 хода до лимита — мягкое предупреждение («укрупняй пачки, новых веток не начинай»), за 2 — принудительная просьба честно резюмировать найденное вместо генерации полупустого ответа.
Агент правит не только код, но и декларативные артефакты — у нас это XML-схемы отчётов (СКД). И здесь главная боль [2]: модель вносит правку, которая структурно валидна и при этом не открывается в платформе. Пользователь сохраняет файл, грузит в конфигуратор — и получает «Поле не найдено».
Поэтому цепочка проверок после каждой правки, до того как ответ агента уйдёт пользователю:
Сходимость тегов и порядок разделов — банально, но нужно.
Сверка с формальной моделью формата. К нам в комплект идёт официальная XDTO-модель схемы из инструментария вендора (8 файлов): вложенность и состав элементов проверяются по ней, с наследованием классов. Грабли: имена классов модели не совпадают с XDTO-именами в XML (таблица соответствий), а незнакомые типы из чужих пространств имён — это НЕ ошибка [3], иначе проверка три хода подряд заставляла модель переписывать здоровый блок.
Ссылочная целостность — дубли имён и битые перекрёстные ссылки (связь наборов данных → несуществующий набор). Это не ловит ни сходимость тегов, ни модель формата: файл валиден по обеим проверкам и всё равно не открывается.
Семантика запросов внутри схемы — дубли псевдонимов в списке выборки одной ветки (платформа такое не открывает, а грамматический парсер пропускает — это уже семантика), битые ссылочные цепочки вида Ссылка.РеквизитТабличнойЧасти, множение строк при соединении с табличной частью.
Проверки делятся на advisory (⚠️ в ответ тула — чинить, но можно) и blocking (правка не применяется, агент обязан исправить).
А теперь самое ценное — честный список проверок, которые мы написали и сняли, потому что они ложно срабатывали на валидных файлах (калибровали на ~600 эталонных схемах из реальных конфигураций):
«дублирующийся dataPath» — точные повторы легальны (97 файлов с «нарушениями»);
«двойные кавычки в запросе» — в языке это экранированная кавычка, легально (159 файлов);
«поле вывода не существует» — виртуальные таблицы и оборотные поля в индексе не живут (139 файлов).
Вывод, который я вынес: «просто валидируй по спеке» не работает. Формат допускает больше, чем кажется, а ваша выборка валидных файлов всегда уже, чем реальный мир. Калибровка на сотнях настоящих файлов — обязательный этап, и правило простое: проверка не имеет права срабатывать на родных, заведомо валидных артефактах. Лучше advisory, чем блок с ложным срабатыванием.
Коротко, но каждый пункт стоил дня отладки:
Обрыв длинных SSE-стримов. CURLOPT_TIMEOUT — это общий лимит на весь запрос, включая чтение стрима. 45 секунд резали длинные ответы посреди передачи. Частичный ответ ретраить нельзя (получишь задвоенный текст) — вопрос падал пользователю. Лечится связкой чисел: таймаут стрима > окно воркера > время чистки зависших задач > клиентский таймаут, в строгом порядке возрастания. Менять по одному нельзя.
Атомарный захват задач из очереди — SELECT … FOR UPDATE до UPDATE status='processing', иначе перекрывающиеся воркеры обрабатывают одну заявку дважды.
Переполнение истории диалога — после десятков сообщений деградирует качество ответов. Сжатие: при превышении порога старые сообщения сворачиваются в сводку, остаются последние N.
Несовпадающие маркеры ретрая. Клиент искал в тексте ошибки одну строку, а реально бросалась другая («Связь с сервером X прерывается») — из-за несовпадения автоматический повтор обрыва связи молча не срабатывал и пользователь видел ошибку. Мелочь, а месяц жила как баг «иногда не работает».
Типовой вопрос средней сложности проходит 6–12 ходов: найти объект → прочитать код → построить граф → проверить реквизиты → ответ. Сложные («перепиши запрос, который сломался после обновления, и объясни выбор данных») — до 20+. Пример реального кейса: задача «свяжи счета на оплату с заказами клиента» — прямого реквизита нет, агент нашёл обходную цепочку через документы-основания счёта-фактуры и собрал корректный запрос с РАЗРЕШЕННЫЕ и проверками на пометку удаления. Наугад такое не пишется — это ровно те факты, которые лежат в индексе.
Что это даёт на практике: ИИ-ассистент перестаёт быть «ChatGPT про 1С» и превращается в инструмент, который отвечает по вашей реальной кодовой базе — весь статический анализ при этом работает локально и без интернета.
Всё описанное — не экспериментальная поделка, а программа MetaVision for 1C: AI, дошедшая до версии 3.2 после полутора лет боевых правок на реальных конфигурациях. Что в ней есть:
статический анализ конфигураций 1С: 9 сканеров проблемного кода (производительность, безопасность, транзакции, блокировки и другие), графы вызовов со скрытыми связями, векторный поиск по смыслу;
загрузка не только основной конфигурации, но и расширений (с учётом аннотаций переопределения) и внешних обработок — анализируется та конфигурация, которая реально работает;
работа ИИ-агента с кодом прямо в программе: правки в две панели (оригинал/доработка с подсветкой изменений), правка отчётных схем семантическими командами с автопроверками, разбор ошибок по скриншоту;
работает на Windows и Linux, бесплатно; платится только работа ИИ — по балансу, по факту.
Редакции две, функционал одинаковый — отличаются тем, чьи модели обрабатывают запросы:
Custom Edition — модели DeepSeek V4 и GLM. Вариант по умолчанию, если нет требований к региону обработки кода.
RU Edition — российские модели (Yandex Qwen3, Yandex DeepSeek V4) через Yandex AI Studio, на серверах в России. Работает из России без VPN, оплата российской картой или через СБП. Выбор для тех, кому важно, чтобы обработка кода шла в российской инфраструктуре.
Использовать можно не только в режиме вайб-кодера («напиши мне функцию»). Второй режим, который пользователи в итоге ценят не меньше, — глубокий анализ: принять чужую конфигурацию и за вечер понять, как она устроена, найти всех, кто ссылается на реквизит перед удалением, разобраться, почему падает отчёт, проследить цепочку вызовов через оповещения и подписки. Вайб-кодинг здесь — частный случай, а не суть.
Сайт и скачивание:
Custom Edition [4]
RU Edition [5]
Автор: sladkiyzmey
Источник [6]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/35982
URLs in this post:
[1] обучения: http://www.braintools.ru/article/5125
[2] боль: http://www.braintools.ru/article/9901
[3] ошибка: http://www.braintools.ru/article/4192
[4] Custom Edition: https://lycurg.com/page_soft_MetaVisionAI.htm
[5] RU Edition: https://lycurg.com/page_soft_MetaVisionAI_ru.htm
[6] Источник: https://habr.com/ru/articles/1086266/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1086266
Нажмите здесь для печати.