Multi-Project Архитектура
Как организован ~/video-projects/, что лежит в каждом проекте, как Claude находит нужный проект из user-команды, что внутри project.yaml и brand.yaml.
Корневая директория
~/video-projects/ ├── director.db # ← shared SQLite (schema v8) ├── _specs/ # внутренние RFC и заметки по архитектуре ├── basdent/ # ← project 1 (стоматология) ├── apparatus/ # ← project 2 (медтехника B2B) ├── sweepstake/ # ← project 3 ├── performante-ai-agency/ # ← project 4 (внутренний — собственное агентство) └── ...другие проекты...
director.db лежит в КОРНЕ ~/video-projects/, а НЕ в папке отдельного проекта. Все db.py скрипты ищут БД на один уровень выше своей --project-dir. Если ты запустил db.py внутри ~/video-projects/basdent/scripts/ и БД пустая — посмотри уровнем выше.
Структура одного проекта
~/video-projects/basdent/ ├── project.yaml # ← главный конфиг проекта ├── brand.yaml # ← для creative-* скиллов (colors/fonts/voice) ├── brief.md # ← бриф клиента (что за бизнес, услуги, тон) ├── api_keys.db # ← per-project API keys (опционально) │ ├── references/ # ← reference photos для Veo / Gemini Image │ ├── ref_doctor_avatar.jpg │ ├── ref_clinic_interior.png │ └── ref_xray_machine.jpg │ ├── creatives/ # ← шаблоны creative-reference для разных услуг │ ├── checkup.md # ← reference creatives для услуги «чекап» │ ├── implants.md │ └── braces.md │ ├── transcripts/ # ← расшифровки лучших клиентских роликов │ ├── client_2024_q4_top1.txt │ └── ... │ ├── clips/ # ← клипы из Veo / user-uploaded (физические файлы) │ ├── clip_001_doctor_smile.mp4 │ ├── clip_002_office_pan.mp4 │ └── ... │ ├── voiceovers/ # ← сгенерированные .mp3 (ElevenLabs) ├── videos/ # ← готовые .mp4 (после director'а) ├── posters/ # ← статика (после creative-poster) │ └── carousel_/ # ← одна папка на одну карусель │ └── slides/ # ← PNG-секвенция слайдов │ ├── carousel-remotion/ # ← per-project Remotion app для каруселей (NPM-проект) │ ├── package.json │ ├── src/ │ │ └── ... │ └── public/photos/ # ← копии refs для slides │ ├── explainer-remotion/ # ← per-project Remotion app для explainer-видео │ ├── package.json │ └── ... │ └── prfmnt-creo/ # (опционально) кастомный final-output dir # см. project.yaml → final_output_dir
Зачем `carousel-remotion/` и `explainer-remotion/` per-project?
Чтобы можно было редактировать TSX-шаблоны под конкретного клиента не ломая других. init_project.py копирует remotion_template/ из скилла в проект и патчит src/lib/brand.ts цветами из brand.yaml. Если клиенту нужен особенный layout слайда — правится TSX в его папке.
project.yaml — главный конфиг
Это «паспорт» проекта. Все скиллы читают project.yaml при старте и берут оттуда параметры (вместо хардкода или повторного спрашивания юзера).
name: "Bas Dent" # отображаемое имя
slug: basdent # машинное имя = имя папки
niche: dentistry # для матчинга на competitor_refs.niche
city: Almaty
language: ru
# Бизнес-контекст
service_directions:
- slug: checkup
name: "Чекап (consultation)"
description: "Первый приём с осмотром и снимком"
price: "10 000 ₸"
reference_creatives: "creatives/checkup.md"
- slug: implants
name: "Импланты"
description: "..."
price: "от 250 000 ₸"
reference_creatives: "creatives/implants.md"
# Demographics для Veo
veo:
demographics:
age_range: "25-50"
gender_skew: "60% female"
region: "Almaty / Kazakhstan"
scene_context: |
Modern dental clinic in Almaty. Patients are middle-class
Kazakhstanis, doctors are local. NO equipment branding visible.
# Voiceover settings
voiceover:
default_voice_id: "21m00Tcm4TlvDq8ikWAM" # ElevenLabs
model: eleven_multilingual_v2
speed: 1.0
# Director settings
director:
aspect: "9:16" # default output aspect
fps: 30
transitions: "cuts_only" # cuts_only / fades / mixed
music_ducking: -10 # dB under voiceover
default_music_volume: 0.20 # 0.20 для TTS, 0.08 для real-mic
# Captions settings
captions:
style: karaoke # karaoke / bold / minimal / pop / tiktok
language: ru
highlight_color: "#FFD700"
# Brand для Remotion (motion graphics)
remotion:
brand:
primary: "#0B5FAE"
accent: "#FFD700"
font_display: Unbounded
font_body: Manrope
# Опционально — кастомный final-output для готовых видео
# (по умолчанию это videos/ внутри проекта)
final_output_dir: "/Users/anatolijstepanov/Desktop/basdent_final/"
# Опционально — Meta Ads config (для perf-import)
meta:
ad_account_id: "act_804392739179929"
page_id: "123456789"
pixel_id: "..."
name, slug, niche, city, language. Остальное опционально (скиллы используют дефолты). Полный конфиг постепенно достраивается по мере роста клиента.
brand.yaml — для creative-* скиллов
Отдельный файл потому что brand.yaml — это про визуальный стиль (как выглядят креативы), а project.yaml — про бизнес-логику (что за услуги / какой voiceover). Творческие команды могут править brand.yaml не лазая в project.yaml.
name: "Bas Dent"
tagline: "Стоматология нового поколения"
colors:
primary: "#0B5FAE" # основной (для bg, headlines)
navy: "#062A5C" # тёмный bg
cyan: "#00BFFF" # accent для подзаголовков
red: "#E63946" # для пометок «акция», urgency
gold: "#FFD700" # для PROFIT-цифр (без кнопки!)
white: "#FFFFFF"
text_dark: "#0E1B2C"
fonts:
headline: Unbounded
body: Manrope
voice:
tone:
- дружелюбный
- экспертный
- без агрессии
- короткие предложения
forbidden_words:
- дешево
- распродажа
- акция только сегодня
- последний шанс
references:
- path: "references/ref_doctor_avatar.jpg"
role: "doctor face"
notes: "Используется в hero shots"
- path: "references/ref_clinic_interior.png"
role: "clinic interior"
# Для creative-explainer-video — VO settings (если отличаются от project.yaml)
vo:
provider: elevenlabs
voice_id: "21m00Tcm4TlvDq8ikWAM"
model: eleven_multilingual_v2
stability: 0.5
similarity_boost: 0.7
Project resolution — как Claude находит проект
Когда юзер пишет «сделай 3 ролика для basdent», video-orchestrator резолвит target project по такой логике:
| Приоритет | Источник | Пример |
|---|---|---|
| 1 | Explicit slug в команде | «для basdent» → ~/video-projects/basdent/ |
| 2 | Explicit path в команде | «в ~/video-projects/apparatus» |
| 3 | State-файл текущего проекта | ~/.claude/state/current-project.json (опционально) |
| 4 | Спросить юзера | «Какой проект: basdent / apparatus / sweepstake?» |
--project-dir или --project <slug> своим скриптам. Никогда не предполагай «текущий проект» в Python-скриптах — это путь к багам когда юзер работает с двумя проектами параллельно.
Как создать новый проект
Используй скилл video-project-setup:
You: «добавь новый проект для клиники Boston Dental в Шымкенте» → skill запускается, задаёт уточняющие вопросы: - slug? (boston-dental) - niche? (dentistry) - city? (Shymkent) - language? (ru) - service_directions? (чекап, импланты, виниры?) → создаёт ~/video-projects/boston-dental/ со всей структурой → генерит project.yaml (минимальный) → генерит brief.md (с шаблоном) → создаёт references/, creatives/, voiceovers/, videos/ папки → регистрирует в `projects` таблице через INSERT → опционально: линкует voices/music от других проектов
После этого можно сразу запускать любой пайплайн.
Cross-project ресурсы (junction-таблицы)
Один клип / голос / музыка может принадлежать нескольким проектам. Это полезно для evergreen-материалов (например, общий B-roll для всех стоматологий).
Механика: ресурс лежит в основной таблице (clips, voices, music), связь с проектом — в junction-таблице (project_clips, project_voices, project_music).
-- Добавить клип, который доступен и basdent, и boston-dental INSERT INTO clips (path, description, duration) VALUES (...); -- clip_id = 42 INSERT INTO project_clips (project_id, clip_id) VALUES (1, 42); -- basdent INSERT INTO project_clips (project_id, clip_id) VALUES (5, 42); -- boston-dental
Подробнее по всем junction-таблицам и SQL-запросам — на странице БД.
API-ключи: где хранятся и как резолвятся
3 источника, в порядке приоритета:
--api-key <key>аргумент CLI (для тестов)~/video-projects/<slug>/api_keys.db— per-project SQLite-таблицаapi_keys (name, value)$GOOGLE_API_KEY,$ELEVENLABS_API_KEY, и т.д. в env
Per-project хранение нужно когда у одного клиента свой ElevenLabs-аккаунт (разделение биллинга), у другого — другой Gemini API-key. По дефолту берём из env.
Что лежит в `_specs/`
Внутренние RFC и заметки по архитектуре. Не обязательно для запуска системы, но полезно если хочешь понять «почему так сделано».
~/video-projects/_specs/ ├── 2025-10-multi-project-design.md # как пришли к junction-tables ├── 2025-12-creative-poster-rules.md # почему запрещены CTA-кнопки в poster ├── 2026-01-gr1-preview-pages.md # обоснование GR-1 └── ...
🔓 Backend-agnostic (2026-05-19)
Higgsfield AI был required dependency для нескольких частей системы. После аудита в мае 2026 — стал опциональным backend. Higgsfield дёргаем только там где он реально незаменим. Остальные пути — local или альтернативные провайдеры.
До → после
| Часть pipeline | Было (Higgsfield-required) | Стало (backend-agnostic) |
|---|---|---|
| Brand auto-fetch при онбординге | higgsfield marketing-studio brand-kits fetch --url |
DEFAULT = scripts/brand_fetch.py (BeautifulSoup + meta theme-color + CSS HEX + Google Fonts detection + logo extraction). Higgsfield через --use-higgsfield только если local confidence < 0.5 |
| Product page parsing | higgsfield marketing-studio webproducts fetch --url |
DEFAULT = scripts/product_fetch.py (schema.org Product JSON-LD + OpenGraph + gallery scraping для Shopify/WooCommerce/Amazon) |
| Product-photoshoot (10 modes) | higgsfield product-photoshoot create --mode |
DEFAULT = Gemini 3 Pro Image через creative-poster с явными prompt templates для всех 10 modes. Higgsfield opt-in только для auto-branding с brand_kit_id |
| Scene regen в video-clone-competitor | Жёстко video-clipgen-higgsfield/gen_video.sh |
regenerate.py --backend {auto | higgsfield | veo}. Auto разводит сцены: Soul-ID / cinematic camera → Higgsfield; generic → direct Veo. ~50% экономия. |
| MCSLA prompt knowledge | Документировался как Higgsfield-specific | Явная пометка: backend-agnostic — MCSLA, 10 жанров, Cinema Studio docs работают для Veo / Sora / Runway / Luma / Pika тоже |
Что осталось Higgsfield-only (и почему оправдано)
- Soul-ID face training — единственный generally-available video AI provider с persistent face training. Veo/Runway/Sora не умеют. Mitigation: используется только для проектов где critical face consistency (talking-head, founder-led ads).
- Cinematic Studio V2/V3 camera moves (robo-arm orbit, vertigo, FPV drone, dolly zoom) — Veo не контролирует надёжно. Mitigation: auto-routing в clone-competitor определяет это по keywords в MCSLA.camera и направляет только нужные сцены через Higgsfield.
- Marketing Studio auto-branding (логотип + цвета overlay) — опционально, только если есть
brand_kit_idот прошлого auto-fetch И юзер явно хочет.
Cost reduction (реальные примеры)
| Сценарий | Old (Higgsfield-heavy) | New (mixed/local) | Savings |
|---|---|---|---|
| Brand auto-fetch при онбординге | $0.06 | $0.00 | 100% |
| 5 static ad creatives | $1.00 (Higgsfield) | $0.20 (Gemini) | 80% |
| 10-сценовый clone reel | $10-15 | $5-7 (auto-routing) | ~50% |
| Cinematic founder portrait orbit | $1.50 | $1.50 (Higgsfield-only) | 0% — оправдано |
Финальная картина зависимостей
┌─────────────────────┐
┌──────────────────────────│ HARD dependencies │
│ │ (нельзя убрать) │
│ └─────────────────────┘
│
↓
Higgsfield CLI/Cloud (Soul-ID + Cinematic Studio camera moves)
Google Cloud Veo 3.1 (direct video gen — основной video backend)
ElevenLabs (TTS — single-vendor для voiceover)
Anthropic Claude (LLM — single-vendor для in-session reasoning)
Google Gemini 3 Pro Image (Image gen — основной static backend)
┌─────────────────────┐
┌──────────────────────────│ Now backend- │
│ │ agnostic │
│ └─────────────────────┘
↓
Brand/product extraction → local scraper (default) → Higgsfield (optional)
Image gen → Gemini (default) → Higgsfield (when auto-branding)
Video regen в clone → direct Veo (default) → Higgsfield (Soul-ID/camera only)
Instagram discovery / analysis → HikerAPI (no Higgsfield)
Concept generation → LLM in-session (no external API)
Дальше
- База данных — schema v8 в деталях, все таблицы, junction-таблицы, типичные запросы
- Пайплайны — пошаговые flow для всех 4 типов выхода + 3 новых intelligence pipelines
- video-project-setup — как именно создаётся новый проект (+ auto-fetch brand)
- trend-picker — auto-concept generation upstream layer
- video-clone-competitor — scene-by-scene rebuild