PromptTemplate: параметризация промптов

Урок про то, как не склеивать промпты строками, а параметризовать их шаблонами.

PromptTemplate — шаблон промпта с именованными переменными, которые подставляются при вызове.

Проблема склейки строк

Собирать промпт через f-строки кажется простым, но быстро превращается в проблему: переменные теряются, экранирование ломается, один и тот же текст копируется по проекту. Шаблон решает это: вы один раз описываете структуру с плейсхолдерами и переиспользуете её.

Сам принцип подстановки можно показать на чистом Python — это ровно то, что делает шаблон внутри:

template = "Переведи на {language}: {text}"
filled = template.format(language="английский", text="привет, мир")
print(filled)

Вывод:

Переведи на английский: привет, мир

PromptTemplate и ChatPromptTemplate

В LangChain есть PromptTemplate (для строкового промпта) и ChatPromptTemplate (для списка сообщений с ролями). Второй используют чаще, потому что он сразу формирует system/human-сообщения.

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "Ты переводчик. Переводи кратко и точно."),
    ("human", "Переведи на {language}: {text}"),
])
messages = prompt.invoke({"language": "английский", "text": "привет, мир"})
print(messages)

Как работает под капотом

Шаблон хранит строку с плейсхолдерами вида {name} и список ожидаемых переменных (input_variables). При вызове invoke() с словарём он подставляет значения и возвращает готовый PromptValue — объект, который умеет отдать себя и как строку, и как список сообщений. Поэтому шаблон легко вставляется в LCEL-цепочку перед моделью: prompt | model. Если вы передадите не все переменные, шаблон сразу выбросит понятную ошибку — это лучше, чем тихо отправить кривой промпт в модель.

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

  • Незакрытые или лишние фигурные скобки. Если в тексте нужна буквальная скобка, её удваивают: {{ и }}.
  • Несовпадение имён переменных. Имена в шаблоне и в словаре должны совпадать точно.
  • Складывать данные пользователя прямо в system-инструкцию. Пользовательский ввод — в human-плейсхолдер, иначе открывается дорога к prompt injection.

Итог

  • Шаблон промпта заменяет ручную склейку строк и переиспользуется.
  • ChatPromptTemplate формирует сообщения с ролями и чаще нужен на практике.
  • Шаблон встраивается в LCEL: prompt | model.
  • Буквальные фигурные скобки в тексте удваивают: {{, }}.
Проверьте себя
1. Зачем использовать PromptTemplate вместо f-строки?
AЭто ускоряет ответ модели
BЧтобы переиспользовать структуру промпта и безопасно подставлять переменные
CЧтобы не платить за токены
Df-строки запрещены в Python
2. Как вставить буквальную фигурную скобку в текст шаблона LangChain?
AЭкранировать обратным слешем \{
BУдвоить её: {{ и }}
CИспользовать {
DНикак, скобки запрещены