Я навайбкодил систему для производства квизов
Павел Королев
Этот доклад о пет-проекте из хобби
Это моя площадка для экспериментов с агентами
План
Квизы
Масштаб
Редактор
База данных
Экспорт
Выводы
Паб-квиз
ПакетУгадай мелодию «Рок»
Раунд 1Разминка
Раунд 2На букву L / Л
Раунд 3Один главный хит + Страны мира
Раунд 4Цвета
Раунд 5Блиц
- 01Назовите группу
- 02Назовите исполнительницу
- 03Назовите исполнителя
- 04Назовите группу
- 05Назовите исполнителя
- 06Назовите группу
- 07Назовите исполнительницу
- 08Назовите группу
- 09Назовите исполнителя
- 10Назовите группу
- 01Назовите исполнителя
- 02Назовите группу
- 03Назовите группу
- 04Назовите исполнительницу
- 05Назовите исполнителя
- 06Назовите группу
- 07Назовите исполнительницу
- 08Назовите группу
- 09Назовите исполнителя
- 10Назовите группу
Один главный хит
- 01Назовите исполнительницу
- 02Назовите группу
- 03Назовите исполнителя
- 04Назовите исполнителя
- 05Назовите группу
Страны мира
- 06Назовите группу
- 07Назовите исполнительницу
- 08Назовите исполнителя
- 09Назовите группу
- 10Назовите исполнителя
- 01Назовите группу
- 02Назовите исполнителя
- 03Назовите группу
- 04Назовите исполнительницу
- 05Назовите исполнителя
- 06Назовите исполнительницу
- 07Назовите группу
- 08Назовите исполнителя
- 09Назовите группу
- 10Назовите исполнительницу
- 01Назовите исполнительницу
- 02Назовите группу
- 03Назовите исполнителя
- 04Назовите группу
- 05Назовите исполнителя
- 06Назовите группу
- 07Назовите исполнительницу
- 08Назовите исполнителя
- 09Назовите исполнительницу
- 10Назовите группу
Играется в баре, команды обсуждают вопросы ведущего и сдают ответы в конце раунда на бланках
Экран вопроса
252423222120191817161514131211109876543210
Назовите группу
Экран ответа
Enter Shikari — The Mindsweep
Каждый игрок рано или поздно хочет написать свой пакет
Потому что в чужих всегда что-то не нравится
Всё началось с простой задачи
Сделать свой пакет для SIGame
Редактор был только под Windows
Windows у меня не было
Быстро навайбкодить свой редактор
Это было почти год назад

Видео по сценам
Коммиты по месяцам
РедакторБаза данных
Таймлайн
Редактор
Я не прочитал ни одной строчки кода
Я его не понимаю
Проблема
Продуктовая задача
Как я начал
01
Описать идею агенту своими словами
02
Попросить расписать требования
03
Почелленджить себя агентом
04
Обсудить реализацию и план
Стек, который предложил агент
- TypeScript
- React
- Electron
- Zustand
- yt-dlp
- ffmpeg
- Canvas
- WaveSurfer
- shadcn/ui
- MediaPipe
- Essentia.js
- TensorFlow.js
- Vite
- Tailwind CSS
- Vitest
- Playwright
Проблема
Без гардрейлов агент будет ломать то, что уже работает
Новые гардрейлы появляются всё время жизни проекта
Проблема
Агенты умеют делать только дженерик дизайн
Как собрать дизайн
01
Просим несколько вариантов в одной сессии
02
Отсматриваем глазами, отмечаем удачные
03
Просим собрать лучшее из отмеченных
Дизайн не бывает хорошим, если он не контекстный
Проблема
Точечные правки размывают архитектуру
Важные границы стоит задать как можно раньше
Границы бывают двух видов
Агент может сам себя удерживать в этих рамках
01
Попросить ревью архитектуры и его же решений
02
Каждое замечание отдельным пунктом
03
Пункты закрывают другие агенты
04
Умная модель анализирует, простая чинит
Модель данных тоже контракт, и её правки держим под контролем
Понятные контракты делают правки изолированными
Проблема
Агент ломает приложение, в котором уже лежат настоящие данные
Бэкап важного лучше завести как можно раньше
Формат пакета
Архив QZPПакетРаундТемаВопросаудиоОтветаудио · фото
ВопросаудиоОтветаудио · фото
Вопросаудио · фотоОтветаудио · фото
ТемаВопросаудиоОтветаудио · фото
ВопросаудиоОтветаудио · фото
Вопросаудио · фотоОтветаудио · фото
РаундТемаВопросаудиоОтветаудио · фото
ВопросаудиоОтветаудио · фото
Вопросаудио · фотоОтветаудио · фото
ТемаВопросаудиоОтветаудио · фото
ВопросаудиоОтветаудио · фото
Вопросаудио · фотоОтветаудио · фото
Догфудинг с агентом начинается с бэкапа
Проблема
Агент не чувствует, что интерфейсом неудобно пользоваться
Любое действие в приложении стоит покрыть аналитикой
Агент по метрикам может накидать идей
Проблема
Фичи делать дёшево, и их становится много
Дешёвый код не делает фичу нужной
Проблема
Когда начинаются проблемы, без понимания кода не сделать ничего
Проблемы производительности
01
Драг-н-дроп, ключевая функция в приложении
02
Начал тормозить из-за лишних перерисовок
03
У агента появилась возможность самому замерять производительность
04
Агент итерируется сам, пока не получит результат
Узлов DOM во время перетаскивания
С метриками агент видит, в ту ли сторону движется
Продуктовая задача
Вырезать нужный отрезок трека прямо в редакторе вопроса
Продуктовая задача
Находить фрагмент трека для каждого вопроса автоматически
Из чего складывается оценка отрезка
Контраст с окружением0,07
Демо: отрезок трека в редакторе вопроса
Алгоритм предлагает, человек правит при желании
Как любой продукт, редактор состоит из кучи мелочей
- Перетаскивание всего
- Аудиоредактор в карточке
- Автовыбор фрагмента
- Почему этот фрагмент
- Поиск и скачивание с YouTube
- Загрузки в фоне
- Автосохранение
- Бэкап всего проекта
- Валидация перед экспортом
- Хоткеи
- Поиск по пакету
- Дубль вопроса и пакета
- Цветные метки
- Замок на пакет
- Генерация из источника
- Замена вопроса через генератор
- Входящие предложения от агента
- Прогрессивная загрузка
- Аналитика без личных данных
- Экспорт в SIGame, HTML и видео
Демо: база артистов и треков
Продуктовая задача
Подбирать артистов и треки для пакета
Источник данных подключается к редактору как плагин
Стек второй системы тоже предложил агент
- Python
- SQLite
- JavaScript
- TypeScript
- http.server
- urllib
- Pillow
- MediaPipe
- dataclasses
- concurrent.futures
- JSON
- pre-commit
Продуктовая задача
Заполнить карточки артистов и треков данными из интернета
Как наполняется база
Код собирает факты из пяти сервисов
Сомнительно: поиск в интернете
Агент сам стал звеном пайплайна, который сам и написал
Продуктовая задача
Собрать из базы артистов и треков пакет вопросов
Что учитывает генератор
Сложность каждого вопроса
Баланс сложности внутри пакета
Баланс эпох
Баланс языков
Артисты не повторяются внутри пакета
Треки не повторяются между выпусками
Ничего заезженного
Темы и механики раундов
Темы генератора
- Разминка
- Фото
- Змейка
- Лесенка
- Алфавит
- Страны мира
- Классический рок
- Хард-рок
- Панк-рок
- Поп-панк
- Гранж
- Инди
- Альтернатива
- Пост-панк и new wave
- Эмо
- Nu-metal
- Core
- Фолк и фолк-рок
- Хип-хоп
- Трэп
- Андеграундный хип-хоп
- Фонк
- Грайм и дрилл
- Поп-хиты
- Инди-поп
- Синти-поп
- Дрим-поп
- K-pop
- Поп-рок
- Один главный хит
- Женский вокал
- Мужской вокал
- Соло-исполнители
- Группы
- Космос
- Профессии
- Два слова
- Транспорт
- Погода
- Цифры
- Животные
- Топонимы
- Цвета
- Имена
- Семейные узы
- Святые и грешники
- Символы
- Удвоенные буквы
Агент сам проверяет сценарии генерации бенчмарком
Бенчмарк генерации
Копия базы
Метрики повторов и сложности
Метрики и бенчмарки нужны даже продуктовым хотелкам
Продуктовая задача
Собрать раунд без его добавления в генератор
Демо: агент присылает раунд
Один вход для агента заменяет фичу под каждую идею
База и генератор тоже состоят из мелочей
- Один артист под разными именами
- Каверы, ремиксы, концертники
- Музыка, закрытая на YouTube
- Треки не повторяются между выпусками
- Артисты отдыхают между выпусками
- Память о сыгранных пакетах
- Сложность на лету
- Сложность артиста и трека врозь
- Свежесть без заезженного
- Баланс языков
- Баланс эпох
- Баланс жанров
- Аудит пакета
- Разминка первой, блиц последним
- Змейка, лесенка, буквы, страны
- Темы по словам в названии
- Замена одного вопроса
- Ревьюер в браузере
- Картинки из двух источников
- Кэш запросов
Продуктовая задача
Из пакета получать готовое видео прямо в редакторе
Видео собирает программа
ПакетВопросы, ответы, медиа
Таймлайн сценВопрос, ответ, таймер
Кадры на CanvasСлои: контент, контекст, таймер
ffmpegСклейка, футаж, музыка
Первое видео
Раунд 1: Разминка · Вопрос 1
252423222120191817161514131211109876543210
Назовите группу
♪
Первое видео
Раунд 1: Разминка · Вопрос 1
252423222120191817161514131211109876543210
Назовите группу
♪
Через месяц
252423222120191817161514131211109876543210
Назовите группу
Агенту достаточно ссылки на референс, разберёт он его сам
Продуктовая задача
Поправить один вопрос после публикации без полного рендера
Раньше заново рендерились все элементы кадраТеперь заново рендерятся только раунд и номер
Enter Shikari — The Mindsweep
Чем быстрее шаг пайплайна, тем быстрее и человек, и агент
Из чего собрано видео
- Кадр на Canvas
- Сборка через ffmpeg
- Кэш трёх слоёв
- Отмена рендера
- Фоновый футаж
- Фоновая музыка
- Логотип и шрифты
- Кроп по лицам
- Сетка фото ответа
- Плашки и счётчик
- Таймер на экране
- Плавное появление ответа
- Заставка, правила, финал
- Видео внутри вопроса
- Нормализация громкости
- Обложка для ролика
- Таймкоды для YouTube
- Рендер без окна
- Смоук на двух вопросах
- Отчёт рендера
Весь пайплайн доступен из командной строки
$ quiz-data pack generate --profile rock --difficulty 3 --out rock-scene-7.qzp $ quiz-builder render rock-scene-7.qzp --preset mindsweep --out rock-scene-7.mp4
CLI даёт агенту быстрый цикл проверки, а мне квиз без спойлеров
Как я удерживал систему
Делил по ответственности
Связывал контрактами
Унифицировал одинаковые операции
Удалял ненужное
Спорные решения проверял бенчмарками
Поддерживал только то, чем пользуюсь
Инструменты новые, инженерные практики прежние
Не весь код одинаково важен
Важны модель данных и стыки между крупными частями, остальное на откуп агенту
Одному человеку с агентами процессные практики не нужны
Тикеты, планы и роадмапы появляются вместе с командой
Каждой задаче своя модель
Считается, что вайбкодингом большой проект не сделать
Большой проект вайбкодингом сделать можно
И нужно
Пока я единственный пользователь
- Ломаю совместимость, когда хочу
- Удаляю фичи за день
Если выпустить его для профессионалов
- Совместимость и миграции
- Тестовый канал и откат
- Релизы и поддержка
Из идеи сделать один пакет выросла целая система, которая делает видеоквизы автоматически
Или почти
Павел Королев nullptr.talks[3]