Системный промпт – это сообщение уровня _"system"_, которое задаёт **роль и правила поведения модели**: на каком языке отвечать, что можно/нельзя делать, как работать с контекстом и что делать, если ответа нет.
В `ChatPromptTemplate` системный промпт – первая часть шаблона диалога, к нему потом добавляются сообщения пользователя (`human`) и, при необходимости, история (`MessagesPlaceholder("history")`).
В RAG через системный промпт мы обычно фиксируем три вещи:
- **откуда брать знания** (только из `{context}`, не фантазировать);
- **как отвечать** (язык, стиль, формат);
- **что делать, если информации недостаточно** (честно сказать, что не знаем).
Если мы хотим модернизировать промпт или добавить свои условия (например ответ строго на русском языке), то нам необходимо составить промпт вручную:
```python
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
(
"system",
"Ты помощник, который ОТВЕЧАЕТ СТРОГО НА РУССКОМ ЯЗЫКЕ. "
"Даже если контекст или вопрос частично на других языках (английский, немецкий и т.п.), "
"ты ВСЁ РАВНО отвечаешь только на русском, используя кириллицу. "
"Не используй слова и фразы на других языках, кроме общепринятых имен собственных и названий. "
"Используй следующие фрагменты контекста для ответа на вопрос. "
"Если ты не знаешь ответа, просто скажи, что не знаешь. "
"Используй максимум три предложения и будь лаконичным."
),
(
"human",
"Контекст: {context}\\n\\nВопрос: {question}"
),
])
prompt
```
В коде мы создаём объект `ChatPromptTemplate`, который объединяет два сообщения – системное (`system`) и пользовательское (`human`) – в единый промпт-шаблон.
Шаблон служит входом для LLM в RAG-пайплайне и определяет структуру данных, которые будут переданы модели при каждом вызове.
Системное сообщение задаёт жёсткие правила выполнения: модель должна всегда возвращать ответ на русском языке, игнорировать языки контекста, использовать только предоставленный фрагмент данных и ограничиваться тремя предложениями.
Это фактически конфиг, который определяет поведение модели на уровне протокола общения.
Пользовательское сообщение содержит параметры `{context}` и `{question}`, которые подставляются рантаймом.
Они выступают интерфейсом между `retriever`'ом, который генерирует контекст, и LLM, которая генерирует ответ.
В итоге `prompt` – это параметризованный шаблон, который принимает словарь вида `{"context": "...", "question": "..."}` и генерирует финальный промпт, полностью совместимый с форматом чат-моделей LangChain.
## Какие есть возможности у ChatPromptTemplate
`ChatPromptTemplate` позволяет гибко собирать промпт из нескольких сообщений и переиспользовать его.
[Prompts | LangChain Reference](https://reference.langchain.com/python/langchain_core/prompts/)
**Основные возможности:**
|Возможность|Зачем нужно|
|---|---|
|`from_messages([...])`|Задать цепочку сообщений: `("system", ...)`, `("human", ...)`, `MessagesPlaceholder("history")` и т.д.|
|`format_messages(**kwargs)` / `invoke`|Подставить значения (`context`, `question`) и получить готовый список сообщений для модели.|
|`partial(...)`|Заранее зашить часть переменных (например, имя ассистента, тон ответа).|
|`append` / `extend`|Динамически добавлять сообщения (например, инструкции, когда меняется режим работы).|
|`MessagesPlaceholder("history")`|Вставлять историю диалога в нужном месте промпта, если RAG чатовый.|
Системный промпт – это не одна строка, а часть нормально структурированного чат-шаблона, который можно версионировать, сохранять и дорабатывать.