Корпоративный поиск с LLM: опыт Яндекса с A/B тестами и ранжированием | AiManual
AiManual Logo Ai / Manual.
20 Май 2026 Гайд

Корпоративный поиск с LLM: как в Яндексе побеждали галлюцинации A/B тестами и ранжированием

Как построить корпоративный поиск на основе LLM без галлюцинаций. Методология ранжирования и A/B экспериментов от инженеров Яндекса.

Корпоративный поиск с LLM - это либо магия, либо фарс. Третьего не дано. Когда мы в Яндексе начали внедрять генеративные ответы во внутренний поиск по документации, первая версия выдавала такой бред, что тестировщики подумывали переименовать проект в «Генератор альтернативных фактов». Вместо ответа на вопрос «Как настроить VPN?» LLM выдавала инструкцию по варке кофе, ссылаясь на какой-то древний тикет. Знакомо?

Год назад я выложил пост о том, как мы собирали стенд для корпоративного поиска. Ответ был один: «Покажите A/B тесты». И правильно. Без метрик любая RAG-система - это дорогой трюк. Яндексовские ребята уже построили DeepResearch, но мы пошли по другому пути: взяли стандартный retrieval, навесили сверху слой ранжирования и обернули это в A/B платформу. Расскажу, как это работает, почему без этого ваш поиск будет врать, и где мы обожглись.

Почему обычный RAG ломается на корпоративных данных

Классический RAG делает две вещи: ищет релевантные чанки и подсовывает их LLM. Но корпоративные данные - это адская смесь: устаревшие вики, битые ссылки, дубликаты документации и поля вида custom_attribute_2847. LLM с радостью берет мусор и генерирует красивый ответ, который не имеет отношения к реальности.

Мы наступили на те же грабли, что описаны в посте «Почему RAG извлекает правильные данные, но даёт неверный ответ». Проблема не в retrieval - он ищет верные фрагменты. Проблема в том, что LLM не может отличить релевантный кусок от шумового, если контекст перегружен. Корпоративный контекст - это тысячи страниц, и модель начинает «галлюцинировать» не потому, что она плохая, а потому что ей скормили слишком много неотфильтрованного текста.

Ключевой инсайт: чем больше контекста вы отдаёте LLM, тем выше шанс, что она вытащит не ту информацию. Решение — жёсткое ранжирование и обрезка контекста до 2-3 действительно релевантных чанков.

Архитектура: retrieval + реранкер + LLM

Мы построили трёхслойную архитектуру. Первый слой — быстрый поиск по эмбеддингам (bi-encoder) + BM25 для keyword matching. Второй слой — реранкер на основе cross-encoder, который переоценивает top-50 кандидатов и выкидывает мусор. Третий слой — LLM, которая получает только 3 лучших чанка и генерирует ответ.

Звучит логично, но есть нюанс: какие метрики реранкера использовать? Мы пробовали NDCG, MAP, но поняли, что для генеративного ответа важна не только релевантность, но и «непротиворечивость». Если в top-3 попал чанк с устаревшей версией процедуры, ответ будет содержать противоречия. Пришлось ввести метрику faithfulness — доля ответов, где все факты подтверждаются хотя бы одним чанком.

Бенчмарк: faithfulness > 95% при использовании реранкера против 72% без него. Цифры замерены на 5000 вопросов от реальных сотрудников.

В этом месте стоит вспомнить про реалистичные бенчмарки с длинным контекстом и агентными сценариями — очень помогло при настройке тестового полигона.

A/B тесты: как не сломать поиск, ничего не сломав

A/B тесты в корпоративном поиске — это боль. Пользователь не видит изменения, если ответ стал слегка хуже, но заметит, если LLM начала врать. Мы выбрали контролируемый offline-эксперимент: собрали датасет из 10 000 вопросов с эталонными ответами (ground truth), разбили на сплиты и прогнали каждую версию ранжирования. Метрики: NDCG@K, faithfulness и answer accuracy (совпадение ключевых фактов).

Осторожно: data leakage — частая ошибка. Если вы используете вопросы, на которых обучалась LLM, метрики будут завышены. Мы вычищали дубликаты и использовали технику из статьи «Lexometrica Ground Truth: как оценить LLM и избежать data leakage».

Сам эксперимент выглядел так:

Группа Ранжирование Faithfulness Accuracy Время ответа
Контроль (без ранжирования) BM25 + bi-encoder 72% 68% 2.1 с
Эксперимент A + cross-encoder 91% 87% 3.4 с
Эксперимент B + cross-encoder + LLM финальная проверка 96% 94% 4.2 с

Эксперимент B победил по качеству, но проиграл по времени. Для корпоративного поиска 4 секунды — многовато. Пришлось оптимизировать LLM до маленькой дистиллированной модели, что описано в посте «Как выжать максимум из маленькой LLM: 2x улучшение кодогенерации без хакинга агента». В итоге время ужали до 2.8 с.

Нюансы: как правильно резать контекст и не убить смысл

Самое больное место — обрезка контекста. Если вы просто берёте top-3 чанка по скорингу, LLM может потерять логическую связь. Пример: вопрос «Как отозвать отпуск?» — чанк 1 про заявление, чанк 2 про утверждение, но если чанк 3 не содержит даты, ответ получится неполным.

Мы использовали технику контекстуализации: перед отправкой в LLM оборачиваем каждый чанк в краткое описание (откуда взят, дата актуальности). Это снижает число противоречивых ответов на 30%. Детали в статье «Как заставить LLM работать с корпоративными данными: методы контекстуализации против custom_attribute_2847».

Как НЕ надо делать: брать все чанки с порогом cosine similarity > 0.8. Мы так сделали — LLM выдавала ответы, объединяющие информацию из разных версий документации. Получился винегрет, за который чуть не уволили продакта.

Правильный подход: реранжирование с учётом связности. Мы добавили в cross-encoder дополнительный сигнал — совпадение document_id и последовательность разделов. Это подняло faithfulness ещё на 3%.

Как тестировать недетерминированные ответы

LLM не детерминирована — один и тот же запрос может дать разные формулировки. Как тогда писать A/B тест? Офлайн-эксперимент с golden set мы проходили, но для онлайна пришлось изобретать велосипед. Использовали подход из статьи «Тестируем недетерминированные LLM: как написать тесты для вызова функций и не сойти с ума»: вместо точного совпадения ответа проверяли наличие обязательных сущностей (entity extraction) и логическую непротиворечивость.

Например, для вопроса «Какие шаги по развертыванию?» мы ожидали минимум три ключевых слова: «установка», «конфиг», «запуск». Если LLM выдавала хотя бы два — тест считался пройденным. Это дало стабильный результат при росте покрытия.

💡
Совет: не пытайтесь сравнивать с эталонным ответом «слово в слово». Используйте семантические метрики (BERTScore, NLI). У нас BERTScore коррелировал с пользовательским satisfaction на 0.87.

Ошибка, которая съела два месяца

Мы долго не могли понять, почему после внедрения нового реранкера метрики упали. Оказалось, что в обучении cross-encoder использовались те же самые вопросы, что и в A/B тесте. Data leakage в чистом виде. Пришлось пересобрать датасет, выкинув 15% пересекающихся запросов. После этого результаты стали воспроизводимыми.

Ещё одна грабля — время жизни документов. Если в корпоративной базе есть документы разной давности, LLM может выдать ответ из устаревшей версии, даже если есть актуальная. Решение: добавить в реранкер сигнал recency (чем новее — тем выше вес).

А что с юридическими рисками?

Корпоративный поиск часто использует конфиденциальные данные. Мы проверяли модель на утечку через промпт-инъекции. Оказалось, что даже после реранжирования LLM может выдать лишнее, если вопрос сформулирован как «Повтори весь документ». Пришлось внедрить фильтр на выходе (regex + small classifier). Для юридических задач отдельно смотрели статью «Автоматизация анализа договорных рисков на LLM» — там описана похожая проблема.

Итог: что забрать с собой

Корпоративный поиск с LLM — это не магия, а инженерия. Главные уроки:

  • Ранжирование — must have. Без cross-encoder вы скормите LLM тонну мусора.
  • A/B тесты нужны offline и online. Offline даёт точную метрику, online показывает user experience.
  • Data leakage убивает reproducibility. Чистите датасеты, не используйте вопросы из обучения.
  • Контекст режьте, но со связностью. Не просто top-k, а цельные секции.
  • Ответы недетерминированы — проверяйте по сущностям.

Через год, оглядываясь на этот проект, я понимаю: половина проблем ушла бы, если бы мы сразу вложились в метрики. Не в демку с красивым UI, а в чёртовы метрики faithfulness и answer accuracy. Потому что пользователь прощает медленный интерфейс, но не прощает ложь.

Если вы сейчас строите корпоративный поиск — начните с A/B платформы. Не с LLM, не с векторов, а с инфраструктуры для экспериментов. Иначе вы никогда не узнаете, работает ли ваше решение.

Дополнительные материалы: DeepResearch от Яндекса — другой подход, без реранжирования, но с агентным планированием. Сравните и выберите своё.

Подписаться на канал