Как я сделал предиктор виральности для Hacker News
Собрал штуку, которую сам давно хотел: клон Hacker News, куда можно вставить draft поста до публикации и увидеть:
— предсказанный score
— p10–p90 диапазон
— похожие старые HN-посты
— почему модель так думает
— и примерные комменты, которые тебе прилетят
Сегодня запостил это на сам HN (найдите в new - 148,421 posts later: A model to predict the Hacker News front page)
Ниже - как оно устроено.
Зачем
HN - странная платформа.
Я захотел сделать инструмент, который хотя бы примерно отвечает на вопрос:
“Этот заголовок вообще имеет шанс?”
Данные
Собрал через публичный Algolia HN Search все посты с 2007 года, которые набрали ≥5 очков.
Получилось 148,421 истории.
Главная деталь: сплит строго хронологический:
— train: до июля 2025
— validation: август–декабрь 2025
— holdout: январь 2026+
Random split здесь ломает задачу. Если случайно перемешать данные, модель начинает подсматривать в будущее через kNN-соседей: на трейне выглядит умной, в проде разваливается.
Это была первая грабля, на которую я наступил.
Эмбеддинги и соседи
Для каждого поста беру title + первые ~200 символов body и прогоняю через Gemini embeddings.
В Postgres / pgvector храню:
— halfvec(3072) для cosine search
— bit(3072) для быстрой бинарной префильтрации
Поиск двухступенчатый: сначала быстрый HNSW по бинарке, потом cosine re-score по halfvec.
На 148K постов p50 получается около 50 мс.
Модель
Поверх kNN-соседей обучен LightGBM на 31 фиче.
Фичи: score ближайших соседей, доля frontpage-попаданий, плотность neighborhood, свежесть соседей, длина заголовка, Show HN / Ask HN, знаки препинания, цифры, время публикации, день недели, доменные priors.
Важная деталь: kNN при тренировке тоже time-causal.
Для поста из 2025 года нельзя искать соседей из 2026-го. Только прошлое. Иначе вся честность хронологического сплита исчезает.
Проанализировал 150к постов на HackerNews и сделал модель, которая поможет завируситься
Ты час подбираешь заголовок для Show HN, нажимаешь submit - и через 30 минут либо летишь в топ, либо тихо умираешь в /newest.
И почти невозможно понять, почему.
В выходные я собрал инструмент, который сам давно хотел:
→ hackernews.foresyn.ai
Это клон HN, где можно прогнать свой Show HN до настоящего поста.
Пишешь title + url + description - и модель показывает:
— сколько очков можно ожидать
— реалистичный p10–p90 диапазон
— похожие прошлые HN-посты
— что тебе, скорее всего, напишут в комментах
— как можно улучшить заголовок
Особенно горжусь - симулятором комментов
Он ищет реальные старые HN-комменты к похожим постам и показывает, кто придёт душнить:
“we built this in 2017”
“why not SQLite?”
“how is this different from X?”
“pricing?”
Ещё есть Auto-improve: модель сама генерит варианты заголовка, перескоривает и greedily лезет вверх до плато.
И Live ledger: каждый день скорим настоящую HN frontpage и публикуем ошибку модели.
В понедельник я хочу запостить это на сам Hacker News. До этого очень нужно, чтобы люди попробовали сломать штуку.
Особенно если вы уже постили на HN:
• верите ли скору?
• где UX бесит?
• какой prediction выглядит нелепо?
Про то, что под капотом напишу отдельный пост: 148K HN-постов, Gemini embeddings, halfvec индекс, LightGBM поверх 31 фичи, kNN-сигналы, domain priors, time-of-day, title craft.
Эмбеддить запрос юзера напрямую - почти всегда плохая идея.
Понял это, пока собирал фильтр для Tech Week NYC.
В Нью-Йорке на тех-неделю предлагают посетить 1,211 ивентов. Захотелось сделать простую тулу: вставляешь LinkedIn или просто описание себя (я тестил даже «люблю лапшу и саке») - и получаешь 6 релевантных ивентов с объяснением, почему именно они.
Попробовать можно тут:
🔗 techweek.foresyn.ai
Главный инсайт такой.
Если взять сырой пользовательский текст, заэмбеддить его и кинуть cosine search, в топ часто попадает что угодно, кроме того, что реально нужно.
Cosine обычно болтается где-то в районе 0.45–0.50.
Что сработало лучше: перед embedding добавить ещё один LLM-вызов, который переписывает запрос в стиле документов, среди которых ищем.
Например:
Вход:
«founder, AI infra, pre-seed, ищу инвесторов»
Выход:
«Pre-seed and seed-stage VCs focused on AI infrastructure. Partners from specialised AI funds investing in agentic workflows.»
И уже это отправлять в embedding.
После этого cosine подскакивает до 0.62–0.70.
А теперь очень хочется хайпануть - так что пожалуйста делитесь ссылкой с теми, кому актуально!
Написал CLI к Meta Graph API и Claude Code skill в комплекте.
После установки, Claude сам публикует посты, отвечает на комменты и собирает аналитику. Просишь словами - он делает.
Как я к этому пришел - помогал друзьям с их маленьким турагенством, хотел автоматизировать и обнаружил что у Meta есть SDK на Python, JS, PHP, а CLI - нет. А агенту CLI - милее всего на свете.
🛠 Как установить
pip install meta-graph-cli
Никакого FB SDK, никакого React-приложения для логина - только токен и тонкая HTTP-оболочка.
Что умеет:
• публиковать фото, видео, рилзы, карусели, сторис;
• читать, отвечать, скрывать и удалять комменты;
• тянуть insights, искать по хэштегам, гонять business-discovery;
• работать через оба flow - Facebook Login и Instagram Login - тип определяется по префиксу токена.
Уже две недели активно использую Claude Design и хочу поделиться полезными практиками, которые я для себя открыл.
Сразу оговорюсь, что у моего проекта особо не было никакого дизайна, так что все с чистого листа. Подозреваю что у проектов, в которых дизайн существует - все подругому.
Первое что я сделал - это набросал прототип приложения через Wireframes - Claude задает кучу вопросов и старается уловить суть. На вопросы лучше всего отвечать подробно, и если есть существующий код - просить Claude Code написать документацию (которую тоже подргузить в Design).
Вторая фаза - то что видно на картинке сверху - это разработка Design System. Для меня это было просто откровение, ну кто бы мог подумать что дизайн можно зафиксировать и сделать из него систему =)
Ну и третья фаза - натянуть дизайн систему на wireframe и собрать готовое, отполоированное приложение (ну ладно, макет), которое потом можно передать в Claude Code (кстати handoff заслуживает отдельного внимания).
Попробовал еще логотип нарисовать, но логотипы вот чет не получаются. Ну буду изучать дальше!