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-системи — наші інженери допоможуть підібрати правильний компресор.