Запись эфира по RAGу без эмбеддингов (ссылка внизу поста) Выписал самое важное и дополнил Главные проблемы поиска на эмбеддингах:
1. Семантическая схожесть ≠ фактическая релевантность (слова те же, смысл другой)
2. Не учитывает "логические операции" в запросе ("и", "не")
3. Не умеет делать промежуточные шаги (сходить в другой кусок текста, чтобы посмотреть значение аббревиатуры или определение)
4. Ломается на агрегации "вот тебе посты из канала, проанализируй слабые и сильные места автора" → найдет посты, где я автор сам что-то пишет про посты/канал и сильные/слабые места. Например, обзор чужого канала. 5. Короткие пользовательские запросы отличаются от длинных чанков документации. И по длине, и по формулировкам
6. Плохо работает с таблицами
———
Запрос пользователя:
"Какие отделы нашей компании, кроме отдела продаж, не выполнили KPI в последнем квартале?"
Догадаетесь, в чем будет проблема с эмбеддингами?
- "Отчет по итогам квартала: Отдел продаж блестяще выполнил KPI, показав рекордный рост!"
- "План на следующий квартал: всем отделам компании, включая отдел маркетинга, поставлена задача выполнить KPI."
- "В последнем квартале отдел разработки успешно выполнил все поставленные KPI."
———
Лечим симптомы (все еще эмбеддинги):
1. query rewriting/expansion и/или Instruction Awareness
2. Векторный поиск по саммари чанков, а для генерации ответа использовать их полный текст
3. Можно делать не просто саммари чанков, а генерировать возможные вопросы по ним и искать уже по вопросам
4. Добавлять текст соседних чанков на этапе Generation
5. reranking
6. Препроцессинг документов с сохранением структуры (marker-pdf, docling, unstructured)
———
Лечим причину:
1. Не используем эмбеддинги
2. В качестве search engine берем легковесную LLM. Прогоняем по страницам документа и выдаем им true/false в зависимости от релевантности вопросу (запросы к разным страницам идут в параллель => работает быстро)
3. Вместо 2 совсем наглеем и передаем в запросе сразу сотни страниц – просим выписать только номера релевантных (держим до 200-300к токенов на запрос, даже если окно 1м)
4. gemini-2.5-flesh круто с этим справляется, а главное – нативно кушает pdf без препроцессинга. Понимает таблицы и картинки 🔥
5. Релевантные страницы передаем в ризонинг модель для Generation как в "классическом RAG"
6. Не забываем делать Structured Output c промежуточными шагами размышлений
———
Альтернативы (Для более структурированного поиска)
Для примера возьмем книгу рецептов и вопрос "что приготовить на ужин, если у меня есть лапша, фарш и 20 минут времени"
1. Сначала для каждого рецепта вычленить структурированные поля (ингредиенты, время приготовления, тип блюда – первое, второе, десерт и т.д.)
2. Сложить в SQL все извлеченные данные и исходный текст рецепта
3. Использовать text2sql, чтобы по запросу пользователя создавать search query
4. В Generation идут исходные текста рецептов
В реальности обычно создаем разные таблички в бд, потому что данные бывают разных типов с разными параметрами
В более простой версии этого подхода, тупо назначаем LLMкой "теги" разным кусочками текста и фильтруем по ним, а потом делаем классический RAG или сразу передаем в LLM
———
Общие мысли и ответы на вопросы
-
Data preparation is a king
-
Промежуточный вызов LLM – хороший reranker, даже для embedding-based подхода
-
Всегда пытаемся передать ссылки на исходные блоки инфы. Увеличивает надежность и тестируемость. Высший пилотаж – показывать не только страницы, но и конкретные строчки, на которые опиралась модель
-
Иногда нужно вообще убрать этап Generation и просто показывать найденные куски информации
-
LLM retrieval стоит сильно дороже, чем эмбеддинги, но для большого числа кейсов это ок. 1 доллар – все дешевле, чем пару часов сотрудника с зп в десятки баксов в час
Доп материалы: Ссылка на сам эфир от @r77_ai (больше деталей, примеров и интересных вопросов от слушателей. сначала разгоняюсь, но потом жара начинается)
- Instruction Awareness
- Промежуточные шаги размышлений в Structured Output
- Кормим pdf в gemini через openai-compatible api
В этом посте были ссылки, но мы их удалили по правилам Сетки