Оптимизация API
Контекстное окно LLM API: лимиты, токены и стоимость
Контекстное окно LLM API — это не только характеристика модели, а бюджет каждой продуктовой операции. В него конкурируют системная инструкция, история диалога, найденные документы, параметры инструмента и будущий ответ. Если не резервировать место и не отбирать релевантный контекст, приложение получает ошибки размера, медленные ответы или незаметный рост стоимости.
Короткий ответ: контексту нужен явный бюджет
Контекстное окно — это максимум входа и выхода, который конкретная модель готова обработать в одном вызове. Нельзя безопасно брать число из старого блога или чужого примера: правила подсчёта и доступный каталог меняются. Перед запуском запросите актуальную информацию в своей консоли, а в коде храните не «магическое» большое число, а конфигурацию модели и лимит сценария с датой проверки.
Эта статья для команды, которая строит чат, поиск по документам, классификацию или tool calling. Практическая цель — не наполнить окно до предела, а оставить запас для качественного ответа и ошибок формата. Хорошая политика заранее отвечает на четыре вопроса: сколько токенов отдать системной инструкции, сколько — пользовательскому вводу, какой объём найденного контекста допустим и сколько зарезервировать на вывод.
Из чего складывается запрос
Условно считайте бюджет так: системная инструкция + сообщения + найденные фрагменты + описания инструментов + запас ответа ≤ лимит сценария. Слово, символ и токен — не одно и то же; русский текст, JSON и код токенизируются по-разному. Поэтому нельзя надёжно оценить стоимость фразой «один токен равен четырём символам». Используйте tokenizer, рекомендованный документацией выбранного клиента, либо консервативный серверный лимит до реального вызова.
| Часть | Риск без лимита | Практика |
|---|---|---|
| System prompt | Разрастается при каждом изменении продукта. | Версионировать и сокращать до обязательных правил. |
| История чата | Старые сообщения вытесняют текущую задачу. | Хранить краткое резюме и последние релевантные ходы. |
| RAG-фрагменты | Дубли, шум и большой счёт за вход. | Ограничить число, длину и порог релевантности. |
| Ответ | Модель не оставит место для формата. | Резервировать максимум вывода до сборки запроса. |
Не путайте «влезло в окно» с «полезно для ответа». Длинная история способна ухудшить качество: важный факт теряется среди устаревших инструкций, а модель получает противоречивые роли. Сначала определите, что пользователю нужно сейчас, затем передавайте доказательства с источником и короткой цитатой. Полный текст документа добавляйте только если тесты показывают, что он меняет результат.
Соберите контекст в четыре шага
Шаг 1 — зафиксируйте резерв. До выбора истории выделите место для ожидаемого ответа и структурированной ошибки. Для JSON-ответа нужен запас не только на поля, но и на повтор валидации. Если задача требует 800 токенов вывода, не рассчитывайте вход так, будто ответ займёт 50. Локальный limiter должен отклонять или упрощать запрос до сетевого вызова, а не ждать ошибку от API.
Шаг 2 — сделайте историю компактной. Оставьте последние сообщения, которые меняют текущую задачу, и сохраните итог предыдущей части диалога в короткой структурированной заметке. Резюме не должно подменять исходные данные или тайно менять инструкции. Храните его отдельно с версией и временем, чтобы при споре было видно, откуда взялся факт. Для персональных данных применяйте минимизацию и свой срок хранения.
Шаг 3 — отберите документы. В RAG сначала найдите кандидатов, затем отфильтруйте дубли, устаревшие версии и фрагменты без источника. В запрос передавайте ограниченное число коротких отрывков с идентификатором документа; не кладите целую базу «на всякий случай». Поиск не снимает обязанности проверять права на материалы и правила использования данных.
Шаг 4 — проверьте итог перед вызовом. Логируйте безопасный счётчик входа, лимит сценария, зарезервированный output и версию политики. Не записывайте полный prompt или ответ ради диагностики. Если бюджет превышен, верните контролируемое действие: попросите сузить вопрос, предложите обработать документ частями или поставьте несрочную задачу в очередь.
Пример серверной сборки запроса
Пример показывает политику, а не точный tokenizer конкретного поставщика. Функция estimateTokens должна быть заменена проверенным счётчиком для вашей модели; грубая оценка нужна только как предварительный предохранитель. Ключ RussiaAPI не передаётся клиенту и не логируется.
const POLICY = { inputBudget: 6000, outputReserve: 900, maxChunks: 4 };
export function buildMessages({ system, summary, recent, chunks }) {
const selected = chunks.slice(0, POLICY.maxChunks)
.filter(chunk => chunk.score >= 0.75)
.map(chunk => `[${chunk.id}] ${chunk.text}`);
const messages = [
{ role: 'system', content: system },
{ role: 'system', content: `Summary: ${summary}` },
...recent,
{ role: 'user', content: `Sources:\n${selected.join('\n')}` }
];
if (estimateTokens(messages) + POLICY.outputReserve > POLICY.inputBudget) {
throw new Error('Request exceeds the configured context budget');
}
return messages; // send server-side with RUSSIAAPI_API_KEY
}Числа 6000, 900, 4 и 0,75 здесь — иллюстрация настройки, а не рекомендуемые лимиты RussiaAPI или конкретной модели. В production вынесите их в версионированную конфигурацию. Так можно провести A/B-тест, откатить изменение и связать рост затрат с конкретной политикой. Если сценарий использует структурированный ответ, проверяйте JSON на сервере и не повторяйте одну и ту же операцию без защиты от дубликатов.
Когда сокращать, суммировать или делить задачу
Сокращение подходит для служебного текста, повторов и старой истории, которая больше не влияет на решение. Суммирование полезно для длинного диалога, но его качество надо тестировать: одно неточное резюме может передать ошибку на много следующих ходов. Деление задачи подходит для больших документов: обработайте части с явными идентификаторами, сохраните результаты и затем сформируйте сводку, не теряя источник каждого вывода.
Для документов с точными формулировками не просите модель «помнить весь архив». Лучше извлечь несколько подтверждённых фрагментов и потребовать ссылку на их ID в ответе. Это упрощает проверку и уменьшает риск уверенного ответа без опоры. Если качество нуждается в большем контексте, сначала измерьте, какая добавка действительно улучшает метрику, а затем измените бюджет и пределы, а не поднимайте их бесконечно.
Контекст связан с задержкой и расходом
Больший вход обычно означает больше обработки, больше данных в логической операции и более сложное восстановление при тайм-ауте. Поэтому мониторьте стоимость успешной задачи вместе с размером контекста, задержкой, retry и долей валидных ответов. Одна цена запроса не показывает, сколько раз приложение отправило его повторно или сколько работы потребовала проверка формата. Подход к таким метрикам разобран в руководстве по мониторингу стоимости.
Не переключайте модель и не увеличивайте контекст автоматически после одной ошибки. Сначала подтвердите класс ошибки, проверьте каталог и проведите тест на ограниченной доле трафика. Для проблем временной доступности нужны deadline, отмена и контролируемые повторы — это отдельный контур, описанный в статье про тайм-ауты. Для выбора модели используйте воспроизводимый набор задач, а не рекламное обещание о «самом большом окне».
Тесты на границе контекста
- Соберите 10–20 синтетических задач: короткий вопрос, длинный русский текст, код, JSON, дубли и устаревший документ.
- Для каждой задачи запишите размер входа, резерв ответа, задержку, валидность и стоимость успешного результата.
- Проверьте поведение на 90 %, 100 % и 110 % внутреннего бюджета: ошибка должна быть понятной и локальной.
- Проверьте, что RAG не возвращает дважды один фрагмент и умеет показать источник ответа.
- Выпустите новую политику на малую долю трафика, оставив rollback и безопасные логи.
Такой набор одновременно помогает выбрать модель. Сравнивайте не только доступный предел, но и результат на языке продукта, latency, устойчивость JSON и цену завершённого сценария. Методика выбора по измеримым критериям есть в матрице моделей для API.
Проверьте контекст на тестовой задаче
В RussiaAPI выберите модель из актуального каталога, создайте отдельный тестовый ключ и измерьте контекст, latency и валидность на синтетическом наборе. Не передавайте секреты и пользовательские данные в клиентский код.
FAQ
Что такое контекстное окно в LLM API?
Это предел объёма входа и ответа в одной операции. В него входят инструкции, история, найденные данные и запас вывода. Точные лимиты и подсчёт проверяют в текущем каталоге выбранной модели.
Можно ли отправлять всю историю чата?
Нет. История повышает задержку и расход, а затем превышает бюджет. Храните короткое резюме, последние релевантные сообщения и извлекайте документы по запросу.
Снижает ли RAG стоимость автоматически?
Нет. Плохой поиск, длинные фрагменты и дубли всё равно расходуют контекст. Измеряйте размер выдачи, качество, задержку и стоимость завершённой задачи на своём тестовом наборе.