Зачем усложнять простой RAG?
Базовый RAG - это как молоток. Берёшь запрос, ищешь похожие чанки, кормишь LLM. Работает в 80% случаев. Но что делать, когда точность падает с 85% до 60% после добавления ещё 10 тысяч документов? Когда пользователи жалуются, что ИИ "врет" или "не понимает контекст"?
Вот тут появляются расширенные функции: оптимизация запросов (query rewriting), расширение соседей (neighbor expansion), гибридный поиск, реранкинг. Каждая добавляет сложность, задержку и стоимость. Но иногда - только иногда - они спасают проект от провала.
Самый частый вопрос в чатах RAG-разработчиков: "Мы добавили гибридный поиск, точность выросла на 5%, но стоимость запроса увеличилась в 2 раза. Это нормально?" Ответ: зависит от того, сколько стоит ваша ошибка.
Цена ошибки против цены запроса
Представьте два сценария:
- Чатбот для интернет-магазина: ошибка в ответе стоит 0 рублей. Клиент получит не тот размер обуви? Ну и что, переспросит.
- Медицинский ассистент: ошибка в дозировке лекарства стоит человеческой жизни. Или как минимум - многомиллионного иска.
В первом случае вам хватит базового RAG с BM25. Во втором - придётся выжимать из системы максимум точности, не считая денег.
Оптимизация запросов: когда LLM должен думать дважды
Пользователь спрашивает: "Как настроить PostgreSQL для высокой нагрузки?" Базовый RAG ищет чанки про "настройку PostgreSQL". Находит 50 результатов. LLM пытается собрать ответ из этого месива.
Оптимизация запросов работает иначе. Сначала другой LLM (обычно меньший и дешевле) анализирует исходный запрос:
# Пример query rewriting на Python
original_query = "Как настроить PostgreSQL для высокой нагрузки?"
# Шаг 1: Разбиваем запрос на подзапросы
sub_queries = [
"PostgreSQL конфигурация performance tuning",
"max_connections shared_buffers work_mem",
"индексы для высокой нагрузки PostgreSQL",
"мониторинг производительности PostgreSQL"
]
# Шаг 2: Параллельный поиск по всем подзапросам
# Шаг 3: Объединение результатов и реранкинг
Результат? Вместо одного расплывчатого поиска получаем 4 точных. Точность вырастает на 15-30%. Но цена запроса увеличивается в 3-5 раз. Нужно запускать дополнительную LLM, делать несколько поисковых запросов, объединять результаты.
1 Когда оптимизация запросов окупается?
- Сложные многосоставные вопросы: "Сравни преимущества Kubernetes против Docker Swarm для микросервисов на Go"
- Профессиональные ниши: медицина, юриспруденция, финансы - где терминология специфична
- Большие базы знаний: когда простой поиск даёт слишком много шума
- Мультиязычные системы: где нужно учитывать синонимы на разных языках
Расширение соседей: поиск того, чего нет в запросе
Классическая проблема RAG: пользователь спрашивает про конкретную ошибку, но в базе знаний нет статьи с точным текстом ошибки. Есть только общие руководства по устранению неполадок.
Расширение соседей решает эту проблему так:
# Алгоритм расширения графа соседей
def expand_neighbors(query_embedding, initial_results, depth=2):
"""
initial_results: первые k ближайших соседей
depth: сколько уровней графа исследовать
"""
all_results = set(initial_results)
for level in range(depth):
neighbors = []
for doc in all_results:
# Ищем документы, связанные с текущим
related = vector_db.search(
query=doc.embedding,
k=5,
filter={"id": {"$nin": [d.id for d in all_results]}}
)
neighbors.extend(related)
all_results.update(neighbors)
return list(all_results)
Идея в том, чтобы найти не только то, что похоже на запрос, но и то, что связано с найденными документами. Как в социальной сети: вы находите одного эксперта по PostgreSQL, а через него - ещё пять.
Осторожно с глубиной расширения! Depth=3 может увеличить время поиска в 10 раз. На больших базах это превращается в снежный ком: каждый документ тянет за собой ещё 5, те - ещё 5, и вот у вас уже 125 документов для обработки вместо изначальных 5.
Гибридный поиск: BM25 + векторный = магия?
В статье "Гибридный поиск для RAG" мы уже разбирали, как поднять точность на 48%. Но давайте посмотрим на цену.
| Метод поиска | Точность | Задержка (ms) | Стоимость запроса | Когда использовать |
|---|---|---|---|---|
| Только BM25 | 65% | 15-50ms | $0.0001 | Текстовые FAQ, документация |
| Только векторный | 70% | 100-300ms | $0.0005 | Семантический поиск, похожие смыслы |
| Гибридный (RRF) | 85% | 150-400ms | $0.0006 | Производственные системы, где важна точность |
| Гибридный + оптимизация | 92% | 500-1500ms | $0.0020 | Критические системы (медицина, финансы) |
Обратите внимание на скачок стоимости между третьей и четвёртой строками. Гибридный поиск сам по себе добавляет немного задержки. Но когда вы добавляете оптимизацию запросов - цена взлетает в 3-4 раза.
Практический эксперимент: медицинский чатбот
Давайте проведём мысленный эксперимент. У нас есть медицинский чатбот с 50 тысячами научных статей. Запросы типа: "Какие есть противопоказания для препарата X у пациентов с болезнью Y?"
Мы тестируем три конфигурации:
2 Конфигурация A: Базовый RAG
- Векторный поиск (FAISS)
- Top-5 результатов
- GPT-4 для генерации ответа
- Стоимость: $0.03 на запрос
- Точность: 76%
3 Конфигурация B: Расширенный RAG
- Query rewriting (GPT-3.5 Turbo)
- Гибридный поиск (BM25 + векторы)
- Расширение соседей (depth=2)
- Реранкинг с cross-encoder
- GPT-4 для генерации
- Стоимость: $0.12 на запрос
- Точность: 94%
Разница в точности - 18%. Разница в стоимости - 4 раза. Оправдано?
Давайте посчитаем. Если система обрабатывает 1000 запросов в день:
# Расчет ROI для медицинского чатбота
cost_per_day_basic = 1000 * 0.03 # $30 в день
cost_per_day_advanced = 1000 * 0.12 # $120 в день
error_rate_basic = 0.24 # 24% ошибок
error_rate_advanced = 0.06 # 6% ошибок
# Предположим, что одна серьёзная ошибка стоит $10,000
# (судебный иск, потеря репутации)
cost_per_error = 10000
errors_per_day_basic = 1000 * 0.24 = 240
errors_per_day_advanced = 1000 * 0.06 = 60
# Не все ошибки серьёзные, допустим 1%
serious_errors_basic = 240 * 0.01 = 2.4
serious_errors_advanced = 60 * 0.01 = 0.6
risk_cost_basic = 2.4 * 10000 = $24,000 в день
risk_cost_advanced = 0.6 * 10000 = $6,000 в день
total_cost_basic = 30 + 24000 = $24,030
total_cost_advanced = 120 + 6000 = $6,120
Внезапно расширенный RAG оказывается в 4 раза дешевле базового. Потому что цена ошибки огромна.
Когда НЕ нужно усложнять
Теперь обратная ситуация. Чатбот для HR-отдела компании. Вопросы типа: "Как оформить отпуск?", "Где найти форму заявления?", "Какие документы нужны для больничного?"
Здесь:
- Ошибка не критична - сотрудник переспросит
- Запросы простые и конкретные
- База знаний маленькая (100-200 документов)
- Требуется низкая задержка (< 500ms)
В этом случае базовый RAG с BM25 поиском будет работать идеально. Добавление расширенных функций только увеличит стоимость без заметного улучшения точности.
LLM judges: судьи, которые дороже подсудимых
Модный тренд - использовать LLM как судью для оценки качества RAG. Вы отправляете вопрос, контекст и ответ, а модель оценивает релевантность по шкале от 1 до 5.
Проблема в стоимости. Каждая оценка стоит денег. Если у вас 1000 запросов в день, и вы хотите оценивать 10% из них:
# Стоимость мониторинга качества RAG
queries_per_day = 1000
sampling_rate = 0.1 # 10%
cost_per_evaluation = 0.001 # GPT-3.5 Turbo
daily_cost = queries_per_day * sampling_rate * cost_per_evaluation
# 1000 * 0.1 * 0.001 = $1 в день
# Плюс инфраструктура для сбора логов,
# хранения оценок, дашбордов...
# Итого: $300-500 в месяц
Для стартапа с 10 пользователями - это безумие. Для банка с миллионом запросов в день - необходимость.
План внедрения: от простого к сложному
4 Шаг 1: Измерьте базовые метрики
Прежде чем что-то улучшать, нужно понять, что улучшать. Соберите данные:
- Задержка ответа (p50, p95, p99)
- Точность (человеческая оценка 100 случайных запросов)
- Стоимость запроса (разбивка по компонентам)
- Частые ошибки пользователей
5 Шаг 2: Определите целевые метрики
Что важнее для вашего случая?
| Тип системы | Приоритет 1 | Приоритет 2 | Можно жертвовать |
|---|---|---|---|
| Медицинская | Точность | Задержка | Стоимость |
| Чат-поддержка | Задержка | Стоимость | Точность |
| Аналитическая | Точность | Стоимость | Задержка |
6 Шаг 3: Добавляйте функции по одной
Не внедряйте всё сразу. Добавили гибридный поиск - неделю мониторьте. Работает стабильно - добавляйте оптимизацию запросов. И так далее.
Типичные ошибки при оптимизации RAG
Ошибка 1: Слепая оптимизация без метрик. "Мы слышали, что гибридный поиск крутой, поэтому добавили". Результат: стоимость x2, точность +2%.
Ошибка 2: Не учитывать закон убывающей отдачи. Первые 20% улучшений дают 80% результата. Следующие 80% улучшений дают 20% результата. Иногда точность 92% достаточно, не нужно гнаться за 95% ценой x10 стоимости.
Ошибка 3: Оптимизировать то, что не болит. Пользователи довольны скоростью ответа в 800ms? Не нужно пытаться снизить до 500ms ценой снижения точности с 85% до 80%.
Самый главный совет
Начните с самого простого RAG. Буквально: загрузите документы в векторную БД, сделайте поиск по косинусной близости, сгенерируйте ответ через GPT-3.5 Turbo.
Запустите в продакшн. Соберите feedback. Только когда увидите конкретные проблемы ("система не понимает сложные вопросы", "путает похожие термины", "пропускает важный контекст") - тогда и только тогда добавляйте расширенные функции.
Каждую функцию тестируйте на реальных запросах пользователей. Измеряйте не только точность, но и стоимость, задержку, satisfaction rate.
И помните: идеальный RAG не существует. Есть RAG, который достаточно хорош для ваших задач и бюджета. Всё остальное - преждевременная оптимизация.
P.S. Если ваша система начала "врать" при росте базы знаний - сначала прочитайте статью "Когда RAG начинает врать". Возможно, проблема не в сложности поиска, а в качестве чанков или эмбеддингов.