Урок 3. Модели: какую выбрать и почему
В прошлом уроке мы собрали первый запрос — и там был параметр model. Мы просто подставили туда строку и пошли дальше. Пора разобраться, что за этой строкой стоит: почему моделей несколько, чем они отличаются и как не переплачивать за задачу, с которой справится самая простая.
Семейство моделей Claude
Anthropic выпускает не одну модель, а семейство: несколько «размеров» внутри одного поколения. Названия устроены так: claude-{размер}-{поколение}. Размеров исторически три, и имена у них поэтических форм японской поэзии — от короткой к длинной:
claude-haiku-4-5— Haiku, самая быстрая и дешёвая. Для объёмных, простых, однотипных задач.claude-sonnet-5— Sonnet, баланс. Рабочая лошадка: заметно умнее Haiku, заметно дешевле Opus.claude-opus-5— Opus, самая мощная. Для сложных рассуждений, длинных агентных цепочек, задач, где ошибка дорого стоит.
Строка модели — обычный параметр запроса, менять её можно в одну правку:
response = client.messages.create(
model="claude-haiku-4-5", # достаточно поменять эту строку
max_tokens=500,
messages=[
{"role": "user", "content": "Объясни фотосинтез одним абзацем."}
]
)
В этом и красота: переезд между моделями почти бесплатен по усилиям. Ни промпт, ни код обычно переписывать не нужно — только сверить качество ответов.
Три оси компромисса
Выбор модели — это всегда торг по трём осям. Улучшая одну, обычно платите другой.
- Скорость (латентность). Насколько быстро приходит ответ. Критично там, где человек ждёт на том конце: чат поддержки, автодополнение, голосовой интерфейс. Модели поменьше отвечают ощутимо быстрее.
- Стоимость. Вы платите за токены — входные и выходные. Модели побольше стоят за токен дороже. На одном запросе разница незаметна, на миллионе запросов в месяц это разница между «работает» и «закрываем проект».
- Качество. Насколько модель справляется со сложным: многошаговые рассуждения, аккуратная арифметика, тонкие инструкции, длинный контекст, код. Тут старшие модели выигрывают — но только там, где задача действительно сложная.
Важная ловушка: разница в качестве проявляется не на каждой задаче. Попросите четыре разные модели объяснить фотосинтез одним абзацем — и все четыре ответят хорошо. Разница вылезает на задачах с подвохом. Поэтому «взять самую мощную на всякий случай» — не осторожность, а способ переплачивать и ждать дольше без выигрыша.
Вам нужно проставить тег «жалоба / вопрос / благодарность» на 200 тысяч коротких сообщений. С какой модели разумно начать?
Как замерить скорость самому
Не верьте на слово — измерьте. Прогоните один и тот же промпт через несколько моделей и засеките время. Вот минимальный скрипт:
import time
def compare_model_speeds():
models = ["claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5"]
task = "Объясни концепцию фотосинтеза одним сжатым абзацем."
for model in models:
start = time.time()
response = client.messages.create(
model=model,
max_tokens=500,
messages=[{"role": "user", "content": task}]
)
elapsed = time.time() - start
tokens = response.usage.output_tokens
print(f"Модель: {model}")
print(f"Ответ: {response.content[0].text}")
print(f"Токенов сгенерировано: {tokens}")
print(f"Время: {elapsed:.2f} с")
print(f"Время на токен: {elapsed / tokens:.3f} с\n")
Одна тонкость про честность замера. Общее время запроса зависит от того, сколько токенов модель написала: если Haiku ответила тремя предложениями, а Opus — восемью, вы сравниваете не скорость, а многословность. Поэтому смотрите на время на один токен, а для строгого сравнения обрезайте все ответы до одинаковой длины через max_tokens (этот параметр разберём в следующем уроке) и усредняйте по десяткам прогонов, а не по одному.
Почему при сравнении скорости моделей смотрят на время на один токен, а не на общее время ответа?
Где разница в качестве видна
Чтобы увидеть разницу, нужна задача, на которой можно ошибиться. Классический приём — взять вопрос с однозначным правильным ответом и прогнать его через каждую модель много раз подряд. Тогда вы меряете не «понравился ответ или нет», а долю попаданий.
Например, такая задача (правильный ответ — 18):
Чему равно среднее геометрическое следующих значений: 24, 15, 7, 16, 31 и 23?
Округли до целого. В ответе выведи только число и ничего больше.
Гоняем каждую модель по семь раз и складываем ответы в список:
def compare_model_capabilities():
models = ["claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5"]
task = (
"Чему равно среднее геометрическое следующих значений: "
"24, 15, 7, 16, 31 и 23? Округли до целого. "
"В ответе выведи только число и ничего больше."
)
for model in models:
answers = []
for _ in range(7):
response = client.messages.create(
model=model,
max_tokens=1000,
messages=[{"role": "user", "content": task}]
)
answers.append(response.content[0].text.strip())
print(model, answers)
Ожидаемая картина: чем старше модель, тем стабильнее правильный ответ; младшие модели чаще промахиваются и заметнее «плавают» от прогона к прогону. Конкретные доли попаданий приводить бессмысленно — они меняются с каждым релизом. Смысл упражнения другой: вы получили дешёвый способ сравнить модели на своей задаче, а не на чужом бенчмарке.
Правило выбора
Практический алгоритм умещается в четыре шага:
- Начните с младшей модели. Haiku быстрая и дешёвая — на прототипе вы за те же деньги успеете перебрать в разы больше вариантов промпта.
- Соберите набор проверок (evals). Десять–тридцать реальных примеров из вашей задачи с известным правильным ответом. Без них «модель стала хуже» — ощущение, а не факт.
- Если качества не хватает — сначала почините промпт. Часто дело не в модели: непонятная инструкция, нет примеров, не задан формат. Апгрейд модели маскирует плохой промпт и делает это за ваши деньги.
- Если и после этого не хватает — поднимите уровень. Haiku → Sonnet → Opus. Прогоните тот же набор проверок и решите, стоит ли прибавка качества прибавки в цене и задержке.
Направление важно: подниматься от дешёвой модели вверх дешевле, чем спускаться от дорогой вниз. Начав с Opus, вы никогда не узнаете, что задача решалась младшей моделью — и будете платить за это каждый месяц.
И ещё: модель не обязана быть одна на весь продукт. Нормальная архитектура — разные модели на разных шагах: Haiku классифицирует входящее и отсекает мусор, Sonnet пишет ответ, Opus подключается только на редких сложных ветках.
Haiku ошибается на вашей задаче. Что сделать в первую очередь?
Упражнения
Возьмите ключ из первого урока и попробуйте руками. Актуальные имена моделей сверьте в документации.
Упражнение 3.1 — Сравнить две модели на одной задаче
Отправьте один и тот же промпт в claude-haiku-4-5 и claude-sonnet-5, замерьте время каждого запроса и число выходных токенов. Возьмите задачу с подвохом — такую, где легко ошибиться, а не «расскажи про котиков».
Решение упражненияСначала попробуйте сами — потом сверьтесь
import time
from anthropic import Anthropic
client = Anthropic()
task = (
"У меня было 12 яблок. Я отдал треть соседу, "
"потом купил ещё 5 и съел 2. Сколько яблок осталось? "
"Ответь одним числом."
)
for model in ["claude-haiku-4-5", "claude-sonnet-5"]:
start = time.time()
r = client.messages.create(
model=model,
max_tokens=300,
messages=[{"role": "user", "content": task}]
)
elapsed = time.time() - start
tokens = r.usage.output_tokens
print(model, "→", r.content[0].text.strip())
print(f" {elapsed:.2f} с, {tokens} токенов, {elapsed / tokens:.3f} с/токен\n")
Правильный ответ — 11. На таком уровне сложности обе модели, скорее всего, справятся, и это ровно тот вывод, ради которого стоит замерять: если разницы в качестве нет, берите ту, что быстрее и дешевле. Чтобы увидеть расхождение, усложняйте задачу до тех пор, пока младшая модель не начнёт ошибаться — эта граница и есть ваш ответ на вопрос «какая модель нужна».
Упражнение 3.2 — Найти точку апгрейда
Возьмите задачу из своей работы (разбор письма, извлечение полей из текста, короткая классификация). Составьте 10 примеров с заранее известным правильным ответом. Прогоните их через Haiku, посчитайте, сколько попаданий. Затем то же самое на Sonnet. Ответьте себе: оправдан ли апгрейд?
Решение упражненияСначала попробуйте сами — потом сверьтесь
cases = [
{"text": "Заказ не приехал третий день, верните деньги", "label": "жалоба"},
{"text": "Подскажите, доставка до Алматы есть?", "label": "вопрос"},
{"text": "Спасибо, всё пришло вовремя!", "label": "благодарность"},
# ... ещё 7 примеров
]
def accuracy(model):
hits = 0
for case in cases:
r = client.messages.create(
model=model,
max_tokens=10,
messages=[{
"role": "user",
"content": (
"Определи тип сообщения: жалоба, вопрос или благодарность. "
"Ответь одним словом.\n\n" + case["text"]
)
}]
)
if r.content[0].text.strip().lower() == case["label"]:
hits += 1
return hits / len(cases)
for model in ["claude-haiku-4-5", "claude-sonnet-5"]:
print(model, f"{accuracy(model):.0%}")
Такой десятистрочный скрипт — уже полноценный мини-eval. Если Haiku набирает столько же, сколько Sonnet, вопрос апгрейда закрыт: остаётесь на младшей. Если Haiku проседает — сначала уточните промпт (добавьте пример на каждый класс, запретите пояснения) и перезамерьте. Апгрейд модели — последний ход, а не первый.
Что запомнить
- Claude — это семейство моделей разного размера:
claude-haiku-4-5(быстрая и дешёвая),claude-sonnet-5(баланс),claude-opus-5(самая мощная). - Выбор модели — торг по трём осям: скорость, стоимость, качество. Улучшая одну, платите другой.
- На простых задачах все модели отвечают хорошо — разница вылезает там, где можно ошибиться.
- Начинайте с младшей модели и поднимайтесь вверх, а не наоборот. Начав с Opus, вы не узнаете, что хватило бы Haiku.
- Перед апгрейдом соберите набор проверок и почините промпт — иначе вы платите деньгами за то, что чинится словами.
- Модель — параметр запроса, а не решение навсегда. Разные шаги пайплайна могут работать на разных моделях.
- Актуальные имена, цены и лимиты — только в документации Anthropic.
Дочитали и сделали упражнения? Зафиксируйте прогресс — отметка сохранится в вашем браузере.