中文翻译暂不可用,显示俄语原文。
Как вы проектируете промпты, которые работают с разными моделями?
Краткий тезис
Ключевая идея — переносимость промптов между моделями достигается за счёт отказа от специфичных для одной модели токенов и инструкций, использования универсальных шаблонов (chat templates) и фреймворков (LangChain), а также тестирования на «минимальной» модели (например, LLaMA-3-8B) перед запуском на более мощных (GPT-4, Claude). Простые, чёткие промпты без излишних деталей работают везде; сложные конструкции и платформенные фичи (tool use, system prompt в нестандартном формате) ломают совместимость.
1. Проблема: модели различаются, промпты — общие
Каждая модель имеет свои ожидания от формата диалога. Например:
| Модель | Ожидаемый формат сообщений |
|---|---|
| GPT-4 (OpenAI) | {"role": "system", "content": "..."}, {"role": "user", "content": "..."} |
| LLaMA-3 (Meta) | `< |
| Claude (Anthropic) | \n\nHuman: ...\n\nAssistant: ... |
| Mistral | [INST] ... [/INST] или <s>[INST] ... [/INST] |
Если написать промпт в формате OpenAI и передать его в LLaMA-3, модель не поймёт, что это инструкция, и ответ будет низкого качества. Поэтому универсальный промпт не должен содержать токенов, свойственных одной модели.
2. Универсальный формат общения (Chat Template)
Лучшая практика — использовать chat template — шаблон, который фреймворк (LangChain, Transformers) автоматически преобразует в формат целевой модели. В LangChain промпт задаётся через ChatPromptTemplate:
from langchain.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "Ты полезный ассистент, отвечай кратко."),
("user", "{question}")
])
При вызове модели LangChain сам применит правильный шаблон для GPT-4, LLaMA или Claude. Это основной способ обеспечить переносимость.
3. Избегание специфичных токенов
Никогда не вставляйте в текст промпта токены вроде <|im_start|>, [INST], \n\nHuman:. Даже если они выглядят как обычный текст, модель может интерпретировать их как служебные. Вместо этого полагайтесь на фреймворк или вручную переводите между форматами через конфигурацию.
Исключение: когда вы точно знаете, что будете использовать только одну модель, но даже тогда лучше держать «чистый» промпт и добавлять токены на уровне кода инференса.
4. Принцип «Keep It Simple» (KISS)
Сложные промпты с многоуровневыми инструкциями, цепочками мыслей (Chain-of-Thought) и форматированным выводом (JSON, XML) работают на GPT-4, но могут «сломаться» на меньших моделях. Поэтому проектируйте так:
- Минимальные инструкции: «Ответь на вопрос, используя предоставленный контекст. Если информации недостаточно, скажи "не знаю".»
- Одна задача на сообщение: не смешивайте несколько подзадач в одном user-сообщении.
- Чёткий разделитель: используйте маркдаун-заголовки (
### Контекст,### Вопрос), которые все модели хотя бы частично понимают.
5. Тестирование на минимальной модели
Всегда сначала тестируйте промпт на самой слабой целевой модели — например, LLaMA-3-8B, Mistral-7B или Phi-3-mini. Если промпт работает на 8B-модели, он почти гарантированно будет работать на GPT-4. Если же промпт требует сложного логирования формата вывода, ошибка проявится в первую очередь на маленькой модели.
Схема тестирования:
models_to_test = ["llama-3-8b", "gpt-4", "claude-sonnet"]
for model in models_to_test:
response = llm.invoke(prompt.format(question="..."), model=model)
print(f"{model}: {response}")
6. Использование фреймворков: LangChain, LiteLLM
LiteLLM позволяет вызывать 100+ моделей единым интерфейсом. Он сам преобразует промпты:
from litellm import completion
messages = [{"role": "user", "content": "Расскажи про квантовые вычисления."}]
response = completion(model="claude-3-haiku", messages=messages)
LangChain добавляет PromptTemplate с переменными, что даёт возможность подставлять контекст, few-shot примеры и системные инструкции, не заботясь о формате.
7. Few-shot примеры в общем виде
Примеры (few-shot) должны быть даны в том же формате, что и основные сообщения. В LangChain это делается через FewShotChatMessagePromptTemplate:
from langchain.prompts import FewShotChatMessagePromptTemplate
examples = [
{"input": "Как погода?", "output": "Солнечно, +25°C."},
{"input": "Что такое ML?", "output": "Машинное обучение."}
]
example_prompt = ChatPromptTemplate.from_messages([
("human", "{input}"),
("ai", "{output}")
])
few_shot = FewShotChatMessagePromptTemplate(
examples=examples,
example_prompt=example_prompt
)
Этот шаблон автоматически подставит примеры в правильной ролевой структуре для любой модели.
8. Управление длиной контекста (context window)
Разные модели имеют разный размер окна контекста: GPT-4-turbo — 128К, LLaMA-3-8B — 8K, Mistral-7B — 8K. Универсальный промпт должен умещаться в наименьшее окно среди целевых моделей. Если вам нужно передать большой контекст (например, 50 страниц текста), придётся либо использовать модель с большим окном, либо делать RAG. Для переносимого промпта всегда ограничивайте себя 4K токенами, если не уверены.
9. Системный промпт: да, но с осторожностью
Не все модели поддерживают отдельного системного сообщения (например, старые версии LLaMA-2 игнорировали его). Универсальный подход — встраивать инструкции в первое user-сообщение:
Инструкция: ты помощник, отвечай кратко.
Теперь вопрос: {question}
LangChain при использовании ("system", ...) автоматически добавит системный промпт, если модель его поддерживает, иначе объединит с user. Доверяйте фреймворку.
10. Обработка ошибок и fallback
Даже при тщательном проектировании какая-то модель может не понять промпт. Создайте fallback промпт — упрощённую версию без системной инструкции и few-shot, только с вопросом. Если получен пустой или бессмысленный ответ, повторите запрос с fallback.
Пример:
def safe_invoke(prompt_obj, question, model):
try:
return llm.invoke(prompt_obj.format(question=question), model=model)
except Exception:
fallback = ChatPromptTemplate.from_messages([("user", "{question}")])
return llm.invoke(fallback.format(question=question), model=model)
11. Автоматизированное тестирование переносимости
Создайте набор тестовых кейсов с известными ожидаемыми ответами (golden answers). Напишите скрипт, который прогоняет каждый кейс через все целевые модели и считает метрики (accuracy, BLEU, ROUGE). Если для какой-то модели метрика падает ниже порога — промпт не переносим.
12. Документирование и версионирование промпта
Ведите версии промпта (Git, DVC), указывая, для каких моделей они протестированы. При обновлении прогоняйте все тесты. Создайте конфигурационный файл:
prompt_version: 2.3
tested_models:
- gpt-4-turbo
- gpt-3.5-turbo
- llama-3-8b
- claude-3-sonnet
universal: true
Это позволяет быстро понять, что промпт сломался на новой версии модели.
Пет-проект для закрепления
Задача Разработать универсальный промпт для классификации тональности отзывов (положительная/отрицательная), который работает на GPT-4, LLaMA-3-8B и Claude-3.
Инструменты Python, LangChain, LiteLLM, набор отзывов (например, из datasets).
Шаги:
- Создайте
ChatPromptTemplateс системной инструкцией и одним user-сообщением. - Напишите функцию
classify(text, model). - Протестируйте на 50 отзывах на каждой модели, соберите accuracy.
- Если точность на LLaMA ниже 90% — упростите промпт (уберите форматирование JSON, сократите инструкцию).
- Добавьте fallback (если LLaMA возвращает не
positive/negative— перезапустите с тривиальным промптом). - Сохраните результаты в таблицу.
Ожидаемый результат Вы получите один и тот же промпт, который показывает accuracy >85% на всех трёх моделях. Вы научитесь итеративно упрощать промпт, сохраняя качество.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 93 | Как вы оцениваете качество промптов? |
| 95 | Как вы адаптируете промпты под разные задачи? |
| 96 | Как вы используете chain-of-thought в промптах? |
| 97 | Как вы обрабатываете многоязычность в промптах? |
| 98 | Как вы защищаете промпты от инъекций? |
| 99 | Как вы управляете версиями промптов? |
Навигация
- Предыдущий: 93
- Следующий: 95
- Индекс: 00. Индекс разборов