Как оценивать затраты на языковые модели
Инженерный материал о базовой метрике, маршрутизации, кэшировании, пакетной обработке и проверке качества.
Retrieval-Augmented Generation выглядит понятно на демо: берём документы, разбиваем на чанки, кладём в векторное хранилище, при запросе достаём релевантные кусочки и передаём в LLM. На практике – в каждом шаге есть нюансы, которые не очевидны заранее.
Этот материал разбирает практические вопросы RAG-пайплайна: качество разбиения, поиск, задержки и проверка ответов. Это не отчёт о конкретном клиентском проекте; параметры и примеры нужно проверять на собственной системе.
Самое влиятельное решение во всём пайплайне – как именно вы режете документы. Фиксированный размер по токенам – самое простое, но редко оптимальное. Проблема: смысловые границы не совпадают с токенными. Предложение разрезается посередине, контекст теряется.
Recursive character text splitting с chunk_size=512 и chunk_overlap=64 можно использовать как исходную точку. Semantic chunking по смысловым блокам требует отдельной проверки качества и времени индексации на вашем корпусе.
# Пример: semantic chunking через embeddings similarity\n\ndef semantic_chunk(text, threshold=0.85):\n sentences = sent_tokenize(text)\n embeddings = embed_model.encode(sentences)\n chunks, current = [], [sentences[0]]\n\n for i in range(1, len(sentences)):\n sim = cosine_similarity(embeddings[i - 1], embeddings[i])\n if sim < threshold:\n chunks.append(\" \".join(current))\n current = []\n current.append(sentences[i])\n\n if current:\n chunks.append(\" \".join(current))\n\n return chunks OpenAI text-embedding-3-small – хороший выбор для русскоязычных документов. Но если у вас специфический домен (юридический, медицинский, технический) – стоит смотреть на fine-tuned модели или multilingual-e5-large.
Важный момент: эмбеддинг-модель для индексирования и для запросов должна быть одна и та же версия. Звучит очевидно, но при обновлении модели нужно переиндексировать весь корпус – иначе пространства не совпадают, и качество поиска деградирует незаметно.
Деградация качества при несовпадении версий эмбеддинга может быть тихой. Проверяйте поиск на контрольной выборке после каждого обновления и фиксируйте методику измерения.
Стандартный профиль запроса: embed запроса → similarity search → fetch документов → LLM completion. В большинстве случаев узкое место – не LLM, а retrieval.
LLM может сформировать неверный ответ, если retrieval возвращает нерелевантный контекст. Связь с нагрузкой проверяйте отдельно: на неё влияют кэширование, очереди, лимиты и деградация поиска.
Порог relevance_score_threshold можно использовать как защитное условие: если ни один чанк не проходит проверку, вернуть нейтральный ответ о нехватке данных. Порог и текст ответа нужно валидировать на своей контрольной выборке.
Второй вариант — cross-encoder reranking поверх первичного retrieval. Он добавляет вычисления, поэтому сравнивайте прирост качества, задержку и стоимость на одной контрольной выборке.
RAG – это не одно решение, это пайплайн из независимых компонентов, каждый из которых нужно тюнить под конкретный домен и нагрузку. Метрики нужны на каждом уровне: не только финальное качество ответа, но и recall@k, MRR, latency p95 по каждому этапу.
Если строите RAG систему – закладывайте время на эксперименты с chunking и эмбеддингами. Это не инфраструктурная задача, это исследовательская.