Как вы проектируете feature engineering для контекста RAG (кроме текста)?

Краткий тезис

Feature engineering для контекста RAG — это процесс извлечения и добавления в промпт LLM не только текста ретривированных чанков, но и структурированных признаков: метаданных документа (domain, recency, authority score, тип документа), свойств самого чанка (длина, позиция, уровень в иерархии) и вычисляемых метрик (релевантность запросу, перекрытие ключевых слов). Такое обогащение позволяет LLM лучше ранжировать источники, отсеивать нерелевантные или устаревшие данные и давать более точные ответы. В agentic RAG агент может динамически выбирать, какие фичи критичны для данного запроса, адаптируя контекст под задачу.

1. Термины: Feature engineering, контекст RAG, Agentic RAG

Feature engineering — это процесс создания и отбора информативных признаков (features) из сырых данных для улучшения работы модели. В контексте RAG фичи извлекаются из документов и их метаданных и подаются LLM вместе с текстом.

Контекст RAG — это часть промпта, содержащая ретривированные документы (чанки) и их описания. Обычно контекст включает только текст, но feature engineering расширяет его дополнительными атрибутами.

Agentic RAG — архитектура, в которой LLM-агент может самостоятельно решать, какие инструменты вызывать (поиск, фильтрация, переранжирование) и как формировать финальный контекст. В такой системе feature engineering может быть динамическим: агент запрашивает нужные метаданные на лету.

2. Зачем обогащать контекст RAG не только текстом?

Базовый RAG подаёт LLM только текст чанков. Это порождает проблемы:

  • Lost in the middle: LLM хуже обрабатывает информацию в середине контекста, а без ранжирующих фичей все чанки выглядят одинаково важными.
  • Неоднозначность достоверности: LLM не знает, какой документ из википедии, а какой — из личного блога. Без authority score модель может одинаково доверять всему.
  • Устаревшая информация: если чанк из новостей трёхлетней давности, а запрос про текущую ситуацию, LLM должна это учитывать. Без recency это невозможно.
  • Тип документа: ответ на юридический вопрос требует ссылки на закон, а не на FAQ. Фича тип документа подсказывает LLM, какой стиль ответа ожидается.

Feature engineering решает эти проблемы, предоставляя LLM сигналы для взвешенного использования контекста.

3. Категории фич для контекста RAG

3.1 Метаданные документа

ФичаТипПример
Domain (домен/тема)категориальный"медицина", "финансы", "технологии"
Recency (свежесть)числовой (дни от публикации)15 дней назад
Authority score (авторитетность источника)числовой (0–1)0.95 для википедии, 0.3 для форума
Тип документакатегориальный"научная статья", "FAQ", "закон", "новость"
Языккатегориальный"ru", "en"
Источник/URLстроковый (для traceability)https://example.com/doc

3.2 Структурные свойства чанка

ФичаОписание
Длина чанка (токенов)Позволяет LLM понять, детальный ли это абзац или короткая заметка.
Позиция в документе (индекс начала/конца)Помогает учесть структуру: введение, тело, заключение.
Уровень в иерархии (заголовок уровня 1/2/3)Указывает на семантическую важность секции.
Количество ссылок/цитат в чанкеМаркер evidence-based информации.

3.3 Вычисляемые фичи (на основе запроса и чанка)

ФичаКак считаетсяЗачем
Cosine similarity между эмбеддингом запроса и чанкаcos(emb_query, emb_chunk)Количественная мера релевантности.
Перекрытие ключевых слов (keyword overlap)Доля общих токенов после стеммингаБыстрая оценка прямого совпадения.
Релевантность через классификатор (NLI)Вероятность entailment между запросом и чанкомБолее точная, но ресурсоёмкая фича.
Позиция в выдаче ретривера (rank)1, 2, … kLLM может видеть, насколько ретривер уверен в релевантности.

3.4 Фичи из внешних источников (для agentic RAG)

  • Рейтинг пользователей (user rating) для документов из community-платформ.
  • Частота цитирования в корпусе (citation count) — индикатор влиятельности.
  • Дата последнего обновления страницы — если документ редактировался.

4. Как добавлять фичи в контекст LLM

Существует два основных подхода:

4.1 Естественно-языковое описание

В системный промпт или в сам контекст добавляется текстовое описание фич для каждого чанка. Пример:

Document 1 (Source: Wikipedia, Recency: 2 days ago, Authority: 0.95, Type: encyclopedia):
[текст чанка]

Document 2 (Source: Personal blog, Recency: 2 years ago, Authority: 0.3, Type: opinion):
[текст чанка]

Плюс: простота, работает с любыми LLM. Минус: увеличивает длину контекста, LLM может игнорировать префиксы.

4.2 Структурированный JSON в контексте

Фичи передаются в виде JSON-объекта, прикреплённого к каждому чанку.

{
  "id": "doc_1",
  "text": "В 2024 году инфляция составила 4.3%...",
  "features": {
    "domain": "экономика",
    "recency_days": 30,
    "authority_score": 0.92,
    "type": "news",
    "rank": 1,
    "cos_sim": 0.87
  }
}

Плюс: LLM может легко извлечь нужные фичи, если обучена работать с JSON. Минус: требует форматирования и может быть неудобно для некоторых моделей.

5. Пример реализации на Python

from typing import List, Dict, Any
import json

def enrich_context(chunks: List[Dict[str, Any]], query: str) -> str:
    """
    Обогащает контекст RAG дополнительными фичами.
    Ожидается, что chunks содержат 'text', 'metadata', 'embedding' и 'rank'.
    """
    enriched_parts = []
    for chunk in chunks:
        meta = chunk.get("metadata", {})
        # Вычисляем cosine similarity (упрощённо)
        sim = chunk.get("cos_sim", 0.0)
        
        feature_block = {
            "text": chunk["text"],
            "features": {
                "domain": meta.get("domain", "unknown"),
                "recency_days": meta.get("recency_days", None),
                "authority_score": meta.get("authority_score", 0.5),
                "document_type": meta.get("type", "generic"),
                "rank": chunk.get("rank", 0),
                "cos_sim": round(sim, 3),
                "length_tokens": len(chunk["text"].split())
            }
        }
        enriched_parts.append(json.dumps(feature_block, ensure_ascii=False))
    
    # Оборачиваем в промпт
    system_prompt = (
        "You are an assistant. Answer based on the following documents. "
        "Each document is provided as JSON with 'text' and 'features'. "
        "Use features to weigh the evidence: prefer high authority, recent documents."
    )
    context = "\n---\n".join(enriched_parts)
    return f"{system_prompt}\n\nContext:\n{context}\n\nQuery: {query}"

6. Динамический выбор фич в Agentic RAG

В agentic RAG LLM-агент может на основе запроса решить, какие фичи критичны. Реализуется через function calling или tool use. Например:

  • Если запрос про свежие новости → агент явно запрашивает фильтр по recency < 30 days.
  • Если запрос юридический → агент повышает вес authority_score и требует document_type == "law".
  • Если запрос требует фактов → агент может добавить фичу citation_count.

Пример loop в agentic RAG:

def agentic_feature_decision(query: str) -> List[str]:
    # Используем LLM для выбора фич (можно через few-shot)
    response = llm(f"Какие фичи важны для запроса: '{query}'? "
                   "Варианты: recency, authority, domain, type, cos_sim.")
    # Парсим ответ и выбираем фичи
    return selected_features

# Затем применяем фильтрацию и обогащение

7. Эксперименты и оценка влияния feature engineering

Для тестирования полезно провести A/B эксперимент:

  • Baseline: стандартный RAG с сырым текстом чанков.
  • Treatment: RAG с обогащённым контекстом (те же чанки, но с JSON-фичами).

Метрики сравнения

МетрикаОписание
Faithfulness (точность по отношению к контексту)Не снизилась ли из-за шума?
Answer RelevanceСтал ли ответ более релевантным запросу?
Context Recall (покрытие)Использовал ли LLM больше документов?
LatencyУвеличилась ли из-за более длинного контекста?

Обычно добавление 2–4 ключевых фич (recency, authority, type, rank) даёт прирост faithfulness на 5–15%.

8. Продвинутые техники

Feature selection через корреляцию отбираем фичи, которые сильнее всего коррелируют с релевантностью в валидационном датасете.

Взвешивание фич подаём не просто значения, а их важность (например, authority_score умножаем на вес, полученный из модели ранжирования).

Иерархические фичи для документов со структурой (например, PDF с разделами) можно добавить фичу section_path — путь от корня.

Сжатие фич если контекст слишком длинный, агрегируем фичи по группам документов (средняя recency, медианный authority).

9. Проблемы и подводные камни

  • Шум от лишних фич: каждая дополнительная фича увеличивает длину контекста и может отвлекать LLM от сути. Нужен отбор.
  • Переобучение на метаданные: если в тренировочных данных authority score всегда совпадает с истинностью, модель может начать слепо доверять authority, игнорируя текст.
  • Эффект “Garbage in, garbage out”: если метаданные неточны (например, recency проставлена неверно), feature engineering ухудшает качество.
  • Совместимость с LLM: некоторые модели не обучены игнорировать случайные JSON-поля и могут хуже обрабатывать структурированный контекст.

Чтобы минимизировать риски, рекомендуется начинать с малого набора фич (recency + authority + rank) и постепенно добавлять новые, проверяя метрики.

Пет-проект для закрепления

Задача: Реализовать RAG-систему, которая для ответа использует не только текст чанков, но и их метаданные. Сравнить качество с обычным RAG.

Инструменты: Python, langchain (или собственный пайплайн), ChromaDB (векторная БД с поддержкой метаданных), OpenAI API / локальная LLM (LLaMA), пакет ragas для оценки.

Шаги:

  1. Соберите датасет из 100–1000 документов разных типов (новости, статьи, FAQ) с метаданными: дата, источник, тип. Разбейте на чанки.
  2. Реализуйте базовый RAG: ретривер (cosine similarity по эмбеддингам) + LLM с промптом “Ответь по тексту из контекста”.
  3. Реализуйте enriched RAG: добавьте к каждому чанку JSON-блок с recency_days, authority_score, document_type, rank. Измените промпт так, чтобы LLM учитывала фичи.
  4. Подготовьте 30–50 вопросов к датасету. Для каждого вопроса вручную отметьте правильный ответ и ожидаемые источники.
  5. Оцените оба подхода по faithfulness и answer relevance (через RAGAS или ручную разметку).
  6. Проанализируйте: на каких вопросах enriched RAG выиграл, на каких проиграл. Попробуйте отбросить одну фичу – изменились ли результаты?

Ожидаемый результат: enriched RAG должен показать более высокий faithfulness на вопросах, где важна достоверность источника или свежесть данных, и аналогичный результат на вопросах, не требующих метаданных. Вы получите практическое понимание, какие фичи действительно улучшают RAG.

Связь с другими вопросами

ВопросТема
5Метрики retrieval, влияют на выбор фич (что измерять)
7Feature engineering увеличивает длину контекста, нужно балансировать
10Self-RAG использует рефлексию над контекстом – схожие идеи взвешивания
273Agentic RAG динамически выбирает фичи
275Инструменты могут добывать внешние фичи (recency, citation)

Навигация