Заметки

Системный промпт: как задать модели роль и правила

M
Markabus
·13 августа 2026 г.
Тёмная графитовая комната, крупный план монитора на рабочем столе: в редакторе вверху экрана небольшой блок подсвеченного синтаксисом текста настроек, ниже — терминал с зелёным выводом; клавиатура в расфокусе на переднем плане, тёплый отблеск от окна на кромке монитора

Одна и та же модель может отвечать как сухой технический справочник, а может — как болтливый копирайтер. Разницу чаще всего задаёт не сам вопрос пользователя, а системный промпт: короткий блок инструкций, который приложение отправляет модели до того, как пользователь напишет первое слово. Это самый дешёвый и самый недооценённый способ управлять поведением ИИ в продукте. Разбираем, что туда класть, как это выглядит в API трёх основных провайдеров и какие ошибки чаще всего превращают системный промпт в бесполезный текст.

Что такое системный промпт

Системный промпт (system prompt, ещё говорят «системная инструкция») — это отдельное поле запроса к модели, куда разработчик кладёт правила игры: кто модель по роли, что она делает, чего не делает, в каком формате отвечает. Пользователь этот текст не видит и, в норме, не может его перезаписать своим сообщением.

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

Важно понимать границы: системный промпт — это не механизм безопасности и не права доступа. Это сильная просьба, а не firewall. Если агент умеет вызывать инструменты, ограничивать его нужно на уровне самих инструментов, а не абзацем текста.

Иерархия инструкций: кто кого перебивает

У современных моделей есть явная иерархия источников инструкций. OpenAI описывает её в Model Spec как «цепочку командования» (chain of command) из пяти уровней: Root — базовые правила, которые нельзя переопределить ничем; System — политики самого провайдера; Developer — инструкции разработчика приложения; User — сообщения конечного пользователя; Guideline — мягкие рекомендации по умолчанию, которые контекст может переопределить. При конфликте побеждает уровень выше.

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

Отдельная тонкость: данные, которые приложение подтягивает из внешнего мира — веб-страницы, письма, содержимое базы, — попадают в контекст как обычный текст и формально не имеют никакой власти. Но модель может принять их за инструкцию. Это и есть промпт-инъекция, и хороший системный промпт должен прямо проговаривать: всё, что пришло из внешнего источника, — это данные, а не команды.

Как задать системный промпт в API

Поле называется по-разному, но смысл везде один — отдельный параметр запроса, не перемешанный с сообщениями.

Claude (Anthropic)

В Messages API это параметр верхнего уровня system — обычная строка (или список блоков):

message = client.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    system="Ты — технический ассистент по Python. Отвечай кодом и коротким пояснением.",
    messages=[{"role": "user", "content": "Как отсортировать список словарей?"}],
)

Anthropic отдельно советует задавать роль: даже одно предложение вроде «Ты — специалист поддержки» заметно меняет тон и фокус ответов. Для сложных системных промптов документация рекомендует структурировать текст XML-тегами — <instructions>, <context>, <rules>.

OpenAI

В Responses API есть параметр instructions, который эквивалентен сообщению с ролью developer:

const response = await client.responses.create({
  model: "gpt-5.6",
  instructions: "Отвечай кратко, без вступлений.",
  input: "Точки с запятой в JS обязательны?",
});

Есть важный нюанс: instructions действует только на текущий запрос. Если вы ведёте диалог через previous_response_id, инструкции прошлых ходов автоматически не переносятся — их нужно передавать каждый раз. Роль system в старом Chat Completions осталась, но в новом API её место занял developer.

Gemini (Google)

Здесь параметр называется system_instruction и передаётся вместе с запросом:

interaction = client.interactions.create(
    model="gemini-3.6-flash",
    system_instruction="Ты — кот. Тебя зовут Neko.",
    input="Привет"
)

В многоходовых сценариях системную инструкцию тоже стоит передавать явно при каждом обращении, если вы сами собираете историю диалога.

Из чего собрать рабочий системный промпт

Универсального шаблона нет, но у устойчивых промптов повторяется одна и та же скелетная структура. Шесть блоков, по убыванию важности:

  1. Роль и задача. Одно-два предложения: кто модель и что она делает. «Ты — ассистент интернет-магазина X, помогаешь покупателям выбрать товар и разобраться с доставкой».
  2. Контекст. Что за продукт, кто аудитория, чего от ответа ждут. Модель не знает вашего бизнеса — это придётся рассказать.
  3. Правила и границы. Формулируйте позитивно и проверяемо. «Если данных о наличии товара нет — скажи, что не знаешь, и предложи связаться с менеджером» работает лучше, чем «не выдумывай».
  4. Формат ответа. Длина, структура, язык, использование списков. Если нужен машиночитаемый ответ — не описывайте JSON словами, используйте структурированный вывод по схеме.
  5. Тон. «Дружелюбно, но по делу, без канцелярита и без восклицательных знаков» — конкретика тут важнее эпитетов.
  6. Примеры. Два-три коротких образца «запрос → правильный ответ» дают больше, чем абзац объяснений. Подробнее — в заметке о практических приёмах промпт-инжиниринга.

Порядок блоков имеет значение: сначала роль и контекст, потом правила, в конце — формат и примеры. Так модель сначала понимает, кем она является, и только потом — как оформлять ответ.

Частые ошибки

Промпт-роман. Три экрана текста с двадцатью правилами: часть из них модель проигнорирует, а вы не поймёте какую. Начинайте с пятнадцати строк и добавляйте правило только после того, как поймали реальную ошибку в ответах.

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

Только запреты. Список «не делай» плохо работает: чтобы не сделать чего-то, модель должна это сначала представить. Заменяйте запреты на описание желаемого поведения.

Данные вместо инструкций. Не зашивайте в системный промпт каталог товаров или базу знаний — он раздувается и устаревает. Знания подтягивайте отдельно, инструкции держите в системном блоке.

Забытые пользовательские данные. Всё, что приходит от пользователя или из внешнего источника, должно попадать в сообщения, а не склеиваться с системным промптом. Иначе вы своими руками открываете дверь для инъекции.

Кэширование и цена вопроса

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

Как тестировать и версионировать

Системный промпт — это код продукта, а не заметка в блокноте. Минимальная гигиена: держите его в репозитории отдельным файлом, а не строкой внутри функции; фиксируйте версию рядом с версией приложения; при каждом изменении прогоняйте набор из 10–20 контрольных запросов и сравнивайте ответы с эталонными.

Меняйте по одному правилу за раз. Если поправить сразу пять формулировок и увидеть улучшение, вы не узнаете, какая из них сработала, — а через месяц не поймёте, какую можно выкинуть.

У агентных инструментов есть свой формат «системного промпта проекта». В Claude Code, например, эту роль играет файл CLAUDE.md: те же правила, только лежат в репозитории и подхватываются автоматически.

Вывод

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

Частые вопросы

Q.Чем системный промпт отличается от обычного сообщения пользователю?

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

Q.Можно ли системным промптом закрыть модели доступ к данным или действиям?

Нет. Системный промпт задаёт поведение, но не является механизмом безопасности. Реальные ограничения нужно ставить на уровне кода и прав самих инструментов, которые вызывает модель, — текстовая инструкция сама по себе не гарантия.

Q.Насколько длинным должен быть системный промпт?

Начинайте с 10–20 строк и добавляйте правила только после того, как поймали конкретную ошибку в ответах. Длинный промпт не только хуже соблюдается, но и оплачивается с каждым запросом — хотя стабильный префикс можно удешевить кэшированием.

Q.Нужно ли передавать системную инструкцию в каждом запросе?

Да, если вы сами собираете историю диалога. В OpenAI Responses API параметр instructions действует только на текущий ответ и не переносится автоматически через previous_response_id; в Claude и Gemini системное поле также передаётся с каждым вызовом.

Источники

Предыдущая
Кэширование в WordPress: обзор способов
Следующая
Скиллы в Claude Code: как научить агента своим процессам

Читайте также