Разработка ИИ-агентов · Модуль 1 · Урок 1.6

Системный промпт: инструкции, роль и формат вывода

Системный промпт — это «программа» агента

В уроке 1.2 мы видели роль system как одно из сообщений. Пора отнестись к ней серьёзно: системный промпт — это код, который выполняет модель. Инструменты дают агенту руки, цикл — возможность действовать, а системный промпт задаёт что агент делает, как рассуждает и где проходят границы. Поменяйте одну фразу в нём — и поведение агента изменится сильнее, чем от смены модели.

Частая ошибка новичка: вылизывать архитектуру цикла и схемы инструментов, оставив системный промпт на уровне «Ты полезный ассистент». Это всё равно что написать идеальный рантайм и подсунуть ему пустую программу. Качество агента определяется качеством инструкций не меньше, чем качеством инструментов.

Из чего состоит хороший системный промпт

Промпт удобно собирать из понятных блоков — так его легче читать, версионировать и менять по частям:

  • Роль и задача. Кто этот агент и какую работу выполняет («Ты агент поддержки биллинга. Твоя задача — решить вопрос пользователя по оплате или эскалировать его»).
  • Контекст. Стабильные факты о мире: язык ответа, кто пользователь, какие данные доступны, текущая дата.
  • Правила и политики. Что можно и чего нельзя: «никогда не выдумывай номер заказа», «перед возвратом средств всегда вызывай confirm_refund», «если данных не хватает — задай уточняющий вопрос, а не угадывай».
  • Когда использовать инструменты. Явная привязка действий к инструментам снимает «угадывание».
  • Формат вывода. Как выглядит ответ: тон, длина, структура, нужен ли строгий JSON (см. урок 2.4).

Эти блоки — не догма, а чек-лист. Для простого агента хватит роли и правил; для сложного добавляются политики безопасности и формат.

Приёмы, которые реально работают

  • Инструкции в позитивной форме. «Отвечай коротко, 2–3 предложения» работает лучше, чем «не пиши длинно»: модели проще следовать тому, что делать, чем удерживать в голове запрет.
  • Приоритет и порядок. Самое важное — в начало и в конец (модель внимательнее к краям, ср. «lost in the middle» из урока 2.2). Критичные правила безопасности дублируйте в конце.
  • Few-shot примеры. Один-два примера «вход → желаемый ответ» задают формат и тон точнее любого описания. Особенно для краевых случаев («вот как отказать вежливо»).
  • Конкретика вместо общих слов. «Профессионально» — пустое; «без сленга, на вы, без эмодзи» — выполнимо.
  • Стабильность префикса. Системный промпт — самый длинный неизменный кусок контекста. Держите его в начале и не меняйте от запроса к запросу: это включает кеширование префикса (prompt caching, урок 4.4) и экономит деньги.

Системный промпт и инструменты — единое целое

Описание инструмента (урок 2.1) говорит модели, что умеет функция. Системный промпт говорит, когда и зачем её звать и какими правилами при этом руководствоваться. Эти два текста должны не противоречить, а дополнять друг друга.

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

Системный промпт как набор блоков-инструкций
flowchart TB
  subgraph SP["Системный промпт (стабильный префикс)"]
    direction TB
    R["Роль и задача"]
    C["Контекст: язык, пользователь, дата"]
    P["Правила и политики (что нельзя)"]
    T["Когда вызывать инструменты"]
    F["Формат вывода + few-shot"]
  end
  SP --> M{{LLM}}
  U["Сообщение пользователя"] --> M
  M --> A["Поведение агента: ответ или tool_use"]
Сборка системного промпта из блоков (читается и версионируется по частям)
// buildSystemPrompt собирает системный промпт из независимых блоков.
// Так его легко менять по частям и держать стабильным префикс для кеша.
func buildSystemPrompt(today string) string {
    blocks := []string{
        // Роль и задача
        "Ты — агент поддержки биллинга. Задача: решить вопрос пользователя по оплате " +
            "или эскалировать его человеку, если не можешь решить сам.",
        // Контекст
        "Отвечай на русском, на «вы», без эмодзи. Сегодня: " + today + ".",
        // Правила и политики
        "Правила:\n" +
            "- Никогда не выдумывай номера заказов и суммы — бери их только из инструментов.\n" +
            "- Возврат средств и отмену подписки выполняй ТОЛЬКО после вызова confirm_action.\n" +
            "- Если данных не хватает — задай один уточняющий вопрос, не угадывай.",
        // Когда использовать инструменты
        "Для любых фактов о счёте пользователя вызывай get_invoice; не отвечай по памяти.",
        // Формат вывода
        "Ответ: 2–4 предложения, по делу. Если эскалируешь — объясни почему.",
    }
    return strings.Join(blocks, "\n\n")
}

func main() {
    messages := []Message{
        {Role: "system", Content: buildSystemPrompt("2026-06-18")},
        {Role: "user", Content: "Снимите с меня подписку и верните деньги за последний месяц."},
    }
    // Хороший промпт заставит агента сначала вызвать get_invoice и confirm_action,
    // а не «согласиться» текстом. Запускаем цикл из урока 1.4.
    _ = messages
}

Anti-patterns

Анти-паттернПочему плохоКак правильно
«Ты полезный ассистент» и всёНет роли, правил и границ — поведение случайноЯвные роль, задача, правила, формат вывода
Запреты вместо инструкций«Не делай X» хуже удерживается, чем «делай Y»Формулировать в позитивной форме, что именно делать
Политики безопасности только в кодеМодель не знает о них и нарушает тон/процессДублировать ключевые политики в системном промпте
Менять системный промпт на каждый запросЛомается prompt caching, растёт стоимостьДержать стабильный префикс; переменное — в user-сообщении
«Будь профессионален» без конкретикиРазмытые слова модель трактует как угодноКонкретные проверяемые требования (на вы, без сленга, до 4 предложений)

Практическое задание

  • Возьмите агента из капстоуна 1.5 и перепишите его системный промпт по блокам: роль, контекст, правила, когда-инструменты, формат.
  • Сформулируйте 3 правила в позитивной форме («делай Y») вместо запретов («не делай X»).
  • Добавьте одно политическое правило про необратимое действие («перед удалением вызови confirm») и проверьте, что агент ему следует.
  • Добавьте 1–2 few-shot примера желаемого ответа (в т.ч. вежливый отказ) и сравните поведение до/после.
  • Убедитесь, что системный промпт не меняется от запроса к запросу — переменные данные перенесите в user-сообщение.

Проверка знаний

Почему системный промпт называют «программой» агента?

  • A Потому что он пишется на языке программирования
  • B Потому что он задаёт поведение, рассуждение и границы агента — то, что выполняет модель на каждом ходу
  • C Потому что он компилируется в байткод перед запуском
  • D Потому что без него модель не запустится

Агент удаления данных по первой же просьбе пользователя удаляет аккаунт без подтверждения, хотя в коде есть инструмент confirm.

Где, скорее всего, корень проблемы и как её исправить промптом?

  • A Нужно увеличить температуру, чтобы модель была осторожнее
  • B В системном промпте нет политики про необратимые действия; добавить правило «удаление выполняй только после confirm»
  • C Нужно убрать инструмент удаления совсем
  • D Проблема в размере модели

Какая формулировка правила надёжнее сработает?

  • A «Не пиши длинно и не используй сложные слова»
  • B «Отвечай на вы, 2–4 предложения, без жаргона»
  • C «Будь максимально профессиональным»
  • D «Старайся, чтобы было хорошо»