# Context Engineering vs RAG: когда что использовать

> Глубокое сравнение context engineering и RAG: когда long context заменяет retrieval, когда нужен RAG, decision framework и современный стек 2026.
> Author: Roman Belov · Published: 2026-06-26 · Source: https://futurecraft.pro/ru/blog/context-engineering-vs-rag/

В 2024 году RAG был ответом на любой вопрос о работе LLM с внешними данными. В 2026 году контекстные окна выросли до 1–2 миллионов токенов, prompt caching снизил стоимость повторных запросов на 90%, а термин «context engineering» оформился в отдельную дисциплину. RAG никуда не делся — но перестал быть единственным решением.

Статья разбирает: что такое context engineering, чем отличается от RAG, когда достаточно long context, когда нужен RAG, и как комбинировать оба подхода. С расчётами стоимости, примерами кода и decision framework. Полную картину дисциплины — шестислойную структуру контекста, паттерны персистентности, изоляцию через субагентов — смотрите в [гайде по context engineering](/ru/blog/context-engineering-guide/).

## Что такое context engineering

Андрей Карпати [сформулировал](https://x.com/karpathy/status/1937902205765607626) определение в июне 2025:

> Context engineering is the delicate art and science of filling the context window with just the right information for the next step.

Ключевое слово — «just the right». Не максимум информации. Не минимум. Ровно то, что нужно для следующего шага.

### Не prompt engineering

Prompt engineering — как сформулировать вопрос (подробнее — в статье [как писать промпты](/ru/blog/how-to-write-prompts/)). Context engineering — что подать модели перед вопросом. Разница принципиальная:

| Аспект | Prompt Engineering | Context Engineering |
|--------|-------------------|-------------------|
| Фокус | Формулировка запроса | Сборка входных данных |
| Scope | Один промпт | Весь пайплайн |
| Компоненты | Роль, формат, chain-of-thought | System prompt + docs + tools + memory + examples |
| Метафора | Как задать вопрос эксперту | Какое досье дать эксперту перед вопросом |

Идеальный промпт с плохим контекстом даёт плохой результат. Посредственный промпт с точным контекстом — хороший.

### Компоненты context engineering

Контекст LLM-запроса собирается из шести источников:

1. **System prompt** — роль, ограничения, стиль поведения
2. **Project context** — стек, конвенции, архитектурные решения (CLAUDE.md, .cursorrules)
3. **Retrieved documents** — результаты RAG, поиска по коду, grep
4. **Tool results** — ответы от API, баз данных, MCP-серверов
5. **Memory** — персистентные заметки между сессиями
6. **Few-shot examples** — образцы ожидаемого поведения

Context engineering оркестрирует все шесть. RAG покрывает только третий пункт.

### Почему это стало дисциплиной

В 2025–2026 совпали три фактора.

**Рост контекстных окон.** Claude Opus 4.8 и Sonnet 4.6 — 1M токенов (GA с марта 2026). GPT-5.5 — 1M (922K input). Gemini 3.1 Pro — 1M стандартно, 2M в расширенных режимах через API. Когда окно вмещает целую кодовую базу, вопрос меняется: не «как извлечь релевантное», а «что именно положить».

**Prompt caching.** Anthropic, Google, OpenAI — все запустили кэширование статичного контекста. Cache read у Claude стоит $0.50/MTok вместо $5.00/MTok. Длинный контекст стал в 10 раз дешевле.

**AI-агенты.** Агентам нужна память между шагами, результаты инструментов, план задачи, контекст проекта. Один промпт это не описывает — нужен пайплайн сборки контекста.

Gartner в июле 2025 заявил: «Context engineering is in, and prompt engineering is out». Тоби Лютке (CEO Shopify) популяризировал термин. Дисциплина получила имя.

## Что такое RAG

RAG (Retrieval-Augmented Generation) — паттерн, при котором LLM получает релевантные документы перед генерацией ответа. Три шага:

1. **Retrieve** — найти релевантные фрагменты в корпусе
2. **Augment** — добавить найденное в промпт
3. **Generate** — сгенерировать ответ с учётом контекста

### Как RAG работает под капотом

```
Документы → Chunking → Embedding → Vector Store
                                        ↓
Запрос → Embedding → Vector Search → Top-K chunks → LLM → Ответ
```

**Chunking** — разбиение документов на фрагменты. Размер чанка определяет гранулярность поиска: слишком мелкие — теряется контекст, слишком крупные — шум.

**Embedding** — преобразование текста в числовой вектор. Семантически похожие тексты получают близкие векторы.

**Vector Store** — база данных для хранения и поиска по векторам. pgvector, Pinecone, Qdrant.

**Retrieval** — поиск ближайших векторов к запросу пользователя. Top-K результатов попадают в промпт.

### Типы RAG

**Naive RAG.** Простейшая реализация: фиксированный размер чанка, один embedding model, cosine similarity, top-5 в промпт. Годится для прототипов.

**Advanced RAG.** Hybrid search (vector + BM25), reranking, parent-child chunking, query expansion. Precision@5 растёт с 0.6 до 0.85+.

**Agentic RAG.** Агент решает, что искать, в каком индексе, сколько раз. Может переформулировать запрос, запросить уточнение, комбинировать результаты из разных источников. Context engineering с RAG как одним из инструментов.

**GraphRAG.** Подход Microsoft (2024), который строит граф сущностей и связей поверх корпуса. Вместо поиска по плоским чанкам модель обходит граф и находит ответы на «глобальные» вопросы — о связях между документами, трендах, паттернах. К 2026 GraphRAG и его облегчённые аналоги (LightRAG, HippoRAG 2) стали востребованным решением для enterprise-корпусов с плотными связями между документами — там, где нужны ответы на вопросы типа «как связаны A и B» или «что произошло во всём корпусе». Практика 2026: vector + graph в гибриде, маршрутизация по типу запроса.

**Adaptive RAG.** Классификатор запросов направляет каждый вопрос к подходящей стратегии retrieval на основе сложности: простой фактический вопрос — прямой поиск, сложный аналитический — multi-hop итеративный агент. Практика 2025–2026: RL-обученные агенты (инспирированные подходами OpenAI Deep Research, Search-R1) заменяют фиксированный pipeline «retrieve → generate» на автономный цикл «план → поиск → рассуждение → критика → следующий поиск».

### Когда RAG стал стандартом

RAG появился в [статье Facebook AI Research](https://arxiv.org/abs/2005.11401) в 2020 году. Стал стандартом к 2023–2024, когда контекстные окна были 4K–32K токенов. При таких ограничениях RAG был единственным способом работать с внешними данными.

## Context engineering vs RAG: ключевые отличия

### Главное: RAG — часть context engineering

RAG — не альтернатива context engineering. RAG — один из инструментов в его арсенале. Сравнивать их — как сравнивать «приготовление еды» и «нарезку овощей». Нарезка — часть процесса.

**Аналогия:** RAG — библиотекарь, который находит нужные книги. Context engineering — редактор, который решает, какие книги запросить, какие главы выбрать, в каком порядке их прочитать и что из них включить в финальный документ.

### Сравнительная таблица

| Критерий | Context Engineering | RAG |
|----------|-------------------|-----|
| **Scope** | Весь пайплайн подготовки контекста | Только retrieval документов |
| **Компоненты** | System prompt, memory, tools, RAG, examples, structured output | Chunking, embedding, vector store, retrieval, reranking |
| **Данные** | Любые: код, API-ответы, файлы, память | Документы в vector store |
| **Инфраструктура** | Prompt caching, MCP, memory files | Vector DB, embedding pipeline, indexing |
| **Latency** | Зависит от размера контекста | Зависит от retrieval + reranking |
| **Стоимость масштабирования** | Линейно с размером контекста | Линейно с размером корпуса (индексация) |
| **Когда обновлять** | При изменении задачи/проекта | При изменении данных в корпусе |
| **Attribution** | Не встроена | Встроена (источник = чанк) |
| **Уровень абстракции** | Orchestration layer | Retrieval component |

### Четыре стратегии, одна из которых — RAG

Context engineering оперирует четырьмя стратегиями управления контекстом:

| Стратегия | Что делает | Примеры |
|-----------|-----------|---------|
| **Write** | Сохраняет информацию вовне | Memory files, scratchpads, CLAUDE.md |
| **Select** | Извлекает релевантное | **RAG**, grep, code search, MCP tools |
| **Compress** | Сжимает контекст | Summarization, compaction, очистка tool results |
| **Isolate** | Изолирует задачи | Субагенты с чистым контекстом |

RAG — реализация стратегии **Select**. Одна из четырёх. Мощная, но не единственная.

## Когда достаточно long context без RAG

### Правило: если влезает — не усложняй

Контекстное окно Claude Opus 4.8 и Sonnet 4.6 — 1M токенов. Gemini 3.1 Pro — 1M. Один миллион токенов — примерно 750 000 слов, или 3 000 страниц текста.

Если весь корпус помещается в контекстное окно — RAG-пайплайн добавляет сложность без пользы.

### Сценарий 1: кодовая база до 100K строк

Средний стартап — 50–80K строк кода. В токенах это ~200–300K. Claude Code загружает нужные файлы в контекст через grep и glob, без vector store. Работает, потому что:

- Код структурирован (файлы, функции, модули)
- Поиск по имени точнее semantic search для кода
- Контекст обновляется при каждом запросе

### Сценарий 2: фиксированный набор документов

Внутренняя документация компании — 50 документов, 200K токенов. Обновляется раз в месяц. Два варианта:

**Вариант A: RAG-пайплайн**
- Chunking + embedding + vector store + retrieval
- Инфраструктура: Qdrant/Pinecone + embedding API
- Поддержка: re-indexing при обновлениях
- Стоимость: $50–200/мес (vector DB + embedding API)

**Вариант B: Long context + prompt caching**
- Все 200K токенов в system prompt
- Prompt caching: первый запрос $1.25/MTok (5-min cache write), последующие $0.50/MTok
- Инфраструктура: ноль
- 200K токенов × $0.50/MTok = $0.10 за запрос (cache read)

При 100 запросах в день: вариант B — $10/день, $300/мес; вариант A — $50–200/мес. При такой нагрузке RAG выгоднее по деньгам, но требует инфраструктуры и поддержки. Long context оправдан при низкой нагрузке — до ~50 запросов/день ($150/мес) или когда стоимость RAG-инфраструктуры учитывается в общей стоимости владения.

### Сценарий 3: анализ одного длинного документа

Юридический контракт на 100 страниц (~80K токенов). RAG разрежет его на чанки и потеряет cross-reference между секциями. Long context сохранит структуру целиком — модель видит весь контракт и находит противоречия между разделами, чего чанковый поиск не умеет.

### Расчёт стоимости long context

Claude Opus 4.8, 500K токенов в контексте, 100 запросов в день:

| Режим | Стоимость за запрос | В день | В месяц |
|-------|-------------------|--------|---------|
| Без кэша | $2.50 | $250 | $7 500 |
| Prompt caching (5-min, cache read) | $0.25 | $25 | $750 |
| Prompt caching (1-hour, cache read) | $0.25 | $25 | $750 |

Cache write (первый запрос): $3.13 (5-min) или $5.00 (1-hour). Но каждый последующий read — $0.25. Окупается со второго запроса.

Claude Sonnet 4.6, те же условия:

| Режим | Стоимость за запрос | В день | В месяц |
|-------|-------------------|--------|---------|
| Без кэша | $1.50 | $150 | $4 500 |
| Prompt caching (cache read) | $0.15 | $15 | $450 |

Gemini 3.1 Pro, 500K токенов (>200K — long context pricing):

| Режим | Стоимость за запрос | В день | В месяц |
|-------|-------------------|--------|---------|
| Стандартный | $1.25 | $125 | $3 750 |
| С context caching | ~$0.16 | $16 | $480 |

### Когда long context не работает

- **Документ > 1M токенов** — не влезает в стандартное окно. Gemini 3.1 Pro поддерживает 2M в расширенном режиме, но это исключение
- **Latency-critical** — обработка 500K токенов занимает 5–15 секунд. Если нужен ответ за 500ms — не вариант
- **Деградация внимания** — [исследование Chroma (2025)](https://www.trychroma.com/research/context-rot) показало: все 18 протестированных фронтирных моделей (Claude 4, GPT-4.1, Gemini 2.5) демонстрируют монотонное падение F1 с ростом контекста. Наиболее резкая деградация — в диапазоне 100K–500K токенов
- **Часто обновляемые данные** — prompt cache инвалидируется при любом изменении контента

## Когда нужен RAG

### Пять сигналов, что RAG необходим

**1. Корпус превышает размер контекстного окна.**
Enterprise knowledge base, юридическая база прецедентов, научная литература — когда суммарный объём данных в токенах не вмещается в 1–2M токенов (даже при Gemini 3.1 Pro в расширенном режиме). Число документов второстепенно: 10 000 коротких статей < 50M токенов, 500 длинных регуляторных документов — вполне могут занять 200M. RAG извлекает top-10 релевантных фрагментов из любого по размеру корпуса.

**2. Данные обновляются часто.**
Тикеты в Jira, сообщения в Slack, статьи в wiki — данные меняются ежедневно. RAG-индекс обновляется инкрементально. Prompt cache инвалидируется полностью при любом изменении.

**3. Нужна attribution.**
«Откуда этот ответ?» — критичный вопрос для compliance, legal, медицины. RAG возвращает конкретные чанки с metadata (документ, страница, дата). Long context — чёрный ящик: ответ есть, источник неясен.

**4. Latency < 1 секунды.**
Chatbot на сайте. Пользователь ждёт ответ за 500ms. RAG: vector search 20ms + reranking 50ms + LLM с 5K токенами контекста 300ms = 370ms. Long context: LLM с 500K токенами = 5–15 секунд.

**5. Оптимизация стоимости при высокой нагрузке.**
10 000 запросов в день. RAG подаёт в среднем 5K токенов → $0.025 за запрос (Sonnet). Long context подаёт 500K → $0.15 за запрос (cache read). Разница: $250/день vs $1 500/день.

### Расчёт: RAG vs Long Context по стоимости

10 000 запросов/день, Claude Sonnet 4.6 ($3/$15 за MTok):

| Подход | Токенов в контексте | Стоимость/запрос | В день | В месяц |
|--------|-------------------|-----------------|--------|---------|
| RAG (5K retrieved) | 8K (system + retrieved) | $0.024 | $240 | $7 200 |
| Long context (без кэша) | 500K | $1.50 | $15 000 | $450 000 |
| Long context (cache read) | 500K | $0.15 | $1 500 | $45 000 |
| RAG + embedding cost | 8K + embedding | $0.03 | $300 | $9 000 |

При 10K запросов/день RAG в 5 раз дешевле даже кэшированного long context. Плюс RAG-стоимость масштабируется линейно с числом запросов, а не с размером корпуса.

## Context engineering без RAG: практические техники

### Prompt caching

Самая недооценённая техника 2025–2026. Статичная часть контекста (system prompt, документация, examples) кэшируется на стороне провайдера. Повторные запросы читают из кэша.

**Стоимость на Claude:**

| Операция | Opus 4.8 | Sonnet 4.6 | Haiku 4.5 |
|----------|----------|------------|-----------|
| Base input | $5.00/MTok | $3.00/MTok | $1.00/MTok |
| Cache write (5-min) | $6.25/MTok | $3.75/MTok | $1.25/MTok |
| Cache write (1-hour) | $10.00/MTok | $6.00/MTok | $2.00/MTok |
| Cache read | $0.50/MTok | $0.30/MTok | $0.10/MTok |

Cache read — 10% от базовой стоимости. 90% экономии на повторных запросах.

**Пример: Anthropic API с prompt caching (Python)**

```python
import anthropic

client = anthropic.Anthropic()

# Статичный контекст — кэшируется
system_content = [
    {
        "type": "text",
        "text": "Ты — AI-ассистент юридической компании.",
    },
    {
        "type": "text",
        "text": full_legal_corpus,  # 200K токенов документации
        "cache_control": {"type": "ephemeral"}  # Кэшировать этот блок
    }
]

# Первый запрос: cache write ($6.25/MTok для Opus)
# Все последующие в течение 5 минут: cache read ($0.50/MTok)
response = client.messages.create(
    model="claude-opus-4-8-20260528",
    max_tokens=4096,
    system=system_content,
    messages=[{"role": "user", "content": "Какие риски в разделе 4.2?"}]
)
```

### CLAUDE.md и system instructions

Проектный контекст, который агент читает автоматически. Claude Code загружает CLAUDE.md при каждом запуске — стек, конвенции, архитектурные решения. Cursor использует `.cursorrules`. Windsurf — `.windsurfrules`.

Context engineering без RAG: статичный контекст проекта, поданный напрямую в промпт.

```markdown
# CLAUDE.md
## Стек
- Python 3.12, FastAPI, SQLAlchemy 2.0, PostgreSQL
- Alembic для миграций, pytest для тестов
## Конвенции
- Type hints обязательны
- Pydantic v2 для валидации
- Async handlers по умолчанию
## Архитектура
- Clean Architecture: domain → application → infrastructure
- Repository pattern для доступа к данным
```

### Tool use (MCP)

Вместо pre-loading всех данных в контекст — подтягивание по запросу. Model Context Protocol (MCP) стандартизирует доступ к внешним инструментам — детали реализации в гайде по [созданию production MCP-серверов](/ru/blog/mcp-production-custom-servers/).

```typescript
// MCP-сервер отдаёт данные по запросу агента
// Агент сам решает, когда и что запросить

// Вместо: загрузить все 500 тикетов в контекст
// Агент вызывает: search_tickets("auth bug priority:high")
// Получает: 3 релевантных тикета, 2K токенов
```

Агент загружает только то, что нужно для текущего шага. Контекст остаётся чистым.

### Memory — персистентность между сессиями

Агент сохраняет знания для будущих сессий. Claude Code записывает паттерны в MEMORY.md. Cursor хранит context в .cursor/rules/.

```markdown
# MEMORY.md (автоматически обновляется агентом)
## Learned Rules
- В этом проекте используется camelCase для API endpoints
- Миграции именуются: YYYY-MM-DD_description.sql
- Тесты группируются по модулям, не по типам
```

Это стратегия **Write** из четырёх стратегий context engineering. Агент пишет заметки для будущего себя.

### Structured output

JSON Schema в ответе гарантирует предсказуемый формат. Context engineering на выходе: вместо free-form текста — структурированные данные.

```python
from pydantic import BaseModel

class CodeReview(BaseModel):
    file: str
    severity: Literal["critical", "warning", "info"]
    issue: str
    suggestion: str
    line_range: tuple[int, int]

# LLM возвращает точно эту структуру
# Никакого парсинга, никаких регулярок
```

### Few-shot examples

Вместо fine-tuning — 3–5 примеров в контексте. Дешевле, быстрее, проще обновлять.

```
## Примеры code review (следуй этому формату):

Файл: auth.py:45-52
Severity: critical
Issue: SQL-инъекция через f-string
Suggestion: Используй параметризованный запрос
---
Файл: utils.py:12
Severity: info
Issue: Неиспользуемый импорт
Suggestion: Удали import os
```

Few-shot examples занимают 500–2000 токенов. С prompt caching они стоят $0.00025–$0.001 за запрос. Fine-tuning стоит $25+ за тренировку и ограничивает гибкость.

## RAG: современный стек 2026

### Chunking strategies

**Fixed-size chunking.** 512–1024 токенов с overlap 10–20%. Просто, предсказуемо, но разрезает семантически связанные блоки.

**Semantic chunking.** Разбивает по смысловым границам — заголовки, абзацы, смена темы. Embedding каждого предложения → если similarity между соседними предложениями падает ниже threshold → граница чанка. Качество выше, но дороже в обработке.

**Parent-child chunking.** Мелкие чанки (128–256 токенов) для поиска, но при retrieval возвращается parent (1024+ токенов) для контекста. Точный поиск + полный контекст.

**Late chunking.** Сначала embedding всего документа одним проходом, потом разбиение на чанки. Каждый чанк сохраняет контекст всего документа в своём embedding. Jina AI предложила подход в 2024, к 2026 он стал стандартом для длинных документов.

```python
# Parent-child chunking с LangChain
from langchain.text_splitter import RecursiveCharacterTextSplitter

# Parent: крупные чанки для контекста
parent_splitter = RecursiveCharacterTextSplitter(
    chunk_size=2000,
    chunk_overlap=200,
)

# Child: мелкие чанки для точного поиска
child_splitter = RecursiveCharacterTextSplitter(
    chunk_size=400,
    chunk_overlap=50,
)

# При поиске: находим child → возвращаем parent
```

### Embedding models (2026)

| Модель | Размерность | Цена/MTok | MTEB Score | Когда использовать |
|--------|------------|-----------|------------|-------------------|
| text-embedding-3-large (OpenAI) | 3072 | $0.13 | ~64.6 | Высокая точность, English-first |
| text-embedding-3-small (OpenAI) | 1536 | $0.02 | ~62.3 | Бюджетный вариант |
| Cohere Embed v4 | 1024 | $0.12 | ~66.3 | Мультиязычность, единственная multimodal-модель (текст + изображения) |
| Voyage 3.5 | 2048 | $0.06 | ~65+ | Лучший retrieval для кода, юридических и медицинских текстов; 32K context |
| BGE-M3 (open-source) | 1024 | $0 (self-host) | ~64+ | Self-hosted, без vendor lock-in |

Рекомендация: для большинства задач — text-embedding-3-small ($0.02/MTok). Для production с высокими требованиями к quality — Voyage 3.5 (особенно для домен-специфичного контента) или Cohere Embed v4 (мультимодальность и мультиязычность).

### Vector stores

| Решение | Тип | Latency (1M vectors) | Стоимость | Когда использовать |
|---------|-----|---------------------|-----------|-------------------|
| **pgvector** | Extension к PostgreSQL | 5–8ms (HNSW) | $0 (часть PostgreSQL) | Уже есть PostgreSQL, <5M vectors |
| **Qdrant** | Standalone, Rust | 3–5ms | Self-hosted / $25+/мес cloud | Performance-critical, >5M vectors |
| **Pinecone** | Managed SaaS | 10–20ms | $70+/мес (Serverless) | Zero-ops, масштаб до миллиардов |
| **Weaviate** | Standalone, Go | 5–10ms | Self-hosted / $25+/мес | Multimodal, GraphQL API |
| **ChromaDB** | Embedded | 1–3ms (small datasets) | $0 | Прототипы, <100K vectors |

**pgvector — правильный старт для 90% проектов.** Если PostgreSQL уже в стеке (а в 2026 это почти всегда так), pgvector устанавливается одной командой:

```sql
-- Установка pgvector (Supabase — включён по умолчанию)
CREATE EXTENSION IF NOT EXISTS vector;

-- Таблица для документов
CREATE TABLE documents (
    id BIGSERIAL PRIMARY KEY,
    content TEXT NOT NULL,
    metadata JSONB DEFAULT '{}',
    embedding VECTOR(1536)  -- text-embedding-3-small
);

-- HNSW индекс — быстрый approximate search
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
```

**RAG-пайплайн на Supabase + pgvector (Python):**

```python
import openai
from supabase import create_client

supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
embeddings = openai.OpenAI()

async def index_document(content: str, metadata: dict):
    """Индексация документа: chunking → embedding → store"""
    chunks = semantic_chunk(content, max_tokens=512)

    for chunk in chunks:
        response = embeddings.embeddings.create(
            model="text-embedding-3-small",
            input=chunk
        )
        vector = response.data[0].embedding

        supabase.table("documents").insert({
            "content": chunk,
            "metadata": metadata,
            "embedding": vector
        }).execute()


async def search(query: str, top_k: int = 5) -> list[dict]:
    """Semantic search: query → embedding → vector search"""
    response = embeddings.embeddings.create(
        model="text-embedding-3-small",
        input=query
    )
    query_vector = response.data[0].embedding

    # pgvector cosine similarity search
    results = supabase.rpc("match_documents", {
        "query_embedding": query_vector,
        "match_threshold": 0.7,
        "match_count": top_k
    }).execute()

    return results.data
```

```sql
-- Supabase Edge Function для semantic search
CREATE OR REPLACE FUNCTION match_documents(
    query_embedding VECTOR(1536),
    match_threshold FLOAT,
    match_count INT
)
RETURNS TABLE (
    id BIGINT,
    content TEXT,
    metadata JSONB,
    similarity FLOAT
)
LANGUAGE plpgsql
AS $$
BEGIN
    RETURN QUERY
    SELECT
        d.id,
        d.content,
        d.metadata,
        1 - (d.embedding <=> query_embedding) AS similarity
    FROM documents d
    WHERE 1 - (d.embedding <=> query_embedding) > match_threshold
    ORDER BY d.embedding <=> query_embedding
    LIMIT match_count;
END;
$$;
```

### Reranking

Vector search возвращает top-20 кандидатов. Reranker переоценивает их точнее. Двухступенчатая архитектура: быстрый recall (vector search) → точный precision (reranker).

| Модель | Цена | Качество | Когда |
|--------|------|----------|-------|
| Cohere Rerank v3.5 | $2/1K searches | Высокое | Production, multilingual (100+ языков) |
| BGE Reranker v2.5 | $0 (self-host) | Среднее-высокое | Self-hosted, бюджет |
| Jina Reranker v2 | $0.02/1K queries | Высокое | Баланс цена/качество |

```python
import cohere

co = cohere.Client(api_key="...")

# Vector search вернул 20 кандидатов
candidates = await search(query, top_k=20)

# Reranker переоценивает релевантность
reranked = co.rerank(
    model="rerank-v3.5",  # Cohere Rerank v3.5, апрель 2026
    query=query,
    documents=[c["content"] for c in candidates],
    top_n=5  # Оставляем top-5
)

# reranked.results — отсортированы по точной релевантности
```

### Hybrid search: vector + BM25

Vector search находит семантически похожее. BM25 находит точные совпадения (keyword search). Hybrid search покрывает оба сценария.

```python
# Reciprocal Rank Fusion (RRF) — простой способ объединить результаты
def reciprocal_rank_fusion(
    vector_results: list,
    bm25_results: list,
    k: int = 60
) -> list:
    """Объединяет vector и keyword search через RRF."""
    scores = {}

    for rank, doc in enumerate(vector_results):
        scores[doc["id"]] = scores.get(doc["id"], 0) + 1 / (k + rank + 1)

    for rank, doc in enumerate(bm25_results):
        scores[doc["id"]] = scores.get(doc["id"], 0) + 1 / (k + rank + 1)

    return sorted(scores.items(), key=lambda x: x[1], reverse=True)
```

pgvector + PostgreSQL Full-Text Search — hybrid search без дополнительной инфраструктуры:

```sql
-- Hybrid search: vector similarity + text relevance
SELECT
    d.id,
    d.content,
    -- Нормализованные скоры
    (1 - (d.embedding <=> query_embedding)) * 0.7 AS vector_score,
    ts_rank(d.fts, plainto_tsquery('english', query_text)) * 0.3 AS text_score,
    -- Комбинированный скор
    (1 - (d.embedding <=> query_embedding)) * 0.7 +
    ts_rank(d.fts, plainto_tsquery('english', query_text)) * 0.3 AS combined_score
FROM documents d
WHERE
    d.fts @@ plainto_tsquery('english', query_text)
    OR (1 - (d.embedding <=> query_embedding)) > 0.5
ORDER BY combined_score DESC
LIMIT 10;
```

### GraphRAG и LightRAG

К 2026 году Microsoft GraphRAG из академической статьи превратился в production-инструмент. Идея: вместо индексации плоских чанков — строить граф сущностей и отношений поверх корпуса, а при поиске обходить граф. Это даёт принципиально другой класс ответов.

**Когда нужен GraphRAG:**
- Вопросы о связях между документами («какие компании работали с X», «как менялась позиция Y во времени»)
- Глобальный суммаризирующий анализ всего корпуса
- Тематические и паттерн-поисковые запросы

**LightRAG** — облегчённая альтернатива от HKU (2024). Тот же граф сущностей, но без тяжёлой инфраструктуры Microsoft. По качеству сопоставим с GraphRAG при 10–30× меньшей стоимости и 6–13× меньшей латентности.

Практика 2026: production-стеки для enterprise-корпусов с богатой семантикой связей всё чаще используют **гибрид vector + graph**, маршрутизируя запрос к нужному индексу по типу вопроса.

```python
# Упрощённая маршрутизация: vector vs graph
def route_query(query: str) -> str:
    """Определяем стратегию retrieval по типу запроса."""
    relational_signals = [
        "как связаны", "отношения между", "что общего у",
        "как менялось", "кто работал с", "паттерн"
    ]
    if any(signal in query.lower() for signal in relational_signals):
        return "graph"  # GraphRAG / LightRAG
    return "vector"  # Обычный vector search + reranking
```

### Agentic RAG

Классический RAG: запрос → search → результат. Agentic RAG: агент решает стратегию поиска.

```python
# Agentic RAG: агент выбирает стратегию
tools = [
    {
        "name": "search_docs",
        "description": "Semantic search по документации",
        "parameters": {"query": "str", "top_k": "int", "filters": "dict"}
    },
    {
        "name": "search_code",
        "description": "Поиск по кодовой базе (grep, AST)",
        "parameters": {"pattern": "str", "file_types": "list[str]"}
    },
    {
        "name": "search_tickets",
        "description": "Поиск по Jira/Linear тикетам",
        "parameters": {"query": "str", "status": "str"}
    },
    {
        "name": "graph_search",
        "description": "GraphRAG — поиск по графу сущностей для вопросов о связях",
        "parameters": {"query": "str", "depth": "int"}
    }
]

# Агент получает вопрос: "Почему auth ломается после деплоя?"
# Агент решает:
# 1. search_code("auth", file_types=["py"]) — найти auth-модуль
# 2. search_tickets("auth deploy bug", status="recent") — найти связанные тикеты
# 3. search_docs("deployment auth configuration") — проверить документацию
# 4. При необходимости переформулирует запрос и повторяет поиск
# Комбинирует результаты и отвечает
```

Agentic RAG — context engineering в действии. Агент не просто извлекает документы, а оркестрирует поиск по нескольким источникам.

## Decision framework: что выбрать

### Блок-схема

```
Размер корпуса данных?
├── < 200K токенов
│   └── → Long context (всё в промпт + prompt caching)
├── 200K – 1M токенов
│   ├── Данные статичны?
│   │   ├── Да → Long context + prompt caching
│   │   └── Нет → RAG (инкрементальный индекс)
│   ├── Latency < 1с?
│   │   ├── Да → RAG
│   │   └── Нет → Long context допустим
│   └── Бюджет ограничен + высокая нагрузка?
│       ├── Да → RAG (меньше токенов на запрос)
│       └── Нет → Long context проще
└── > 1M токенов
    └── → RAG (обязательно)
        ├── Нужна attribution? → RAG с metadata
        ├── Вопросы о связях между документами? → GraphRAG / LightRAG
        ├── Complex multi-hop queries? → Agentic RAG
        └── Multilingual? → Cohere Embed v4 / BGE-M3
```

### Матрица решений

| Сценарий | Размер данных | Обновления | Latency | Рекомендация |
|----------|--------------|-----------|---------|-------------|
| Чатбот поддержки | 500+ документов | Еженедельно | <1с | RAG + reranking |
| Code assistant | 50–100K строк | Постоянно | 2–5с допустимо | Long context (grep/glob) |
| Legal research | 100K+ документов | Редко | Не критична | RAG + hybrid search |
| Документация продукта | 20–50 документов | Ежемесячно | <2с | Long context + cache |
| Customer analytics | 1M+ записей | Ежедневно | <500ms | RAG + structured retrieval |
| Onboarding assistant | 30 internal docs | Раз в квартал | <3с | Long context + cache |
| Research assistant | 10K+ papers | Еженедельно | Не критична | Agentic RAG + GraphRAG + reranking |

### Реальные сценарии

**Customer support bot.** 2000 статей FAQ, обновляются еженедельно, нужен ответ за 1 секунду, нужна ссылка на источник. → RAG. Hybrid search (vector + BM25) + Cohere Rerank + attribution через metadata.

**Code assistant (Claude Code).** Кодовая база 80K строк, обновляется непрерывно, latency 2–5с допустима, нужен полный контекст файлов. → Long context. Grep/glob для retrieval, весь файл в контекст, CLAUDE.md для проектных конвенций.

**Legal research.** 50 000 судебных решений, обновляются ежемесячно, нужна точная citation, запросы сложные (перекрёстные ссылки, связи между прецедентами). → Agentic RAG + GraphRAG. Parent-child chunking, hybrid search, reranking, граф сущностей для связей между делами, agent решает стратегию поиска.

**Internal knowledge base.** 40 документов, 150K токенов, обновляются раз в месяц, 50 запросов/день. → Long context + prompt caching. Все документы в system prompt, cache read за $0.10/запрос. Стоимость: $5/день = $150/мес. RAG-инфраструктура обойдётся дороже.

## Комбинированный подход

### RAG + Context Engineering — не either/or

Production-системы 2026 комбинируют оба подхода. RAG отвечает за retrieval. Context engineering — за assembly.

```
┌─────────────────────────────────────────────────┐
│                Context Assembly                  │
│  (Context Engineering — orchestration layer)     │
├─────────────────────────────────────────────────┤
│                                                  │
│  1. System Prompt          ← Статичный, cached   │
│     ├── Role definition                          │
│     ├── Project context (CLAUDE.md)              │
│     └── Output format                            │
│                                                  │
│  2. Retrieved Context      ← RAG pipeline        │
│     ├── Vector search results                    │
│     ├── BM25 keyword matches                     │
│     └── Reranked top-K                           │
│                                                  │
│  3. Tool Results           ← On-demand via MCP   │
│     ├── Database queries                         │
│     ├── API responses                            │
│     └── Code search results                      │
│                                                  │
│  4. Memory                 ← Persistent storage  │
│     ├── Previous conversation summary            │
│     ├── User preferences                         │
│     └── Learned patterns                         │
│                                                  │
│  5. Few-shot Examples      ← Cached at the end   │
│                                                  │
│  → Assembled Context → LLM → Response            │
│                                                  │
└─────────────────────────────────────────────────┘
```

### Пример архитектуры: support bot с комбинированным подходом

```python
async def handle_query(user_query: str, user_id: str) -> str:
    """Комбинированный подход: RAG + context engineering."""

    # 1. System prompt (cached, стратегия Write)
    system = build_system_prompt(
        role="support_agent",
        company_policies=CACHED_POLICIES,  # prompt caching
        output_format=TICKET_SCHEMA
    )

    # 2. RAG retrieval (стратегия Select)
    relevant_docs = await rag_search(
        query=user_query,
        top_k=5,
        rerank=True
    )

    # 3. User context (стратегия Select — tools)
    user_history = await get_recent_tickets(user_id, limit=3)
    user_plan = await get_subscription_plan(user_id)

    # 4. Memory (стратегия Write/Select)
    conversation_summary = await get_conversation_memory(user_id)

    # 5. Assembly (Context Engineering — оркестрация)
    context = assemble_context(
        system=system,
        retrieved_docs=relevant_docs,      # RAG результаты
        user_context={
            "history": user_history,
            "plan": user_plan
        },
        memory=conversation_summary,
        examples=FEW_SHOT_SUPPORT_EXAMPLES  # Cached
    )

    # 6. Сжатие если нужно (стратегия Compress)
    if count_tokens(context) > MAX_CONTEXT:
        context = compress_context(context, target_tokens=MAX_CONTEXT)

    # 7. LLM call
    response = await llm.generate(context=context, query=user_query)

    # 8. Сохранить в memory (стратегия Write)
    await update_conversation_memory(user_id, user_query, response)

    return response
```

### Когда комбинация необходима

- **Персонализация.** RAG находит документы, но ответ нужно адаптировать под пользователя (план, историю, предпочтения). Без context engineering получается generic ответ.

- **Multi-source retrieval.** Данные в нескольких системах: docs в vector store, тикеты в Jira, код в Git. RAG не знает про Jira. Context engineering оркестрирует все источники.

- **Stateful conversations.** RAG — stateless. Каждый запрос независим. Для диалога нужна memory — стратегия Write. RAG + memory = комбинированный подход.

- **Quality optimization.** RAG вернул 5 чанков. Но один — дубликат, другой — устаревший. Context engineering фильтрует, дедуплицирует, расставляет приоритеты.

## Метрики и оценка

### Метрики качества контекста

| Метрика | Что измеряет | Как считать |
|---------|-------------|-------------|
| **Relevance** | Насколько контекст релевантен запросу | LLM-as-judge: «оцени релевантность 1–5» |
| **Coverage** | Покрывает ли контекст все аспекты вопроса | % аспектов вопроса, на которые есть данные в контексте |
| **Noise ratio** | Доля нерелевантного контента | Токены нерелевантного / общие токены |
| **Token efficiency** | Сколько полезных токенов на единицу стоимости | Relevance score / cost per query |

### RAG-метрики

**Precision@K** — из K извлечённых документов, сколько релевантны.
```
Precision@5 = 4 релевантных из 5 извлечённых = 0.80
```

**Recall@K** — из всех релевантных документов в корпусе, сколько попали в top-K.
```
10 релевантных документов в корпусе, 4 попали в top-5 → Recall@5 = 0.40
```

**MRR (Mean Reciprocal Rank)** — на какой позиции первый релевантный документ.
```
Первый релевантный на позиции 2 → RR = 1/2 = 0.50
Среднее по всем запросам = MRR
```

**NDCG (Normalized Discounted Cumulative Gain)** — учитывает не только наличие, но и позицию каждого релевантного документа.

### End-to-end метрики

| Метрика | Что измеряет | Инструменты |
|---------|-------------|-------------|
| **Answer accuracy** | Правильность ответа | Eval set + LLM-as-judge |
| **Faithfulness** | Ответ основан на контексте, а не на hallucination | RAGAS, DeepEval |
| **Hallucination rate** | % утверждений без основания в контексте | RAGAS faithfulness metric |
| **Latency (p50, p95)** | Время от запроса до ответа | [Langfuse](/ru/blog/llm-observability-langfuse/), LangSmith |
| **Cost per query** | Полная стоимость: embedding + retrieval + LLM | Billing API + custom tracking |

### Eval pipeline

```python
from ragas import evaluate
from ragas.metrics import (
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall
)

# Eval dataset: вопрос + эталонный ответ + контекст
eval_results = evaluate(
    dataset=eval_dataset,
    metrics=[
        faithfulness,          # Ответ основан на контексте?
        answer_relevancy,      # Ответ релевантен вопросу?
        context_precision,     # Извлечённый контекст точен?
        context_recall,        # Контекст покрывает все аспекты?
    ]
)

# Результат:
# faithfulness: 0.92
# answer_relevancy: 0.88
# context_precision: 0.85
# context_recall: 0.78 → нужно улучшить retrieval
```

## Итог

Context engineering и RAG — не конкуренты. Context engineering — дисциплина. RAG — один из инструментов внутри неё.

Четыре правила:

1. **Данные влезают в контекстное окно и не меняются часто** — long context + prompt caching. Проще, дешевле, надёжнее.

2. **Корпус большой, данные обновляются, нужна attribution или latency** — RAG. С hybrid search и reranking.

3. **Нужны ответы о связях между документами, паттернах, глобальном анализе корпуса** — GraphRAG или LightRAG. Граф сущностей там, где плоский vector search не справляется.

4. **Production** — комбинация. RAG для retrieval, context engineering для assembly, prompt caching для экономии. Граф — там, где нужны связи. Одно без другого работает хуже, чем оба вместе.

Контекстные окна продолжат расти. Стоимость токенов — падать. Но принцип останется: качество ответа определяется не количеством токенов в контексте, а их релевантностью. Context engineering — про это.
