П/ВИН

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

·9 мин чтения
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 слайдов выглядят так:

  1. Титул с именем клиента и обещанием
  2. Контекст рынка (макро-данные, актуальность)
  3. Точка А — где клиент сейчас (из диагностики)
  4. Цена бездействия — что будет, если ничего не менять
  5. Before/After кейс — реальный пример трансформации
  6. Решение — суть программы
  7. Как это работает — механика программы
  8. Релевантные модули — 3-4 модуля из 10, подобранные под клиента
  9. Результаты — метрики, кейсы, отзывы
  10. ROI-калькулятор — персонализированный расчёт
  11. Программа и тарифы
  12. Следующий шаг — 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, вебхук триггерит деплой, готово.

Но нет. Вебхук был настроен на ветку, которая не совпадала с основной. В результате деплой не триггерился автоматически. Пришлось:

  1. Найти нужный контейнер среди нескольких сервисов на VPS
  2. Исправить настройку ветки в Dokploy
  3. Запустить деплой вручную через API
  4. Подождать, пока билд пройдёт (клонирование репо, 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 минут — это дёшево, но они случились только потому, что проверка была отложена на финал.

Система сейчас работает и готова к первым реальным генерациям. Следующий шаг — прогнать несколько реальных транскриптов диагностик через пайплайн, посмотреть на качество промтов, скорректировать шаблоны через админку без единого деплоя. Именно для этого и строилась вся эта архитектура.


Технологии в проекте:

Паша Вин
Паша Вин

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

Связанный проект

Slides Generator