Как мы научили ИИ-агента понимать чужую кодовую базу: вместо чанков — три источника фактов

Мы — разработчики MetaVision for 1C: AI, десктопной программы для статического анализа конфигураций 1С с ИИ-агентом. Столкнулись с очевидной, в ретроспективе, проблемой: стандартная RAG-схема «порезать код на чанки, посчитать embeddings, достать похожие» на реальных кодовых базах почти не работает. Рассказываем, почему, и что мы построили вместо неё — на живых примерах из нашей программы.
Откуда мы и с какой проблемой столкнулись
MetaVision for 1C: AI — десктопная программа для статического анализа кода 1С, поверх которой работает ИИ-агент с tool-calling. Пользователь задаёт вопрос по своей базе — «кто вызывает эту процедуру», «где мы проверяем просрочку», «собери запрос по этим объектам» — а агент отвечает по фактам из его реальной конфигурации, а не «в среднем по интернету».
Для этого агент должен как-то видеть кодовую базу. Классическое решение — RAG: режем тексты на чанки, считаем embeddings, по векторному поиску достаём топ-K похожих кусков и вкладываем их в промпт. Мы попробовали этот путь на конфигурациях 1С — тысячах объектов, сотнях тысяч строк — и быстро поняли, что он не работает. Не «работает плохо», а именно не работает: агент уверенно отвечал «в базе такого нет» там, где такое было. Разбираем по пунктам, почему.
Почему чанки провалились на коде
Причина 1. Ответ — часто не текст, а структура.
«Кто вызывает эту процедуру?» — ответ не «похожий кусок кода», а список мест, то есть связи между объектами. «У каких документов есть реквизит с таким-то типом?» — ответ лежит в схеме базы, а в тексте его нет вообще. Похожие чанки таких ответов не содержат в принципе.
Причина 2. Чанки рвут связи.
Функция попадает в один чанк, место её вызова — в другой, а связь между ними может быть прописана не в коде, а в настройках системы (в 1С — подписки на события и оповещения). Векторный поиск вернёт три нерелевантных куска — и LLM с уверенным лицом ответит «таких мест нет». Для пользователя это худший из ответов: он звучит как факт.
Причина 3. Вопросы «перечисли все» не влезают в контекст.
«Перечисли все модули, которые пишут в этот регистр» — это запрос с группировкой по всей базе. RAG решает его перебором чанков в контексте — на большой базе контекста LLM не хватит. А SQL решает за миллисекунды.
Что мы построили: три источника фактов в одной SQLite
Вместо «поиска похожих кусков» мы собрали в локальной базе SQLite три источника — и научили агента выбирать между ними.
1. SQL-индекс по структуре базы. Из выгрузки кода собирается настоящая реляционная база: объекты, реквизиты с типами, движения документов, права. Агент ходит по ней обычным SQL. Все вопросы про структуру — «кто ссылается на реквизит», «какие документы делают движения по регистру» — его территория: точно, быстро, с группировками.
2. Полнотекстовый поиск (FTS5). Быстрый поиск по точным словам. Если вы знаете имя функции или переменной — это самый короткий путь. Но спросите «где мы проверяем просрочку», а в коде слово «просрочка» не встречается ни разу — FTS молча вернёт пустоту.
3. Векторный поиск по смыслу. Каждая функция получает embedding — «отпечаток смысла» своего кода (локальная модель, считается на ПК пользователя без интернета). Именно векторный поиск находит «проверку просрочки», когда ни одно слово из вопроса не совпадает с кодом. Это тот самый RAG-слой — просто не единственный источник, а третий из трёх.
И четвёртый, бонусный источник — граф вызовов, посчитанный заранее, включая скрытые связи: динамический Выполнить(), оповещения, подписки на события. Этих связей в тексте кода нет в принципе — никакой поиск по тексту их не найдёт, их можно только вычислить заранее.
Принципиальное решение: мы НЕ склеили источники в один «гибридный поиск». Какой источник нужен — зависит от вопроса, и выбирать должен ИИ-агент в моменте, а не автоматический пайплайн до него.
Как это работает на живых вопросах
Агент получает инструменты — по одному на каждый источник (всего у него 71 инструмент, лимит — 30 шагов расследования). Три реальных маршрута:
«Где мы проверяем просрочку по контрагенту?» — ни одно слово из вопроса не встречается в коде. Агент идёт в векторный поиск → находит функцию с именем КонтрольЗадолженностиКонтрагента → читает её → отвечает с адресом.
«Кто вызывает эту процедуру?» — агент идёт в граф вызовов → получает готовый список, включая два оповещения и одну подписку, которые поиск по тексту не видит никогда.
«Свяжи счета на оплату с заказами клиента» — прямого реквизита связи нет. Агент проверил по SQL-индексу реквизит «Основания» — не связывает; нашёл через таблицу документов-оснований счёта-фактуры обходную цепочку; собрал корректный запрос. Каждый шаг опирается на факт из базы, а не на догадку.
Грабли, на которые мы наступили
Результаты надо резать. Если инструмент вернёт 500 строк, они съедят контекст и ответ станет хуже. У каждого инструмента — свой потолок результата.
Инструменты надо фильтровать. Описания всех 71 инструмента — это 80 КБ текста на каждый запрос к LLM. Поэтому агенту подставляются только инструменты, подходящие к теме вопроса.
Агент всё забывает. Модель не помнит, что сама делала пять шагов назад: ходит по кругу, противоречит себе. Лечится журналом: каждое обращение к инструменту пишется в короткий журнал (последние 40 записей), и он подкладывается агенту перед ответом — «ты это уже проверял».
Пустой ответ — не ответ. Если поиск ничего не нашёл, это не значит, что «в базе такого нет». Правило агента: минимум две попытки разными инструментами, прежде чем заявлять об отсутствии.
Итоги
Главный вывод полутора лет работы: чанковый RAG отлично подходит текстам — статьям, документации, PDF. Но код живёт не в тексте, а в структуре: связи, типы, схема базы. Поэтому «дать LLM доступ к коду» — это не «вложить похожие куски в промпт», а построить несколько источников фактов и научить агента выбирать между ними:
SQL — для вопросов про структуру;
FTS5 — для точных имён;
векторный поиск — для смысла;
граф вызовов — для связей, которых в тексте нет.
Всё это уже работает в MetaVision for 1C: AI (версия 3.2): ИИ-агент с 71 инструментом отвечает по вашей реальной конфигурации 1С, весь статический анализ — локально и без интернета, программа бесплатная, есть редакция с ИИ на серверах в России (RU Edition).
Ознакомиться:
MetaVision for 1C: AI Custom Edition
MetaVision for 1C: AI · RU Edition
Статья с примерами на infostart
Расскажите в комментариях, как вы даёте нейросетям доступ к своему коду — и что из этого работает, а что нет.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.