LangChain Промпты -- Системный промпт и динамический промпт
Системный промпт — это основное средство управления поведением Agent.
В этом разделе рассказывается об использовании статических и динамических промптов.
Параметр system_prompt
Параметр system_prompt функции create_agent() принимает две формы:
Пример
from langchain.chat_models import init_chat_model
from langchain.messages import SystemMessage
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
# Способ 1: строка (самый простой)
agent = create_agent(
model=model,
system_prompt="Вы — консультант по обучению в Example. Отвечайте кратко и профессионально.",
)
# Способ 2: объект SystemMessage (многоразовый)
system_msg = SystemMessage(
content="Вы — консультант по обучению в Example. Отвечайте кратко и профессионально."
)
agent = create_agent(model=model, system_prompt=system_msg)
Разработка эффективных системных промптов
Хороший system_prompt должен включать следующие элементы:
Пример
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
from langchain.tools import tool
@tool
def search_course(keyword: str) -> str:
"""Поиск курсов на Example"""
courses = {
"python": "Базовое руководство по Python3 (бесплатно)",
"html": "Базовое руководство по HTML (бесплатно)",
}
return courses.get(keyword.lower(), "Не найдено подходящих курсов")
# Хорошо продуманный system_prompt
GOOD_PROMPT = """Вы — консультант по обучению для Example.
## Ваш ИИ
- Помогайте пользователям находить подходящие курсы по программированию
- Отвечайте на вопросы, связанные с изучением программирования
- Рекомендуйте пути обучения с учётом уровня пользователя
## Кодекс поведения
- Делайте ответы краткими, не более 3 предложений каждый раз
- Предпочитайте использовать инструмент search_course для запроса информации о курсах
- Если пользователь — полный новичок, в первую очередь рекомендуйте вводные курсы
- Не используйте эмодзи
- Если не знаете, скажите об этом; не выдумывайте"""
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
tools=[search_course],
system_prompt=GOOD_PROMPT,
)
result = agent.invoke({
"messages": [HumanMessage(content="Я полный новичок и хочу научиться программировать. Что вы посоветуете?")]
})
print(result["messages"][-1].content)
Вывод:
建议从 Python3 基础教程开始学习。Python 语法简洁,适合零基础入门。 该课程在Example 上免费提供,内容系统全面。
@dynamic_prompt — Динамическое создание промптов
Статический system_prompt обрабатывает всех пользователей одинаково. Однако в реальных приложениях может потребоваться динамически адаптировать промпт на основе информации о пользователе, контекста разговора, времени и т. д.
@dynamic_promptДекоратор позволяет динамически генерировать system_prompt перед каждым вызовом модели.
Пример
from langchain.agents.middleware import dynamic_prompt
from langchain.agents.middleware.types import ModelRequest
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
from langchain.tools import tool
@tool
def search_course(keyword: str) -> str:
"""Поиск курсов на Example"""
courses = {
"python": "Базовый учебник по Python3 (бесплатно, 20 часов)",
"html": "Базовый учебник по HTML (бесплатно, 15 часов)",
"java": "Базовый учебник по Java (бесплатно, 25 часов)",
}
return courses.get(keyword.lower(), "Не найдено подходящих курсов")
# декоратор @dynamic_prompt: принимает ModelRequest, возвращает новый system_prompt
@dynamic_prompt
def personalized_prompt(request: ModelRequest) -> str:
"""Динамически генерировать персонализированный промпт на основе контекста беседы"""
messages = request.state.get("messages", [])
message_count = len(messages)
# Вы можете динамически настраивать промпт в зависимости от различных условий
base_prompt = "Вы консультант по обучению в Example."
if message_count <= 2:
# Беседа только началась; терпеливо направляйте
return base_prompt + (
"Пользователь только что начал разговор; сначала тепло поприветствуйте его,"
"затем спросите о его целях обучения и текущем уровне."
)
elif message_count > 10:
# Долгий разговор; напомнить, чтобы отвечать кратко
return base_prompt + (
"Разговор уже довольно длинный; постарайтесь отвечать как можно короче,"
"не более 2 предложений каждый раз."
)
else:
# Обычная фаза разговора
return base_prompt + (
"Порекомендуйте подходящие курсы на основе предыдущих вопросов пользователя,"
"используйте инструмент search_course для запроса информации о курсах."
)
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
tools=[search_course],
middleware=[personalized_prompt], # Внедрено через middleware
)
# Первый разговор (message_count <= 2, режим подсказок)
result = agent.invoke({
"messages": [HumanMessage(content="Hello")]
})
print(f"Ответ первого раунда: {result['messages'][-1].content}")
Вывод:
First reply: 你好!欢迎来到Example。请问您想学习什么内容? 目前的编程水平如何?我可以根据您的情况推荐合适的课程。
@dynamic_prompt Продвинутый уровень — объединение контекста времени выполнения
Параметр request у @dynamic_prompt предоставляет богатую информацию:
Пример
from langchain.agents.middleware import dynamic_prompt
from langchain.agents.middleware.types import ModelRequest
@dynamic_prompt
def context_aware_prompt(request: ModelRequest) -> str:
"""Динамически генерировать промпты на основе информации о пользователе, времени и этапе разговора"""
# Получить информацию о пользователе из runtime.context
context = request.runtime.context
user_name = context.get("user_name", "Студент") if context else "Студент"
user_level = context.get("user_level", "Начинающий") if context else "Начинающий"
# Получить текущее время
now = datetime.now()
greeting = "Доброе утро" if now.hour < 12 else "Добрый день" if now.hour < 18 else "Добрый вечер"
# Получить текущее количество сообщений
messages = request.state.get("messages", [])
prompt = f"""Ты — консультант по обучению для Example.
Текущее время: {now.strftime('%Y-%m-%d %H:%M')}
Информация о пользователе: {user_name}, уровень {user_level}
## Кодекс поведения
- Обращайтесь к пользователю как "{user_name}"
- Рекомендуйте курсы подходящей сложности с учётом уровня пользователя ({user_level})
- Будьте дружелюбны, но не многословны"""
# Добавить упрощающий промпт для длинных разговоров
if len(messages) > 20:
prompt += "\n- Разговор очень длинный; отвечайте как можно короче"
return prompt
@dynamic_prompt выполняется перед каждым вызовом модели, поэтому промпт может меняться по мере развития беседы. Однако избегайте тяжёлых вычислений внутри него, так как это повлияет на скорость ответа.
Ручное управление приоритетом системного промпта
Если одновременно заданы system_prompt у create_agent() и middleware @dynamic_prompt, middleware имеет более высокий приоритет — он переопределяет статический промпт.
Пример
from langchain.agents.middleware import dynamic_prompt
from langchain.agents.middleware.types import ModelRequest
from langchain.chat_models import init_chat_model
@dynamic_prompt
def override_prompt(request: ModelRequest) -> str:
"""system_prompt этого промежуточного ПО переопределит настройку в create_agent"""
return "Ты — кот; каждый ответ должен заканчиваться на 'meow'."
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0.7)
agent = create_agent(
model=model,
system_prompt="Вы — профессиональный консультант по обучению в Example.", # Переопределено
middleware=[override_prompt], # Более высокий приоритет
)
result = agent.invoke({
"messages": [{"role": "user", "content": "Представься"}]
})
print(result["messages"][-1].content)
Вывод:
I am a cute cat assistant, meow~ Here specifically to help everyone answer all kinds of questions, meow!
Если вы хотите, чтобы промпт промежуточного ПО объединялся со статическим промптом, а не переопределял его, можно вручную объединить их в @dynamic_prompt. Исходный system_prompt не доступен напрямую в request, поэтому если нужно сохранить исходное содержимое, рекомендуется ссылаться на статический промпт как на переменную в функции.
Контрольный список для проектирования системного промпта
| Элемент | Описание | Пример |
|---|---|---|
| Определение роли | Определите идентичность и обязанности ИИ | Вы — консультант по обучению для Example |
| Кодекс поведения | Ограничьте стиль и границы ответов | Ответы должны быть краткими, не более 3 предложений каждый раз |
| Рекомендации по использованию инструментов | Указывайте модели, когда какой инструмент использовать | При запросах курсов предпочитайте инструмент search_course |
| Ограничения границ | Укажите, что нельзя делать | Если вы не знаете, скажите об этом; не выдумывайте |
| Требования к формату | Укажите формат ответов (необязательно) | Ответы используют формат Markdown |
Теперь мы освоили использование статических и динамических промптов. В следующей статье будет рассмотрен потоковый вывод, позволяющий ответам Агента появляться посимвольно, как при наборе текста.
Другие расширения