разборragllmпоиск

Contextual Retrieval: как дать каждому куску документа память о целом

· 2 мин · BadRabbit

Вчера был поиск по словам. Сегодня поговорим о том, почему RAG часто находит не то, и как это лечит Contextual Retrieval от Anthropic.

Проблема

Классический RAG режет документы на куски (chunks), превращает каждый в эмбеддинг и при запросе ищет ближайшие. Но кусок теряет контекст. Пример из статьи: фрагмент финансового отчёта «выручка компании выросла на 3% по сравнению с прошлым кварталом». Какой компании? Какой квартал? В самом куске этого нет, и поиск по запросу «выручка ACME во втором квартале» может его пропустить.

Решение

Перед индексацией каждому куску приписывается короткий контекст в 50–100 токенов: где он находится в документе и о чём документ. Контекст генерирует сама модель: ей дают весь документ и кусок и просят кратко объяснить, к чему этот кусок относится.

Дополненный кусок индексируется двумя способами:

  • контекстные эмбеддинги для смыслового поиска;
  • контекстный BM25 для поиска по точным словам: названиям, кодам ошибок, номерам.

Результаты

Доля случаев, когда нужный кусок не попал в топ-20:

  • только контекстные эмбеддинги: на 35% меньше провалов;
  • плюс контекстный BM25: на 49% меньше;
  • плюс реранкинг найденных кусков отдельной моделью: на 67% меньше.

Цена

Модель должна прочитать весь документ ради каждого куска. Звучит дорого, но с кешированием промптов документ кешируется один раз, и предобработка обходится примерно в $1 на миллион токенов документов. Платится один раз при индексации.

Совет, который все пропускают

Если вся база знаний меньше 200 тысяч токенов (около 500 страниц), RAG может быть не нужен вообще. Проще положить её целиком в промпт и закешировать.

Мой комментарий

Правила в llm-wiki короткие и самодостаточные, поэтому проблема «потерянного контекста» стоит там мягче, чем у отчётов. Но у меня есть библиотека книг, из которых агент извлекает кандидатов в правила, и вот там она в полный рост: цитата из 14-й главы без контекста ничего не значит. Поэтому в индексе llm-wiki у каждого куска хранится не только текст, но и заголовок страницы и раздела, а извлечение из книг идёт по явным диапазонам глав. Цитата всегда знает, откуда она.

И первый вывод про 200 тысяч токенов очень отрезвляет: прежде чем строить RAG, посчитай, сколько у тебя на самом деле данных.