Как LLM «понимает» инструкцию: предсказание токенов

Под капотом модель не «выполняет команду», а раз за разом предсказывает самый вероятный следующий токен — и это объясняет почти все приёмы промптинга.

Токен — кусочек текста (часто часть слова), которым модель оперирует. Модель предсказывает следующий токен по всем предыдущим, добавляет его и повторяет.

Авторегрессия простыми словами

LLM обучена на огромном корпусе текста решать одну задачу: «дан кусок текста — какой токен идёт следующим?». Генерация ответа — это многократное применение этого предсказания: модель добавляет токен, потом смотрит на новый, чуть более длинный текст, и снова предсказывает следующий. Так слово за словом рождается ответ.

Отсюда важный вывод: промпт задаёт контекст, в котором следующий токен становится вероятным. Вы не «приказываете» модели — вы создаёте текст, продолжением которого естественно будет нужный вам ответ.

Почему это объясняет приёмы промптинга

Через призму предсказания токенов многие техники становятся очевидными:

  • Роль («ты опытный юрист») сдвигает распределение к текстам, похожим на речь юриста — лексика, осторожность, ссылки на нормы становятся вероятнее.
  • Примеры (few-shot) создают шаблон: увидев два-три примера «вход → выход», модель достраивает следующий по тому же образцу.
  • «Думай пошагово» побуждает модель сначала сгенерировать рассуждение; промежуточные токены становятся контекстом для финального ответа и повышают его точность.

Маленький эксперимент с вероятностями

Идея «следующий токен — самый вероятный» работает и на простом коде. Смоделируем выбор продолжения по частоте в обучающем «корпусе».

from collections import Counter

# Мини-корпус: пары (контекст -> что шло дальше)
corpus = [
    ("небо", "голубое"),
    ("небо", "голубое"),
    ("небо", "ясное"),
    ("трава", "зелёная"),
]

counts = Counter()
for ctx, nxt in corpus:
    counts[(ctx, nxt)] += 1

def predict(ctx):
    # соберём кандидатов-продолжения для данного контекста
    cand = {nxt: v for (c, nxt), v in counts.items() if c == ctx}
    best = max(cand, key=cand.get)
    return best, cand

best, cand = predict("небо")
print("Кандидаты для 'небо':", cand)
print("Самый вероятный следующий токен:", best)

Вывод:

Кандидаты для 'небо': {'голубое': 2, 'ясное': 1}
Самый вероятный следующий токен: голубое

Настоящая модель делает то же самое, но в пространстве десятков тысяч токенов и с учётом всего контекста. Меняя контекст (промпт), вы меняете, какой токен окажется «самым вероятным».

Температура и почему ответы не идентичны

Модель не всегда берёт самый вероятный токен. Параметр temperature управляет случайностью: при 0 выбор почти детерминированный (всегда топ-вариант), при высоких значениях модель чаще берёт менее вероятные токены — ответы разнообразнее, но и рискованнее. Для строгих задач (извлечение данных, классификация) ставьте низкую температуру; для творческих — выше.

Итог

  • Генерация = многократное предсказание следующего токена.
  • Промпт не «команда», а контекст, делающий нужный ответ вероятным продолжением.
  • Роли, примеры и пошаговость работают, потому что сдвигают распределение вероятностей.
  • temperature регулирует случайность выбора токенов.
Проверьте себя
1. Что на самом деле делает LLM при генерации ответа?
AВыполняет инструкцию как программа
BИщет ответ в базе данных
CМногократно предсказывает следующий токен по предыдущему тексту
DСравнивает запрос с шаблонами FAQ
2. Почему few-shot примеры в промпте улучшают ответ с точки зрения предсказания токенов?
AОни дообучают модель прямо в промпте
BОни задают шаблон «вход → выход», продолжением которого модель достраивает следующий ответ
CОни увеличивают температуру
DОни уменьшают число токенов
3. Какое значение temperature разумно для строгого извлечения данных?
AВысокое — для разнообразия
BНизкое — для предсказуемого, почти детерминированного вывода
CНе влияет на извлечение
DРовно 1.0 всегда
Поддержать проект