# System prompt и streaming: два кита API Claude

Канонический URL: https://zero2claude.ru/blog/api-system-and-streaming
Дата: 2026-08-17
Теги: api, новичкам, claude

System prompt задаёт характер модели на весь разговор, streaming отдаёт ответ по буквам. Два параметра, без которых не собрать живое приложение на Claude.

Первый запрос к Claude через API ты уже сделал: отправил вопрос, получил ответ, всё работает. И почти сразу упёрся в две стены. Первая: как заставить модель отвечать одинаково в каждом ответе — кратко, по-русски, в роли техподдержки, — а не сваливаться то в стихи, то в лекцию? Вторая: почему в чате текст печатается живьём, по словам, а твоя программа замирает на пару секунд и потом вываливает простыню целиком?

Обе стены пробиваются двумя понятиями, которые встретишь в любом приложении на Claude: **system prompt** (он задаёт поведение) и **streaming** (ответ приходит по мере генерации). Звучит технически, но за каждым стоит простая идея. Разберём на пальцах.

<Cover src="/blog/api-system-and-streaming.jpg" alt="Дирижёр у пульта и поток оранжевых световых частиц, текущий по ленте слева направо" />

## System prompt: инструктаж, который модель держит в голове

Представь, что нанимаешь человека в поддержку. Прежде чем посадить его к клиентам, ты проводишь инструктаж: «Ты оператор магазина чая. Отвечай вежливо, по-русски, коротко. Скидок не обещай. Не знаешь — предложи написать на почту». Этот инструктаж он держит в голове весь день, для каждого клиента, не переспрашивая.

**System prompt — ровно такой инструктаж, только для модели.** Ты задаёшь его один раз, и он действует на весь разговор. Вопрос пользователя идёт в поле `user`, а характер и правила — в отдельное поле `system`. Модель относится к ним по-разному: `user` — это то, что спрашивают здесь и сейчас; `system` — рамки, внутри которых она вообще отвечает.

В запросе это выглядит как отдельный параметр:

```json
{
  "system": "Ты оператор магазина чая. Отвечай коротко, по-русски, без обещаний скидок.",
  "messages": [
    { "role": "user", "content": "Здравствуйте, есть ли у вас улун?" }
  ]
}
```

Заметь: текст в `system` пишется **обычными словами**, ровно как ты объяснял бы человеку. Никакого магического синтаксиса, никаких спецсимволов — те же приёмы, что и в чате, просто живут отдельно от вопроса. Что туда обычно кладут:

- **Роль и тон.** «Ты дружелюбный наставник для новичков» или «строгий редактор» — и стиль подстроится под это.
- **Рамки и запреты.** «Отвечай только про кулинарию», «не давай медицинских советов», «максимум три предложения».
- **Формат по умолчанию.** «Всегда возвращай ответ списком» — и не придётся повторять это в каждом вопросе.

<Callout type="tip">
Не сваливай всё в `user`-сообщение. Правила поведения («отвечай кратко», «ты в роли X») работают стабильнее в `system` и не теряются, когда диалог разрастается. Простое правило: «кто ты и как себя ведёшь» — в `system`, конкретный вопрос — в `user`.
</Callout>

## Streaming: ответ по кусочкам, а не одним пакетом

Теперь вторая стена. По умолчанию API работает так: ты отправил запрос, модель целиком придумала ответ — и только потом одним куском вернула его тебе. Если ответ длинный, пользователь несколько секунд смотрит на пустой экран и гадает, не завис ли сайт.

**Streaming** (потоковая выдача) это переворачивает. Модель отдаёт текст **по мере генерации**, маленькими кусочками. Твоё приложение получает их один за другим и сразу дорисовывает на экран — тот самый эффект «печатающейся» речи, как в чате Claude.

Бытовая аналогия. Без стриминга — заказать пиццу и ждать у закрытой двери, пока курьер не привезёт всю коробку. Со стримингом — будто тебе режут и подают по кусочку прямо с пылу: общее время то же, но есть начинаешь сразу и не нервничаешь.

Технически разница — один флаг в запросе:

```json
{
  "stream": true,
  "messages": [
    { "role": "user", "content": "Расскажи историю про кота-программиста" }
  ]
}
```

С `"stream": true` сервер вместо одного ответа присылает поток событий: «вот кусочек текста», «вот ещё кусочек», «всё, я закончил». Твоя задача — собирать эти кусочки и дописывать на экран по мере прихода. Что это даёт на практике:

- **Ощущение скорости.** Первые слова появляются почти мгновенно, даже если весь ответ длинный.
- **Можно прервать.** Видишь, что модель ушла не туда, — останавливаешь, не дожидаясь конца, и не платишь за хвост, который не нужен.
- **Живой интерфейс.** Любой чат-бот ощущается «настоящим» именно из-за бегущего текста; без стриминга он кажется тормозным.

<Callout type="note">
Стриминг меняет **только способ доставки** — не сам ответ и не его цену: токенов тратится столько же. И помни: пока кусочки идут, полного текста у тебя ещё нет. Нужен весь ответ целиком (например, распарсить JSON) — сначала собери поток до конца, а уже потом разбирай.
</Callout>

## Как они работают вместе

В реальном приложении ты используешь оба сразу, и они не мешают друг другу. System prompt отвечает на вопрос **«как модель себя ведёт»**, streaming — **«как ответ попадает к пользователю»**. Это разные слои, и каждый делает своё.

Собери в голове мини-помощника на сайте магазина чая:

- В `system` один раз прописал роль и правила: оператор, вежливо, коротко, без скидок.
- Включил `"stream": true`, чтобы ответы печатались вживую и сайт не выглядел зависшим.
- Дальше просто шлёшь вопросы пользователя в `user`, а кусочки ответа дорисовываешь на экран.

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

Главное, что стоит унести: за страшными словами «system prompt» и «streaming» прячутся две простые вещи — инструктаж заранее и выдача по кусочкам. Освоишь их — и собрать собственное приложение на Claude станет делом техники, а не магии.
