Context Engineering vs RAG: когда что использовать
Что такое context engineering?
Context engineering — дисциплина осознанной сборки контекста для LLM-запроса: выбор документов, структурирование данных, управление памятью, оркестрация tool results и RAG-результатов. Отличается от prompt engineering тем, что охватывает весь пайплайн подготовки входных данных, а не только формулировку вопроса.
TL;DR
- -Context engineering — дисциплина сборки контекста для LLM; RAG — один из её инструментов, а не альтернатива
- -При низкой нагрузке (до ~50 запросов/день) документ до 200K токенов дешевле загрузить в контекст с prompt caching, чем строить и поддерживать RAG-пайплайн
- -RAG необходим когда корпус в токенах не вмещается в контекстное окно, при частых обновлениях данных и требованиях к attribution
- -Prompt caching снижает стоимость повторных запросов на 90% — $0.50 vs $5.00 за 1M токенов на Claude Opus 4.8
- -Комбинированный подход RAG + context assembly + prompt caching — стандарт production-систем 2026; GraphRAG добавляет граф сущностей для enterprise-корпусов
В 2024 году RAG был ответом на любой вопрос о работе LLM с внешними данными. В 2026 году контекстные окна выросли до 1–2 миллионов токенов, prompt caching снизил стоимость повторных запросов на 90%, а термин «context engineering» оформился в отдельную дисциплину. RAG никуда не делся — но перестал быть единственным решением.
Статья разбирает: что такое context engineering, чем отличается от RAG, когда достаточно long context, когда нужен RAG, и как комбинировать оба подхода. С расчётами стоимости, примерами кода и decision framework. Полную картину дисциплины — шестислойную структуру контекста, паттерны персистентности, изоляцию через субагентов — смотрите в гайде по context engineering.
Что такое context engineering
Андрей Карпати сформулировал определение в июне 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 — как сформулировать вопрос (подробнее — в статье как писать промпты). Context engineering — что подать модели перед вопросом. Разница принципиальная:
| Аспект | Prompt Engineering | Context Engineering |
|---|---|---|
| Фокус | Формулировка запроса | Сборка входных данных |
| Scope | Один промпт | Весь пайплайн |
| Компоненты | Роль, формат, chain-of-thought | System prompt + docs + tools + memory + examples |
| Метафора | Как задать вопрос эксперту | Какое досье дать эксперту перед вопросом |
Идеальный промпт с плохим контекстом даёт плохой результат. Посредственный промпт с точным контекстом — хороший.
Компоненты context engineering
Контекст LLM-запроса собирается из шести источников:
- System prompt — роль, ограничения, стиль поведения
- Project context — стек, конвенции, архитектурные решения (CLAUDE.md, .cursorrules)
- Retrieved documents — результаты RAG, поиска по коду, grep
- Tool results — ответы от API, баз данных, MCP-серверов
- Memory — персистентные заметки между сессиями
- 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 получает релевантные документы перед генерацией ответа. Три шага:
- Retrieve — найти релевантные фрагменты в корпусе
- Augment — добавить найденное в промпт
- 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 в 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) показало: все 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)
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: статичный контекст проекта, поданный напрямую в промпт.
# 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-серверов.
// MCP-сервер отдаёт данные по запросу агента
// Агент сам решает, когда и что запросить
// Вместо: загрузить все 500 тикетов в контекст
// Агент вызывает: search_tickets("auth bug priority:high")
// Получает: 3 релевантных тикета, 2K токенов
Агент загружает только то, что нужно для текущего шага. Контекст остаётся чистым.
Memory — персистентность между сессиями
Агент сохраняет знания для будущих сессий. Claude Code записывает паттерны в MEMORY.md. Cursor хранит context в .cursor/rules/.
# MEMORY.md (автоматически обновляется агентом)
## Learned Rules
- В этом проекте используется camelCase для API endpoints
- Миграции именуются: YYYY-MM-DD_description.sql
- Тесты группируются по модулям, не по типам
Это стратегия Write из четырёх стратегий context engineering. Агент пишет заметки для будущего себя.
Structured output
JSON Schema в ответе гарантирует предсказуемый формат. Context engineering на выходе: вместо free-form текста — структурированные данные.
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 он стал стандартом для длинных документов.
# 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 устанавливается одной командой:
-- Установка 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):
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
-- 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 | Высокое | Баланс цена/качество |
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 покрывает оба сценария.
# 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 без дополнительной инфраструктуры:
-- 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, маршрутизируя запрос к нужному индексу по типу вопроса.
# Упрощённая маршрутизация: 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: агент решает стратегию поиска.
# 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 с комбинированным подходом
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, LangSmith |
| Cost per query | Полная стоимость: embedding + retrieval + LLM | Billing API + custom tracking |
Eval pipeline
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 — один из инструментов внутри неё.
Четыре правила:
-
Данные влезают в контекстное окно и не меняются часто — long context + prompt caching. Проще, дешевле, надёжнее.
-
Корпус большой, данные обновляются, нужна attribution или latency — RAG. С hybrid search и reranking.
-
Нужны ответы о связях между документами, паттернах, глобальном анализе корпуса — GraphRAG или LightRAG. Граф сущностей там, где плоский vector search не справляется.
-
Production — комбинация. RAG для retrieval, context engineering для assembly, prompt caching для экономии. Граф — там, где нужны связи. Одно без другого работает хуже, чем оба вместе.
Контекстные окна продолжат расти. Стоимость токенов — падать. Но принцип останется: качество ответа определяется не количеством токенов в контексте, а их релевантностью. Context engineering — про это.