Управление промптами: промпты как код
Перейти к разделу
Почему промпты не принадлежат коду
В прототипе у вас промпт в виде строки в коде. В продакшене промпт меняется в 10 раз чаще окружающей логики. Каждое изменение промпта требует деплоя, код-ревью и сборочного пайплайна. Это лишнее трение. Промптам нужен собственный жизненный цикл — версионирование, тестирование, откат — независимо от кода приложения.
Управление промптами имеет три уровня зрелости. Уровень 1: промпты в коде в виде строк-шаблонов. Уровень 2: промпты в выделенных файлах с переменными и версионированием через git. Уровень 3: реестр промптов — центральный сервис, раздающий промпты через API, позволяющий проводить A/B-тестирование и отслеживать метрики качества по версиям.
Промпты как шаблоны с переменными
Каждый продакшен-промпт — это шаблон. Он содержит статическую часть (инструкции, формат, ограничения) и динамические переменные (ввод пользователя, контекст, few-shot примеры). Разделяйте их явно. Используйте Mustache, Handlebars или обычную интерполяцию строк — но имейте чёткий контракт о том, какие переменные ожидает промпт.
// prompts/summarize.v2.yaml
// name: summarize
// version: 2
// variables: [document, max_length, language]
// model: claude-sonnet-4-20250514
const promptTemplate = `
Summarize the following document in {{language}}.
Maximum length: {{max_length}} words.
Focus on actionable insights, skip background.
Document:
{{document}}
Output format: bullet points, each starting with a verb.
`;
function renderPrompt(
template: string,
vars: Record<string, string>
): string {
return template.replace(
/\{\{(\w+)\}\}/g,
(_, key) => vars[key] ?? ''
);
}Версионирование и откат
Каждая версия промпта должна быть неизменяемой. Версия 2 никогда не перезаписывает версию 1 — обе существуют параллельно. Новая версия сначала деплоится на канарейный трафик (5–10% запросов), качество сравнивается с базовой линией, и только после этого становится версией по умолчанию. При деградации новой версии откат — это одно переключение конфигурации.
Простейшая реализация: промпты в YAML-файлах в git-репозитории, с версией в имени файла (summarize.v1.yaml, summarize.v2.yaml). Конфигурация определяет, какая версия активна. Более сложная конфигурация: реестр промптов как микросервис с REST API, базой данных версий и вебхуками деплоя.
// Simple file-based prompt registry
interface PromptVersion {
name: string;
version: number;
template: string;
model: string;
variables: string[];
metadata: { author: string; changedAt: string; reason: string };
}
class PromptRegistry {
private prompts = new Map<string, PromptVersion[]>();
getActive(name: string): PromptVersion {
const versions = this.prompts.get(name);
if (!versions?.length) throw new Error(`Prompt '${name}' not found`);
return versions[versions.length - 1];
}
getVersion(name: string, version: number): PromptVersion {
const v = this.prompts.get(name)?.find(p => p.version === version);
if (!v) throw new Error(`Prompt '${name}' v${version} not found`);
return v;
}
}A/B-тестирование промптов
Изменение одного слова в промпте может сдвинуть качество вывода на 20%. Без A/B-тестирования вы этого не узнаете. Базовая настройка: случайно назначайте каждый запрос варианту (A = текущая версия, B = кандидат), логируйте вариант вместе с выводом, и после достаточной выборки сравнивайте метрики.
Метрики зависят от задачи: для суммаризации измеряйте длину, охват ключевых тезисов и пользовательские оценки. Для классификации — точность и F1-меру. Для генерации кода — компилируется ли код и проходит ли тесты. Всегда имейте хотя бы одну автоматическую метрику и одну человеческую.
// A/B test assignment
function assignVariant(
userId: string,
testName: string,
variants: string[],
weights?: number[]
): string {
// Deterministic assignment based on user+test hash
const hash = createHash('sha256')
.update(`${userId}:${testName}`)
.digest();
const bucket = hash.readUInt32BE(0) % 100;
const w = weights ?? variants.map(() => 100 / variants.length);
let cumulative = 0;
for (let i = 0; i < variants.length; i++) {
cumulative += w[i];
if (bucket < cumulative) return variants[i];
}
return variants[variants.length - 1];
}Композиция промптов и цепочка мышления
Сложные задачи требуют композиции промптов — разбиения проблемы на шаги, где вывод одного промпта является входом следующего. Классический паттерн: первый промпт извлекает релевантную информацию из документа, второй анализирует её, третий генерирует вывод. Каждый шаг имеет собственный промпт с собственным версионированием.
Chain-of-thought (CoT) в продакшене — это не просто «думай шаг за шагом». Это структурированный формат, где модель сначала генерирует рассуждение (которое вы логируете, но не показываете пользователю), а затем финальный ответ. CoT улучшает качество на аналитических задачах на 10–30%, но увеличивает количество токенов и задержку.
Промпт — это продакшен-артефакт, как код: ему нужны версионирование, ревью, тестирование и откат. Относитесь к нему так с первого дня.
Логируйте версию промпта, модель и хеш входных переменных при каждом API-вызове. Когда вы будете отлаживать плохой вывод, вы будете точно знать, что получила модель.
Добавьте поле 'reason' в метаданные промпта — почему была создана эта версия. Через месяц вы не вспомните, зачем меняли формулировку, если не запишете это сейчас.
Создайте простой реестр промптов: 1) Сохраните две версии одного промпта в YAML-файлах. 2) Напишите функцию, детерминированно назначающую вариант на основе ID пользователя (разделение 50/50). 3) Логируйте вариант, версию промпта и (симулированный) вывод модели в консоль. 4) После 100 симулированных запросов посчитайте, сколько ушло к каждому варианту.
Подсказка
Детерминированное назначение через хеш гарантирует, что один и тот же пользователь всегда получает один вариант — критически важно для стабильного UX и валидного A/B-тестирования.
Реализуйте простую систему версионирования промптов для вашего проекта. Требования: 1) Промпты хранятся в файлах (не захардкожены), 2) Каждый промпт имеет версию, 3) Изменения промптов отслеживаются в git, 4) A/B-тестирование двух версий промпта легко реализуемо. Не нужен специализированный инструмент — папка с YAML/JSON-файлами и простой загрузчик вполне подходят.
Подсказка
Документируйте процесс и результаты — они послужат справочником для похожих задач в будущем.
Реализуйте 3-промптовый пайплайн для анализа документов: 1) Промпт 1 извлекает ключевую информацию из текста (сущности, факты, числа). 2) Промпт 2 анализирует извлечённую информацию и делает выводы. 3) Промпт 3 генерирует структурированный отчёт. Каждый промпт имеет собственную версию и конфигурацию модели. Измерьте качество: пайплайн или один большой промпт даёт лучшие результаты?
Подсказка
Пайплайны лучше работают для сложных задач, где каждый шаг требует разного рассуждения. Для простых задач накладные расходы излишни.
- Промпты меняются быстрее кода — им нужен собственный жизненный цикл
- Каждая версия промпта неизменяема, откат — это переключение конфигурации
- A/B-тестирование выявляет различия в качестве, которые вы пропускаете при ручном тестировании
- Логируйте версию промпта и модель при каждом вызове — без этого отладка невозможна
В следующем уроке мы разбираем оценку выводов ИИ: измерение качества — техника, которая даст вам явное преимущество. Разблокируйте полный курс и продолжайте прямо сейчас.
2/7 завершено — продолжайте!