Два агента с одной и той же моделью и одинаковыми инструментами могут вести себя совершенно по-разному. Один отвечает коротко, по делу и сначала проверяет данные инструментом. Другой пишет длинные абзацы, выдумывает номера заказов и обсуждает с клиентом погоду. Разницу создаёт системный промпт — текст, который агент получает перед каждым обращением к модели.
После урока вы сможете писать системный промпт по понятной структуре: роль, цель, правила работы с инструментами, формат ответа и примеры. Вы научитесь проверять, что промпт действительно меняет поведение, и держать его коротким, ведь он оплачивается на каждом шаге агента.
Что уже умеем
Вы уже создаёте агента через create_agent, передаёте ему инструменты с хорошими описаниями и обрабатываете ошибки инструментов. Параметр system_prompt вы встречали в первом агенте, а в уроке 1.3 задавали поведение модели через instructions в Responses API. Теперь разберёмся, что именно писать в этот параметр.
Что вы узнаете в рамках статьи
- из каких частей состоит хороший системный промпт агента;
- как задать роль и цель так, чтобы агент не выходил за рамки задачи;
- как сформулировать правила использования инструментов;
- что такое few-shot и как добавить примеры в промпт;
- как проверять промпт на наборе вопросов и учитывать его стоимость.
Ключевые термины
- Системный промпт — инструкция для модели, которая задаёт роль, правила и формат ответа; агент добавляет её перед каждым вызовом модели.
- Роль — описание того, кем является агент и для кого работает.
- Правило — конкретное требование к поведению: что делать всегда, чего не делать никогда.
- Few-shot — приём, при котором в промпт добавляют несколько примеров «вопрос — правильный ответ».
- Галлюцинация — правдоподобный, но выдуманный ответ модели, не подтверждённый данными.
Из чего состоит системный промпт
Удобно собирать промпт из блоков, каждый из которых отвечает на свой вопрос. Роль и цель: кто ты и что должен сделать. Правила: как работать с инструментами и какие темы вне зоны ответственности. Формат ответа: длина, язык, структура. Примеры: как выглядит хороший ответ. Блоки удобно разделять заголовками — модели так проще ориентироваться, а вам проще редактировать.
from langchain.agents import create_agent
SYSTEM_PROMPT = """
# Роль
Ты агент поддержки интернет-магазина «Книжная полка». Помогаешь клиентам
узнать статус заказа и стоимость доставки.
# Правила
- Отвечай только на вопросы о заказах и доставке. На другие темы вежливо
откажись и напомни, с чем можешь помочь.
- Номера заказов, статусы и цены бери только из инструментов. Никогда не
придумывай их.
- Если для инструмента не хватает данных, например номера заказа, спроси
клиента, а не угадывай.
# Формат ответа
По-русски, на «вы», не длиннее трёх предложений.
""".strip()
agent = create_agent(
model="openai:gpt-6-luna",
tools=[order_status, delivery_cost],
system_prompt=SYSTEM_PROMPT,
)
Здесь order_status и delivery_cost — инструменты из прошлого урока. Что увидим в консоли на вопрос «Где мой заказ?»: «Подскажите, пожалуйста, номер заказа, и я проверю его статус». Без правила про недостающие данные модель могла бы вызвать order_status с выдуманным номером.
Роль и границы задачи
Роль задаёт агенту рамки. Фраза «ты полезный ассистент» почти ничего не меняет: модель и так старается быть полезной. Работает конкретика: для какой компании агент работает, кто его пользователи, какую задачу он решает. Ещё важнее границы — что агент делает, если вопрос вне его зоны.
result = agent.invoke(
{"messages": [{"role": "user", "content": "Посоветуй хороший фильм на вечер"}]}
)
print(result["messages"][-1].content)
Что увидим: «К сожалению, с выбором фильма я не помогу. Могу проверить статус вашего заказа или рассчитать доставку». Агент не вызвал ни одного инструмента и сразу ответил, потому что правило явно описывает такой случай. Без границ агент магазина охотно обсуждал бы кино, тратя деньги компании на посторонние разговоры.
Пишите правила утвердительно и проверяемо. «Будь аккуратен с данными» — расплывчато. «Номера заказов бери только из инструмента order_status» — понятно и легко проверить по логам.
Правила работы с инструментами
Описание инструмента говорит, что он делает. Системный промпт говорит, как инструменты сочетаются между собой и в каком порядке их применять. Это особенно важно, когда задача требует нескольких шагов.
TOOLS_RULES = """
# Работа с инструментами
- Чтобы назвать стоимость доставки, всегда вызывай delivery_cost,
даже если цена кажется очевидной.
- Если клиент спрашивает и о заказе, и о доставке, сначала вызови
order_status, затем delivery_cost.
- Если инструмент вернул ошибку, объясни её клиенту простыми словами
и предложи, что сделать дальше.
""".strip()
agent = create_agent(
model="openai:gpt-6-luna",
tools=[order_status, delivery_cost],
system_prompt=SYSTEM_PROMPT + "\n\n" + TOOLS_RULES,
)
Что увидим: на вопрос «Заказ 1099 ещё не пришёл, сколько будет стоить отправить новый, 2 кг в Казань?» агент сначала вызовет order_status, получит «заказ не найден», затем delivery_cost и в ответе объяснит обе части. Порядок шагов задан правилом, а не оставлен на волю модели.
Не дублируйте в промпте описания инструментов целиком. Модель и так их получает, а повтор лишь увеличивает число токенов.
Few-shot: показать, а не рассказать
Иногда проще показать желаемый ответ, чем описать его словами. Приём few-shot — это несколько примеров «вопрос — ответ» прямо в промпте. Модель подхватывает тон, длину и структуру из примеров точнее, чем из абстрактных правил.
EXAMPLES = """
# Примеры ответов
Клиент: Где заказ 1042?
Ответ: Заказ 1042 доставлен. Если вы его не получили, напишите, и я помогу.
Клиент: Сколько стоит доставка 3 кг в Самару?
Ответ: Обычная доставка 3 кг в Самару — 450 руб. Срочная — 675 руб.
""".strip()
agent = create_agent(
model="openai:gpt-6-luna",
tools=[order_status, delivery_cost],
system_prompt="\n\n".join([SYSTEM_PROMPT, TOOLS_RULES, EXAMPLES]),
)
Что увидим: ответы станут короткими, в одном стиле, и агент начнёт сам предлагать срочный вариант доставки, как в примере. Важно: цифры в примерах — это только образец формата. Агент всё равно должен получать реальные данные из инструментов, поэтому правило «никогда не придумывай цены» остаётся в промпте.
Двух-трёх разнообразных примеров обычно достаточно. Если все примеры про один случай, агент начнёт копировать его там, где это неуместно. И помните о цене: каждый пример добавляет токены к каждому обращению к модели.
Как проверить промпт
Промпт — это код, и его тоже нужно тестировать. Соберите небольшой набор вопросов, включая неудобные: вопрос не по теме, вопрос без нужных данных, просьбу с ошибкой. Прогоняйте его после каждого изменения промпта.
test_questions = [
"Где заказ 1042?",
"Где мой заказ?",
"Сколько стоит срочно отправить 4 кг в Казань?",
"Расскажи анекдот",
]
for question in test_questions:
result = agent.invoke({"messages": [{"role": "user", "content": question}]})
print(f"> {question}\n{result['messages'][-1].content}\n")
Что увидим: четыре пары «вопрос — ответ», по которым видно, соблюдены ли правила. Если агент рассказал анекдот, правило о границах сформулировано слабо. Меняйте по одному блоку за раз, чтобы понимать, какая правка что дала.
Частые ошибки
- Писать общие слова вместо правил. «Будь полезным и точным» не меняет поведение. Формулируйте конкретные требования, которые можно проверить по ответу.
- Не описывать, что делать вне зоны ответственности. Без явной границы агент будет отвечать на всё подряд и тратить токены.
- Копировать в промпт описания инструментов. Модель уже получает их отдельно. Промпт описывает порядок и сочетание инструментов, а не их устройство.
- Делать промпт огромным. Он уходит модели на каждом шаге. Лишние 1 000 токенов в промпте умножаются на число шагов и запросов.
Наиболее частые вопросы
- Можно ли передать промпт как
SystemMessage? — Да,system_promptпринимает и строку, и объектSystemMessage. Для текстового промпта строки достаточно. - На каком языке писать промпт? — Модель хорошо понимает русский. Главное — указать язык ответа явно, иначе агент может отвечать на языке примеров.
- Сколько примеров нужно для few-shot? — Обычно два-три разных примера. Больше нужно редко, а стоимость растёт с каждым.
- Почему агент иногда нарушает правила? — Промпт повышает вероятность нужного поведения, но не гарантирует его. Жёсткие ограничения дополняют проверками в коде, о них поговорим в уроке 2.5.
Итоги
Здорово продвинулись! Теперь вы умеете не просто создать агента, а задать ему характер: роль с чёткими границами, правила работы с инструментами, формат ответа и примеры. Вы знаете, что хороший промпт конкретен и проверяем, что его нужно тестировать набором вопросов и что каждый его токен оплачивается на каждом шаге.
Пока наш агент отвечает на каждый вопрос с чистого листа и не помнит, что клиент писал минуту назад. В следующем уроке исправим это: подключим память диалога и научимся следить, чтобы история не разрасталась бесконечно.