31 ключ API, 17 промптов, 0 продаж. Отдаю в open source Telegram-бота, который превращает голосовые в посты
Я инди-разработчик. 4 месяца по вечерам я собирал AudioToPostBot: Telegram-бот, в который надиктовываешь голосовое — получаешь готовый пост, выжимку, тред или конспект. Внутри не один промпт, а маленький завод: предобработка звука, фильтры галлюцинаций ASR, приоритетные очереди, ротация ключей, библиотека стилей, оплата звёздами.
Потом я попытался продать его white-label владельцам каналов. Не продал. И вместо того чтобы молча заархивировать репозиторий, открываю его: ниже вся внутренняя кухня и все промпты дословно.
Что получилось
Голос превращается в десять режимов: пост для Telegram, пост-история, тред для X, выжимка, мыслесборник, личный бренд, конспект для учёбы, анти-выгорание, описание товара, пост для соцсетей.
Вокруг этого — продуктовый слой: тарифы и рассрочка за звёзды, рефералка с квалификацией (накрутить альтами нельзя), стрики, квесты, колесо дня, win-back по уснувшим у пейвола, архив всех генераций с поиском, командный тариф с ролями и общей библиотекой стилей.
Сколько пользователей прошло через бота и сколько обработок сделано? Пришло 70 человек, попробовали 2 раза из 4-х бесплатных и ушли.
Почему я не смог это продать — и почему это нормально
Я сходил к двум типам людей, которые казались идеальными покупателями. Топ-блогер с агентством и каналами на десятки тысяч: у него входящий поток писем отфильтрован так, что человек с фразой «я сделал бота» не доживает до второго абзаца. Автор поменьше, с курсами по нейросетям и собственными «ИИ-сотрудниками»: он собирает такое сам за вечер на no-code, и его час стоит дороже всей моей лицензии.
Главный вывод я сформулировал для себя жёстко: продукт без функции продаж — это не бизнес, а портфолио. White-label сделка для соло-разработчика означает юрлицо, счета, поддержку и ответственность за чужой бренд. Я к этому не готов и, честно, не хочу. Те же недели, влитые в продажи, принесли ноль рублей. Те же недели в новом проекте — принесли движение. Поэтому бот уезжает на GitHub, а я ухожу дальше.
Внутренности: звук
Скачиваем ogg, прогоняем через ffmpeg: срез гула 80 Гц, срез верха 7,5 кГц, денойз с трекингом шума (метро и улица меняются, фильтр должен следить), динамическая нормализация, лимитер. На выходе FLAC 16 кГц моно.
От loudnorm я отказался намеренно: он ориентируется на среднюю громкость файла и не вытягивает шёпот после крика. dynaudnorm поднимает тихие куски до +29 дБ и не раздувает паузы. Если ffmpeg упал — в Whisper уходит сырой файл, пользователь не блокируется. Деградация вместо отказа.
Внутренности: Whisper
language=ru, temperature=0, verbose_json. В prompt только 50 слов: сленг («чё», «щас», «кринж») и слова с дефисом («по-моему», «всё-таки»). Примеры-омофоны не работают: Whisper начинает их подставлять сам, проверено.
Сегменты выкидываются по четырём правилам: no_speech_prob выше 0.6 при avg_logprob ниже -0.8 (само правило Whisper «тут нет речи»), compression_ratio выше 2.4 (зацикленный повтор), avg_logprob ниже -1.5 (модель сама не уверена), либо текст совпал с чёрным списком галлюцинаций вроде «субтитры сделал…». Если Whisper вернул собственный prompt — это не речь, результат пустой. Пусто — значит «не удалось распознать», и лимит не списывается.
Фильтровать выход распознавания важнее, чем улучшать вход. Это самая дорогая моя находка.
Внутренности: слоёный пирог промптов
Системный промпт контентного режима собирается из четырёх слоёв: контракт стиля → жёсткие правила из кода → образец авторского стиля (до 1500 знаков, с оговоркой «факты не копируй») → промпт режима. Cleaner и corrector в контракт не входят: это техническая обработка, а не контент.
Контракт стиля — это правила тона и оформления для любого текста: никаких решёток и звёздочек (Telegram показывает их как мусор), никаких кавычек, регистр речи определяется по диктовке и держится, чёрный список клише («давайте разберёмся», «ни для кого не секрет»), ритм: после длинного предложения короткое, одна мысль в одном месте.
Приёмы, которые реально сработали:
— Определи тип входа. Режим поста сначала различает поток мысли и готовое произведение (песня, стих). Поток собирается в пост, готовое не трогается: форма неприкосновенна, припевы не схлопываются.
— Порог сохранения. «Минимум 70% смысловых предложений доживают до выхода в формулировках автора» работает лучше, чем любое «сохраняй стиль».
— Мат не повод для отказа. Человек ругался — значит, так и надо оформить. Прописано и в контракте, и в cleaner.
— Усиль юмор, но один раз. Одна панч-строка на текст, и только если ирония была в диктовке. Сухая диктовка — ноль шуток. Шутка из ниоткуда хуже отсутствия шутки.
— Серьёзная цель побеждает настроение. Реферат будет серьёзным, даже если автор в голосовом паясничал.
— Анти-выгорание с предохранителем: не диагностировать, не обесценивать; при признаках суицида или самоповреждения мягко направить к живому специалисту, а не «закрывать» темой выгорания.
Код вместо обещаний
Промпту можно сказать «не ставь кавычки» — и модель всё равно поставит. Поэтому часть правил живёт в коде:
— sanitize: markdown превращается в HTML-теги Telegram, кавычки вырезаются регуляркой, а не просьбой.
— isRefusal: если ответ короче 400 знаков и похож на «I'm sorry, I can't help» — это отказ. Пользователь получает понятное сообщение, обработка не списывается.
— Аудит цифр: из результата достаются все числа и сверяются с диктовкой и блоком поисковых фактов. Чужие уходят на точечную правку при температуре 0.2 — убрать предложение или поставить [проверить цифру]. Полная перегенерация не нужна: дешёвая точечная правка лучше.
Надёжность
До 31 ключа Groq в ротации по кругу. 429 или 401 — ключ в карантин на пять минут, до трёх попыток на запрос. Приоритетный семафор: шесть одновременных запросов к генерации, четыре к поиску, три к Whisper. Приоритет Бизнес выше Премиума, Премиум выше Про, внутри уровня FIFO. Слот не освободился за 20 секунд — «сервер перегружен», обработка не списана.
Одна диктовка на пользователя за раз: параллельные голосовые раньше проскакивали мимо лимита и давали несколько «первых бесплатных». Логика списаний вообще простая: сбой, отказ модели или перегрузка не стоят пользователю ничего. Ничего не списывай, пока результат не доставлен.
Что я бы сказал себе в начале
Правило, которое нельзя нарушить, должно быть в коде. Промпт — это просьба.
Фильтровать выход распознавания важнее, чем улучшать вход.
Дешёвая точечная правка цифр лучше полной перегенерации.
Поиск — бонус: если он упал, пользователь не должен это заметить.
Ничего не списывай, пока результат не доставлен.
Почему open source и где забирать
репозиторий с кодом — весь бот одним файлом index.js: Telegraf, better-sqlite3 в WAL, очереди, миграции, админ-команды. Ключей внутри нет.
файл со всеми промптами там же — все 17 промптов дословно: контракт стиля, cleaner, corrector, десять режимов, блоки фактов и жёсткие правила.
Лицензия — в том же репозитории. Бери, форкай, собирай своего бота. Если у кого-то на этом вырастет свой продукт — это ровно то, зачем я это выкладываю.
Почему отдаю бесплатно, а не продаю за 20 тысяч
Я посчитал. White-label сделка — это не «отправил код, получил деньги». Это недели переговоров, юрлицо, счета, поддержка и правки под чужой бренд. Я один, и те же недели в новом проекте приносят больше.
Сейчас я делаю Arena — бота для стримов. Продавать и обещать здесь ничего не буду: про Arena напишу отдельно, когда появится что показать, кроме намерений.
Этот пост — не его реклама. Это способ закрыть главу с аудио-ботом так, чтобы код работал у людей, а не гнил на диске, и чтобы любой мой будущий читатель видел путь целиком, включая провалы.
Вопросы по внутренностям — в комментариях, отвечу. Вопрос «как продать white-label блогеру» не задавайте: я не знаю. В этом и есть весь пост.