- BrainTools - https://www.braintools.ru -

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

Мы — разработчики MetaVision for 1C: AI, десктопной программы для статического анализа конфигураций 1С с ИИ-агентом. Столкнулись с очевидной, в ретроспективе, проблемой: стандартная RAG-схема «порезать код на чанки, посчитать embeddings, достать похожие» на реальных кодовых базах почти не работает. Рассказываем, почему, и что мы построили вместо неё — на живых примерах из нашей программы.

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

Откуда мы и с какой проблемой столкнулись

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. Поэтому агенту подставляются только инструменты, подходящие к теме вопроса.

Агент всё забывает [1]. Модель не помнит, что сама делала пять шагов назад: ходит по кругу, противоречит себе. Лечится журналом: каждое обращение к инструменту пишется в короткий журнал (последние 40 записей), и он подкладывается агенту перед ответом — «ты это уже проверял».

Пустой ответ — не ответ. Если поиск ничего не нашёл, это не значит, что «в базе такого нет». Правило агента: минимум две попытки разными инструментами, прежде чем заявлять об отсутствии.

Итоги

Главный вывод полутора лет работы: чанковый RAG отлично подходит текстам — статьям, документации, PDF. Но код живёт не в тексте, а в структуре: связи, типы, схема базы. Поэтому «дать LLM доступ к коду» — это не «вложить похожие куски в промпт», а построить несколько источников фактов и научить агента выбирать между ними:

  • SQL — для вопросов про структуру;

  • FTS5 — для точных имён;

  • векторный поиск — для смысла;

  • граф вызовов — для связей, которых в тексте нет.

Всё это уже работает в MetaVision for 1C: AI (версия 3.2): ИИ-агент с 71 инструментом отвечает по вашей реальной конфигурации 1С, весь статический анализ — локально и без интернета, программа бесплатная, есть редакция с ИИ на серверах в России (RU Edition).

Ознакомиться:

 MetaVision for 1C: AI Custom Edition [2]

MetaVision for 1C: AI · RU Edition [3]

Статья с примерами на infostart [4]

Расскажите в комментариях, как вы даёте нейросетям доступ к своему коду — и что из этого работает, а что нет.

Автор: sladkiyzmey

Источник [5]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/36033

URLs in this post:

[1] забывает: http://www.braintools.ru/article/333

[2] MetaVision for 1C: AI Custom Edition: https://lycurg.com/page_soft_MetaVisionAI.htm

[3] MetaVision for 1C: AI · RU Edition : https://lycurg.com/page_soft_MetaVisionAI_ru.htm

[4] Статья с примерами на infostart: https://infostart.ru/1c/articles/2773363/

[5] Источник: https://habr.com/ru/articles/1086582/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1086582

www.BrainTools.ru

Rambler's Top100