личный блог

Статьи · ai

Dashi PPT: skill для ИИ-агента, который собирает презентацию из документа

·13 мин чтения ·Статьи·

Презентации, которые собирает языковая модель, обычно ломаются в одном и том же месте: слайды выходят, но править их нечем. Либо это картинки, либо разметка, в которую страшно лезть. Dashi PPT решает задачу с другого конца: модель не рисует слайды, а заполняет текстом готовые макеты, и на выходе получается не файл, а веб-редактор, в котором у каждого слайда своя панель настроек.

Репозиторий создан 10 июня 2026 года, у него больше девяти тысяч звёзд и восьмисот форков. Разбираемая версия — 0.4.14. README обещает 12 тем, 1020 макетов и экспорт в настоящий редактируемый PPTX. Большая часть обещаний подтверждается кодом, но в нескольких местах README и код говорят разное — в том числе про сеть и про то, кому виден локальный сервер.

Что это и из чего состоит

Dashi PPT — не приложение и не сервис, а навык (skill) для ИИ-агента: папка с инструкцией SKILL.md, генератором на Node.js и набором скриптов. Агент читает инструкцию, сам вызывает скрипты и отдаёт пользователю ссылку на готовую презентацию. Нужен агент с доступом к файлам и командной строке; для веб-чатов без локального окружения навык не годится, и README говорит об этом прямо.

Внутри папки навыка около 56 МБ до установки зависимостей:

Цифры из README воспроизводятся по каталогу макетов: в нём ровно 12 тем, 1020 макетов и 8576 элементов управления. Из них 4276 переключателей, 2372 ползунка и 1825 выпадающих списков. На один макет приходится от одного до пятнадцати элементов, в среднем около восьми.

А вот «20 ролей страниц» — обложка, оглавление, метрики, тренд, сравнение, риски и так далее — в каталоге не записаны. Роль макету назначается в момент поиска, по ключевым словам в его названии. Это таксономия для запроса, а не свойство макета.

Свободного выбора цвета нет: палитра — это список из готовых вариантов. Автор объясняет это в FAQ: стабильный результат важнее произвольной раскраски.

Как агент собирает презентацию

Инструкция ведёт агента по жёсткому маршруту. Писать HTML слайдов руками ей запрещено.

  1. Бриф. Тема, цель, аудитория, число страниц. По умолчанию около десяти, не меньше восьми.
  2. Тема и медиа. Агент обязан показать пользователю картинку с двенадцатью темами и спросить, нужны ли изображения. Выбирать за пользователя разрешено, только если тот прямо сказал «решай сам».
  3. Подбор макетов. Команда layout:query возвращает кандидатов по теме и роли страницы. Выбор зависит от зерна случайности, поэтому при том же зерне и тех же входных данных макеты получаются те же.
  4. Контракт макета. inspect:layout сообщает, какие у макета текстовые поля, сколько символов в них помещается и сколько элементов видно в списках.
  5. Содержание. Агент пишет page-content-pack.json: у каждой страницы одна главная мысль, заголовок и резюме в полной и короткой форме, факты, данные для графика.
  6. План. goal:scaffold превращает содержание в goal.json — полное описание презентации.
  7. Рендер. Один скрипт проверяет план, собирает HTML, проверяет результат и поднимает сервер предпросмотра.

Сам скрипт рендера короткий, и по нему видно, сколько проверок стоит вокруг генерации:

npm run props:safe -- --goal "$SPEC_PATH" --write
npm run validate:goal-spec -- "$SPEC_PATH"
npm run render:goal -- "$SPEC_PATH" "$OUT_PATH"
npm run validate:swiss -- "$OUT_PATH"
npm run validate:goal-copy -- "$SPEC_PATH" "$OUT_PATH"
npm run preview:start -- "$OUT_DIR" "$PREVIEW_PORT"

До рендера план сверяется со схемой, после — готовый HTML сверяется с планом: все ли файлы на месте и весь ли текст из плана дошёл до страницы. В текстовых полях проверка пропускает только простые теги вроде <b>, <em> и <br>; остальные теги, обработчики событий и ссылки javascript: отклоняются.

После машинных проверок инструкция требует от агента приёмки по смыслу: попадает ли презентация в цель, все ли выводы на месте, не остался ли демо-текст из шаблона. Статусов три — принято, нужна правка, заблокировано. На исправления даётся два круга.

Четыре варианта каждой страницы

Главное архитектурное решение проекта — правило «три плюс один». На каждую логическую страницу генератор делает четыре варианта:

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

В предпросмотре десять логических страниц превращаются в сорок физических слайдов, и на каждой странице можно выбрать вариант. Экспортировать можно либо все сорок, либо только выбранные.

Цена такого решения — токены и время: каждая страница описывается и рендерится четырежды. В README названа оценка в 100 тысяч токенов на десять страниц.

Редактор внутри готового файла

Результат лежит в папке output/<имя>/ppt/: файл index.html и каталог assets/ с библиотеками, шрифтами и картинками темы. Шрифты и текстуры разложены локально, презентация открывается без интернета.

Редактор — часть самого файла. Его код лежит в шаблоне страницы на 476 КБ и написан на обычном читаемом JavaScript без фреймворка; React отвечает только за содержимое слайдов. В редакторе можно править текст кликом, менять картинки перетаскиванием, двигать ползунки панели, переставлять, скрывать и дублировать страницы, включать режим показа.

Автосохранение устроено в два слоя. Каждая правка сразу пишется в хранилище браузера, а через две секунды уходит на локальный сервер. Сервер принимает только известные поля состояния — порядок слайдов, скрытые и удалённые страницы, текст, параметры, выбранные варианты — и переписывает блок состояния прямо в index.html. Вставленные картинки при этом сохраняются файлами в assets/user-media/.

Отсюда важное следствие: файл презентации сам себя изменяет, но только пока открыт через сервер навыка. Если открыть index.html двойным кликом или раздать его любым другим статическим сервером, правки останутся в браузере и до файла не дойдут. Инструкция запрещает агенту подменять сервер по этой причине.

Сервер предпросмотра

Сервер запускается отдельным фоновым процессом и переживает сессию агента. По умолчанию он завершается сам после четырёх часов простоя. Порт по умолчанию 5200; если он занят, перебираются следующие.

Про доступность сервера README и код расходятся. В README сказано, что предпросмотр доступен в локальной сети для просмотра. В коде адрес по умолчанию — 127.0.0.1, а для сети нужно явно задать переменную:

const host = process.env.DASHI_PPT_PREVIEW_HOST || process.env.HOST || '127.0.0.1';

Код здесь безопаснее документации. Но если сервер всё же открыть в сеть, стоит понимать, как он защищён. Пароля и токена нет. Запросы к /api/* — сохранение и экспорт — проверяются по заголовкам Origin и Referer: источник должен быть из списка разрешённых. При открытии в сеть в этот список попадают и адреса машины в локальной сети. Запросы без обоих заголовков принимаются, только когда сервер слушает локальный адрес. Статические файлы презентации отдаются без проверок. По коду выходит, что браузер с другой машины в той же сети, открывший страницу, сможет и сохранять правки; на практике это поведение не подтверждено.

HTTP и HTTPS живут на одном порту: сервер смотрит на первый байт соединения и сам решает, поднимать ли TLS. Сертификат самоподписанный, на 365 дней, создаётся системным openssl и лежит в папке навыка.

Экспорт в PPTX и PDF

Экспорт в PPTX — самая интересная и самая закрытая часть. Сервер запускает браузер без интерфейса через playwright-core, открывает в нём собственную страницу предпросмотра и передаёт её движку html-deck-to-pptx. Движок обходит живой DOM активного слайда и собирает файл через библиотеку pptxgenjs:

Движок распространяется только в собранном виде, поэтому точные правила выбора между фигурой и картинкой по коду не прослеживаются. В описании пакета названа доля редактируемых элементов 0,851; набор тестов, на котором она получена, в репозиторий не входит. FAQ формулирует осторожно: PowerPoint не умеет всего, что умеет HTML, но редактируемость сохраняется, где возможно.

Если сервер не может запустить браузер, PPTX собирается прямо в браузере пользователя и загружается на сервер готовым файлом.

PDF устроен проще: это снимки страниц, собранные в файл. Выделяемого текста в таком PDF нет.

Для экспорта нужен Chrome, Chromium или Edge. Путь к нему можно задать переменной CHROME_PATH; если её нет, скрипт ищет браузер в стандартных местах macOS и Windows. Экспортированные файлы складываются не рядом с презентацией, а в project/output/exports/ внутри папки навыка.

Что уходит в сеть

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

Что Куда Когда
Установка зависимостей реестр npm или зеркало первый рендер
Проверка доступности реестра registry.npmjs.org, зеркало один раз перед установкой
Загрузка браузера для экспорта серверы Playwright или зеркало при каждом рендере, если браузера ещё нет
Проверка версии registry.npmmirror.com, registry.npmjs.org, raw.githubusercontent.com после каждой задачи

Проверка версии — обычный GET-запрос без тела и без номера текущей версии, с таймаутом пять секунд. Выключателя у неё нет: её запускает агент, потому что так написано в инструкции. Отключить можно, только убрав строку из SKILL.md или сам скрипт.

Отдельная деталь для тех, кто следит за цепочкой поставки: в файле .npmrc проекта по умолчанию прописано китайское зеркало registry.npmmirror.com. Перед первой установкой скрипт проверяет, доступен ли основной реестр npm, и если да — убирает зеркало. Если проверка не прошла, зависимости и браузер ставятся с зеркала.

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

Установка и запуск

Нужны Node.js 20 или новее и npm; для экспорта — браузер на базе Chromium. Требование к версии Node записано в документации, в коде проверки нет.

npx dashi-ppt-skill@latest

Установщик ищет каталоги навыков в домашней директории — ~/.agents/skills, ~/.codex/skills и ещё два. Здесь README опять расходится с кодом: написано, что навык ставится во все найденные каталоги, а на деле — в один. Во все он ставится только с флагом --all, а при неоднозначности установщик останавливается и просит указать путь через --dir.

Обновление — та же команда. Папка навыка заменяется целиком и атомарно, через временный каталог и переименование. Установленные зависимости при этом переносятся. Всё остальное — нет: экспортированные файлы из project/output/ и собственные правки в SKILL.md после обновления пропадают.

Дальше работа идёт через агента: ему отдаётся документ и просьба сделать презентацию. Экспорт доступен из редактора кнопкой и из командной строки:

npm --prefix <папка-проекта> run export:pptx -- <папка-презентации>/ppt out.pptx
npm --prefix <папка-проекта> run export:pdf  -- <папка-презентации>/ppt

Полезные переменные окружения:

Лицензии

Корневая лицензия — AGPL-3.0. Пользоваться, менять и распространять можно, в том числе коммерчески; но изменённую версию или сервис на её основе придётся открыть на тех же условиях.

Из этого есть исключение, и оно касается самой ценной части. Движок экспорта html-deck-to-pptx — проприетарный компонент: его разрешено использовать только в составе навыка, а извлекать, распространять отдельно, менять и разбирать запрещено. До версии 0.2.7 он выходил под MIT, и это разрешение действует только для тех версий. В самом пакете при этом осталась рассогласованность: файл лицензии проприетарный, а его README всё ещё называет MIT.

Есть и третий слой. Библиотека анимации GSAP, которая копируется в каждую презентацию, распространяется по собственной бесплатной лицензии GreenSock, а не по открытой.

Ограничения и риски

Кому подойдёт

Dashi PPT хорошо ложится на типовые рабочие презентации: отчёт, обзор рынка, разбор конкурентов, план проекта, внутреннее обучение. Там важнее цельная структура и аккуратный вид, чем уникальный дизайн, а возможность поправить слайд ползунком экономит круг переписки с агентом.

Он не подойдёт для презентаций в собственном фирменном стиле — темы закрыты и не настраиваются — и для сред, где нельзя ставить зависимости из внешних реестров или держать фоновый процесс. Тем, кому важна проверяемость всего кода, стоит помнить о двух закрытых частях: компонентах тем и движке экспорта.

Самое ценное в проекте — не темы, а подход. Модели оставлена работа, с которой она справляется: разобрать документ на страницы и написать текст нужной длины. Вёрстка, проверки и экспорт вынесены в детерминированный код, а последнее слово — в редактор, где человек доводит результат сам.

Олег Букатчук
Олег Букатчук
DevOps- и SRE-инженер. Строил отказоустойчивую инфраструктуру для классифайда, e-commerce и госсектора: cian.ru, aliexpress.ru, mos.ru.