video-copywriter
AI-копирайтер агентства Performante. Пишет тексты, которые потом озвучивает ElevenLabs и которые становятся voiceover-скриптами для рекламных роликов. 7 типов текстов — от storytelling до адаптации конкретного конкурентного креатива.
Что делает простыми словами
Это копирайтер, который знает 7 разных «форматов» рекламного текста. Юзер говорит «напиши текст про импланты в стиле storytelling» — а скилл:
- Читает
project.yaml→ понимает нишу, язык, направления услуг - Читает
brief.md→ знает бизнес-контекст, ЦА, УТП - Читает
creatives/<direction>.md→ видит лучшие тексты этого направления для референса - Читает transcriptions из БД → знает что у клиента уже хорошо сработало
- Читает последние 10 текстов → чтобы не повторяться
- Пишет новый текст в выбранном из 7 типов
- Сохраняет в
generated_textsс привязкой к проекту черезproject_texts
Дальше этот текст подхватывает voiceover и озвучивает.
SKILL.md — это набор инструкций «как писать», который грузится в контекст. Сами тексты пишет Claude (то есть мы), а скрипты только сохраняют/читают.
Core принципы (что отличает текст, который конвертит)
7 типов текстов
1. STORYTELLING
Личный нарратив, который втягивает через общую боль и арку трансформации. Структура: hook с болью + hook to stay («досмотри до конца — расскажу как») → проблема ДО → discovery → как работает → results + social proof → CTA. От первого лица. Числа везде.
2. DIRECT OFFER
Максимальная компрессия. Формула: измеримый результат + срок + safety + CTA. Самый короткий формат. Каждое слово отрабатывает. Если цена — конкурентное преимущество или промо — лидируем ценой.
3. EXPERT VIDEO
Educational контент. Структура: viral hook (вопрос / триггер по deep pain) → expert-объяснение через бытовые аналогии → решение → CTA с оффером (если есть промо). Позиционирует бизнес как авторитета, потом мягко переходит к оферу.
4. TELEGRAM POST
Информационный/educational, НЕ direct selling. 500-1000 символов. Структура: интересный факт/инсайт → развитие темы (полезная инфа) → soft conclusion (можно вопрос аудитории, без жёсткого CTA). Строит экспертизу через контент. Можно bold и абзацы.
5. THREADS POST
Короткий, провокативный, на engagement. 100-280 символов. Структура: bold statement / неожиданный вопрос → краткое объяснение (1-2 фразы, опц.) → вопрос аудитории. Должен триггерить комментарии. Без явной рекламы.
6. TEXTOVER HOOK
Структурированный текст для анимированного оверлея на видео (без voiceover). Рендерится Remotion'ом. Видео 15 сек, каждый блок появляется поочерёдно с анимацией. Строгая структура из 4 блоков:
OFFER: Имплантация зубов за 1 день без боли BULLET: • Гарантия 10 лет BULLET: • Без разрезов и швов BULLET: • Бесплатный КТ-снимок PROFIT: Рассрочка 0% на 12 месяцев CTA: Записаться на консультацию
| Блок | Лимит | Правило |
|---|---|---|
| OFFER | 1 строка, 6-12 слов | Hook, останавливающий скролл |
| BULLETS | ровно 3, по ≤5 слов | НЕ повторять слова из OFFER |
| PROFIT | 1 короткая строка | Бонус/промо, НЕ дублирует OFFER/BULLETS |
| CTA | 2-5 слов | НЕ повторяет OFFER |
Это не сценарий — это billboard copywriting. Каждый блок 2-4 сек на экране.
7. REFERENCE (адаптация конкурента)
Самая важная фича скилла. Адаптирует конкретный конкурентный креатив под нашего клиента. Использует таблицу competitor_refs, которая наполняется из tools/dentistry-research/ через npm run stage6.
info_score (0..100) — приоритизация рефересов
Каждый импортированный креатив имеет info_score — это композитный показатель «насколько он informative + operationally heavy». Чем выше — тем больше у нас «мяса» для адаптации.
| Компонент | Weight | Откуда |
|---|---|---|
длина transcript | 25 | analysis.transcript (озвучка видео — самое богатое) |
| длительность активности рекламы | 18 | creatives.total_active_time (proxy для ROI) |
| сколько креативов всего у клиники | 15 | derived из creatives table (proxy для marketing maturity) |
длина body_text | 12 | creatives.body_text (FB caption) |
| variations (A/B count) | 9 | creatives.ads_count (сколько ротировались A/B) |
| currently active | 9 | creatives.is_active (крутится ли прямо сейчас) |
| длина OCR-текста | 8 | analysis.ocr_text (текст на картинке) |
| длина scene_description | 4 | analysis.scene_description |
--min-score 50 и ORDER BY score DESC. Stick to that:
- ≥70 — rare (~1% всех импортов), top-tier от больших клиник с long-running active video
- 50..69 — bulk usable refs
- <50 — обычно короткие image-only креативы или untested one-offs. Bad raw material
Reference workflow (тип 7)
1. Определить направление
Юзер упомянул услугу («имплантация», «брекеты», etc.). Мапим на global slug (см. PROJECT_SLUG_TO_GLOBAL в db.py) или берём project slug напрямую.
2. Список кандидатов
python ~/.claude/skills/video-copywriter/scripts/db.py list-competitor-refs \ <project-dir> \ --direction implantation \ --language ru \ --limit 10 \ --min-score 50 # → #142 [s73] [implantation] A/- BasDent / Алматы / ru / video | Верните зубы за один... # → #98 [s64] [implantation] -/- White / Астана / ru / video | Болят зубы?...
Каждая строка: #<id> [s<score>] [direction] A/- <clinic> / <city> / <lang> / <media_type> | <preview>.... Если 0 результатов — дропнуть порог до 30, потом до 0; сказать юзеру.
3. Выбрать один
Либо юзер выбирает по ID, либо берём top-scored. Скажи, какой ref выбрал и почему (score + ещё одна причина — city match, similar service, strong hook).
4. Загрузить полный контент
python ~/.claude/skills/video-copywriter/scripts/db.py get-competitor-ref <project-dir> 142 # → JSON c полями: transcript, body_text, ocr_text, scene_description, # clinic_name, service_direction, headline, cta_type
5. Идентифицировать source text
Приоритет: transcript (озвучка — самое богатое) → body_text (FB caption) → ocr_text (текст на картинке). Это то, что адаптируем.
6. Адаптировать, сохраняя формат
| Сохранить | Заменить | Избегать |
|---|---|---|
| Структура, sentence rhythm, hook style | Название клиники → клиент (из brief) | Литеральное копирование |
| Эмоциональная арка | Цены, услуги, сроки → клиентские данные | Добавление своих структурных элементов |
| Наличие/отсутствие CTA как в источнике | Город | Микс двух креативов |
| Длина/компактность | Имена врачей, отзывы → наши (или опустить) | Push в сторону какого-то из 6 других типов |
7. Сохранить с привязкой
python ~/.claude/skills/video-copywriter/scripts/db.py save-text <project-dir> \ --type reference \ --competitor-ref-id 142 \ --text "<adapted text>" \ --for-video
--competitor-ref-id сохраняет линк на источник — для будущего анализа «что мы у кого адаптировали».
Команды
Загрузить контекст проекта
python ~/.claude/skills/video-copywriter/scripts/db.py get-brief <project-dir> python ~/.claude/skills/video-copywriter/scripts/db.py list-transcriptions <project-dir> --json python ~/.claude/skills/video-copywriter/scripts/db.py list-texts <project-dir> --json --limit 10
Сохранить сгенерированный текст
python ~/.claude/skills/video-copywriter/scripts/db.py save-text <project-dir> \ --type storytelling \ --text "<текст>" \ --for-video
--for-video — флаг «это voiceover-скрипт» (vs social post). По нему voiceover потом находит готовые к озвучке тексты.
Управление transcriptions (best-performing client creatives)
python ~/.claude/skills/video-copywriter/scripts/db.py add-transcription <project-dir> \ --text "<транскрипт лучшего ролика клиента>" \ --score 85 python ~/.claude/skills/video-copywriter/scripts/db.py list-transcriptions <project-dir> --json
Получить конкретный текст
python ~/.claude/skills/video-copywriter/scripts/db.py get-text <project-dir> <text-id>
Voiceover length guidelines
Тексты часто становятся voiceover-скриптами на 1.2× speed:
| Target длительность видео | Слов (русский) | Символов |
|---|---|---|
| 15 секунд | 35-45 | 200-300 |
| 30 секунд | 70-90 | 400-600 |
| 45 секунд | 100-130 | 600-900 |
| 60 секунд | 130-170 | 900-1200 |
Это rough guides. Точную длительность даст voiceover после TTS.
Mandatory pre-flight: загрузить reference creatives
ВСЕГДА перед генерацией — прочитать project.yaml → service_directions, и для каждого direction открыть creative_ref файл. Пример:
service_directions:
- slug: "implantation"
name: "Имплантация зубов"
creative_ref: "creatives/implantation.md"
Без этого скилл пишет «в пустоту» — без знания, какие тексты в нише уже отрабатывают.
competitor_refs вместо creative_ref файлов. Если тип 1-6 — игнорируем competitor_refs, опираемся на brief + transcriptions + creative_ref.
Внутренности
Скрипты
| Файл | Что делает |
|---|---|
scripts/db.py | CRUD по generated_texts, transcriptions, brief reader, competitor_refs list/get (project-scoped через junction) |
scripts/schema.py | Schema source-of-truth (v8) — копия одинакова во всех скиллах |
Таблицы БД, которые трогает
| Таблица | Действие | Зачем |
|---|---|---|
brief | Read | Бизнес-контекст, ЦА, УТП |
transcriptions | Read / INSERT | Лучшие тексты клиента — для тона/стиля |
generated_texts | INSERT / Read | Все генерации (новые и для проверки «не повторяться») |
project_texts | INSERT | Junction: scope текста к проекту |
competitor_refs | Read | Импортированные конкурентные креативы (для type 7) |
Конфиг из project.yaml
language: "ru" # язык генерации
niche: "Стоматология" # для контекста
service_directions: # обязательно для пред-загрузки
- slug: "implantation"
name: "Имплантация зубов"
creative_ref: "creatives/implantation.md"
- slug: "checkup"
name: "Чекап полости рта"
creative_ref: "creatives/checkup.md"
Gotchas и tips
list-texts --limit 10. Если последние 3 текста были storytelling — переключайся. Если все три были про «гарантию 10 лет» — найди другой angle.
--type textover_hook + --for-video = именно textover-pipeline.
--min-score 70. Если в нише по 50+ пусто — дропни до 30, потом до 0, и скажи юзеру что сделал и почему.
Место в пайплайне
Copywriter = первое звено генерации. Без него не существует, что озвучивать. Опирается на материалы из analyzer (transcriptions) и project setup (creative_ref файлы).
Источники контекста: brief.md (бизнес), creatives/*.md (примеры от клиента), transcriptions table (transcripts его лучших роликов), competitor_refs table (только для type 7). Выход: запись в generated_texts с привязкой через project_texts.