RAG (поиск + генерация)
Устройство RAG-пайплайна, стратегии чанкинга, гибридный поиск, векторные базы и HNSW, заземление/отказ и разделение качества поиска и генерации.
9 вопросов
JuniorТеорияОчень частоЗачем сочетать лексическую ранжирующую функцию BM25 с плотными векторами, и что упускает каждый?
Зачем сочетать лексическую ранжирующую функцию BM25 с плотными векторами, и что упускает каждый?
BM25 сопоставляет точные токены, поэтому уверенно находит редкие литералы — коды ошибок, артикулы, имена — но упускает перефразировку. Плотные векторы ловят смысл и перефразировку, но размывают редкие литералы. Гибрид гоняет оба и сливает два списка рангов.
Типичные ошибки
- ✗Ждать от плотных embedding такой же надёжности на точных идентификаторах, как у ключевых слов
- ✗Складывать оценки двух ретриверов, не нормализовав их несопоставимые шкалы
- ✗Считать гибридный поиск оптимизацией задержки, а не полноты
Уточняющие вопросы
- →Как метод слияния рангов Reciprocal Rank Fusion объединяет два списка без калибровки оценок?
- →Почему в многоходовом чате уточняющий вопрос переписывают до того, как его увидит ретривер?
JuniorТеорияОчень частоПройдите по стадиям пайплайна RAG (генерация с поиском) и скажите, что ломается на каждой.
Пройдите по стадиям пайплайна RAG (генерация с поиском) и скажите, что ломается на каждой.
На индексации документы режутся на чанки, эмбеддятся и попадают в индекс. Запрос эмбеддится, достаются top-k чанков, переранжируются и идут в промпт. Чанкинг разрывает ответ, embedding промахивается, поиск отдаёт не те чанки, генерация выдумывает.
Типичные ошибки
- ✗Считать RAG дообучением — он подаёт контекст на инференсе и не меняет веса
- ✗Винить модель в неверном ответе, когда поиск вообще не положил факт в промпт
- ✗Пропускать построение индекса и эмбеддить весь корпус заново на каждый запрос
Уточняющие вопросы
- →Когда дообучение выигрывает у RAG на задаче со знаниями, а когда наоборот?
- →Куда встраивается переписывание запроса в многоходовом чате и что оно чинит?
MiddleДизайнЧастоВы индексируете 40 тыс. страниц продуктовой документации — глубокая иерархия заголовков, длинные таблицы API-справочника и короткие release notes. Поиск гибридный (плотный плюс ключевые слова), генератору достаётся примерно 4k токенов контекста, и ответу часто нужно определение плюс ограничение, указанное абзацем ниже. Выберите между чанкингом фиксированного размера, рекурсивным, семантическим и parent-document для этого корпуса, обоснуйте размер чанка и перекрытие и скажите конкретно, чем обходится слишком мелкий чанк на этапе ответа и слишком крупный — на этапе поиска.
Вы индексируете 40 тыс. страниц продуктовой документации — глубокая иерархия заголовков, длинные таблицы API-справочника и короткие release notes. Поиск гибридный (плотный плюс ключевые слова), генератору достаётся примерно 4k токенов контекста, и ответу часто нужно определение плюс ограничение, указанное абзацем ниже. Выберите между чанкингом фиксированного размера, рекурсивным, семантическим и parent-document для этого корпуса, обоснуйте размер чанка и перекрытие и скажите конкретно, чем обходится слишком мелкий чанк на этапе ответа и слишком крупный — на этапе поиска.
Резать по структуре — заголовки, затем абзацы — окном фиксированного размера лишь как запасной вариант. Цель — одна самодостаточная мысль на чанк, несколько сотен токенов, плюс перекрытие, чтобы граница не разрезала ответ. Мелкий теряет контекст, крупный размывает embedding.
Типичные ошибки
- ✗Брать один размер чанка на весь корпус независимо от глубины заголовков и структуры таблиц
- ✗Ставить нулевое перекрытие и терять любой ответ, лежащий на границе чанков
- ✗Считать, что крупный чанк всегда поднимает полноту, игнорируя размывание embedding
Уточняющие вопросы
- →Как parent-document retrieval позволяет эмбеддить мелко, но отдавать генератору крупный контекст?
- →Какой сигнал говорит, что неверен именно размер чанка, а не слаба модель embedding?
MiddleДизайнЧастоВаш гибридный ретривер отдаёт 50 кандидатов примерно за 30 мс, а генератор выдаёт первый токен ещё через ~900 мс; бюджет продукта end-to-end — 2 секунды. Офлайн-замер показывает: нужный чанк попадает в top-50 примерно в 94% случаев, а в top-5 — тот срез, что реально доходит до промпта, — лишь в 61%. Решите, ставить ли cross-encoder-переранжировщик между поиском и генерацией: объясните, почему он упорядочивает кандидатов лучше уже имеющихся векторных оценок, и сопоставьте добавляемую задержку с выигрышем в полноте.
Ваш гибридный ретривер отдаёт 50 кандидатов примерно за 30 мс, а генератор выдаёт первый токен ещё через ~900 мс; бюджет продукта end-to-end — 2 секунды. Офлайн-замер показывает: нужный чанк попадает в top-50 примерно в 94% случаев, а в top-5 — тот срез, что реально доходит до промпта, — лишь в 61%. Решите, ставить ли cross-encoder-переранжировщик между поиском и генерацией: объясните, почему он упорядочивает кандидатов лучше уже имеющихся векторных оценок, и сопоставьте добавляемую задержку с выигрышем в полноте.
Bi-encoder считает embedding запроса и чанка порознь, поэтому корпус предпосчитан, но пара не читается совместно. Cross-encoder читает пару вместе и ранжирует лучше — ценой прохода модели на кандидата. Ищем широко и дёшево, а переранжируем лишь верхние десятки.
Типичные ошибки
- ✗Считать, что оценки cross-encoder можно предпосчитать так же, как embedding у bi-encoder
- ✗Переранжировать сотни кандидатов и съедать весь бюджет задержки ещё до генерации
- ✗Читать высокую полноту на top-50 как доказательство, что ответ уже лежит в промпте
Уточняющие вопросы
- →Как выбрать глубину переранжирования по замеренной кривой полноты против задержки?
- →Когда небольшой дистиллированный переранжировщик лучше, чем убрать стадию совсем?
SeniorДебаггингЧастоБот уверенно и неверно отвечает про факт, который есть в корпусе — как локализовать причину?
Бот уверенно и неверно отвечает про факт, который есть в корпусе — как локализовать причину?
Пройти стадии по порядку и спросить, где выпадает нужный чанк. Убедиться, что он проиндексирован и эмбеддится, затем проверить его ранг в поиске, затем ранг после переранжирования, затем дошёл ли он до промпта. Только если чанк дошёл до промпта, виновата генерация.
Открыть задачу →Типичные ошибки
- ✗Называть любой уверенный неверный ответ галлюцинацией, не проверив, что лежало в промпте
- ✗Считать наличие чанка в корпусе доказательством, что он дошёл до контекста генератора
- ✗Пропускать стадию переранжирования при бисекции, из-за чего регресс порядка остаётся невидимым
Уточняющие вопросы
- →Как логировать каждую стадию, чтобы такая бисекция занимала минуты, а не день?
- →Как выглядел бы тот же трейс, если бы действительно была виновата модель embedding?
JuniorДизайнИногдаВы описываете бота поддержки, который отвечает строго по версионированному корпусу базы знаний. Комплаенс требует прослеживаемости каждого утверждения до источника, а владелец продукта предпочтёт отказ уверенной догадке. Часть входящих вопросов касается функций, которых в корпусе нет вовсе; другие описаны лишь в статье, устаревшей два релиза назад. Определите контракт ответа — когда бот обязан отказать вместо ответа, на что должна указывать ссылка на источник и как в CI перед релизом проверять, что заземление действительно держится, а не просто выглядит правдоподобно.
Вы описываете бота поддержки, который отвечает строго по версионированному корпусу базы знаний. Комплаенс требует прослеживаемости каждого утверждения до источника, а владелец продукта предпочтёт отказ уверенной догадке. Часть входящих вопросов касается функций, которых в корпусе нет вовсе; другие описаны лишь в статье, устаревшей два релиза назад. Определите контракт ответа — когда бот обязан отказать вместо ответа, на что должна указывать ссылка на источник и как в CI перед релизом проверять, что заземление действительно держится, а не просто выглядит правдоподобно.
Отвечать только по найденным чанкам. Если ничего не прошло порог — отказать и назвать, чего не хватило. Каждое утверждение ссылается на id чанка и версию документа. В CI гоняется набор отвечаемых и неотвечаемых вопросов, падающий на утверждении без ссылки.
Типичные ошибки
- ✗Считать отказ провалом продукта, из-за чего бот гадает при слабом поиске
- ✗Ссылаться на живой URL документа вместо конкретного прочитанного чанка и его версии
- ✗Проверять заземление только на отвечаемых вопросах, но не на тех, где корпус бессилен
Уточняющие вопросы
- →Как сделать отказ полезным — что он должен сообщить пользователю помимо самого отказа?
- →Как версионирование документов меняет то, что обязана фиксировать ссылка со временем?
MiddleПроизводительностьИногдаЧто балансируют M и ef_search в графовом индексе приближённых соседей HNSW?
Что балансируют M и ef_search в графовом индексе приближённых соседей HNSW?
HNSW — приближённый графовый индекс. M, соседи на узел, фиксируется при построении и определяет память и качество графа. ef_search, список кандидатов на запросе, покупает полноту ценой задержки. Поднимайте ef_search, пока замеренный recall@k не выйдет на цель.
Типичные ошибки
- ✗Верить, что приближённый индекс при любых настройках отдаёт истинных ближайших соседей
- ✗Крутить
ef_searchна глаз вместо замера recall@k на размеченном наборе - ✗Забывать, что
Mзашивается при построении и меняется только полной переиндексацией
Уточняющие вопросы
- →Как собрать эталонный набор, без которого замер recall@k теряет смысл?
- →Когда квантованный индекс лучше снижения
ef_searchдля того же целевого времени ответа?
SeniorДизайнИногдаRAG-ассистент вышел три месяца назад и собирает жалобы — ответы читаются гладко, но пользователи называют их неверными или ничем не подкреплёнными, а единственная метрика на дашборде — доля лайков, просевшая с 78% до 61%. У вас есть логи запросов, корпус и бюджет на небольшой размеченный набор. Спроектируйте оценку: какие метрики поиска вы посчитаете, какие метрики генерации, как размечается каждая, и скажите, какую половину станете чинить первой при деградации обеих — и почему этот порядок не произволен.
RAG-ассистент вышел три месяца назад и собирает жалобы — ответы читаются гладко, но пользователи называют их неверными или ничем не подкреплёнными, а единственная метрика на дашборде — доля лайков, просевшая с 78% до 61%. У вас есть логи запросов, корпус и бюджет на небольшой размеченный набор. Спроектируйте оценку: какие метрики поиска вы посчитаете, какие метрики генерации, как размечается каждая, и скажите, какую половину станете чинить первой при деградации обеих — и почему этот порядок не произволен.
Оценивать две половины раздельно. Поиску — recall@k и MRR по размеченным чанкам: дошёл ли факт до промпта. Генерации — верность этим чанкам плюс релевантность ответа. Чинить сначала поиск: оценивать генерацию на контексте без нужного факта бессмысленно.
Типичные ошибки
- ✗Отчитываться одним сквозным числом, по которому не понять, какая половина пайплайна просела
- ✗Крутить промпты и генератор, пока нужный чанк вообще не попадает в контекст
- ✗Читать оценки близости из поиска как метрику качества без разметки релевантности
Уточняющие вопросы
- →Как дёшево собрать размеченный набор релевантности из уже имеющихся логов запросов?
- →О чём говорит высокая верность контексту при низкой релевантности ответа?
SeniorДизайнРедкоСпроектируйте RAG над корпусом в 10 млн документов, общим для 400 корпоративных арендаторов, где пользователь вправе читать только документы, разрешённые его ролью, а часть документов переиздаётся ежедневно. Ответ должен укладываться в две секунды, а единственная утечка текста одного арендатора в ответ другому — инцидент, разрывающий контракт. Разберите шардирование и индексацию векторов, место контроля доступа относительно поиска, доставку свежести в индекс без полной пересборки и то, как доказать аудитору, что межарендаторская утечка структурно невозможна, а не просто пока не наблюдалась.
Спроектируйте RAG над корпусом в 10 млн документов, общим для 400 корпоративных арендаторов, где пользователь вправе читать только документы, разрешённые его ролью, а часть документов переиздаётся ежедневно. Ответ должен укладываться в две секунды, а единственная утечка текста одного арендатора в ответ другому — инцидент, разрывающий контракт. Разберите шардирование и индексацию векторов, место контроля доступа относительно поиска, доставку свежести в индекс без полной пересборки и то, как доказать аудитору, что межарендаторская утечка структурно невозможна, а не просто пока не наблюдалась.
Контроль доступа применяется на поиске, а не в промпте. На каждый чанк вешается ACL и фильтрация идёт внутри индекса, либо шардирование идёт по арендатору, чтобы запрос не доставал чужие векторы. Постфильтрация после top-k тянет запретный текст в память и молча роняет полноту.
Типичные ошибки
- ✗Обеспечивать изоляцию арендаторов инструкциями в промпте, а не на границе поиска
- ✗Постфильтровать top-k, молча срезая полноту и всё равно читая запретный текст
- ✗Пересобирать индекс целиком ради свежести вместо upsert и пометки удалённых по документу
Уточняющие вопросы
- →Как шардирование по арендаторам меняет бюджет полноты и задержки против одного фильтруемого индекса?
- →Что показать аудитору как доказательство изоляции, помимо зелёного набора тестов?