Что реально уходит, когда вы нажимаете Send
Что происходит
Один и тот же вопрос в двух чат-приложениях — разные ответы. Даже если в обоих выбран «один и тот же» Claude или GPT. Первое объяснение, которое приходит в голову, неверное: «модель сегодня в другом настроении». Модель тут ни при чём — приложения отправили разные запросы.
Ваш вопрос — это только одна строка в запросе. В том же запросе передаются история переписки, системные инструкции, определения инструментов и десяток параметров.
До определения
Пользователь набрал одну строку: «Почему небо голубое?». Ниже — то, что реально ушло на сервер (сокращено):
{
"model": "<id модели>",
"max_tokens": 200,
"system": "Ты отвечаешь кратко и по-русски.",
"messages": [
{"role": "user", "content": "Почему небо голубое?"}
]
}
Системная инструкция «отвечай кратко» пользователь не писал — её добавило приложение. Именно поэтому приложения отвечают по-разному на один и тот же вопрос.
Определение
API-запрос — это JSON-документ, который приложение отправляет провайдеру по HTTP; модель не видит «ваш вопрос» — она видит только этот документ.
Роль сообщения (role) — поле, указывающее, от кого реплика: системные/developer-инструкции, пользователь, ассистент. От роли зависит вес, который модель придаёт реплике.
Mental model
Представьте, что вы диктуете письмо секретарю. Секретарь — приложение. Он берёт ваш текст, прикладывает к нему устав компании (system), предыдущую переписку (history) и инструкцию «какие инструменты разрешены» (tools), а затем отдаёт всё это в модель.
Ограничение аналогии: секретарь ничего не переписывает и не «понимает» — он механически собирает JSON. Ровно поэтому баг в сборке запроса выглядит как «странное поведение модели».
Under the hood
Что лежит в запросе (упрощённо, по документации двух провайдеров):
- model — id модели;
- messages — массив реплик
{role, content}. У OpenAI роли:developer | system | user | assistant | tool | function; у Anthropic в messages —user | assistant, а системный промпт передаётся отдельным top-level параметромsystem; - инструкции: у Anthropic
system— отдельное поле; у OpenAI-моделей нового поколения (o1 и новее) инструкции передаются рольюdeveloper— она используется вместо ролиsystemи имеет приоритет выше пользовательских сообщений; - лимиты генерации: у Anthropic
max_tokens— обязательный параметр; у OpenAI —max_tokens/max_completion_tokens; - параметры сэмплинга:
temperatureдоступен не везде (у Anthropic он deprecated для моделей после Opus 4.6); - stream — включить потоковую доставку (SSE);
- tools — описания инструментов, которые модель может попросить вызвать (мир 7).
В ответ приходит JSON: текст, stop_reason/finish_reason и usage — сколько
токенов вошло и вышло (у OpenAI — prompt_tokens/completion_tokens и cached_tokens в details, у Anthropic — input_tokens/output_tokens). Токенам и счётчикам посвящён мир 2.
Inspect
Ответ на минимальный запрос (структура по документации; значения сокращены):
{
"role": "assistant",
"content": [{"type": "text", "text": "..."}],
"stop_reason": "end_turn",
"usage": {"input_tokens": 21, "output_tokens": 57}
}
Поле usage содержит точные размеры входа и выхода; при разборе стоимости и лимитов на него смотрят в первую очередь.
Попробуйте сами
Соберите тело запроса для своего вопроса и отправьте его. Единственные подстановки — ключ ($ANTHROPIC_API_KEY) и id модели из личного кабинета провайдера — реальных креденшелов
в уроке нет:
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "'"$MODEL_ID"'",
"max_tokens": 200,
"system": "Ты отвечаешь кратко.",
"messages": [{"role": "user", "content": "Почему небо голубое?"}]
}' | python3 -m json.tool
Затем замените system на пользовательское сообщение и сравните ответ. Вы только что
изменили приоритет инструкции, не меняя «вопрос».
А теперь сломаем
Уберите max_tokens из запроса к Anthropic. Запрос упадёт с ошибкой 400: параметр
обязателен. Теперь добавьте temperature к модели, которая его не поддерживает
(выпущенной после Opus 4.6) — снова ошибка. Модель не сломалась: ошибку содержит код, собирающий API-вызов, а не текст пользователя.
Ещё один случай без сообщения об ошибке: две подряд реплики одной роли. Anthropic их объединяет в одну — история, которую вы «передали», отличается от той, что увидела модель.
Диагностика
Симптом: «тот же вопрос — другой ответ» или «после обновления библиотеки всё сломалось».
- Посмотрите на фактически отправляемый JSON (лог/
curl -v/mitm-прокси в dev). - Сравните: совпадают ли роли, порядок сообщений, системные инструкции, значения параметров.
- Проверьте
usageв ответе — не превышает ли вход ожидаемый размер (лишняя история/tools).
Не начинайте с «промпт плохой»: сначала проверьте, что промпт вообще дошёл в том виде, в котором вы его задумали.
С чем это путают
- «Промпт» и «запрос». Ваш текст — часть запроса. Запрос шире: инструкции, история, параметры, инструменты.
- Модель и продукт вокруг неё. Модель — предиктор токенов по входному документу;
чат-приложение, гарнес и API — разные обёртки с разной сборкой запроса (
CONTEXT.md§4). systemу разных провайдеров. У Anthropic — top-level поле; у OpenAI — роль (в новых моделях её место занимаетdeveloper). Не переносите примеры между провайдерами дословно.
Проверка
- (scenario) Инструкция должна быть выше пользовательских, API — OpenAI-совместимый, модель новая (o1+). Какую роль использовать для инструкции?
- (multiple) Что из перечисленного может находиться внутри API-запроса к модели?
- (scenario) Два приложения с одной моделью отвечают по-разному. Что проверить первым?
Полный набор — 01-what-happens-on-send.quiz.json.
Что помнить
- Модель видит не ваш текст, а JSON-документ, собранный приложением.
- Роли и системные инструкции — механизм управления приоритетом, а не «часть промпта».
max_tokensи доступностьtemperatureзависят от провайдера и модели.usageв ответе — точные размеры входа и выхода.- Первый шаг любой диагностики — посмотреть фактический JSON запроса.
Sources
claude-messages-api— Anthropic Messages API: system top-level, роли, max_tokens обязателен, temperature deprecated после Opus 4.6, объединение подряд идущих реплик (verified 2026-10-04).openai-python-sdk— роли Chat Completions; developer «replace the previous system messages» для o1+ (verified 2026-10-04).openai-openapi— структураusage(prompt_tokens/completion_tokens/total_tokens, cached_tokens, reasoning_tokens),finish_reason(verified 2026-10-04).