В последние годы любая серьёзная система автодополнения или генерации кода (от небольших чат-ботов до мощных корпоративных решений) использует встроенный механизм поиск кода (code retrieval) — то есть поиск подходящих сниппетов кода по векторному представлению (эмбеддингам) как запроса, так и фрагментов кода. Однако многие разработчики жалуются, что непонятно, как именно объективно проверять качество такого векторного поиска. В новостном материале Voyage AI детально разбирается данная проблема — от описания подсущностей запроса до того, почему все существующие открытые бенчмарки для поиска кода часто не отражают реальной картины.
Почему векторный поиск по коду так важен?
🧩 Ускорение разработки
Если IDE или чат-ассистент может по запросу (например, «напиши функцию для усредняющего пуллинга (average pooling) в PyTorch») быстро находить уже готовые решения, то разработчику не придётся «изобретать велосипед». Это особенно востребовано для больших репозиториев кода.
🧩 Унификация подходов
Разработчики всё чаще используют embedding-модели, которые «упаковывают» и код, и текстовые запросы в одно и то же векторное пространство. Тогда поиск становится обычным запросом поиска ближайшего соседа (nearest-neighbor) в этом пространстве, что сильно унифицирует архитектуры бэкенда.
🧩 Сложность реальной оценки
Проблема в том, что реальный код может быть многоязыковым, содержать алгоритмические нюансы, а также иметь разрозненную документацию. Поэтому не всё так просто — нельзя просто сказать: «Если функция называется так же, то она подходит».
Три ключевых вида задач поиска
Voyage AI выделяет три основных подзадачи, каждая — со своим типом запроса (query):
- 💬 Поиск кода по текстовому запросу (Text-to-code): мы имеем естественный язык (например, «функция усреднённого пуллинга в PyTorch»), а хотим найти соответствующие сниппеты кода.
- 🧑💻 Поиск кода по коду (Code-to-code): на входе — фрагмент кода, на выходе — аналогичный или похожий сниппет, возможно на разных языках.
- 📝 Поиск кода по описанию (Docstring-to-code): пользователь вводит сигнатуру функции, её вход-выход (что-то вроде «подпись: avg_pool_1d(input, kernel_size) -> Tensor»), а система ищет подходящие реализации.
На практике в приложении смешиваются эти типы запросов, но для оценки проще выделить их отдельно.
Проблемы существующих бенчмарков
🔎 Датасет CoSQA и ошибки разметки
Например, датасет CoSQA популярен, но, как выяснили исследователи, до 51% меток там некорректны. Коды и вопросы взяты из разных источников (Bing-поиск, CodeSearchNet), и часто несостыкованы по смыслу. Итог: даже если метрики кажутся высокими, это может быть просто «угадывание» шумных совпадений.
🔎 Прямые совпадения строк (CodeSearchNet)
Часто запросы и код в датасетах фактически совпадают по формулировке (как будто комментарии из кода один-в-один сформулированы в запрос query). Это сильно упрощает задачу и «задирает» оценку точности, тогда как реальные ситуации сложнее.
🔎 Переобучение (data contamination)
Многие наборы имеют публичный выборку тренировочную и тестовую (train + test), и модель фактически «запоминает» тестовые фрагменты. Тогда кажущееся высокое качество не означает, что решение будет работать на незнакомом проекте. Это типично и для других универсальных тестов для поиска (general-purpose retrieval MTEB).
Как создавать датасеты «с нуля»
Voyage AI предлагает два подхода:
- 🤔 Переиспользовать QA-датасеты
Любой вопрос-ответ (Q,A) можно превратить в задачу поиска, где Q — это «запрос», а все ответы (A) в совокупности образуют пул документов. Тогда задача — найти именно тот ответ (A), который правильно отвечает на вопрос. Если говорить о коде, это может быть коллекция решений на алгоритмическом QA, где Q — формулировка задачи, A — конкретная реализация.
Преимущество: минимизируем ложные метки, так как ответы однозначны. - 🤔 Issues и PR из GitHub
Если взять реальные задачи (issues) из репозитория и посмотреть, какие файлы / функции были изменены, чтобы решить задачу, можно сформировать пару («issue» → нужный фрагмент кода). У Voyage AI есть такой набор данных SWE-bench-lite, где репозиторий и связанные задачи дают репрезентативный набор реальных случаев.
Метрики: Recall@k, NDCG
Стандартная метрика для поиска кода — Recall@k: доля случаев, когда среди top-k найденных документов есть «золотой» (gold) ответ. Ещё распространён NDCG (Normalized Discounted Cumulative Gain - нормализованная дисконтированная кумулятивная прибыль), где учитывается порядок расположения верных ответов.
Однако, если разметка некачественная (как в CoSQA), модель, даже будучи хорошей, может показывать абсурдные результаты. С другой стороны, если в обучающей выборке случайно присутствуют тестовые данные, результат может искусственно «зашкаливать» из-за переобучения.
Новый взгляд: предложения Voyage AI
Для реальной (промышленной) оценки стоит:
- 🤖 Избегать обучающей утечки: не включать те же фрагменты в тренировочной выборке, что и в тестовой выборке.
- 🤖 Добавлять больше сложных, «алгоритмических» примеров, где требуется понять суть (binary search, graph traversal).
- 🤖 Проверять на нескольких подзадачах (text-to-code, code-to-code, docstring-to-code) и нескольких языках.
- 🤖 Использовать QA-датасеты и задачи, чтобы реплики были действительно релевантны, а не взяты «с потолка».
- 🤖 Соблюдать объективность: возможно, там, где нет очевидного «одного» правильного ответа, нужно несколько релевантных сниппетов.
К чему всё ведёт
Векторный поиск по коду — это уже стандартный механизм во множестве компаний и в open-source индустрии. Но чтобы такая технология и дальше развивалась, нужны:
- 🛠️ Более «честные» тестовые наборы без случайных совпадений и неправильных меток.
- 🛠️ Лучшее понимание многоязычных запросов (C++ → Python, TypeScript → Go).
- 🛠️ Учёт «реальных» примеров, где вопрос звучит так, как пользователь действительно сформулировал бы в IDE или чат-модели.
Фактически, задача всё ещё остаётся открытой: большая часть публичных датасетов не годится для строгой валидации (проблемы с утечками, шумом, упрощённостью). Надёжный бенчмарк, возможно, появится, если сообщество начнёт публиковать свежие датасеты без повторов. Voyage AI обещает выпустить часть наработок в открытый доступ, так что остаётся лишь ждать и, может, присоединяться к их инициативе.