Контекст и память: почему модель забывает
Ты рассказал модели своё имя в начале разговора, а через сто сообщений она его «забыла». Это не баг и не каприз — так устроена память модели, и сейчас ты поймёшь почему.
Главная мысль урока: у модели нет памяти в привычном смысле. Всё, что она «помнит» прямо сейчас, — это текст текущего разговора, который влезает в ограниченное окно. Что не влезло или попало в другой чат — для неё просто не существует.
Зачем тебе это понимать
Знакомая ситуация? Ты долго переписываешься с ChatGPT: дал ему свои вводные, объяснил задачу, накидал деталей. А потом в какой-то момент он вдруг переспрашивает то, что ты уже говорил полчаса назад. Или начинаешь новый чат — и модель ведёт себя так, будто видит тебя впервые. Возникает обида: «Я же тебе это рассказывал!»
На самом деле модель ничего тебе не должна была запомнить — и не запоминала. Понимание того, как устроена её память, — это не занудная теория, а очень практичная штука. Когда ты знаешь, что и почему «забывается», ты перестаёшь злиться и начинаешь грамотно строить разговор: повторять важное в нужный момент, не растягивать диалог до бесконечности и понимать, почему два разных чата — это два разных мира.
В прошлом уроке про промпт мы разобрали, как правильно формулировать запрос. Сегодня сделаем шаг дальше: разберёмся, что происходит со всеми твоими запросами и ответами на протяжении долгого разговора — и почему модель в принципе не может помнить всё.
К концу урока ты будешь понимать, что такое контекст, почему он ограничен, и сможешь сам прикинуть, сколько примерно текста модель удержит, прежде чем начнёт забывать начало.
Что такое контекст: метафора с доской
Представь школьную доску в кабинете. Учитель пишет на ней условие задачи, потом промежуточные вычисления, потом ещё что-то. Доска большая, но не бесконечная. Когда место заканчивается, чтобы написать новое, приходится стереть что-то старое — обычно то, что было написано в самом верху, давным-давно.
Так вот, контекст модели — это и есть такая доска. Весь твой разговор — твои сообщения и ответы модели — записан на ней как один длинный текст. Когда модель готовит очередной ответ, она смотрит на всё, что написано на доске прямо сейчас. Не на то, что было стёрто. Не на то, что осталось на доске в соседнем кабинете (это другой чат). Только на текущую доску.
Контекст — это весь текст разговора, который модель видит перед собой в момент, когда формирует ответ. Это её единственная «рабочая память».
И вот тут самое важное и неожиданное: между твоими сообщениями модель не хранит ничего. Она не сидит и не «думает» о вас в перерыве. Каждый раз, когда ты отправляешь новое сообщение, программа берёт всю доску целиком (весь разговор) и заново даёт его модели на вход. Модель читает это как один большой текст и предсказывает продолжение — следующий ответ. Помнишь наш сквозной пример из всего курса — фразу Кошка пьёт ..., по которой модель учится предсказывать следующее слово? Здесь происходит ровно то же самое, только «фраза» — это весь ваш разговор, а «следующее слово» — это её новый ответ.
Откуда тогда ощущение, что она помнит
Если память не хранится, почему же кажется, что модель помнит контекст разговора? Потому что программа-обёртка (то самое приложение ChatGPT) каждый раз подсовывает модели всю историю заново. Ты пишешь третье сообщение — а модель получает на вход первое, второе, её собственные ответы и твоё третье, всё вместе. Создаётся полная иллюзия памяти, хотя на деле это похоже на актёра, которому перед каждой репликой заново суют весь сценарий с начала.
Почему доска ограничена: токены и окно
Доска ограничена не из вредности, а из устройства. Помнишь термин токен из раздела про устройство ChatGPT? Токен — это кусочек текста: слово или его часть. Модель оперирует не буквами и не целыми предложениями, а токенами. Грубо: одно обычное слово — это примерно один-два токена, а длинное или редкое слово может разбиться на несколько кусочков.
Так вот, у каждой модели есть ограничение длины контекста — максимальное число токенов, которое влезает на доску за один раз. Это называют контекстным окном. Например, окно в 8000 токенов — это примерно 6000 слов, или несколько страниц текста. Звучит много, но в длинном разговоре с кодом, цитатами и подробностями это набирается быстрее, чем кажется.
| Что | Сколько примерно |
| 1 токен | примерно 3-4 буквы / часть слова |
| 1 обычное слово | примерно 1-2 токена |
| 1 страница текста | примерно 400-500 слов = 600-900 токенов |
| Окно 8000 токенов | примерно 6-10 страниц всего разговора |
Когда разговор дорос до края окна, происходит ровно то, что с доской: чтобы поместить новое, программа отрезает самое старое — начало разговора. Оно просто перестаёт попадать модели на вход. Вот почему «забывается» именно то, что ты говорил в самом начале: оно физически стёрто с доски, чтобы освободить место.
Разбираем на примерах
Дальше будет немного простого кода — он не настоящая модель, а наглядная прикидка. Мы посчитаем, как заполняется окно и что из него выпадает. Этого достаточно, чтобы прочувствовать механику памяти.
Пример 1. Прикидываем, сколько токенов в разговоре
Точное число токенов считает специальный алгоритм модели, но для интуиции хватит грубой оценки: возьмём примерно 1.3 токена на слово. Посчитаем, влезает ли разговор в окно.
// грубая оценка: примерно 1.3 токена на одно слово
function tokensFor(text) {
const words = text.trim().split(/\s+/).length;
return Math.round(words * 1.3);
}
const oknoTokenov = 50; // маленькое окно для примера: 50 токенов
const messages = [
"Меня зовут Лера и я учусь в девятом классе",
"Помоги придумать тему для проекта по информатике",
"Хочу что-то про нейросети и распознавание картинок"
];
let used = 0;
messages.forEach((m, i) => {
used += tokensFor(m);
console.log("После сообщения " + (i + 1) + ": занято " + used + " из " + oknoTokenov + " токенов");
});
console.log("Влезает целиком? " + (used <= oknoTokenov ? "да" : "нет, начало придётся стереть"));
Что здесь по шагам. Функция tokensFor считает слова и умножает на 1.3 — это наша прикидка токенов. Дальше мы идём по сообщениям и копим занятое место в used. После каждого сообщения печатаем, сколько токенов уже занято. В конце сравниваем с размером окна. Окно мы взяли крошечное (50 токенов) специально, чтобы быстро упереться в потолок.
Вывод:
После сообщения 1: занято 12 из 50 токенов После сообщения 2: занято 22 из 50 токенов После сообщения 3: занято 32 из 50 токенов Влезает целиком? да
Пока всё помещается. Но представь, что разговор продолжается ещё на двадцать сообщений — счётчик used перевалит за 50, и тут начнётся самое интересное.
Пример 2. Что выпадает, когда окно переполнено
Теперь смоделируем переполнение. Если весь разговор не влезает в окно, программа держит только самые свежие сообщения, а старые отрезает с начала. Имя «Лера» из первого сообщения как раз и вылетит первым.
function tokensFor(text) {
return Math.round(text.trim().split(/\s+/).length * 1.3);
}
const oknoTokenov = 40; // токенов помещается на "доску"
const messages = [
"Меня зовут Лера", // самое старое
"Помоги с проектом по информатике",
"Тема про нейросети и кошек с собаками",
"А как объяснить это однокласснику попроще" // самое свежее
];
// держим только свежие сообщения, пока влезаем в окно
let kept = [];
let used = 0;
for (let i = messages.length - 1; i >= 0; i--) {
const t = tokensFor(messages[i]);
if (used + t > oknoTokenov) break; // дальше не влезает - старое отрезаем
kept.unshift(messages[i]);
used += t;
}
console.log("Модель сейчас видит:");
kept.forEach(m => console.log(" - " + m));
console.log("Знает ли модель твоё имя? " + (kept.some(m => m.includes("Лера")) ? "да" : "нет, оно выпало"));
Разбор по шагам. Мы идём по сообщениям с конца — от самого свежего к старому — и набираем их в kept, пока хватает места в окне. Как только очередное сообщение уже не влезает, мы прерываемся: всё, что осталось «выше», отрезано. В конце проверяем, попало ли в видимую часть слово «Лера». Окно в 40 токенов слишком мало, чтобы удержать все четыре сообщения, поэтому первое (с именем) выпадает.
Вывод:
Модель сейчас видит: - Тема про нейросети и кошек с собаками - А как объяснить это однокласснику попроще Знает ли модель твоё имя? нет, оно выпало
Вот он, момент «забывания» вживую. Имя не потерялось у тебя в чате — оно просто перестало попадать модели на вход. Спросишь её сейчас «как меня зовут?» — и она честно не будет знать, потому что этой строки больше нет на доске.
Пример 3. Разные чаты — разные доски
Самая частая путаница — про разные чаты. Каждый новый чат — это чистая доска. Ничего из соседнего разговора туда не переносится. Покажем это совсем просто.
// два независимых чата, у каждого своя "доска"
const chatA = ["Меня зовут Лера", "Люблю рисовать"];
const chatB = []; // новый чат - пустая доска
function modelSees(chat) {
return chat.length ? chat.join(" | ") : "(пусто)";
}
console.log("Чат A видит: " + modelSees(chatA));
console.log("Чат B видит: " + modelSees(chatB));
console.log("Знает ли чат B про имя из чата A? " + (chatB.join(" ").includes("Лера") ? "да" : "нет"));
Тут две отдельные доски — два массива. Функция modelSees показывает, что лежит на каждой. Чат B пустой, и в нём нет ничего из чата A, как бы тесно ни были связаны темы у тебя в голове. Поэтому в новом чате модель и правда видит тебя «впервые».
Вывод:
Чат A видит: Меня зовут Лера | Люблю рисовать Чат B видит: (пусто) Знает ли чат B про имя из чата A? нет
Пример 4. А что с нашей кошкой и собакой?
Вернёмся к сквозной задаче «отличить кошку от собаки». Допустим, в начале долгого разговора ты объяснил модели: «в моём проекте кошки — это класс 0, собаки — класс 1». Через сотню сообщений про обучение, признаки и ошибки это первое объяснение вылетело из окна. И вот ты пишешь: «а класс 0 — это кто?» — а модель уже не помнит твою договорённость, потому что строки с ней нет на доске. Она либо честно переспросит, либо, что хуже, угадает и выдаст галлюцинацию — уверенно звучащий, но выдуманный ответ. Знание про контекст помогает поймать такой момент и просто напомнить договорённость заново.
Частые ошибки и подводные камни
Когда впервые разбираешься с памятью модели, легко наступить на пару граблей. Вот самые частые.
- «Модель помнит меня между чатами». Нет. Каждый новый чат — чистая доска. Если хочешь, чтобы модель учла что-то из прошлого разговора, перенеси это руками в новый чат. (Бывают отдельные функции «памяти профиля» в некоторых приложениях, но это надстройка сверху, а не свойство самой модели — и работает она тоже через подсовывание текста в контекст.)
- «Если я сказал это один раз, модель будет помнить всегда». Только пока сказанное помещается в окно. В длинном разговоре начало стирается. Важные вещи имеет смысл повторять, когда снова к ним возвращаешься.
- «Раз модель забыла — она поглупела или сломалась». Нет, она работает ровно как задумано. Забывание начала — это не поломка, а следствие ограниченного окна. Сравни с тетрадью, в которой кончились страницы: тетрадь не «глупая», просто место вышло.
- «Чем длиннее разговор, тем умнее ответы». Скорее наоборот. Когда доска забита под завязку, нужные детали могут вытесняться шумом и старыми репликами, и модель начинает теряться. Иногда лучше начать свежий чат и коротко изложить только суть.
- «Модель забыла, потому что я ей не понравился». У модели нет отношения к тебе и нет намерений между сообщениями. Между твоими репликами она вообще ничего не делает и ни о чём не думает. Забывание — чисто механическое: текст не влез в окно.
Мини-практика: посчитай своё окно
Теперь твоя очередь. Ниже заготовка, которая считает, сколько твоих сообщений поместится в заданное окно, и сообщает, на каком из них «доска» переполнится. Впиши свои реальные сообщения в массив messages и поэкспериментируй с размером окна.
function tokensFor(text) {
return Math.round(text.trim().split(/\s+/).length * 1.3);
}
// ЗАДАНИЕ: впиши сюда свои сообщения и поменяй размер окна
const oknoTokenov = 30; // <-- меняй этот размер
const messages = [ // <-- впиши свои фразы
"Привет, помоги с домашкой",
"Объясни, что такое контекст у модели",
"А теперь приведи пример из жизни"
];
let used = 0;
let overflowAt = -1;
messages.forEach((m, i) => {
used += tokensFor(m);
if (overflowAt === -1 && used > oknoTokenov) overflowAt = i + 1;
console.log("Сообщение " + (i + 1) + ": всего занято " + used + " токенов");
});
if (overflowAt === -1) {
console.log("Всё влезло в окно " + oknoTokenov + " токенов");
} else {
console.log("Окно переполнилось на сообщении " + overflowAt + " - старое начнёт стираться");
}
Поиграй с числом window: поставь его маленьким (например, 10) и увидишь, как разговор переполняется уже на первом-втором сообщении. Потом увеличь до 200 — и всё уместится. Так ты руками почувствуешь связь между размером окна и тем, как быстро модель начинает «забывать» начало.
Вывод (для стартовых значений):
Сообщение 1: всего занято 5 токенов Сообщение 2: всего занято 13 токенов Сообщение 3: всего занято 22 токенов Всё влезло в окно 30 токенов
Задание со звёздочкой: добавь в массив ещё пять-шесть длинных сообщений и подбери такой размер окна, чтобы переполнение случилось ровно на четвёртом сообщении. Это та же логика, по которой реальное приложение решает, какие старые реплики пора отрезать.
Как работать с памятью модели: короткие советы
Раз уж ты понял механику, вот что с этим делать на практике.
- Повторяй важное. Если разговор затянулся, а ты возвращаешься к старой договорённости, напомни её одним предложением. Дешевле, чем надеяться, что она ещё на доске.
- Держи ключевое ближе к концу. Самое свежее точно в окне. Если что-то критично для ответа прямо сейчас — упомяни это в текущем сообщении, а не уповай на начало разговора.
- Не бойся начинать новый чат. Когда тема сменилась или разговор оброс шумом, чистая доска часто даёт ответы лучше. Просто перенеси в неё нужную суть.
- Давай контекст явно. Если задача опирается на твои вводные (как наши «кошка — класс 0, собака — класс 1»), выпиши их прямо в сообщении, а не предполагай, что модель их «держит в голове».
Итоги
Давай соберём всё вместе.
- Контекст — это весь текст разговора, который модель видит в момент ответа. Это её единственная рабочая память.
- Между сообщениями модель ничего не хранит: каждый раз ей заново подсовывают всю историю, отсюда иллюзия памяти.
- Доска ограничена: есть максимальное число токенов (контекстное окно). Когда оно заполнено, самое старое — начало разговора — отрезается.
- Разные чаты — разные доски. В новом чате модель не знает ничего из соседнего.
- Наш сквозной пример виден и тут: модель предсказывает свой ответ как «следующее слово» по всему тексту разговора, что попал в окно — будь то фраза про кошку или твоя домашка.
- На практике: повторяй важное, держи ключевое ближе к концу, не бойся свежего чата и давай контекст явно.
В следующем уроке мы поговорим про галлюцинации — почему модель иногда уверенно выдаёт выдуманные факты и как это связано с тем, что ты узнал сегодня про контекст. Спойлер: когда нужного на доске нет, модель не молчит, а додумывает — и теперь ты понимаешь, откуда у неё на это «право».