Contextual Compression для RAG: реализация и оптимизация

Реализация Contextual Compression для RAG

Направления AI-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1440
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    997
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1264
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    712
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1002

Реализация Contextual Compression для RAG

Представьте: ваша RAG-система городит контекст из 10 чанков по 800 токенов, а полезной информации — на 100 токенов. LLM платит за шум, а ответы — каша. Типичный кейс — поддержка техдокументации: 10 чанков, релевантны 2–3. Каждый чанк весит около 800 токенов, а полезной информации — на 100. LLM тратит контекстное окно на нерелевантный текст, что приводит к галлюцинациям и неполным ответам. Тратится контекст, растёт стоимость. Contextual Compression — техника, которая выкусывает из каждого чанка только релевантный запросу фрагмент. Снижаем шум, сокращаем токены, повышаем faithfulness. За время работы в AI/ML мы внедрили это в 15+ проектах — делимся опытом. Получите консультацию по оптимизации вашей RAG-системы.

Проблема без Contextual Compression

Стандартный RAG передаёт LLM полные чанки (512–1024 токена). Типичная картина: чанк содержит 600 токенов, из которых 80 действительно отвечают на вопрос, остальные — нерелевантный контекст. Это:

  • Увеличивает стоимость (больше input tokens)
  • Снижает точность (LLM «теряется» в нерелевантном тексте)
  • Уменьшает effective context window (меньше места для действительно важных чанков)

Как работает LLM-based Contextual Compression?

from langchain.retrievers import ContextualCompressionRetriever from langchain.retrievers.document_compressors import LLMChainExtractor from langchain_openai import ChatOpenAI # Компрессор на основе LLM llm = ChatOpenAI(model="gpt-4o-mini", temperature=0) compressor = LLMChainExtractor.from_llm(llm) compression_retriever = ContextualCompressionRetriever( base_compressor=compressor, base_retriever=vectorstore.as_retriever(search_kwargs={"k": 8}), ) compressed_docs = compression_retriever.invoke( "Каков порядок согласования договоров?" ) # Каждый документ содержит только релевантный фрагмент for doc in compressed_docs: print(len(doc.page_content), "chars (vs оригинальных ~2000)") 

Согласно документации LangChain, LLMChainExtractor использует ту же LLM для извлечения релевантного контента. Это даёт высокую точность, но увеличивает latency.

Когда использовать Embedding-based Compressor?

Более быстрый и дешёвый вариант — фильтрация по косинусному сходству. Мы часто используем его как первый этап пайплайна:

from langchain.retrievers.document_compressors import EmbeddingsFilter from langchain_openai import OpenAIEmbeddings embeddings = OpenAIEmbeddings() embeddings_filter = EmbeddingsFilter( embeddings=embeddings, similarity_threshold=0.76, ) filtering_retriever = ContextualCompressionRetriever( base_compressor=embeddings_filter, base_retriever=vectorstore.as_retriever(search_kwargs={"k": 8}), ) 

Порог 0.76 – эмпирическое значение, которое даёт хороший баланс между полнотой и точностью. Для вашего датасета его нужно калибровать.

Почему стоит комбинировать Compression и Reranking?

EmbeddingsFilter отсекает явно нерелевантные чанки, но не ранжирует оставшиеся. Cross-encoder reranker (например, BAAI/bge-reranker-large) даёт более точную сортировку по релевантности, но дороже. Комбинация даёт золотую середину: фильтр убирает 40–60% чанков, reranker уточняет порядок top-N. Pipeline с Filter и Reranker даёт faithfulness на 15% выше, чем без компрессии, при этом в 2,5 раза дешевле LLM Extractor.

Сравним методы:

Метод Cost per query Latency p99 Faithfulness gain
Без compression 1.8 с
EmbeddingsFilter 0.2× 0.3 с +8%
LLM Extractor 0.5× 2.4 с +19%
Pipeline (Filter + Reranker) 0.4× 0.9 с +15%

Как построить Pipeline с Compression и Reranking?

from langchain.retrievers.document_compressors import DocumentCompressorPipeline from langchain_community.document_transformers import EmbeddingsRedundantFilter from langchain.retrievers.document_compressors import CrossEncoderReranker from langchain_community.cross_encoders import HuggingFaceCrossEncoder cross_encoder = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-large") reranker = CrossEncoderReranker(model=cross_encoder, top_n=3) compressor_pipeline = DocumentCompressorPipeline( transformers=[ EmbeddingsFilter(embeddings=embeddings, similarity_threshold=0.75), EmbeddingsRedundantFilter(embeddings=embeddings), reranker, ] ) pipeline_retriever = ContextualCompressionRetriever( base_compressor=compressor_pipeline, base_retriever=vectorstore.as_retriever(search_kwargs={"k": 10}), ) 

Какой компрессор выбрать для вашего сценария?

В production мы предпочитаем гибридный подход: EmbeddingsFilter для фильтрации шума, затем LLM-компрессор для ключевых запросов, где важна высокая точность. Если latency критична — используем только EmbeddingsFilter с низким порогом (0.7–0.75).

Шаги внедрения Contextual Compression

  1. Аудит текущей RAG-системы: метрики, узкие места, сценарии.
  2. Выбор и калибровка компрессора (LLM / Embedding / Pipeline).
  3. Интеграция через LangChain или кастомный код.
  4. Тестирование: faithfulness, relevancy, latency, cost.
  5. Документация и обучение команды.
  6. Мониторинг и оптимизация threshold под новые данные.

Практический кейс: из практики нашего клиента

Задача: ассистент для технических мануалов (чанки ~800 токенов). После compression средний контекст уменьшился с 4800 до 1200 токенов на запрос.

Метрика Без Compression С Compression (LLM)
Input tokens/запрос 5200 1450
Faithfulness (RAGAS) 0.79 0.94
Answer Relevancy 0.81 0.89
Стоимость (GPT-4o-mini) 0.3×
Latency 1.8с 2.4с (+compression LLM)

Сжатие снизило стоимость в 3.3× при росте faithfulness на 19%. Наши инженеры подобрали threshold и модель компрессора за 2 дня, ещё 2 дня ушло на интеграцию.

Что входит в реализацию

  • Аудит текущей RAG-системы: метрики, узкие места, сценарии
  • Выбор и калибровка компрессора (LLM / Embedding / Pipeline)
  • Интеграция через LangChain или кастомный код
  • Тестирование: faithfulness, relevancy, latency, cost
  • Документация и обучение команды
  • Гарантия на результаты оптимизации по KPI

Мы сопровождаем проект после внедрения — фиксим threshold под новые данные, добавляем мониторинг. Закажите оптимизацию вашей RAG-системы и получите снижение токенов до 4 раз. Свяжитесь с нами для обсуждения вашего кейса.

Сроки и стоимость

  • Базовая интеграция: от 2 дней
  • Калибровка и тестирование: 2–3 дня
  • Полный цикл (включая pipeline и reranker): 1 неделя

Стоимость рассчитывается индивидуально под объём данных и требования. Средняя экономия на токенах — 60–70%. Закажите оптимизацию вашей RAG-системы — наши инженеры помогут подобрать правильный компрессор.