
Открываешь агента, даёшь задачу — и видишь, как он уверенно лезет не в тот модуль. Не потому что глупый: он не знает, что «оплата» у нас живёт в папке billing, а не в payments. Пока не подскажешь, он листает репозиторий наугад и жжёт контекст.
Раньше я решал это по-человечески: держал в голове карту проекта и подсовывал нужные файлы руками. Тридцать тысяч строк, из которых в конкретной задаче важны пять. grep выручает, когда помнишь точное имя функции, и молчит, когда помнишь смысл: «где мы вообще считаем скидки».
Что изменилось
Google DeepMind выложила EmbeddingGemma 2 — открытую модель эмбеддингов под Apache 2.0. Она кладёт текст (включая код), картинки, видео и аудио в одно векторное пространство на 768 измерений. Всего 740 миллионов параметров, но текстовое ядро из них — 270, остальное подключаемые энкодеры зрения (170) и звука (300). Для поиска по коду нужна только текстовая часть.
Цифры, которые меня зацепили: в квантованном виде текстовая часть занимает около 191 МБ оперативной памяти, полная мультимодальная — 567 МБ. Контекст 8 тысяч токенов, больше ста языков, а по коду прирост против первой версии заметный: в MTEB Code 78,68 против 68,76.
Как это выглядит в работе
Репозиторий индексируется один раз: каждый файл превращается в вектор и ложится в локальную базу. Дальше на запрос «где считаются скидки для постоянных клиентов» поиск отдаёт пять файлов по смыслу — и ровно их получает агент. В облако не уходит ничего: модель работает на ноутбуке, вектора тоже лежат у меня.
Одна тонкость из практики: голый код индексируется хуже, чем код с подсказками. Полезно вытащить сигнатуру функции, разбить слипшиеся имена вроде calcDisc на отдельные слова и подмешать докстринги с комментариями — тогда запрос «где считаем скидки» находит нужный файл, а не соседний с похожим названием.
Выигрыш не в качестве ответа, а во времени: агент перестаёт перебирать репозиторий и сразу берётся за дело. И это не только про код — та же модель находит нужный кусок в записи созвона или кадр в видео.
Где подвох
EmbeddingGemma 2 ничего не отвечает — она только ищет. Ответ по-прежнему пишет языковая модель, и если поиск подсунул мусор, ответ будет мусорным.
Вектора надо где-то хранить: 768 чисел на каждый фрагмент — это гигабайты на большом проекте. Спасает «матрёшка»: размерность можно урезать до 512, 256 или 128 и хранить в шесть раз меньше почти без потери качества. Восемь тысяч токенов — это не целый файл, а его часть, так что резать код на куски всё равно придётся самому.
Что я бы сделал на вашем месте
Взять текстовую часть — веса есть и в GGUF, квантованные версии собрал unsloth, — проиндексировать один свой репозиторий и неделю смотреть, как часто агент попадает в нужные файлы с первого раза. Попадает — индекс оставляем. Не попадает — значит, дело было не в поиске.