TL;DR
Исследователи создали RAG-систему для исторических газет с OCR-ошибками и устаревшей орфографией. Проблема: стандартный поиск по таким текстам проваливается — современный запрос "Первая мировая война" не находит архивную статью с текстом "Вѣликая Война" или "Borld W@r" (OCR-мусор). Система комбинирует расширение запроса через LLM (генерирует 5 вариаций: синонимы, архаизмы, переформулировки) и строгий промпт для генерации ответа (только из источников, явный отказ если данных нет).
Главная находка: расширение запроса через вариации смягчает провалы поиска. Если один вариант запроса промахнулся из-за OCR-шума, другие вытягивают релевантные документы. В чистом виде эта RAG-система требует векторные базы и код, но два принципа применимы в чате: (1) генерируй несколько формулировок запроса перед поиском по документам, (2) используй жёсткие constraints в промпте при работе с источниками — "только из контекста" и "откажись если нет данных".
Техника полезна для работы с зашумлёнными или устаревшими источниками — сканы документов, старые тексты, материалы с ошибками, когда прямой поиск по ключевым словам не работает. Или когда нужна строгая фактчек-генерация — модель не додумывает, только пересказывает источники или отказывается.
Схема метода (оригинальная система)
ФАЗА 1: Расширение запроса
Запрос пользователя
→ LLM генерирует 5 вариаций (синонимы, архаизмы, переформулировки)
→ Получаем 6 версий запроса (оригинал + 5 вариаций)
ФАЗА 2: Поиск (требует RAG-инфраструктуру)
6 запросов → параллельный поиск по векторной базе
→ Fusion результатов через Reciprocal Rank Fusion
→ Топ-K релевантных документов
ФАЗА 3: Генерация с constraints
Структурированный контекст (документы + метаданные + разделители)
→ Промпт с жёсткими constraints
→ Ответ (только из источников) ИЛИ отказ
Пример применения
Задача: Готовишь аналитическую записку для клиента. У тебя 15 PDF-сканов отраслевых отчётов — качество среднее, OCR накосячил, термины менялись ("электронная коммерция" → "e-commerce" → "онлайн-торговля"). Нужно найти данные по динамике рынка 2019-2023.
Промпт (шаг 1 — расширение запроса):
Переформулируй этот запрос 5 способами для поиска в отраслевых отчётах 2019-2023. Используй разные термины, синонимы, аббревиатуры:
"Какая была динамика роста рынка электронной коммерции в России 2019-2023?"
Требования:
- Сохраняй смысл
- Варьируй термины (e-commerce, онлайн-торговля, интернет-ритейл)
- Краткость
- По одной строке
- Без нумерации
Результат (шаг 1): Модель выдаст 5 вариаций — разные синонимы, аббревиатуры, формулировки. Дальше ты вручную ищешь по каждой вариации в своих документах (Cmd+F в PDF или через поиск по загруженным файлам в Claude). Собираешь найденные фрагменты.
Промпт (шаг 2 — генерация с constraints):
Ты эксперт по отраслевой аналитике. Ответь на вопрос используя ИСКЛЮЧИТЕЛЬНО информацию из предоставленных ниже отчётов.
Отчёты:
[вставить найденные фрагменты с указанием источника]
Вопрос: Какая была динамика роста рынка электронной коммерции в России 2019-2023?
Ограничения:
- Не используй внешние знания и не делай предположений.
- Если информации недостаточно, напиши: "Не могу ответить на вопрос только на основе предоставленной информации."
- Проверяй, что извлечённые данные относятся именно к основному событию вопроса.
- Если упоминаешь актёров/компании, убедись что их связь явно описана в отчётах.
- Не ссылайся на себя как на "AI модель".
Результат (шаг 2): Модель выдаст структурированный ответ с данными по динамике, ссылаясь только на предоставленные фрагменты. Если данных нет — явно откажется. Не додумает цифры.
Почему это работает
Слабость LLM: Поиск по ключевым словам хрупок к вариациям терминологии и шуму. Если в документе написано "онлайн-ритейл", а ты ищешь "электронная коммерция" — не найдёшь. OCR-ошибки усугубляют: "рост" → "ро@т". Одна формулировка запроса = одна точка отказа.
Сильная сторона LLM: Модель отлично генерирует семантически эквивалентные вариации текста — синонимы, переформулировки, архаизмы, аббревиатуры. Она понимает что "Первая мировая" = "Великая война" = "WWI" = "мировой конфликт 1914-1918". Также модель умеет строго следовать constraints — если явно запретить выходить за рамки источников и дать формулировку отказа, она будет отказываться вместо выдумывания.
Как метод использует это: Расширение запроса размножает точки входа — 6 разных формулировок = 6 шансов найти релевантный текст даже через OCR-шум и вариации терминов. Один промах не роняет всю систему. Промпт с жёсткими constraints превращает генерацию в пересказ, блокируя параметрическую память модели. Explicit abstention clause даёт модели "выход" — не додумывать, а отказаться.
Рычаги управления:
- Количество вариаций (5 в исследовании) → уменьши до 3 для простых задач, увеличь до 7-10 если терминология очень вариативна
- Типы вариаций → добавь в инструкцию "с опечатками" или "на другом языке" если ожидаешь такой шум
- Abstention clause → убери если хочешь чтобы модель пыталась выдать хоть что-то, оставь если критична точность
- "Без внешних знаний" → замени на "используй и контекст и свои знания" если хочешь дополнений, а не чистого пересказа
Шаблон промпта
Шаг 1: Расширение запроса
Переформулируй следующий вопрос {num_variations} разными способами для поиска в {тип_источников}.
Ограничения:
- Сохраняй исходный смысл
- Будь лаконичен
- Одна переформулировка на строку
- Не нумеруй переформулировки
Вопрос: {исходный_запрос}
Переформулировки:
Где:
- {num_variations} — количество вариаций (обычно 3-5)
- {тип_источников} — описание где ищешь ("исторические архивы", "отраслевые отчёты", "сканы документов")
- {исходный_запрос} — твой вопрос
Шаг 2: Генерация с constraints
Ты эксперт по {домен}. Ответь на вопрос используя ИСКЛЮЧИТЕЛЬНО информацию из предоставленных ниже источников.
Источники:
{контекст}
Вопрос: {запрос}
Ограничения:
- Не используй внешние знания и не делай предположений.
- Если информации недостаточно, напиши: "Не могу ответить на вопрос только на основе предоставленной информации."
- Проверяй, что извлечённые данные относятся именно к основному событию вопроса, исключая упомянутые вскользь, если причинная связь не явная.
- Если упоминаешь актёров/компании/события, убедись что их связь явно описана в источниках.
- Не ссылайся на себя как на "AI модель".
- Следствие — это результат, происходящий ПОСЛЕ события. Событие-причина — не следствие.
Ответ:
Где:
- {домен} — твоя область ("история", "финансы", "маркетинг")
- {контекст} — найденные фрагменты с указанием источников
- {запрос} — исходный вопрос
🚀 Быстрый старт — вставь в чат:
Вот шаблон для работы с зашумлёнными источниками через расширение запроса. Адаптируй под мою задачу: [опиши задачу и тип источников].
Задавай вопросы, чтобы заполнить поля.
[вставить оба шаблона выше]
Модель спросит: какой запрос расширить, сколько вариаций нужно, какой тип источников, какой домен экспертизы. Это нужно чтобы настроить генерацию вариаций под твою терминологию и контекст, а промпт для генерации — под твою роль и требования к точности.
Ограничения
⚠️ Требует RAG-инфраструктуру для полной реализации: Оригинальная система использует векторные базы, embedding models, Reciprocal Rank Fusion — это всё требует код. В чате применимы только два элемента: расширение запроса и структурированный промпт для генерации.
⚠️ Query expansion не заменит качественный поиск: Вариации запроса помогают против шума, но не творят чудеса. Если OCR полностью уничтожил ключевые слова или источники не содержат информации — расширение не поможет. Это смягчение провалов, не их устранение.
⚠️ Ручной workflow: Без RAG-системы придётся вручную искать по каждой вариации запроса (Cmd+F в документах или поиск в чате по загруженным файлам), затем собирать контекст для второго промпта. Это работает, но трудозатратно при большом объёме источников.
⚠️ Abstention не всегда срабатывает: Несмотря на явную инструкцию отказываться, модели иногда всё равно пытаются выдать ответ на основе параметрической памяти. Чем сильнее модель "знает" ответ из обучающих данных, тем выше риск, что проигнорирует constraint. Проверяй output на соответствие источникам.
Как исследовали
Команда из французских университетов взяла MIRACL dataset — 689 тысяч текстовых чанков на французском и английском из Википедии с размеченной релевантностью. Это НЕ настоящие исторические газеты с OCR-ошибками (использовали как прокси для многоязычности и вариаций терминологии). Протестировали три компонента раздельно:
1. NER-модели (4 штуки) — сравнивали по скорости, количеству найденных сущностей и синтаксической релевантности (извлекают ли полные слова или фрагменты вроде "##iste allemand"). Победила wikineural — баланс скорости и качества, выдаёт чистые entities без мусора.
2. Embedding модели (5 штук) — мерили Top-5 similarity rate (сколько из топ-5 результатов релевантны), confidence drop (разрыв между 1-м и 2-м результатом) и время индексации. E5-модели обошли всех (>90% Top-5 rate), но SFR-Embedding-Mistral и linq-embed-mistral оказались в 17-50 раз медленнее при сопоставимом качестве. Выбрали multilingual-e5-large — лучший Top-5 rate (91.34%) при приемлемой скорости и структуре латентного пространства (кластеры семантически разделены).
3. Hybrid retrieval — сравнивали single-query (один запрос) vs multi-query + RRF (5 вариаций + fusion). Multi-query показал более стабильный recall — если одна формулировка промазала, другие вытянули. RRF сгладил разброс производительности между запросами.
Интересная находка: Модель bert-base-historical-multilingual-cased, специально обученная на исторических текстах, ПРОИГРАЛА обычному bert-base-multilingual-cased по качеству NER. Доменная предтренировка без явной оптимизации под задачу не гарантирует выигрыш — иногда создаёт дополнительный оверхед без роста точности.
Логика результатов: Query expansion работает потому что размножает шансы на попадание — каждая вариация ищет своим путём, fusion объединяет. Один промах не роняет recall. Structured prompting работает потому что explicit constraints блокируют параметрическую память — модель не додумывает, следует инструкциям. Abstention clause даёт "легальный выход" — отказаться лучше чем соврать.
Адаптации и экстраполяции
🔧 Техника: Расширение для визуального контента → улучшенный поиск изображений
Оригинальное исследование расширяло текстовые запросы. Тот же принцип применим к поиску изображений в большой библиотеке (скриншоты, фото продуктов, референсы). Генерируешь 5 вариаций описания изображения (разные углы, детали, термины), затем ищешь по каждой. Особенно полезно если названия файлов неинформативны или метаданные зашумлены.
Опиши это изображение 5 способами для поиска похожих в библиотеке: - С акцентом на композицию - С акцентом на цветовую гамму - С акцентом на объекты/элементы - С акцентом на стиль/настроение - Краткое техническое описание [загрузить изображение]
🔧 Техника: Убрать "без внешних знаний" → режим дополнения и контекста
Если нужно дополнить фрагментарные источники, замени constraint. Вместо "только из контекста" → "используй контекст как основу, дополни своими знаниями там где контекст неполон, явно помечай дополнения". Получишь полный ответ с разметкой что из источников, что додумано.
Ограничения: - Используй предоставленные источники как основу - Если информация неполная, дополни из общих знаний, но ЯВНО ПОМЕТЬ: "[Дополнение]" - Разделяй факты из источников и общеизвестную информацию
🔧 Техника: Комбинация с Chain-of-Thought → прозрачная верификация
Добавь CoT перед генерацией ответа: модель сначала выписывает все релевантные фрагменты из источников, затем генерирует ответ. Видишь КАК она пришла к выводу, легче проверить на галлюцинации.
Шаг 1: Выпиши все фрагменты из источников, релевантные вопросу. Шаг 2: На основе ТОЛЬКО этих фрагментов сформулируй ответ. Шаг 3: Если фрагментов недостаточно — напиши: "Не могу ответить..."
Ресурсы
Hybrid Retrieval-Augmented Generation for Robust Multilingual Document Question Answering
Код: https://anonymous.4open.science/r/RAGs-C5AE/
Anthony Mudet (L3i-lab, La Rochelle Université), Souhail Bakkali (IRISA, Univ Rennes, CNRS)
