Кейс 02 · e-commerce · собственный продукт
Персональная детская книга за одну анкету: от Telegram до типографии без иллюстратора, автора и верстальщика
Контекст
Персональная детская книга, где главный герой — ваш собственный ребёнок и выглядит он именно так, как выглядит, — это подарок, который родители хотят. Классическое производство такой книги требует автора, иллюстратора и верстальщика: недели работы и себестоимость, несовместимая с розничной ценой массового подарка.
Нейросети напрашиваются как решение, но генерация «в лоб» даёт брак, который родитель замечает за секунду. Герой меняет цвет волос между страницами. Бабушка выходит ростом с внука. Зимняя сцена — ребёнок без шапки. В лодке скамейки идут вдоль борта.
Взрослый читатель простит слабый сюжет. Ребёнок, листающий книгу про себя, не простит, что на пятой странице он стал другим человеком.
При этом каждая перерисовка стоит реальных денег, и без жёсткого контроля расход улетает: на одном из ранних заказов система сожгла семьдесят пять картинок на шестнадцать страниц — вчетверо больше плана.
И отдельная стена в конце пути — печать. Типографии принимают только строгий PDF/X-1a с точной геометрией. «Почти правильный» файл означает отклонённый заказ уже после того, как клиент заплатил.
Это продуктовая часть истории — как книга собирается. Про то, как этим продуктом управляет автономная система агентов, — отдельный кейс.
Ограничения
- Один человек и бюджет самозанятого. Сервер на одном ядре и двух гигабайтах — параллелизм генерации и рендера пришлось искусственно занижать
- Экономика на грани. Себестоимость картинки исчисляется рублями, комиссия платёжного канала доходит до трети чека. Каждая лишняя перерисовка съедает маржу напрямую
- Схемы структурированного вывода не прощают лишнего слова. Одно неподдерживаемое ключевое слово в схеме — и весь вызов падает с ошибкой, а вместе с ним падает оплаченный заказ
- Генератор изображений нестабилен: отдаёт от 630 до 1024 пикселей там, где для печати нужно от 1900, и принимает максимум три референса на запрос
- Полиграфия работает по своим законам. PDF/X-1a — это уровень PDF 1.3: любая прозрачность в вёрстке молча растрирует текст. Обрезной формат должен совпадать до десятых долей миллиметра
- API типографии без документации на половину правил: прайса нет, цены считаются формулой, статусы заказов скачут между «отклонён» и «загружен», создание заказа занимает больше минуты
- Правило, написанное промптом, исполняется «иногда». На длинной книге модель теряет инструкцию: шапка пропадала на трёх страницах из шестнадцати
Решение
Что это даёт
Родитель проходит анкету в Telegram: имя ребёнка, возраст, тема истории, при желании фото. До оплаты он видит превью героев — то есть понимает, что покупает. После оплаты получает готовый PDF и одной кнопкой заказывает печатный экземпляр с доставкой до двери.
Между анкетой и книгой нет ни одного человека.
Как устроено
Ядро — конвейер генерации с многоуровневым контролем качества.
Текст пишет одна модель. Затем отдельный «раскадровщик» одним проходом по всей сказке строит спецификацию каждой страницы: кто в кадре, где стоит, что держит, во что одет, что рисовать запрещено. Один холистический проход вместо постраничного — это и дешевле, и связнее: непрерывность рассуждается по всей книге сразу, а не собирается из шестнадцати независимых решений.
Поверх модели работают детерминированные слои на обычном коде. Гардероб по локации и сезону: дома тапки, на катке шлем. Карта относительного роста героев по возрастам. Выравнивание цвета обуви между страницами.
Здесь главный принцип всего проекта: повторяющийся дефект лечится кодом, а не четвёртым абзацем в промпте. Всё, что обязано выполняться всегда, не может зависеть от внимания модели на шестнадцатой странице.
Дальше каждая картинка проходит проверку зрением: модель-контролёр сверяет кадр со спецификацией по чек-листу примерно из четырнадцати категорий — анатомия, физика сцены, одежда, освещение. Финальный контроль смотрит книгу целиком и ловит то, что не видно постранично: «между четвёртой и пятой что-то поменялось».
Расходом управляет жёсткий бюджет с раздельными именными пулами — обязательные кадры, перерисовки, резерв. Каждая необязательная генерация обязана «спросить талон». Плюс пиксельные детекторы, отлавливающие круглые виньетки и белые поля, с гарантированным спасением через кроп.
Вёрстка — отдельный модуль: HTML и CSS рендерятся браузером в PDF, с возрастными типографическими системами (свой кегль и плашки для трёх-пяти, шести-восьми и девяти-двенадцати лет), вшитыми шрифтовыми сабсетами и замером переполнения текста прямо в браузере.
Печатный контур собирает из тех же исходников файлы для типографии: PDF/X-1a в CMYK, точная геометрия страницы, вылеты. Предпечатный контроль работает по правилам конкретной типографии — файл, который их валидатор отклонит, не уходит вообще, а владелец видит точную причину до отправки.
Вокруг конвейера — полный продуктовый контур: оплата с восстановлением после перезапусков, автовозвраты, личный кабинет, продолжения историй с теми же героями, реферальная механика, интерфейс на двенадцати языках.
Архитектура
Один холистический проход раскадровки вместо N постраничных: плюс один вызов на книгу вместо шестнадцати, и связность рассуждается сразу целиком.
Детерминированные слои поверх модели — гардероб, рост, цвет. Критичные правила не доверяются вниманию LLM.
Бюджет картинок в контекстной переменной с раздельными пулами и аварийным стопом при неучтённых путях расхода.
Fail-open для проверок, fail-loud для генерации. Сбой контролёра не роняет заказ — книга просто выйдет без одной проверки. Сбой этапа генерации — честная ошибка с возвратом денег, а не тихая деградация.
Одна вёрстка — два таргета. Экранный PDF и печатный блок собираются из одних исходников, поэтому бумажная книга гарантированно совпадает с цифровой.
Разные модели под разные задачи: диалог — быстрая, сказка — сильная, проверки зрением — сильная, картинки — специализированный генератор. Кэширование системных промптов даёт около десятой части цены на повторном чтении.
Каждый живой дефект становится автотестом. Журнал всех поломок, доехавших до клиента, с номерами заказов в названиях блоков. Отсюда семьсот проверок — это не покрытие ради покрытия, а история болезней.
Стек
Результат
Книга, на которую в классическом производстве уходят автор, иллюстратор и верстальщик, собирается из одной анкеты без участия человека.
Макеты проходят автоматическую валидацию типографии и модерацию — два тиража в печати. До появления предпечатного контроля файлы отклонялись уже после того, как клиент заплатил: заказ есть, денег нет, книги не будет.
Расход на генерацию удерживается жёстким бюджетом с именными пулами. До его появления один заказ мог сжечь вчетверо больше картинок, чем заложено, — и съесть маржу целиком.
Семьсот регрессионных проверок, каждая привязана к реальному дефекту, доехавшему до пользователя.
Интерфейс на двенадцати языках, причём анкета работает даже при недоступности модели.
| Показатель | Было | Стало |
|---|---|---|
| Производство книги | автор, иллюстратор, верстальщик | одна анкета в Telegram |
| Приёмка макетов типографией | отклонение после оплаты | автоматическая валидация до отправки |
| Перерасход генераций | до ×4 от плана | жёсткий бюджет с пулами |
| Регрессионные проверки | 0 | ~700, каждая — живой дефект |
| Языки интерфейса | — | 12 |
Что бы сделал иначе
- Молчаливый фолбэк — зло. Новый движок при сбое тихо откатывался на старый. Клиент получил книгу «не тем путём», и об этом сообщила одна строчка в логе. Переделано на честную ошибку с возвратом денег: лучше признать сбой, чем незаметно отдать не то
- Большая переделка одним куском не взлетела. Вторую версию движка непрерывности собрали по большому техзаданию, задеплоили — и через два дня удалили целиком, качество не устроило. Эволюция маленькими проверяемыми шагами бьёт революцию
- Детектор по ключевым словам без контекста хуже, чем ничего. Поиск слова «вода» превращал кастрюльку с кипятком в морскую сцену, и домашняя страница уезжала на пляж. Наступили дважды. Теперь только контекстные детекторы с отрицаниями
- Данные теряются на границах сериализации. Возраст героев читался из базы, но не писался в неё — и правило роста молча исчезало из промптов. Отсюда бабушка ростом с внука. Поле, которого нет в списке обязательных, модель не вернёт
- Статусам внешних систем нельзя верить с одного чтения. Заказ мигнул статусом «отклонён» и вернулся в «загружен». По одному чтению бот вернул бы деньги за книгу, которую типография потом напечатала. Теперь необратимые действия — только после подтверждающего второго чтения
- Полиграфия не прощает «почти». 154,18 мм вместо 154,0 — отказ. Вылеты нужны, но размер обязан быть стандартным, и разгадка оказалась в правильной геометрии обрезного блока. Прозрачность в CSS молча превращает текст в растр
- У некоторых таймаутов пустое текстовое представление — в логе оставалось «типография недоступна: » без причины. Все ошибки внешних API теперь логируются полным представлением объекта
Есть продукт, где качество генерации решает всё?
Напишите — разберём, что можно автоматизировать в вашем случае.