KP-Generator: автоматизация B2B-презентаций с AI

Однажды я поставил себе задачу, которая звучит немного самонадеянно: сделать самую лучшую в мире КП-презентацию для B2B. Не просто «хорошую» или «конверсионную» — а буквально лучшую, с опорой на реальные данные, кейсы Gong (67 тысяч записей звонков), исследования Prospeo 2026 и McKinsey. Оказалось, что путь от этой идеи до работающего инструмента — интересная инженерная история.
Откуда растут ноги
Контекст такой: есть консалтинговая программа «Секреты Корпорации» на базе Toyota/Lean, обещание — рост прибыли 20-30% за 3 месяца без найма. Целевая аудитория — собственники бизнеса. Продажи идут через живые звонки-диагностики, после которых клиент должен получить персонализированное КП.
Проблема была классическая: каждое КП собиралось руками, занимало время, выглядело одинаково и не использовало весь потенциал информации, полученной на диагностике. Хотелось автоматизировать процесс так, чтобы на входе был транскрипт звонка, а на выходе — готовая презентация на 12 слайдов с персонализированными данными, правильным нарративом и сильным визуалом.
При этом у нас уже существовал генератор документов на germanyou.online/generator — линейный визард, который через GPT-4o и @react-pdf/renderer делал PDF-документы. Бордово-золотая тема, базовая типографика, без особых изысков. Хорошо, но не «лучшее в мире КП».
Структура: выбор из трёх подходов
Первое решение, которое нужно было принять — структура самой презентации. Я изучил три подхода:
Структура A («Data-Driven Spine») — от Gong и Prospeo: проблема → цена бездействия → решение → доказательства → ROI. Очень аналитическая, работает на рациональных покупателей.
Структура B («Emotional Arc») — нарративный фреймворк Raskin's Arc: история трансформации, эмоциональный крюк, идентификация с кейсом. Хорошо работает на встречах лицом к лицу.
Структура C («Гибрид») — комбинация: начинаем с персонализированного контекста (данные из диагностики), строим эмоциональный нарратив, заземляем на ROI и реальных кейсах.
Выбрал гибрид — он сочетает силу обоих подходов. Итоговые 12 слайдов выглядят так:
- Титул с именем клиента и обещанием
- Контекст рынка (макро-данные, актуальность)
- Точка А — где клиент сейчас (из диагностики)
- Цена бездействия — что будет, если ничего не менять
- Before/After кейс — реальный пример трансформации
- Решение — суть программы
- Как это работает — механика программы
- Релевантные модули — 3-4 модуля из 10, подобранные под клиента
- Результаты — метрики, кейсы, отзывы
- ROI-калькулятор — персонализированный расчёт
- Программа и тарифы
- Следующий шаг — CTA
Архитектура системы
Вместо того чтобы делать отдельный инструмент, я встроил KP-модуль прямо в существующий генератор. Добавил трёхтабный layout поверх текущего линейного визарда:
┌─────────────────────────────────────────────────┐
│ Генератор документов │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Документы │ │Презентация│ │ Админ │ │
│ │ (PDF) │ │ (КП) │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────┘
Таб «Документы» — старый функционал без изменений. Таб «Презентация» — новый KP-генератор. Таб «Админ» — полный контроль над всем.
Пайплайн генерации выглядит так:
Транскрипт звонка
↓ (существующий GPT-промт)
Структурированная диагностика (pointA[], keyFindings[])
+
program-content.ts (10 модулей)
+
Реальные кейсы
+
Данные клиента (имя, бизнес, тариф)
↓
МЕТА-ПРОМТ (двухфазная генерация)
↓
12 персонализированных Stitch-промтов
↓
HTML-слайды → PDF или Google Slides
Ключевое решение — двухфазная генерация промтов. На первой фазе мета-промт анализирует диагностику и выбирает релевантные модули, кейсы, рассчитывает monthly_loss и другие персонализированные метрики. На второй фазе эти данные инжектируются в шаблоны конкретных слайдов.
База данных: схема kp в Supabase
Для хранения конфигурации слайдов, кейсов и настроек создал отдельную схему в Supabase:
-- Слайды с шаблонами промтов
CREATE TABLE kp.slides (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
order_index INTEGER NOT NULL,
title TEXT NOT NULL,
enabled BOOLEAN DEFAULT TRUE,
stitch_prompt_template TEXT NOT NULL,
variables JSONB DEFAULT '[]',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Реальные кейсы
CREATE TABLE kp.cases (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
company_type TEXT NOT NULL,
before_state TEXT NOT NULL,
after_state TEXT NOT NULL,
metrics JSONB NOT NULL,
enabled BOOLEAN DEFAULT TRUE
);
-- Дизайн-система
CREATE TABLE kp.design_settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);
-- Настройки промтов
CREATE TABLE kp.prompt_settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);
-- Сессии генерации
CREATE TABLE kp.generation_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
client_name TEXT NOT NULL,
input_data JSONB NOT NULL,
generated_prompts JSONB,
status TEXT DEFAULT 'pending',
created_at TIMESTAMPTZ DEFAULT NOW()
);Пять таблиц покрывают весь функционал: слайды с шаблонами, кейсы для вставки в слайды, дизайн-система (цвета, шрифты), настройки промтов и история генераций.
API: 6 роутов на Next.js
Весь backend — это 6 API роутов в рамках Next.js App Router:
// /api/generator/kp/slides - CRUD для слайдов
export async function GET() {
const { data, error } = await supabase
.from('kp.slides')
.select('*')
.order('order_index');
if (error) return NextResponse.json({ error }, { status: 500 });
return NextResponse.json(data);
}
export async function PUT(req: Request) {
const body = await req.json();
// Обновление слайда + переорdering
const { data, error } = await supabase
.from('kp.slides')
.update(body)
.eq('id', body.id)
.select();
if (error) return NextResponse.json({ error }, { status: 500 });
return NextResponse.json(data[0]);
}Роуты:
GET/PUT /api/generator/kp/slides— управление слайдамиGET/PUT /api/generator/kp/cases— управление кейсамиGET/PUT /api/generator/kp/settings— дизайн и промт-настройкиPOST /api/generator/kp/generate— двухфазная генерация промтов
Двухфазная генерация — самое интересное место:
export async function POST(req: Request) {
const { clientData, diagnosticData } = await req.json();
// Фаза 1: мета-анализ диагностики
const metaPrompt = buildMetaPrompt(clientData, diagnosticData);
const metaResult = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: metaPrompt }],
response_format: { type: 'json_object' }
});
const enrichedData = JSON.parse(metaResult.choices[0].message.content);
// enrichedData содержит: relevantModules, selectedCase, monthly_loss, roi, etc.
// Фаза 2: генерация промтов для каждого слайда
const slides = await getEnabledSlides();
const generatedPrompts = slides.map(slide => ({
slideId: slide.id,
title: slide.title,
prompt: interpolateTemplate(slide.stitch_prompt_template, {
...clientData,
...enrichedData
})
}));
// Сохраняем сессию
await saveGenerationSession(clientData, generatedPrompts);
return NextResponse.json({ prompts: generatedPrompts });
}Админка: полный контроль без деплоя
Самая важная часть — это именно админ-панель. Идея простая: я не хочу деплоить каждый раз, когда нужно поменять формулировку в промте слайда или добавить новый кейс.
Админка состоит из 4 секций:
Секция «Слайды» — drag-and-drop менеджер с inline-редактором:
┌─────────────────────────────────────────────────────┐
│ Слайды презентации [+ Добавить] │
│─────────────────────────────────────────────────────│
│ ≡ 1. Титул 🟢 [✏️] [🗑️] │
│ ≡ 2. Контекст рынка 🟢 [✏️] [🗑️] │
│ ≡ 3. Точка А 🟢 [✏️] [🗑️] │
│ ... │
└─────────────────────────────────────────────────────┘
Кликаешь на карандаш — открывается редактор с полем для шаблона промта, списком переменных, превью. Меняешь, сохраняешь — следующая генерация уже использует новый промт.
Секция «Дизайн-система» — контроль над визуалом: акцентный цвет (выбрали насыщенный благородный красный), шрифты, отступы, стиль карточек.
Секция «Кейсы» — добавление и редактирование реальных историй трансформации с метриками.
Секция «Настройки» — параметры промтов: модель, температура, системный промт для мета-анализа.
Seed data: 12 дефолтных промтов
Для быстрого старта написал seed-файл с дефолтными промтами для всех 12 слайдов. Каждый промт содержит:
- Описание визуальной раскладки (Bento Grid или классика)
- Инструкции по типографике
- Плейсхолдеры для персонализированных данных
- Указания по цветовой схеме
Пример шаблона для слайда «Точка А»:
{
title: 'Точка А — текущая ситуация',
order_index: 3,
stitch_prompt_template: `
Create a professional B2B presentation slide.
Style: Light minimal, accent color {{accent_color}}, white background.
Layout: Bento grid with 3-4 cards.
Title: «{{client_name}}, вот где вы сейчас»
Cards content:
{{#each point_a_items}}
- Card: {{this.metric}}: {{this.current_value}}
Subtext: {{this.context}}
{{/each}}
Bottom bar: key finding from diagnostics:
"{{key_finding_quote}}"
Typography: Bold numbers, muted labels.
No decorative elements, data-first.
`,
variables: ['client_name', 'accent_color', 'point_a_items', 'key_finding_quote']
}Визуальный стиль — светлый минимализм с насыщенным красным акцентом. Из трёх вариантов (тёмный премиум а-ля Apple, светлый минимал а-ля McKinsey, бордо+золото как в текущем генераторе) выбрали именно светлый + красный. Он передаёт энергию и уверенность, но не перегружает слайд — данные читаются легко.
Деплой: неожиданные грабли
После написания 3261 строки кода в 21 файле пришло время деплоя на Dokploy. Казалось бы, всё просто: запушил на main, вебхук триггерит деплой, готово.
Но нет. Вебхук был настроен на ветку, которая не совпадала с основной. В результате деплой не триггерился автоматически. Пришлось:
- Найти нужный контейнер среди нескольких сервисов на VPS
- Исправить настройку ветки в Dokploy
- Запустить деплой вручную через API
- Подождать, пока билд пройдёт (клонирование репо, npm install, next build)
Локально билд проходил чисто — next build без единой ошибки, все 6 API роутов видны, все страницы компилируются. На сервере воспроизвелось то же самое после правки ветки.
Урок: всегда проверяй настройку вебхука сразу после подключения репо к Dokploy, не жди до финального деплоя.
Что получилось в итоге
За несколько сессий разработки система прошла путь от идеи до работающего модуля:
- 21 новый файл — типы, API роуты, компоненты, seed data
- 3261 строка кода на TypeScript
- 5 таблиц в Supabase для хранения конфигурации
- 6 API роутов с полным CRUD
- 12 слайдов с детальными Stitch-промтами
- Двухфазная генерация — сначала мета-анализ диагностики, потом персонализированные промты
- Полная админка — слайды, дизайн-система, кейсы, настройки промтов
Выводы и уроки
Главный вывод этого проекта: граница между «набором промтов» и «полноценным продуктом» очень тонкая. Мы начали с идеи просто написать хорошие Stitch-промты для каждого слайда — и достаточно быстро пришли к тому, что нужна система управления этими промтами, система управления кейсами, дизайн-система и история генераций. Это классическая ловушка, но в данном случае она оправданная: без администрирования инструмент превращается в ещё один текстовый файл, который никто не будет обновлять.
Второй урок — важность двухфазной архитектуры генерации. Первый инстинкт был сразу инжектировать данные диагностики в шаблоны слайдов. Но тогда каждый шаблон должен был бы содержать сложную логику выбора релевантных модулей, расчёта ROI, выбора подходящего кейса. Вынос этой логики в мета-промт (фаза 1) сделал шаблоны слайдов простыми и редактируемыми даже для нетехнического пользователя.
Третий урок — ценность персонализации. Исследования (в том числе данные Gong по 67К звонкам) показывают, что персонализированные предложения конвертируют в 3+ раза лучше шаблонных. Всё, что было сделано в этом проекте — сложная архитектура, двухфазная генерация, плейсхолдеры — служит одной цели: чтобы каждый слайд содержал имя клиента, его реальные цифры из диагностики, релевантный кейс из его отрасли. Это не «красивее», это «работает лучше».
Четвёртый урок — про деплой и инфраструктуру. Сколько бы ни был хорош код, если вебхук настроен на неправильную ветку, ничего не задеплоится. Инфраструктурные вещи нужно проверять в самом начале, а не в конце. Потраченные на отладку деплоя 30 минут — это дёшево, но они случились только потому, что проверка была отложена на финал.
Система сейчас работает и готова к первым реальным генерациям. Следующий шаг — прогнать несколько реальных транскриптов диагностик через пайплайн, посмотреть на качество промтов, скорректировать шаблоны через админку без единого деплоя. Именно для этого и строилась вся эта архитектура.
Технологии в проекте:
- Next.js App Router — фреймворк и API роуты
- Supabase — PostgreSQL + PostgREST
- TypeScript — типизация всего
- OpenAI API — GPT-4o для генерации
- Dokploy — деплой и оркестрация контейнеров

AI-инженер, предприниматель, маркетолог. Основатель feberra.com и x10seo.ru. 13 лет в перфоманс-маркетинге, 3 года в системной интеграции AI в бизнес.
Связанный проект
Slides Generator →