Урок 1. Токены: как текст превращается в числа и почему это важно
1. Что такое токен
Большая языковая модель не получает строку пользователя напрямую как набор «слов». Перед вычислениями текст проходит через токенизатор — отдельный алгоритмический компонент, который преобразует входную строку в последовательность токенов, а затем в числовые идентификаторы (token IDs).
Токен — это не обязательно слово. В зависимости от токенизатора токеном может быть целое слово, часть слова, знак пунктуации, последовательность пробелов, байтовая последовательность или специальный служебный маркер. Поэтому правило «1 токен = 1 слово» неверно.
Числовой token ID — это индекс элемента в vocabulary конкретного токенизатора, а не математический «смысл» слова. У разных семейств моделей одна и та же строка может разбиваться по-разному и получать другие ID.
2. Vocabulary: откуда берутся допустимые токены
У токенизатора есть vocabulary — конечный набор токенов, которые он умеет выдавать. Vocabulary формируется заранее при построении токенизатора и фиксируется для конкретной модели или семейства моделей.
Во время обычного inference токенизатор не обучается на prompt и не создаёт новый токен специально под новое слово. Он применяет уже существующие правила. Если крупного токена для последовательности нет, строка представляется несколькими более мелкими токенами.
3. BPE и идея merge rules
Один из известных подходов к токенизации — Byte Pair Encoding (BPE) и его byte-level варианты. Современные модели могут использовать модификации BPE или другие алгоритмы, но BPE хорошо объясняет базовую идею.
На этапе построения токенизатора анализируется большой корпус текста. Алгоритм многократно находит часто встречающиеся соседние пары и добавляет правила их объединения.
Каждая merge-операция объединяет два соседних элемента. При этом процесс не обязан быть простым проходом слева направо: итог определяется выученными правилами и их приоритетами.
Если итоговый токен hello существует и правила позволяют до него дойти, токенизатор может вернуть один ID. Если нет — например, два: [hel] [lo].
Byte-level BPE
В byte-level BPE базовым уровнем являются байты. ASCII-слово Hello в UTF-8 представляется байтами 72, 101, 108, 108, 111. Затем к последовательности применяются выученные merge rules.
UTF-8 bytes → merge rules → tokens → token IDs
Байтовое основание позволяет представить практически любую входную строку, даже если для неё нет готового крупного токена.
4. Почему разные языки требуют разное число токенов
Одинаковое число слов не означает одинаковое число токенов. Эффективность кодирования зависит от vocabulary и статистики, на которой строился токенизатор. Если частые последовательности языка представлены крупными токенами, текст кодируется компактнее.
Это влияет на стоимость input, объём текста в context window, потенциальную длину output и вычислительную нагрузку.
В одном практическом сравнении из материалов курса одинаковый по смыслу текст дал 886 токенов против 557. Отношение:
886 / 557 ≈ 1.59
Корректный вывод: в этом конкретном тесте один вариант потребовал примерно в 1.59 раза больше токенов. Это не универсальный коэффициент для языков.
5. Опечатки, URL, UUID и код
Необычные последовательности часто токенизируются менее компактно. Частое слово может иметь удобное разбиение hello → [hello], а опечатка helol — разбиться на несколько фрагментов.
Подобный эффект часто виден для UUID, хешей, длинных URL, base64, редких идентификаторов и случайных строк. Поэтому 10 КБ естественного языка и 10 КБ случайных идентификаторов могут давать заметно разное число токенов.
6. Tokenizer не понимает смысл текста
Токенизатор решает задачу сегментации и кодирования. Если пользователь написал helol, токенизатор не обязан исправлять его на hello. Он только кодирует вход. Уже Transformer по контексту может интерпретировать строку как опечатку.
Именно векторы поступают в Transformer. В слоях модели представление токена становится контекстным: один и тот же токен может интерпретироваться по-разному в разных окружениях.
8. Токены строки и input tokens API — не одно и то же
Счётчик отдельной строки может показать меньше токенов, чем usage реального Chat API. В model input могут входить system/developer instructions, роли сообщений, история, tool definitions, tool results, документы, изображения и служебное форматирование API.
Для production-расчётов лучше использовать token-counting endpoint или фактический usage выбранного провайдера.
Прикладные выводы / Best Practices
После этого урока полезно оставить несколько инженерных правил.
Считайте реальные токены, а не слова или символы. Для оценки стоимости и context budget используйте tokenizer/token-counting механизм именно той модели или API, с которыми работает приложение.
Не переносите коэффициент токенизации одного теста на все тексты. В примере урока украинская версия потребовала 886 / 557 ≈ 1.59 раза больше токенов, но это результат конкретных текстов и конкретного токенизатора, а не постоянное свойство языка.
Для внутренних prompt'ов можно проверять более токенно-компактный язык. Если английская формулировка для выбранной модели требует меньше токенов и не ухудшает качество, это может уменьшить стоимость и расход context window. Пользовательский ответ при этом должен оставаться на нужном пользователю языке.
Убирайте токенный шум. Ненужные повторения, длинные URL, UUID, base64, случайные идентификаторы и огромные необработанные данные могут занимать непропорционально много токенов.
Не оптимизируйте prompt “на глаз”. Короткая по символам строка не обязательно токенно дешёвая: сначала измерение, затем оптимизация.
Учитывайте сразу несколько последствий token usage: стоимость, context window, prefill latency и доступный объём ответа.
Для API считайте весь model input. System/developer instructions, история, tool definitions/results и вложения тоже могут расходовать token budget.
Не пытайтесь вручную “играть” с BPE без необходимости. Знание BPE нужно прежде всего для понимания поведения токенизатора; production-оптимизацию лучше строить вокруг фактического usage.
Короткая эвристика:
Не “сколько здесь слов?”,
а “сколько токенов реально увидит модель и зачем каждый из них нужен?”.
Урок 2. Input vs Output токены: разница в цене и лимитах
1. Что относится к input tokens
Input tokens — токены контекста, которые модель должна обработать. Это не только последняя фраза пользователя. В типичном API-запросе сюда могут входить system/developer instructions, история, текущий user message, tool definitions, результаты инструментов и документы.
Если приложение каждый раз отправляет всю историю, эта история снова входит в input текущего запроса.
2. Что относится к output tokens
Output tokens — токены, которые модель генерирует как результат запроса. Для обычной autoregressive LLM ответ строится последовательно:
input → token_1 → token_2 → token_3 → ...
Следующий токен зависит от уже сгенерированного префикса.
3. Prefill: обработка входного контекста
Первую фазу inference обычно называют prefill. Модель получает известную заранее последовательность input tokens, прогоняет её через Transformer и формирует внутреннее состояние, включая данные для KV cache.
Поскольку input известен заранее, prefill хорошо поддаётся параллельным вычислениям на ускорителе. Это не означает, что длинный input «бесплатен»: с ростом контекста растут вычисления, latency и память.
4. Decode: генерация output
После prefill начинается decode. На каждом шаге модель использует текущий контекст и KV cache, вычисляет logits следующего токена, выбирает токен и добавляет его к последовательности.
Полностью вычислить будущий output заранее нельзя: token N+1 зависит от токенов 1..N. Это одна из фундаментальных причин, почему генерация имеет другой вычислительный профиль, чем prefill.
5. KV cache
Без кэша при каждом новом токене пришлось бы повторно пересчитывать attention-представления для всего уже обработанного префикса. KV cache хранит ранее вычисленные key/value представления attention-слоёв.
Упрощённо:
Prefill → сохранить K/V prompt
Decode token1 → добавить новые K/V
Decode token2 → добавить новые K/V
...
Кэш уменьшает повторную работу, но занимает память, причём её объём растёт с длиной активной последовательности.
6. Почему output часто стоит дороже
Нужно разделять технический и коммерческий аспекты.
Технически decode более последовательный по длине ответа и хуже параллелится, чем обработка заранее известного input. Коммерчески конкретную цену за input/output назначает провайдер. У многих API output дороже, но коэффициент зависит от модели и со временем меняется.
Пример показывает, что короткий prompt не гарантирует дешёвый вызов: длинный output может доминировать в стоимости.
8. Output limit и context window — разные ограничения
У модели могут быть как минимум два отдельных ограничения:
context window — объём контекста, доступный модели;
maximum output — верхний предел новых токенов ответа.
Они связаны, но не являются синонимами. Точные правила нужно проверять в документации конкретной модели/API.
9. Зачем ограничивать max output
max_tokens / max_output_tokens помогает ограничивать потенциальные расходы и latency, оставлять запас контекстного бюджета и стабилизировать формат ответа.
Слишком маленький лимит может обрезать полезный ответ, поэтому его стоит выбирать под конкретную задачу, а не ставить произвольный максимум.
10. Язык output и стоимость
Если один язык кодируется конкретным токенизатором менее компактно, это касается не только input, но и generated output. Один и тот же смысл на разных языках может требовать разного количества output tokens.
Но правило «всегда генерировать на английском» слишком грубое. Нужно учитывать необходимость перевода, качество терминологии и реальную разницу в стоимости на вашей нагрузке.
11. Cached input
Современные API могут поддерживать prompt caching. Это полезно, когда большой префикс повторяется:
неизменная инструкция + большой документ + маленький новый вопрос
Кэш может изменить стоимость и latency повторной обработки. Однако cached input не перестаёт быть частью логического контекста модели: caching и context capacity — разные понятия.
12. Практические стратегии оптимизации
Полезно не отправлять ненужную историю, суммаризировать старые диалоги, ограничивать tool results, применять retrieval вместо загрузки всей базы, использовать prompt caching и ставить реалистичный output limit.
Главная идея — оптимизировать весь token budget запроса и ответа, а не только количество слов в prompt.
Прикладные выводы / Best Practices
Главный практический вывод урока — стоимость LLM-вызова определяется не только размером prompt, но и выбранной моделью, длиной output и сложностью задачи.
Не используйте самую мощную модель автоматически для каждого запроса. Выбирайте модель по сложности задачи и требуемому качеству.
В рамках таблицы моделей на слайде урока:
Claude Opus 4.6 — наиболее сильная модель; её лучше оставлять для задач, где глубина анализа оправдывает более высокую цену: проектирование архитектуры, сложный reasoning, глубокий анализ, разбор неоднозначных технических решений.
Claude Sonnet 4.6 — баланс качества и скорости; основной выбор для большинства серьёзных инженерных задач: написание и анализ кода, code review, большие рабочие задачи.
Claude Haiku 4.5 — наиболее быстрая модель в приведённой таблице; подходит для простых массовых операций: классификация, форматирование, извлечение простых полей и routing.
Сначала выбирайте минимально достаточную модель, затем повышайте класс модели только при необходимости.
Контролируйте output. В таблице урока output тарифицируется в 5 раз дороже input для всех трёх приведённых моделей; кроме того, decode выполняется последовательно. Не запрашивайте длинный ответ, если достаточно нескольких строк или структурированного результата.
Ставьте реалистичный max_output_tokens. Это ограничивает худший сценарий по стоимости и latency.
Считайте стоимость на масштабе. Небольшая разница на одном запросе превращается в существенную на тысячах и миллионах вызовов.
Оптимизируйте повторяющийся input. Не отправляйте ненужную историю; используйте prompt caching, когда API и сценарий это поддерживают.
Разделяйте pipeline по сложности. Haiku может выполнять простую классификацию, Sonnet — типичную инженерную работу, Opus — редкий глубокий анализ.
Логируйте фактический usage. Для production полезно хранить модель, input/output tokens, latency и рассчитанную стоимость каждого типа запроса.
Язык output тоже влияет на token usage. Для внутренних промежуточных данных можно измерять более компактный язык/формат; пользовательский output должен соответствовать требованиям продукта.
Практическая схема выбора:
Простая массовая операция
↓
Haiku
Большая типичная инженерная задача
↓
Sonnet
Архитектура / сложное решение / глубокий анализ
↓
Opus
Названия моделей и цены со временем меняются. Устойчивый инженерный принцип — выбирать минимально достаточную модель под задачу.
Урок 3. Контекстное окно: что это, выгорание контекста и переполнение
1. Что такое контекст
Контекст — информация, доступная модели при вычислении следующего токена. В чат-приложении он может включать system/developer instructions, предыдущие сообщения, текущий запрос, tool definitions/results, RAG-документы, вложения и уже сгенерированную часть ответа.
Важно: модель не получает человеческую долговременную память только потому, что UI показывает старые сообщения. Чтобы факт повлиял на inference, платформа должна сделать его доступным модели — напрямую, через summary, retrieval, memory или другой механизм.
2. Context window
Context window — максимальный объём токенизированной информации, который модель/API способен использовать в одном контекстном вычислении по правилам провайдера.
Большое окно полезно для длинных документов, истории, codebase-фрагментов и multi-document задач. Но большое номинальное окно не означает, что его полезно заполнять до предела.
3. Переполнение и деградация — разные проблемы
Hard overflow
Если запрос превышает технический лимит, API может отклонить его или продукт может применить собственную стратегию truncation/compaction. Конкретное поведение зависит от платформы.
Деградация до hard limit
Даже если весь prompt помещается в окно, модель может использовать длинный контекст неравномерно. Исследование Lost in the Middle показало, что релевантная информация в середине длинного контекста в некоторых задачах извлекалась хуже, чем информация ближе к началу или концу.
Следовательно, «помещается в context window» и «будет надёжно использовано» — не одно и то же.
4. Context rot / «выгорание контекста»
Термин context rot не является единым строгим API-стандартом. Обычно им описывают практическую деградацию при росте и усложнении контекста: важные инструкции конкурируют с шумом, старые факты теряют заметность, появляются конфликтующие версии информации, а в длинных agentic loops накапливаются ошибки.
Поэтому корректнее говорить не «после N токенов модель обязательно забывает», а «с ростом и сложностью контекста риск деградации возрастает, и его профиль зависит от модели и задачи».
5. Что происходит в длинном чате
UI может хранить очень длинную историю, но модель не обязана получать её всю буквально. Продукт может использовать truncation, summarization, retrieval из старой истории, server-side memory, compaction или комбинацию механизмов.
Для собственного API-приложения контекст определяет ваша архитектура: backend решает, какие сообщения и данные отправить на очередной inference.
6. Token budget и запас для ответа
Предположим, в учебном примере доступно 100 000 токенов, а для ответа требуется оставить до 10 000.
100 000 - 10 000 = 90 000 tokens input budget
Но если реально достаточно 8 000 релевантных токенов, добавление ещё 82 000 шума может увеличить стоимость и prefill latency, а также усложнить поиск нужного факта.
Полезная цель — минимальный достаточный контекст, а не максимально заполненное окно.
7. Attention и доступность информации
Self-attention позволяет позициям учитывать другие части последовательности, но реальная модель имеет конечную вычислительную способность и не обязана одинаково хорошо извлекать любой факт из любой позиции.
Для критичных данных полезно удалять нерелевантный текст, явно структурировать evidence, избегать конфликтующих инструкций и использовать retrieval для отбора небольшого числа релевантных фрагментов.
8. RAG как управление контекстом
Retrieval-Augmented Generation (RAG) — не только способ подключить внешнюю базу знаний, но и способ экономно использовать context window.
user query → retrieval → top relevant chunks → LLM context
Вместо загрузки тысяч документов модель получает несколько наиболее релевантных частей. Это уменьшает input tokens, шум и latency.
Но RAG создаёт новый риск: нужный документ может не попасть в top-k. Поэтому качество retrieval нужно оценивать отдельно от качества генерации.
9. Summarization и compaction
Длинную историю можно периодически заменять структурированным summary:
старые сообщения → summary + последние сообщения + текущий запрос
Хороший summary должен сохранять решения, ограничения, имена сущностей, незавершённые задачи и важные запреты. Summarization — lossy compression: если важная деталь не попала в summary и оригинал больше не передаётся, модель не сможет надёжно восстановить её.
10. Контекст в agentic systems
У агента контекст растёт не только за счёт пользователя:
instruction + plan + tool call + tool result + next call + next result + ...
Большие tool results особенно быстро раздувают контекст. Если SQL/tool вернул 50 000 строк, лучше агрегировать и фильтровать данные до передачи в LLM, возвращать только нужные поля или хранить большие результаты вне активного prompt.
11. Long context vs external memory
Context window — это рабочая память текущего inference. Долговременное состояние лучше хранить во внешних системах: PostgreSQL, vector database, object storage, search index, application state.
External state → retrieve needed subset → Active context → Model
Хорошая agentic architecture не пытается превратить context window в базу данных.
12. Практический backend-пример
Для анализа DNS-инцидента плохой подход — передать модели весь Slack за неделю, полный Grafana export и сотни тысяч строк логов.
Лучше сначала ограничить временной диапазон, отфильтровать логи по сервисам/correlation IDs, агрегировать повторяющиеся ошибки, извлечь релевантные сообщения и только затем передать компактный evidence set.
Цель — не «максимум данных», а максимум релевантного сигнала на один токен.
13. Признаки проблем с контекстом
Полезно отслеживать резкий рост input tokens, рост prefill latency, увеличение стоимости без роста качества, противоречия ранним требованиям, игнорирование деталей больших документов, context-length errors и ненужные tool calls после длинной истории.
Это признаки того, что стоит улучшать context engineering, а не просто выбирать модель с ещё большим окном.
14. Context engineering
Context engineering — проектирование того, какая информация и в каком виде попадает в активный контекст. Сюда относятся system/developer instructions, подбор истории, RAG, memory retrieval, формат tool results, summaries, порядок документов и промежуточные результаты agentic workflow.
Для agentic engineering это ключевой навык: качество системы зависит не только от модели, но и от качества информации, которую система показывает ей в конкретный момент.
Liu et al. — Lost in the Middle: How Language Models Use Long Contexts: https://arxiv.org/abs/2307.03172
Прикладные выводы / Best Practices
Контекст нужно воспринимать как ограниченный вычислительный ресурс, а не как место, куда следует складывать всё доступное состояние системы.
Не заполняйте context window только потому, что модель это позволяет. Больший input увеличивает стоимость и prefill latency, а дополнительный шум может мешать использовать важные данные.
Стремитесь к минимальному достаточному контексту. Передавайте модели только информацию, которая нужна для текущего шага.
Новая независимая задача — кандидат для нового чистого контекста. Не переносите длинную старую историю, если она не влияет на новое решение.
Длинные диалоги периодически compact/summarize. Summary должно сохранять решения, ограничения, идентификаторы, открытые вопросы и важные запреты.
Не используйте context window как долговременную БД. Состояние агента лучше хранить во внешнем state store и извлекать только нужную часть.
Фильтруйте tool results до передачи модели. Вместо десятков тысяч строк SQL или полного набора логов передавайте агрегации, нужные поля и релевантные записи.
Используйте RAG для больших наборов знаний. Retrieval должен выбирать небольшой набор релевантных фрагментов вместо загрузки всей базы в prompt.
Проверяйте retrieval quality. Если нужный факт не попал в retrieval или summary, модель не сможет надёжно использовать его.
Оставляйте token budget под output. При проектировании длинного input заранее учитывайте ожидаемую длину ответа.
Следите за признаками context rot: рост input tokens/latency, противоречия ранним требованиям, игнорирование деталей, повторное выяснение уже известных фактов и лишние tool calls.
Повышайте signal-to-noise ratio. Удаляйте дубли и устаревшие данные, структурируйте evidence и отделяйте факты от инструкций.
Context engineering — часть архитектуры агента. Качество системы зависит не только от модели, но и от того, какие данные приложение выбирает, хранит, сжимает и возвращает модели на каждом шаге.
Короткая эвристика:
Context window ≠ база данных.
Больше контекста ≠ больше качества.
Нужен не максимальный объём, а максимальный релевантный сигнал.