Почему ваш AI‑чатбот стоит $30k/мес и как снизить расходы
Разбираем реальные драйверы стоимости LLM‑чатботов: токены, контекст, RAG, tool‑calling, кэш. Даём архитектуру и код, как урезать счёт в 2–6 раз без потери качества.

Если ваш счёт за чатбот на LLM приближается к $30k в месяц — значит, вы платите не только за интеллект модели, но и за архитектурные потери: раздутый контекст, лишние tool‑calls, отсутствующий кэш и слабую маршрутизацию по моделям. Эти ошибки системные и дорогие.
Коротко: расходы взлетают от трёх вещей — неправильная модель «по умолчанию», слишком длинный контекст без обрезки и агрессивный tool‑calling от RAG/плагинов. Рецепт экономии: маршрутизатор моделей (cheap/fast vs smart), строгая диета токенов (промпт + память + сжатие контекста), семантический кэш, дисциплина функций и телеметрия «стоимости». Ниже — как это выглядит в продакшене.
Где сгорают деньги в LLM‑чатботах
Главная валюта — токены. Итоговая цена = входные токены + выходные токены + эмбеддинги + RAG‑инфраструктура + накладные на логи и ретраи. Типичный разбор одной «дорогой» сессии:
- Системный промпт 1–3k токенов (роль, стиль, политика безопасности, длинный список инструментов).
- Память пользователя 3–10k токенов (история, профили, последние N сообщений).
- Сообщение пользователя 200–800 токенов.
- RAG: 5–20 документов по 300–800 токенов каждый (реже — «сжатые» версии, чаще — сырые блоки).
- Функции: 1–3 tool‑call до БД, поиска, платежей, плюс egress/ingress токены.
- Выход модели 300–1.5k токенов.
Даже при «умеренных» настройках одна реплика может тянуть 5–15k входных токенов. Если вы используете дорогую модель для всех запросов, получите счёт уровня десятков тысяч. И это без учёта ретраев, где токены сгорают повторно.
Быстрый sanity‑чек: откуда $30k/мес
Возьмём порядок цен 2024 для крупных моделей (условно): вход $3–5 за 1M токенов, выход $10–15 за 1M токенов у «сильной» модели; у «мини» — $0.1–0.3 и $0.5–0.7 соответственно. Если у вас 200k обращений/мес, средний запрос — 6k входных + 600 выходных токенов на «тяжёлой» модели, получаем: вход 1.2e9 токенов ($6k), выход 1.2e8 токенов ($1.8k). Звучит терпимо — но добавьте RAG‑эмбеддинги, ретраи, tool‑calls, всплески контекста до 20k, ночные бэч‑прогоны, и в реальности легко выезжаем к $20–40k. Ошибка — считать «средний» кейс, игнорируя «хвост» (длинные диалоги и edge‑кейсы). Именно хвост сжигает бюджет.
Базовая архитектура недорогого чатбота
Цель — разделить «ум» и «дисциплину». Ум — это модель и RAG. Дисциплина — это маршрутизация, бюджетирование токенов, кэш, троттлинг и телеметрия.
Архитектурный скелет:
- API‑шлюз: аутентификация, лимиты по тарифам/организациям, rate‑limit на пользователя.
- Cost‑Guard Middleware: считает ожидаемые токены, обрезает контекст, запрещает дорогие пути при исчерпании бюджета, устанавливает «сейф‑слова» для выхода из глубоких цепочек рассуждений.
- Router (LLM Policy): дешёвая модель по умолчанию; переход на «умную» по детектору сложности (критерии: длина, наличие кода/SQL, неуверенность, история неудачных ответов).
- RAG Service: эмбеддинги, поиск (гибрид: BM25 + векторы), переранжирование и сжатие контента (LLM‑компрессор перед подстановкой в промпт).
- Semantic Cache: кэш по смысловой близости вопроса и контекста; возврат готовых ответов/планов действий при высокой близости.
- Tool Gateway: единая прослойка для функций (БД, платежи, внешние API) с бюджетом на число вызовов и временем.
- Providers: OpenAI/Anthropic/DeepSeek API + локальный vLLM/LM Studio кластер под узкие задачи.
- Telemetry: лог токенов, стоимости, «прыжков» маршрутизатора и tool‑calls. Дашборды и алерты по SLA/стоимости.
Поток запроса:
- Пользователь → API → нормализация текста, детект языка, проверка тарифа.
- Cost‑Guard прикидывает токены и обрезает историю/контекст по «бюджету на шаг».
- Semantic Cache: если попадание > τ, сразу отдаём кэш или короткий ответ + ссылки.
- Router выбирает модель: mini/sonnet/4o и т.п.
- RAG (по необходимости): топ‑k, фильтры, переранжирование, компрессия цитат.
- Модель отвечает, потоково стримим пользователю (SSE/WebSocket), параллельно считаем стоимость и пишем метрики.
Мы часто видим, как пропущенный пункт 2 или 3 удваивает счёт. Один слой дисциплины окупает день внедрения.
Три главных рычага экономии
1) Маршрутизатор моделей
Дешёвая модель (mini) справляется с 60–80% бытовых вопросов, переформулировок и «коротких» задач. Сильная нужна для редких сложных кейсов (много контекста, программирование, правовые формулировки). Простой эвристический роутер уже экономит 30–50%. Подбор моделей по продакшен‑кейсам мы разбирали в статье OpenAI GPT‑5 vs Claude vs DeepSeek для продакшн‑SaaS.
2) Диета токенов: контекст и память
- Системный промпт: держите <600–800 токенов. Все политики вынесите в «модули» и подмешивайте по необходимости.
- История: храните краткий саммари последних N сообщений, полную историю — в cold storage; при всплеске — динамически ресуммаризируйте.
- RAG‑вставки: до 2–4 документов по 150–300 токенов каждый, после компрессии; добавляйте цитаты/ссылки вместо полного текста.
3) Семантический кэш
Кэшируйте:
- Частые вопросы (FAQ‑уровень),
- «Планы» для tool‑calling (разобранная последовательность действий),
- Результаты тяжёлых запросов к базе/поиску.
Семантический кэш снижает стоимость до 2–3 раз на повторяющихся доменных вопросах. Для сегментов b2b с повторами — must‑have.
// TypeScript: middleware + простой роутер и кэш
import crypto from 'crypto'
import { createClient } from 'redis'
const redis = createClient({ url: process.env.REDIS_URL })
await redis.connect()
type Model = 'mini' | 'smart'
function estimateTokens(s: string) {
// Грубая оценка: 1 токен ≈ 4 символа латиницы / 2–3 кириллицы
return Math.ceil(Buffer.byteLength(s, 'utf8') / 3.5)
}
function chooseModel(input: string, contextTokens: number): Model {
const hasCode = /```|SELECT |INSERT |function\s|class\s|\{|\}|<\/?\w+>/.test(input)
const long = contextTokens > 4000
if (hasCode || long) return 'smart'
if (input.length > 800 && /юридическ|договор|регламент/i.test(input)) return 'smart'
return 'mini'
}
async function semanticCacheKey(userId: string, q: string, contextHash: string) {
const h = crypto.createHash('sha256').update(q + '|' + contextHash).digest('hex')
return `semcache:${userId}:${h}`
}
async function getCached(userId: string, q: string, contextHash: string) {
const key = await semanticCacheKey(userId, q, contextHash)
const v = await redis.get(key)
return v ? JSON.parse(v) : null
}
async function setCached(userId: string, q: string, contextHash: string, value: any, ttlSec = 86400) {
const key = await semanticCacheKey(userId, q, contextHash)
await redis.set(key, JSON.stringify(value), { EX: ttlSec })
}
interface CostPolicy { maxIn: number; maxOut: number; maxToolCalls: number }
const POLICIES: Record<string, CostPolicy> = {
free: { maxIn: 4000, maxOut: 600, maxToolCalls: 1 },
pro: { maxIn: 12000, maxOut: 1200, maxToolCalls: 3 },
ent: { maxIn: 24000, maxOut: 2000, maxToolCalls: 5 },
}
async function handleChat(req, res) {
const { userId, plan, message, history, ragSnippets } = req.body
const policy = POLICIES[plan] || POLICIES.free
const sysPrompt = 'Ты ассистент. Отвечай кратко. Цитируй источники при RAG.'
let context = [sysPrompt, history?.summary || '', ...(ragSnippets || [])].join('\n')
// Бюджет входных токенов
let budget = policy.maxIn
const msgTokens = estimateTokens(message)
let ctxTokens = estimateTokens(context)
while (ctxTokens + msgTokens > budget && context.length > 200) {
// Грубая обрезка контекста (в реале — «умное» сжатие LLM)
context = context.slice(Math.floor(context.length * 0.7))
ctxTokens = estimateTokens(context)
}
const contextHash = crypto.createHash('md5').update(context).digest('hex')
const cached = await getCached(userId, message, contextHash)
if (cached) return res.json({ ...cached, cached: true })
const model: Model = chooseModel(message, ctxTokens + msgTokens)
const response = await callProvider(model, {
input: message,
context,
maxOutputTokens: policy.maxOut,
toolCallBudget: policy.maxToolCalls,
})
// Телеметрия стоимости (упрощённая)
const cost = estimateTokens(context + message) * (model === 'smart' ? 0.00002 : 0.000002)
+ estimateTokens(response.text) * (model === 'smart' ? 0.00006 : 0.000006)
await setCached(userId, message, contextHash, { text: response.text, model, cost })
return res.json({ text: response.text, model, cost })
}
async function callProvider(model: Model, payload: any) {
const provider = model === 'smart' ? process.env.PROVIDER_SMART : process.env.PROVIDER_MINI
const r = await fetch(`${provider}/chat`, {
method: 'POST', headers: { 'content-type': 'application/json' },
body: JSON.stringify(payload)
})
if (!r.ok) throw new Error('LLM provider error')
return r.json()
}
Код нарочито упрощён: в продакшене добавляем «умное сжатие» (compress‑chain), трекер реальных токенов от провайдера, контекстуальные политики (категории запросов), а также stratified‑cache (горячий/тёплый/холодный).
RAG без переплат: от индекса до вставки
RAG чаще всего раздувает контекст и приводит к повторным вызовам модели. Основные рычаги:
- Чанкинг 300–500 токенов с явными заголовками и скользящими окнами 20–30% — повышает recall без лишней избыточности.
- Гибридный поиск: BM25 (pg_trgm) + векторы (pgvector) и «учёт разделов» (source/section filters) — меньше нерелевантного шума.
- Переранжирование mini‑моделью (cross‑encoder) до top‑k=3–5 — дешевле, чем тащить 15 длинных фрагментов в «умную» модель.
- Компрессия перед вставкой: попросить mini‑модель сжать каждый документ до 120–200 токенов с цитатами/якорями.
- Инъекции: санитария промпта + политики на уровне Retriever, чтобы документы не «просили» расширить контекст.
Выбор хранилища и подхода к векторному поиску
| Подход | Экономия | Риски | Когда использовать |
|---|---|---|---|
| Postgres + pgvector + pg_trgm | Низкая стоимость эксплуатации, меньше сервисов | Тюнинг индексов критичен; пиковые нагрузки потребуют реплики | 100К–10М документов, средние нагрузки, DevOps‑дисциплина есть |
| Managed Vector DB (Pinecone/Weaviate Cloud) | Быстрый старт, SLA, auto‑scaling | Оплата за QPS/хранилище; сетевой egress | Когда критичны время и SLA, команда небольшая |
| Self‑host Weaviate/Qdrant | Гибкость, контроль затрат | Операционные риски, апгрейды | Нужен контроль/изолированность, on‑prem/air‑gapped |
| Только BM25 (без векторов) | 0 на эмбеддинги | Падение качества на синонимах/парафразах | Узкая терминология, короткие документы |
Сами эмбеддинги — ещё одна строка в счёте. Оптимизация:
- Снизить размерность (например, small‑модель для эмбеддингов) и использовать переранжирование поверх.
- Дедупликация и агрегация «похожих» чанков.
- Асинхронная индексация, ночные бэчи по тарифам с низкой нагрузкой.
Про «суверенные» модели для RAG/эмбеддингов и как это режет капитальные/операционные издержки — см. наш разбор Sovereign LLM на 80% дешевле? Практика.
Tool‑calling под контролем
Плагины и функции полезны, но без лимитов вы получите каскады: модель запускает поиск, затем БД, затем ещё один поиск… и так 6–8 шагов. Правила:
- Жёсткий бюджет
maxToolCallsна шаг и на сессию. - Отложенные инструменты: сначала резюмировать вопрос, сформулировать «план», затем один батч‑запрос.
- Кэширование результатов инструментов (особенно запросов к товарам/каталогам/отчётам).
- Guard‑промпты с «ранним выходом» при слабой уверенности: просить пользователя уточнить.
- Трассировка инструментов с затратами: какие функции сжигают больше всего токенов/времени.
В реальных продуктах дисциплина tool‑calling даёт 10–30% экономии без видимой потери качества. Маленькая мера, большой эффект.
Что ломается в продакшене
- Prompt‑инъекции, которые «заставляют» подмешивать всё больше контекста, растя стоимость. Лечится фильтрацией и контекст‑компрессией.
- Ретраи и timeouts: двойные/тройные вызовы на одну реплику. Нужны таймаут‑политики и идемпотентность.
- Длинные чаты без усечения: «вечные» диалоги быстро переходят 100k токенов истории. Принудительное саммари каждые N сообщений.
- Отсутствие потоковой отдачи: пользователь ждёт, вы увеличиваете температурy/максимум токенов «на всякий случай». Стрим уменьшает панику и издержки.
- Платёжки за эмбеддинги: бэчите, кэшируйте, отключайте частую переиндексацию.
- Непрозрачные графики провайдера: провайдер считает токены иначе, чем вы. Следите за фактом через их usage API и сводите с вашими логами.
- Нестабильные векторные индексы на больших коллекциях без VACUUM/REINDEX — запросы становятся дорогими и медленными, пока не прилетит ночной алерт.
Одна сухая шутка: самый быстрый способ обнулить бюджет — дать модели задачу «подумать вслух» и забыть выключить chain‑of‑thought в продакшене.
Деньги и ROI: когда $30k — норма, а когда — нет
Формула счёта:
- Модель: вход + выход токенов × тариф.
- Эмбеддинги: документы × средняя длина × тариф.
- Хранилище: объем индексов, QPS.
- Ретраи/дубли: коэффициент 1.1–1.4, если политика агрессивная.
- Инструменты: egress и токены на форматирование/парсинг.
Сценарий 1 (дорого):
- 150k обращений/мес, средний контекст 7k входных + 900 выходных токенов на «умной» модели.
- 40% запросов идут в RAG (4 вставки по 400 токенов каждая без компрессии), 1.4× ретраи на хвосте.
- Оценка: вход ~1.47e9, выход ~1.89e8 токенов → с текущими тарифами «сильных» моделей + эмбеддинги/хранилище, счёт легко переваливает $25–35k.
Сценарий 2 (оптимизировано):
- Тот же трафик, но: 70% запросов на mini, «умная» — только по признаку сложности.
- Компрессия RAG до 2–3 вставок по 180–220 токенов, кэширование повторов.
- История в саммари, системный промпт 500–700 токенов.
- Ретраи ограничены, tool‑calling ≤2/шаг.
- Итог: вход/выход токенов падают в 2–4 раза, средняя цена за обращение — в 2–6 раз. Итоговый счёт $6–12k вместо $30k.
ROI зависит от конверсий и LTV. Если чат — core‑функция (саппорт, продажи, критичная аналитика), «умная» модель вверху воронки может быть оправдана. Если чат — вспомогательная фича, экономьте агрессивно и давайте пользователю «кнопку умнее ответ» как платную опцию.
Практические чек‑листы по снижению стоимости
- Включите маршрутизатор: mini по умолчанию; smart — по сложности/неуверенности/кейсу.
- Пороговый кэш: если семантическая близость > τ и контекст свежий — отдаём из кэша.
- Компрессор контекста: LLM‑пресс до 150–300 токенов на документ, не более 3–4 доков.
- История в self‑summary с регулярным пересчётом; хранить полный лог вне промпта.
- Tool‑budget: жёсткие лимиты на шаг, батчинг запросов, кэширование результатов инструментов.
- Телеметрия: графики токенов по маршрутам, алерты при росте >20% за час/день.
- Тесты‑оценки (evals) с «стоимостью на тест»; не гнаться за +0.5 балла, если это ×2 по цене.
FAQ
Почему «длинный контекст» так дорог?
Потому что модель пересчитывает все входные токены. Каждые +2–5k токенов истории — это линейный рост цены на каждый следующий ответ. Храните историю в саммари и подмешивайте только релевантные фрагменты.
Можно ли обойтись без векторной базы?
Иногда да: для узких доменов и коротких документов хватит BM25/pg_trgm. Но для синонимов/парафразов и смешанного языка векторы сильно помогают. Компромисс — Postgres с pgvector, без managed‑стоимости.
Семантический кэш не испортит актуальность?
Решается TTL и «ключом по контексту»: учитывайте версию индекса и хэш источников. Для динамических данных — маленький TTL или кэшируйте только «планы» и пояснения без чисел.
Когда оправдано держать локальную модель (vLLM)?
Когда есть стабильный объём, предсказуемые нагрузки, требования к приватности, и команда SRE. Для рваных нагрузок API‑провайдер часто дешевле по TCO.
Что с chain‑of‑thought — отключать полностью?
В продакшене либо отключайте, либо используйте «скрытую» короткую разметку на mini‑модели только для планирования. Хранить CoT в ответе пользователю редко нужно и всегда стоит денег.
Как выбрать «правильную» mini‑модель?
Соберите свой короткий eval: 50–200 кейсов из реальных диалогов, меряйте качество и стоимость на мини и «умной» модели. Часто разница в качестве <10%, а в цене ×5–×10.
Ключевые выводы
- Основной драйвер цены — входные токены: усечённый и сжатый контекст экономит больше всего.
- Маршрутизатор моделей + семантический кэш дают 2–6× экономии без критичной потери качества.
- RAG без компрессии и переранжирования — прямой путь к переплатам и шуму.
- Tool‑calling должен иметь бюджет; иначе получаются дорогие «петли» вызовов.
- Телеметрия стоимости и алерты — обязательны; без них счёт растёт незаметно.
Если вы строите или оптимизируете AI‑чатбот и хотите сократить чек без потери качества, MTBYTE спроектирует архитектуру, внедрит кэш/маршрутизацию и поставит метрики. Напишите нам через /contact — начнём с аудита ваших реальных диалогов и затрат.
СЛЕДУЮЩИЙ ШАГ
Понравилось как мыслим?
Применяем те же принципы в клиентских проектах: AI, автоматизации, продукты, которые не умирают после релиза.