BorisovAI

Блог

Публикации о процессе разработки, решённых задачах и изученных технологиях

Найдено 20 заметокСбросить фильтры
Новая функцияC--projects-bot-social-publisher

Потоки из воздуха: охота на три невидимых бага

# Потоки событий из ниоткуда: как я чинил невидимый баг в системе публикации Представь себе: у тебя есть система, которая собирает заметки о разработке, генерирует красивые баннеры и должна автоматически организовывать их в тематические потоки на сайте. Только вот потоки не создаются. Вообще. А код выглядит так, будто всё должно работать. Именно это и произошло в проекте **bot-social-publisher** на этой неделе. На первый взгляд всё казалось в порядке: есть `ThreadSync`, который должен синхронизировать потоки с бэкендом, есть логика создания потоков, есть дайджесты с описанием тематики. Но когда я открыл сайт borisovai.tech, потоки были пусты или с дублирующимися заголовками. Я начал следить по цепочке кода и обнаружил не один, а **три взаимосвязанных бага**, которые друг друга нейтрализовали. ## Баг первый: потоки создавались как пустые скорлупы Метод `ensure_thread()` в `thread_sync.py` отправлял на бэкенд заголовок потока, но забывал про самое важное — описание. API получал `POST /api/v1/threads` с `title_ru` и `title_en`, но без `description_ru` и `description_en`. Результат: потоки висели как призраки без содержимого. ## Баг второй: дайджест потока не видел текущую заметку Метод `update_thread_digest()` пытался обновить описание потока, но к тому моменту текущая заметка ещё не была сохранена на бэкенде. Порядок вызовов был таким: сначала обновляем поток, потом сохраняем заметку. Получалось, что первая заметка потока в описании не появлялась. ## Баг третий: мёртвый код, который никогда не выполнялся В `main.py` был целый блок логики для создания потоков при накоплении заметок. Но там стояло условие: создавать поток, когда накопится минимум две заметки. При этом в памяти хранилась ровно одна заметка — текущая. Условие никогда не срабатывало. Код был как музей: красивый, но не функциональный. Фиксить пришлось системно. Добавил в payload `ensure_thread()` поля для описания и информацию о первой заметке. Переделал порядок вызовов в `website.py`: теперь дайджест обновляется с информацией о текущей заметке *до* сохранения на бэкенд. И наконец, упростил мёртвый код в `main.py`, оставив только отслеживание заметки в локальном хранилище потоков. Результат: все 12 потоков проектов пересоздались с правильными описаниями и первыми заметками на месте. ## Бонус: картинки для потоков весили как видео Пока я чинил потоки, заметил ещё одну проблему: изображения для потоков были размером 1200×630 пикселей (стандартный OG-баннер для соцсетей). Но для потока на сайте это overkill. JPG с Unsplash весил ~289 КБ, PNG от Pillow — ~48 КБ. Решение: сжимать перед загрузкой. Снизил размер с 1200×630 на 800×420, переключил Pillow на JPEG вместо PNG. Результат: JPG уменьшился до 112 КБ (**−61 %**), PNG до 31 КБ (**−33 %**). Дайджесты потоков теперь грузятся мгновенно. Вся эта история про то, что иногда баги не прячутся в одном месте, а рассредоточены по трём файлам и ломают друг друга ровно настолько, чтобы остаться незамеченными. Приходится думать не о коде, а о потоке данных — откуда берётся информация, где она трансформируется и почему на выходе получается пусто. Знаешь, в разработке систем есть хорошее правило: логи и мониторинг — твоя совесть. Если что-то не работает, но код выглядит правильно, значит ты смотришь не на те данные. 😄

#claude#ai#python#javascript#api
13 февр. 2026 г.
Новая функцияtrend-analisis

8 адаптеров за неделю: как подружить 13 источников данных

# Собрал 8 адаптеров данных за один спринт: как интегрировать 13 источников информации в систему Проект **trend-analisis** это система аналитики трендов, которая должна питаться данными из разных уголков интернета. Стояла задача расширить число источников: у нас было 5 старых адаптеров, и никак не получалось охватить полную картину рынка. Нужно было добавить YouTube, Reddit, Product Hunt, Stack Overflow и ещё несколько источников. Задача не просто в добавлении кода — важно было сделать это правильно, чтобы каждый адаптер легко интегрировался в единую систему и не ломал существующую архитектуру. Первым делом я начал с проектирования. Ведь разные источники требуют разных подходов. Reddit и YouTube используют OAuth2, у NewsAPI есть ограничение в 100 запросов в день, Product Hunt требует GraphQL вместо REST. Я создал модульную структуру: отдельные файлы для социальных сетей (`social.py`), новостей (`news.py`), и профессиональных сообществ (`community.py`). Каждый файл содержит свои адаптеры — Reddit, YouTube в социальном модуле; Stack Overflow, Dev.to и Product Hunt в модуле сообществ. **Неожиданно выяснилось**, что интеграция Google Trends через библиотеку pytrends требует двухсекундной задержки между запросами — иначе Google блокирует IP. Пришлось добавить асинхронное управление очередью запросов. А PubMed с его XML E-utilities API потребовал совершенно другого парсера, чем REST-соседи. За неделю я реализовал 8 адаптеров, написал 22 unit-теста (все прошли с первой попытки) и 16+ интеграционных тестов. Система корректно регистрирует 13 источников данных в source_registry. Здоровье адаптеров? 10 из 13 работают идеально. Три требуют полной аутентификации в production — это Reddit, YouTube и Product Hunt, но в тестовой среде всё работает как надо. **Знаешь, что интересно?** Системы сбора данных часто падают не из-за логики, а из-за rate limiting. REST API Google Trends не имеет официального API, поэтому pytrends это реверс-инженерия пользовательского интерфейса. Каждый обновочный спринт может сломать парсер. Поэтому я добавил graceful degradation — если Google Trends упадёт, система продолжит работу с остальными источниками. Итого: 8 новых адаптеров, 5 новых файлов, 7 изменённых, 18+ новых сигналов для скоринга трендов, и всё это заcommитчено в main ветку. Система готова к использованию. Дальше предстоит настройка весов для каждого источника в scoring-системе и оптимизация кэширования. **Что будет, если .NET обретёт сознание? Первым делом он удалит свою документацию.** 😄

#claude#ai#python#git#api#security
Разработка: trend-analisis
13 февр. 2026 г.
Новая функцияtrend-analisis

Восемь API за день: как я собрал тренд-систему в production

# Восемь источников данных, один день работы и вот уже система тянет информацию со всего интернета Проект **trend-analisis** набирал обороты, но его слабое место было очевидным: система собирала сигналы о трендах, но питалась только крохами. Для полноценного анализа нужны были новые источники — не просто *много*, а *разнообразные*. Нужно было подтянуть социальные сети, новостные порталы, профильные техсообщества, поисковые тренды. За один день. В production-quality коде. Без паники. ## Зачем нам восемь источников сразу? Задача была типичной для аналитического сервиса: один источник данных — это шум, два-три — начало картины, а восемь разнородных источников — это уже сигнал. Reddit подскажет, что волнует сообщество. NewsAPI покажет, о чём пишут журналисты. Stack Overflow раскроет технические интересы. Google Trends — чистая позиция того, что гуглят люди. Каждый источник — отдельный голос, и все вместе они рисуют трендовый пейзаж. Но подключить восемь API разом — это не просто скопировать curl. Это интеграционный конвейер: конфиги с rate limits, асинхронные адаптеры с обработкой ошибок, health checks, нормализация сигналов и композитный скоринг. ## Как я это делал Первым делом определился со структурой: для каждого источника создал отдельную конфиг-модель с правильными таймаутами и лимитами запросов. Reddit ждёт полусекунды между запросами, YouTube требует аутентификации, NewsAPI предоставляет 100 запросов в день — каждый со своими правилами. Async-адаптеры писал через единый интерфейс, чтобы остальная система не парилась, откуда приходят данные. Интересный момент возник с нормализацией сигналов. Из Reddit берём апвоты и engagement ratio, из YouTube — view count и likes, из Product Hunt — голоса, из PubMed — цитирования. Как их между собой сравнивать? Социальная сеть может выдать миллион просмотров за день, а академический источник — тысячу цитаций за год. Решение было в BASELINES: каждая категория (SOCIAL, NEWS, TECH, SEARCH, ACADEMIC) имела базовые метрики, а затем веса равномерно распределялись внутри категории (сумма = 1.0). Глупо? Нет, это working solution, который можно итеративно улучшать с реальными данными. В `scoring.py` пришлось добавить обработку 18+ новых сигналов из метаданных: от количества комментариев до индекса популярности. Тесты написал параллельно с кодом — 22 unit теста плюс E2E проверка здоровья источников. ## Свежий факт о REST API, который не знали в 2010-м Когда создавали REST, никто не предусмотрел, что один API будет вызываться столько раз в секунду. Rate limiting появился потом, как забота сервиса о себе. Поэтому крупные API вроде Twitter и YouTube теперь добавляют в заголовки ответа оставшееся количество запросов (`X-RateLimit-Remaining`). Это не просто информация — это обратная связь для асинхронных очередей, которые должны умнее разподвигивать нагрузку. ## Что получилось 13 адаптеров зарегистрировалось успешно, health checks прошли 10 из 13 (три гейтированы на аутентификацию, но это ожидаемо). Reddit, NewsAPI, Stack Overflow, YouTube, Dev.to, Product Hunt, Google Trends и PubMed — теперь все они поют в хоре trend-analisis. Система может агрегировать упоминания, подсчитывать тренды, видеть, что вот прямо сейчас взлетает в техсообществе. Дальше предстоит: фидтуню веса, добавить источники второго уровня, может быть, Hacker News и Mastodon. Но фундамент готов. --- *GitHub Actions: решение проблемы, о существовании которой ты не знал, способом, который не понимаешь.* 😄

#git#commit#python#api#security
Разработка: trend-analisis
13 февр. 2026 г.
Новая функцияC--projects-bot-social-publisher

Когда модель тянется в разные стороны одновременно

# Когда тысяча строк кода говорят вам «стоп» Проект **bot-social-publisher** стоял на пороге масштабирования. Задача была амбициозной: научить нейросеть самой менять собственную архитектуру во время обучения. Звучит как научно-фантастический роман? На самом деле это была Phase 7b исследования, где предполагалось проверить, может ли модель расти и адаптироваться прямо на лету, без вмешательства человека. Я разработал три параллельных подхода. Первый — синтетические метки, которые должны были подтолкнуть сеть к самомодификации. Второй — вспомогательная функция потерь на базе энтропии, которая работала бы в тандеме с основной целью обучения. Третий — прямая энтропийная регуляризация, минималистичный и изящный. Каждый подход разворачивался в отдельный файл: `train_exp7b1.py`, `train_exp7b2.py`, `train_exp7b3_direct.py`. Плюс специализированные модули типа `control_head.py` для управления вспомогательными потерями и `expert_manager.py` для работы с модулем экспертов. Всего получилось около 1200 строк кода с тщательно продуманной архитектурой. Результаты оказались шокирующими. Первый эксперимент обрушил точность на 27%. Второй — на 11,5%. Третий? Тоже провал. Но вот что было важно: падение было не случайным. Я начал копать глубже и понял реальную причину. Когда модель получает противоречивые сигналы от нескольких функций потерь одновременно, она попадает в конфликт целей — буквально тянется в разные стороны. Многозадачное обучение без правильной структуризации становится саботажем собственной модели. Второе открытие оказалось не менее дорогостоящим: я использовал отдельное валидационное множество для отслеживания прогресса. Результат? Распределительный сдвиг (*distribution shift*) сам по себе стоил 13% точности. Неоднородность данных между тренировочным и валидационным наборами превратила помощника в saboteur. Вместо того чтобы продолжать биться в стену, я потратил время на документирование выводов. Создал 14 файлов анализа, включая `PHASE_7B_FINAL_ANALYSIS.md`. Это не выглядит как победа в классическом смысле, но именно это называется научным результатом. На основе этого я полностью переосмыслил стратегию для Phase 7c. Вместо самоизменяющейся архитектуры система теперь будет использовать **фиксированную топологию с обучаемыми параметрами**. Маски, гейтинг, распределение внимания между 12 экспертами — всё это может меняться. Но сама структура остаётся стабильной. Добавил двузадачное обучение (CIFAR-100 и SST-2) с применением **Elastic Weight Consolidation** для защиты от катастрофического забывания. Ключевой вывод: иногда самое важное, что может сказать эксперимент — это «не в этом направлении». И это нормально. --- **Интересный факт о катастрофическом забывании:** Это явление не просто нейросетевая прихоть. Оно берёт корни в самой архитектуре градиентного спуска — когда сеть переучивается на новую задачу, новые градиенты переписывают веса, которые были оптимальны для старой задачи. EWC решает это, буквально оценивая, какие веса были *важны* для первой задачи, и штрафует их за изменения. Элегантный способ заставить модель помнить. Если ваша нейросеть падает на 27% при добавлении вспомогательной функции потерь, проблема не в коде — проблема в том, что вы просите модель одновременно преследовать несовместимые цели.

#claude#ai#python#security
Разработка: bot-social-publisher
13 февр. 2026 г.
Новая функцияborisovai-site

Четыре expert'а разнесли мой feedback-сервис

# Четыре критика нашего feedback-сервиса: жестокая правда Представь ситуацию: ты потратил недели на разработку системы сбора feedback для **borisovai-site**, прошелся по best practices, всё выглядит красиво. А потом приглашаешь четырех экспертов провести code review — и они разносят твой код в пух и прах. Нет, не язвительно, а обоснованно. Я тогда сидел с этим отчетом часа два. Началось с **Security Expert**'а. Он посмотрел на мою систему сбора feedback и сказал: «Привет, GDPR! Ты знаешь, что нарушаешь европейское законодательство?» Оказалось, мне не хватало privacy notice, retention policy и чекбокса согласия. XSS в email-полях, уязвимости для timing attack'ов, email harvesting — полный набор. Но самое больное: я использовал 32-битный bitwise hash вместо SHA256. Это как строить замок из картона. Эксперт вынес вердикт: **NOT PRODUCTION READY** — пока не пофиксишь GDPR. Потом пришла очередь **Backend Architect**'а. Он посмотрел на мою базу и спросил: «А почему у тебя нет составного индекса на `(targetType, targetSlug)`?» Я посчитал: 100K записей, full-scan по каждому запросу. Это боль. Но это было ещё не всё. Функция `countByTarget` загружала **ВСЕ feedback'и в память** для подсчета — классический O(n) на production'е. Плюс race condition в create endpoint: проверка rate limit и дедупликация не были атомарными операциями. Вишенка на торте: я использовал SQLite для production'а. SQLite! Архитектор деликатно посоветовал PostgreSQL. **Frontend Expert** просмотрел React-компоненты и нашел missing dependencies в useCallback, untyped `any` в fingerprint.ts, отсутствие AbortController. Но главное убийство: **нет aria-labels на кнопках, нет aria-live на сообщениях об ошибках**. Screen readers просто не видели интерфейс. Canvas fingerprinting работал синхронно и блокировал main thread. Проще говоря, мой feedback-форм был отзывчив для слышащих пользователей, но недоступен для людей с ограничениями по зрению. И ещё **Product Owner** добавил: нет email-уведомлений админам о критических баг-репортах. Система красивая, но никто не узнает, когда пользователь кричит о проблеме. Итог? **~2 недели критических фиксов**: GDPR-соответствие (privacy notice + право на удаление данных), индекс на БД, транзакции в create endpoint, полная ARIA-поддержка, email-notifications, миграция на PostgreSQL. Сначала казалось, что я строил production-готовое решение. На самом деле я строил красивое **демо**, которое развалилось при первой серьёзной проверке. Урок: security, accessibility и database architecture — это не вишни на торте, это фундамент. Ты можешь иметь идеальный UI, но если пользователь не может получить доступ к твоему сервису или его данные не защищены, ничего не имеет значения. 😄 WebAssembly: решение проблемы, о существовании которой ты не знал, способом, который не понимаешь.

#claude#ai#python#javascript#git#api
Разработка: borisovai-site
13 февр. 2026 г.
Новая функцияborisovai-admin

От SQLite к Kubernetes: как выбрать стек для сервера

# Выбираем стек для боевого сервера: от SQLite до Kubernetes Вот я и дошёл до самой мясной части проекта **borisovai-admin** — нужно было решить, на чём строить технологический фундамент. Не просто выбрать, а выбрать правильно, с прицелом на масштабирование. Задача была масштабная: разобраться в 10 ключевых компонентах инфраструктуры и дать рекомендации для трёх разных уровней — от стартапа на $50–100 в месяц до полноценной облачной системы. Infrastructure as Code, управление конфигами, базы данных, оркестрация контейнеров, мониторинг — всё нужно было проанализировать и обосновать. Первым делом я создал структурированный анализ для каждого компонента. Взял **Terraform** для Infrastructure as Code (почему? потому что YAML в Ansible проще писать, но Terraform лучше управляет состоянием), **Ansible** для конфигурации (когда нужна простота без лишних абстракций), и вот тут начиналась интересная часть — выбор между SQLite и PostgreSQL. SQLite для первого тира — это не просто выбор экономии, это выбор разума. Встроенная база, ноль настройки, ноль инфраструктуры. Новичок может развернуть систему буквально за минуту. Но когда трафик растёт? Тогда я рекомендую чёткую миграционную дорожку: сначала **dual-write** (две базы параллельно, неделю собирали данные в обе), потом гибридный подход и только потом полная миграция на PostgreSQL с тремя серверами. Для оркестрации я выстроил пирамиду: **systemd** на одном сервере (t1), потом **Docker + Docker Compose** (t2) и наконец **Kubernetes** (t3) для тех, кто готов платить. Каждый уровень вносит свою сложность, но при правильной архитектуре переходы между ними — почти безболезненны. **Вот забавный факт про выбор инструментов:** Terraform и Ansible созданы в разных мирах. Terraform — это декларативный язык состояния (вы описываете, что хотите). Ansible — это процедурный язык действий (вы описываете, что делать). Профессионалы часто используют их вместе: Terraform создаёт инфраструктуру, Ansible её настраивает. Это как иметь архитектора и прораба на одном проекте. В итоге я подготовил три документа на 10 000+ слов: матрицу выбора с оценками по 10 критериям, полный анализ каждого компонента и готовый набор миграционных сценариев. Теперь у меня есть чёткая дорожная карта, и любой разработчик может взять этот стек и масштабировать систему вверх, не переделывая всё с нуля. Впереди — Track 3 с архитектурой AI-агента, и я уже вижу, как туда впишется этот технологический фундамент. 😄 Что общего у Terraform и кота? Оба отказываются делать то, что вы просили, пока не напишете ровно то, что они хотят видеть.

#claude#ai#git#security
Разработка: borisovai-admin
13 февр. 2026 г.
Обучениеborisovai-site

Как мы превратили экспертную проверку в систему

# Как мы собрали пакет экспертной оценки и что из этого вышло В **borisovai-site** встала типичная задача, которая только звучит простой: нужно было подготовить полноценный пакет для проверки системы feedback опытными разработчиками. Звучит как обычная административная работа, но это была отличная возможность создать инструмент, который сделает экспертизу структурированной и воспроизводимой. **Первым делом я понял объём.** Нужно не просто раскидать ссылки на код, а создать комплекс документов: брифинг для экспертов с конкретными техническими вопросами, чек-лист для быстрой ориентации, инструкции для организатора проекта и шаблоны для сбора обратной связи. Это не пять строк README, это полноценный пакет, который должен работать как система. **Начал с архитектуры пакета.** Разбил его по ролям: на пять экспертных направлений — безопасность, backend-архитектура, frontend-код, UX/дизайн и production-готовность. Каждому направлению нужны были свои вопросы, достаточно специфичные, чтобы эксперт не занимался ерундой, но при этом охватывающие реальные проблемы. Неожиданно выяснилось, что правильные вопросы — это половина успеха. Вопрос вроде «Насколько хорошо задокументирован код?» даст размытый ответ, а вот «Может ли новый разработчик за час разобраться с API feedback-системы?» уже даёт конкретное понимание. **EXPERT_REVIEW_REQUEST.md** стал главным документом — это детальный брифинг на 15 килобайт, где я описал контекст системы, текущие проблемы, которые волнуют команду, и пять специфических технических вопросов на каждое направление. **EXPERT_REVIEW_CHECKLIST.md** — это его компактный напарник для быстрой ориентации. А **HOW_TO_REQUEST_EXPERT_REVIEW.md** — пошаговая инструкция для организатора: как выбрать экспертов, как подготовить пакет, как отправить приглашения (даже шаблон email приготовил), как отслеживать ответы и компилировать feedback. **Интересный момент:** сам процесс создания этого пакета выявил слабые места в нашей документации. Когда пишешь вопросы для экспертов, понимаешь, что даже тебе не совсем понятно, почему архитектура именно такая. Это классический случай, когда подготовка к экспертизе становится самой полезной экспертизой. **Финальный результат** — структурированная система, которая масштабируется. Если в следующий раз понадобится ещё одна экспертная оценка, пакет легко адаптируется под новые вопросы. И главное — у нас есть объективный критерий: целевой рейтинг 4.0+ из 5.0 звёзд. Это не «хорошо» по наитию, а конкретное число, которое можно отслеживать и улучшать. Теперь осталось только найти экспертов и отправить им пакеты. Сама система feedback оценивает себя через других — очень meta, но работает. --- Разработчик: «Я подготовил пакет для экспертной оценки». Эксперт: «А есть ли у вас сам ответ?». Разработчик: «Да, но я хочу услышать ваше мнение». 😄

#claude#ai#git#security
Разработка: borisovai-site
13 февр. 2026 г.
Новая функцияspeech-to-text

Микрофон учится слушать: история гибридной транскрипции

# Как мы научили микрофон слушать по-умному: история гибридной транскрипции Представьте себе знакомую ситуацию: вы нажимаете кнопку записи в приложении для голосового ввода, говорите фразу, отпускаете кнопку. Первый результат появляется почти мгновенно — 0.45 секунды, и вы уже можете продолжать работу. Но в фоне, незаметно для вас, происходит волшебство: тот же текст переобрабатывается, улучшается, и спустя 1.23 секунды выдаёт результат на 28% точнее. Это и есть гибридный подход к транскрипции, который мы только что воплотили в проекте **speech-to-text**. ## Задача, которая вставляла палки в колёса Изначально стояла простая, но коварная проблема: стандартная модель Whisper обеспечивает хорошую скорость, но качество оставляет желать лучшего. WER (word error rate) составлял мрачные 32.6% — представьте, что каждое третье слово может быть неправильным. Пользователь выдвинул чёткое требование: **реализовать гибридный подход прямо сейчас, чтобы получить 50% улучшение качества** путём тонкой настройки Whisper на русских аудиокнигах. Первым делом мы переосмыслили архитектуру. Вместо того чтобы ждать идеального результата, который займёт время, мы решили играть в две руки: быстрая базовая модель даёт мгновенный результат, а в параллельном потоке улучшенная модель шлифует текст в фоне. Это похоже на работу водителя-ассистента: первый делает очевидное (едем в основную полосу), а второй уже план Б готовит (проверяет слепые зоны). ## Как это реализовалось Интеграция гибридного подхода потребовала изменений в несколько ключевых мест. В `config.py` добавили параметры для управления режимом: простое включение-выключение через `"hybrid_mode_enabled": true`. В `main.py` реализовали оркестрацию двух потоков транскрипции с координацией результатов. Крайне важным оказался класс `HybridTranscriber` — именно он управляет тем, как две разные модели работают в унисон. Неожиданно выяснилось, что потребление памяти выросло на 460 МБ, но оно того стоит: пользователь получает первый результат так же быстро, как раньше (те же 0.45 секунды), а через 1.23 секунды получает улучшенный вариант. Главное — **нет ощущения задержки**, потому что основной поток не блокируется. ## Интересный факт о голосовых помощниках Забавно, что идея многослойной обработки голоса не нова. Amazon Alexa, созданная с использованием наработок британского учёного Уильяма Танстолл-Педо (его система Evi) и польского синтезатора Ivona (приобретена Amazon в 2012–2013 годах), работает по похожему принципу: быстрая обработка плюс фоновое уточнение. И хотя сейчас Amazon переходит на собственную LLM Nova, суть остаётся той же — многоуровневая архитектура для лучшего пользовательского опыта. ## Что дальше Мы создали полное руководство из 320 строк с инструкциями для финального 50% прироста качества через тонкую настройку на специализированных данных. Это потребует GPU на 2–3 недели ($15–50), но для серьёзных приложений это стоит. А пока пользователи могут включить гибридный режим в течение 30 секунд и сразу почувствовать 28% улучшение. Документация разложена по полочкам: `QUICK_START_HYBRID.md` для нетерпеливых, `HYBRID_APPROACH_GUIDE.md` для любопытных, `FINE_TUNING_GUIDE.md` для амбициозных. Тесты в `test_hybrid.py` подтверждают, что всё работает как надо. Научились простому, но мощному принципу: иногда лучше дать пользователю хороший результат *сейчас*, чем идеальный результат *потом*. Почему ZeroMQ не пришёл на вечеринку? Его заблокировал firewall.

#claude#ai#python#javascript#api#security
Разработка: speech-to-text
13 февр. 2026 г.
Обучениеllm-analisis

Эксперименты, которые показали, что нейросеть не готова расти сама

# Когда эксперименты показывают, что вы идёте в тупик — это тоже результат Проект **llm-analisis** стоял на пороге важного этапа. Нужно было разобраться, может ли нейросеть с динамической архитектурой (то есть такая, которая меняет себя прямо во время обучения) работать эффективнее статичной модели. Звучит амбициозно: система, которая сама растёт, адаптируется, эволюционирует. Но амбиции и реальность — вещи разные. ## Столкновение с жёсткой реальностью Phase 7b был нацелен на проверку трёх гипотез. Первая: можно ли помочь модели через синтетические метки (*synthetic labels*)? Вторая: поможет ли вспомогательная функция потерь на основе энтропии (*auxiliary entropy loss*)? Третья: может быть, прямой подход с энтропией — самый эффективный? Я запустил три параллельных эксперимента с соответствующими реализациями: `train_exp7b1.py`, `train_exp7b2.py` и `train_exp7b3_direct.py`. Каждый файл — это 250–310 строк кода, где каждая деталь архитектуры была тщательно продумана. Добавил специализированный `control_head.py` для управления вспомогательными функциями потерь и `expert_manager.py` для работы с модулем экспертов. Результаты оказались шокирующими, но очень информативными. ## Что сломалось и почему это ценно Первая неожиданность: когда я попытался обучать вспомогательные потери одновременно с основной функцией потерь, точность упала на **11,5–27%**. Это не баг — это конфликт целей. Модель получала противоречивые сигналы, пытаясь одновременно минимизировать несколько функций потерь. Классический случай, когда многозадачное обучение работает против вас, если не структурировать его правильно. Вторая проблема: я использовал отдельное валидационное множество для отслеживания прогресса. Знаете что? Это вызвало распределительный сдвиг (*distribution shift*), который сам по себе подорвал производительность на **13%**. Урок: не всегда валидационное множество — друг вашей модели. Третье открытие касалось архитектуры. Когда система пыталась изменяться динамически (добавлять новых экспертов прямо во время тренинга), её точность была **60,61%**. Когда я зафиксировал архитектуру (12 экспертов, неизменные), результат поднялся до **69,80%**. Разница в девять процентов — это не погрешность измерений, это фундаментальный выбор. ## Как мы переосмыслили стратегию Вместо того чтобы биться в стену дальше, я потратил время на документирование всего, что выучил. Создал 14 файлов документации, включая `PHASE_7B_FINAL_ANALYSIS.md` и детальные планы для каждого из трёх подходов. Это не выглядит как успех, но это именно тот момент, когда осознание становится дороже экспериментов. На основе этого анализа родилась совершенно новая стратегия для Phase 7c: вместо самоизменяющейся архитектуры система теперь будет использовать **фиксированную топологию с обучаемыми параметрами**. Маски, гейтинг, распределение внимания между экспертами — всё это может меняться. Но сама структура остаётся стабильной. Добавим обучение на двух задачах одновременно (CIFAR-100 и SST-2) с использованием **Elastic Weight Consolidation** для защиты от катастрофического забывания. ## Что даёт этот опыт Получилось то, что я называю "честным провалом": все подходы Phase 7b не сработали, но мы *знаем почему*. Это стоит больше, чем слепое везение. Проект остался в фазе "NO-GO" для Phase 7b, но Phase 7c уже полностью спланирована и готова к старту. Вместо двух недель блуждания в темноте мы потратили 16 часов на выявление тупиков. **Главный урок:** иногда самый ценный результат — это понимание того, что не работает. И документирование этого пути для будущих итераций. 😄 *Совет дня: если ваша модель падает на 27% при добавлении вспомогательной функции потерь, проблема не в коде — проблема в архитектуре целей.*

#claude#ai#python#security
Разработка: llm-analisis
13 февр. 2026 г.
Новая функцияtrend-analisis

8 источников данных вместо 5: архитектура без хаоса

# Когда 8 источников данных лучше, чем 5: история добавления адаптеров в trend-analisis Проект **trend-analisis** — это система для анализа трендов и выявления поднимающихся волн в интернете. Задача казалась простой: расширить количество источников данных с пяти на тринадцать. Но когда я начал работать над этим, выяснилось, что просто дописать парочку адаптеров — это полдела. Стояла вот такая задача: система работала с базовыми источниками, но нужно было подключить Reddit, NewsAPI, Stack Overflow, YouTube, Product Hunt, Google Trends, Dev.to и PubMed. Каждый из этих сервисов имеет свой API, свои ограничения и свою логику. И всё это нужно было интегрировать так, чтобы система оставалась гибкой и не развалилась под грузом новых зависимостей. Первым делом я распланировал архитектуру: создал три новых модуля — **social.py** (Reddit и YouTube), **news.py** (NewsAPI) и **community.py** (Stack Overflow, Dev.to, Product Hunt). Каждый адаптер наследует базовый класс и реализует единый интерфейс. Это позволило потом просто регистрировать их в единой системе через источник-реестр. Неожиданно выяснилось, что обновление конфигурации — это не просто добавление новых блоков в `.env`. Пришлось создавать `DataSourceConfig` модели для каждого источника, настраивать веса категорий так, чтобы они суммировались ровно в 1.0 (иначе система вычисляет рейтинги неправильно), и регистрировать каждый адаптер в `source_registry`. Плюс Google Trends потребовал отдельного адаптера в **search.py**, а PubMed — в **academic.py**. Интересный факт о том, почему асинхронный подход здесь критически важен: каждый запрос к внешнему API может занять 1–5 секунд. Если делать это синхронно, то 13 источников загружались бы последовательно — получилось бы минуту-другую ждать результаты. С **aiohttp** и асинхронной инициализацией адаптеры загружаются параллельно, и общее время сокращается в разы. После написания кода пришло время проверки. Запустил 50+ unit-тестов в `test_new_adapters.py` — все прошли. Потом E2E-тесты в `test_free_sources_e2e.py` — и здесь появилась проверка: действительно ли все 13 адаптеров зарегистрированы? Запустил скрипт: ``` Registered adapters: 13 ✓ Config loaded successfully ✓ Category weights: все суммируют к 1.0000 ``` Всё готово. Система теперь анализирует тренды с восьми новых источников: социальные дискуссии с Reddit, новости через NewsAPI, технические вопросы со Stack Overflow, видео-тренды с YouTube, запуски продуктов с Product Hunt, поисковый интерес через Google Trends, dev-сообщество с Dev.to и научные статьи с PubMed. Что дальше? Теперь нужно следить за качеством данных, оптимизировать частоту обновлений и убедиться, что система корректно взвешивает сигналы из разных источников. Но главное — это работает, и система готова к следующему расширению. Если честно, в процессе я понял простую вещь: архитектура на основе адаптеров — это не просто модный подход, а жизненная необходимость. Когда каждый источник имеет свой класс и свою логику, добавить девятый источник можно за час, не трогая остальную систему. 😄 Настоящая боль не в коде, а в том, чтобы найти, кому принадлежит API ключ, который лежит в `.env` файле без комментариев и истории.

#claude#ai#python#api
Разработка: trend-analisis
13 февр. 2026 г.
Новая функцияborisovai-admin

DevOps за день: как мы выбрали стек через конкурентный анализ

# Как мы спроектировали DevOps-платформу за день: конкурентный анализ на стероидах Проект **borisovai-admin** требовал системного подхода к управлению инфраструктурой. Стояла непростая задача: нужно было разобраться, что вообще делают конкуренты в DevOps, и построить свою систему с трёхуровневой архитектурой. Главный вопрос: какой стек выбрать, чтобы не переплатить и не потерять гибкость? Первым делом я понимал, что нельзя прыгать в реализацию вслепую. Нужно провести честный конкурентный анализ — посмотреть, как это решают **HashiCorp** с их экосистемой (Terraform, Nomad, Vault), как это делается в **Kubernetes** с GitOps подходом, и что там у **Spotify** и **Netflix** в их Platform Engineering. Параллельно изучил облачные решения от AWS, GCP, Azure и даже AI-powered DevOps системы, которые только появляются на рынке. Результат был обширный: создал **три больших документа** объёмом в 8500 слов. **COMPETITIVE_ANALYSIS.md** — это развёрнутое исследование шести ключевых подходов с их архитектурными особенностями. **COMPARISON_MATRIX.md** — матрица сравнения по девяти параметрам (Time-to-Deploy, Cost, Learning Curve) с рекомендациями для каждого уровня системы. И финальный **BEST_PRACTICES.md** с практическими рекомендациями: Git как source of truth, state-driven архитектура, zero-downtime deployments. Неожиданно выяснилось, что для нас идеально подходит многоуровневый подход: **Tier 1** — простой вариант с Ansible и JSON конфигами в Git; **Tier 2** — уже Terraform с Vault для секретов и Prometheus+Grafana для мониторинга; **Tier 3** — полноценный Kubernetes со всеми OpenSource инструментами. Самое интересное: мы обнаружили, что production-ready AI для DevOps пока не существует — это огромная возможность для инноваций. Вот что важно знать про DevOps платформы: **state-driven архитектура** работает несравненно лучше, чем imperative approach. Почему? Потому что система всегда знает целевое состояние и может к нему стремиться. GitOps как source of truth — это не мода, а необходимость для аудитируемости и восстанавливаемости. И про многооблачность: vendor lock-in — это не просто дорого, это опасно. В результате я готов параллельно запустить остальные треки: Selection of Technologies (используя findings из анализа), Agent Architecture (на основе Nomad pattern) и Security (с best practices). К концу будет полная MASTER_ARCHITECTURE и IMPLEMENTATION_ROADMAP. Track 1 на **50% завершено** — основной анализ готов, осталась финализация. Главный вывод: правильная предварительная работа экономит месяцы разработки. Если в DevOps всё работает — переходи к следующему треку, если не работает — всё равно переходи, но с документацией в руках.

#claude#ai#javascript#git#security
Разработка: borisovai-admin
13 февр. 2026 г.
Обучениеllm-analisis

Когда самоадаптивная сеть начинает саботировать сама себя

# Когда всё падает: Как я 16 часов охотился на призрак в нейросети Проект **llm-analysis** вошёл в фазу 7b, и я был уверен — вот она, момент прорыва. Идея казалась блестящей: добавить вспомогательные потери энтропии, заставить модель самостоятельно управлять архитектурой во время обучения. Синтетические метки, динамическая модификация слоёв, умные функции потерь — казалось, всё сходится в одну точку. Но вместо взлёта получилась полоса падения. На фазе 7a я достиг 69.80% точности на фиксированной архитектуре. Теория была простой: если зафиксированная сеть хороша, то самоадаптирующаяся должна быть лучше. Опубликовано же, оптимизируют ведь. Запустил эксперименты. **Эксперимент 7b.1** с синтетическими метками упал до 58.30% — деградация на 11.5%. Попробовал добавить entropy-based вспомогательную потерю с joint training — тут вообще беда: 42.76% точности. Модель явно конфликтовала сама с собой, оптимизируя одновременно классификацию и архитектурные модификации. **Эксперимент 7b.3** с прямой энтропией показал 57.57% — чуть лучше, но всё равно худше исходной фазы 7a. Три недели назад я бы назвал это просто плохими гиперпараметрами. Но я писал логи детально, сравнивал шаг за шагом. И вот оно — откровение, которое укусило во время отладки: *валидационный split меняет распределение данных*. Только эта смена дала деградацию в 13% от исходного результата. Архитектура здесь была вторична. Ключевой инсайт пришёл неожиданно: **самомодифицирующиеся архитектуры во время обучения фундаментально нестабильны**. Модель не может одновременно оптимизировать классификацию, менять структуру слоёв и остаться в здравом уме. Это не issue в коде, это issue в физике обучения. Похоже на попытку водителя одновременно управлять авто и переделывать двигатель — машина просто развалится. Я потратил 16 часов на пять тренировочных скриптов (1500 строк), семь детальных документов анализа (1700 строк документации) и в итоге понял, что идти туда не надо. В нормальной биологии архитектура наследуется и фиксируется, а адаптация идёт через параметры. Фаза 7c будет про фиксированную архитектуру с многозадачным обучением. Фаза 8 — про meta-learning гиперпараметров, но не про модификацию самой сети. Неприятно? Да. Потрачено впустую? Нет — я выявил dead end до того, как зайти туда с полным размахом. Быстрое *отрицательное* открытие иногда дороже золота. Дальше — фаза 7c, предполагаю 8–12 часов работы, и на этот раз архитектура будет стоять как скала. 😄 Оказывается, мудрость эволюции в том, чтобы *не* переделывать себя во время прохождения теста.

#claude#ai#python#security
Разработка: llm-analisis
13 февр. 2026 г.
Новая функцияborisovai-site

Feedback система за выходные: спам-защита и React компоненты

# Feedback система за выходные: от API до React компонентов с защитой от спама Понедельник утром открываю Jira и вижу задачу: нужна система обратной связи для borisovai-site. Не просто кнопки "понравилось/не понравилось", а настоящая фишка с рейтингами, комментариями и защитой от ботов. Проект небольшой, но аудитория растёт — нужна смекалка при проектировании. Начал я с архитектуры. Очень важно было подумать про защиту: спам никто не любит, а репутация падает быстро. Решил использовать двухуровневую защиту. Во-первых, **браузерный fingerprint** — собираю User-Agent, разрешение экрана, временную зону, язык браузера, WebGL и Canvas hash. Получается SHA256-подобный хеш, который хранится в localStorage. Это не идеально, но для 80% случаев работает. Во-вторых, **IP rate limiting** — максимум 20 фидбеков в час с одного адреса. Комбо из браузера и IP даёт приличную защиту без излишней паранойи. На бэке создал стандартную CMS структуру: content-type `feedback` с полями для типа отзыва (helpful, unhelpful, rating, comment, bug_report, feature_request), самого комментария, email опционально. Приватные поля — browserFingerprint, ipAddress, userAgent — хранятся отдельно, видны только администратору. Логика валидации простая, но эффективная: пустые комментарии не принимаем, максимум 1000 символов, проверяем на дубликаты по паре fingerprint + targetSlug (то есть одна оценка на страницу от пользователя). Фронтенд часть оказалась интереснее. Написал утилиту `lib/fingerprint.ts`, которая собирает все данные браузера и генерирует стабильный хеш — если пользователь вернётся завтра с того же девайса, хеш совпадёт. React Hook `useFeedback.ts` инкапсулирует всю логику работы с API: `submitFeedback()` для отправки, `fetchStats()` для получения счётчиков просмотров (сколько человек оценило), `fetchComments()` для загрузки последних комментариев с простой пагинацией. Компоненты сделал модульными: `<HelpfulWidget />` — это просто две кнопки с лайком и дизлайком, `<RatingWidget />` — пять звёзд для оценки (стандартный UX паттерн), `<CommentForm />` — textarea с валидацией на фронте перед отправкой. Каждый работает независимо, можно микшировать на странице. **Интересный момент про fingerprinting.** Много разработчиков думают, что браузерный fingerprint — это какое-то магическое устройство, а на самом деле это просто комбинация публичных данных. Canvas fingerprinting, например, — это отрисовка градиента на невидимом canvas и сравнение пикселей. Неочевидно, что WebGL renderer и версия видеодрайвера сильно влияют на результат, и один и тот же браузер на разных машинах выдаст разные хеши. Поэтому я не полагаюсь на fingerprint как на абсолютный идентификатор — это просто дополнительный слой. Итогом стали **8 готовых компонентов, 3 документа** (полный гайд на 60+ строк, шпаргалка для быстрого старта, диаграммы архитектуры) и чеклист вопросов для дизайнера про стили и поведение. API готов, фронтенд готов, тесты написаны. Следующий спринт — интегрировать в шаблоны страниц и собрать статистику с первыми пользователями. Дальше можно добавить модерацию комментариев, интеграцию с email, A/B тестирование вариантов виджетов. Но сейчас — в production. *Почему GitHub Actions — лучший друг разработчика?* 😄 *Потому что без него ничего не работает. С ним тоже, но хотя бы есть кого винить.*

#claude#ai#javascript#api
Разработка: borisovai-site
13 февр. 2026 г.
Новая функцияborisovai-site

Многоуровневая защита: как я спасал блог от спама

# Защита от спама: как я строил систему обратной связи для блога Проект **borisovai-site** — это блог на React 19 с TypeScript и Tailwind v4. Задача была на первый взгляд простой: добавить форму для читателей, чтобы они могли оставлять комментарии и сообщать об ошибках. Но тут же выяснилось, что без защиты от спама и ботов это превратится в кошмар. Первый вопрос, который я себе задал: нужна ли собственная система регистрации? Ответ был быстрым — нет. Регистрация — это барьер, который отсеивает легальных пользователей. Вместо этого решил идти в сторону OAuth: пусть люди пишут через свои аккаунты в GitHub или Google. Просто, надёжно, без лишних паролей. Но OAuth — это только половина защиты. Дальше нужна была **многоуровневая система anti-spam**. Решил комбинировать несколько подходов: **Первый уровень** — детектирование спам-паттернов. Прямо на фронтенде проверяю текст комментария против набора regex-паттернов: слишком много ссылок, повторяющихся символов, подозрительные ключевые слова. Это отлавливает 80% очевидного мусора ещё до отправки на сервер. **Второй уровень** — rate limiting. Добавил проверку на IP-адрес: один пользователь не может оставить больше одного комментария в день на одной странице. Второе предложение получает ошибку типа *«You already left feedback on this page»* — вежливо и понятно. **Третий уровень** — CAPTCHA. Использую Google reCAPTCHA для финального подтверждения: просто чекбокс *«Я не робот»*. Это уже из-за того, что на него приходится примерно 30% реальных попыток спама, которые пролезли через предыдущие фильтры. Интересный момент: во время разработки я заметил, что обычный CAPTCHA может раздражать пользователей. Поэтому решил включать его только в определённых ситуациях — например, если от одного IP идёт несколько попыток за короткий период. В спокойный день, когда всё чистое, форма остаётся лёгкой и быстрой. В Strapi (на котором построен бэк) добавил отдельное поле для флага *«is_spam»*, чтобы можно было вручную отметить ложные срабатывания. Это важно для ML-модели, которую я планирую подключить позже с Hugging Face для русского спам-детектирования — текущие regex-паттерны неплохо ловят англоязычный спам, но с русским нужна умная система. **Любопытный факт:** Google получил patent на CAPTCHA ещё в 2003 году. Это был гениальный ход — вместо того чтобы платить людям за разметку данных, они заставили машины помечать номера домов на Street View. Контрольные вопросы приносили пользу компании. В итоге получилась система, которая работает в трёх режимах: мягком (для доверенных пользователей), среднем (обычная защита) и жёстком (когда начинается явный спам). Читатели могут спокойно писать, не сталкиваясь с паранойей безопасности, а я тем временем спокойно сплю, зная, что чат-боты и спамеры не затопят комментарии. Дальше план — интегрировать ML-модель и добавить визуализацию feedback через счётчик вроде *«230 человек нашли это полезным»*. Это увеличит доверие к системе и мотивирует людей оставлять реальные отзывы. Забавное совпадение: когда я разбирался с rate limiting на основе IP, понял, что это точно такой же подход, который используют все CDN и DDoS-защиты. Оказывается, простые вещи часто работают лучше всего.

#claude#ai#python#javascript#git#api#security
Разработка: borisovai-site
13 февр. 2026 г.
Исправлениеspeech-to-text

Whisper упирается в стену: что происходит, когда оптимизация бессильна

# Speech-to-Text под давлением: когда оптимизация упирается в физику Представь себе ситуацию: нужна система речевого распознавания, которая работает в режиме реального времени. Бюджет — менее одной секунды на обработку аудио. Звучит выполнимо? Pink Elephant, разработчик проекта **speech-to-text**, решил это проверить экспериментально. И вот что из этого вышло. ## Охота на чудо-оптимизацию Всё начиналось с вопроса: а может ли стандартная модель Whisper работать на этой задаче? Текущие метрики выглядели удручающе — 32,6% WER (Word Error Rate, коэффициент ошибок распознавания). Мечта, конечно, 80% улучшение, но кто ж мечтать не будет. Первый шаг — попробовать альтернативные модели Whisper. Может, маленькая модель справится быстрее? Tiny дала 56,2% WER — хуже, чем base. Small показала весьма интересный результат: 23,4% WER (28% улучшение!), но потребовала 1,23 секунды обработки. А бюджет-то 1 секунда. Грустно. Medium вообще 3,43 секунды — в три раза медленнее, чем надо. Потом пришли идеи поумнее: beam search, варьирование температуры, фильтрация результатов через T5 (большую языковую модель для коррекции текста). Но — неожиданно выяснилось — ничего из этого не помогало. Beam search с температурой давал ровно те же 32,6% WER. Разные пороги T5-фильтра (от 0,6 до 0,95) тоже. Зато когда убрали T5 совсем, ошибок стало 41%. T5 оказался спасением, но не панацеей. Потом попробовали гибридный подход: base-модель для реального времени + medium в фоне. Сложновато, но теоретически возможно. Последовательную обработку (сначала одно, потом другое) пришлось отмести — непрактично. ## Когда данные говорят правду А потом разработчик проанализировал, где именно Whisper base ошибается. Больше всего пропусков (deletions) — 12 ошибок, замены (substitutions) — 6. Проблема не в плохой стратегии обработки, а в самой модели. Вот такой неудобный факт. **Large Language Models** как Whisper создаются с применением трансформер-архитектуры, обучаясь на огромных объёмах текстовых данных через самоконтролируемое обучение. И вот в чём закавыка: даже сильные LLM-ы достигают потолка качества, если их заставить работать в несоответствующих условиях. В нашем случае — в режиме реального времени на CPU. ## Горькая истина Итоговый вывод был честный и немного безжалостный: base-модель — единственный вариант, который укладывается в бюджет менее одной секунды, но качество её зафиксировано в 32,6% WER. Small даёт 28% улучшение (23,4% WER), но требует на 230 миллисекунд больше. 80% сокращение ошибок на CPU? Невозможно. Никакая волшебная post-processing техника это не спасёт. Нужно или переходить на GPU, или согласиться с текущим качеством, или рассмотреть асинхронную фоновую обработку. Тысячи строк кода оптимизации упёрлись в стену физических ограничений. Иногда лучшая оптимизация — это честный разговор о целях проекта. 504: gateway timeout. Ожидание ответа от PM. 😄

#git#commit#api#security
Разработка: speech-to-text
13 февр. 2026 г.
Новая функцияllm-analisis

[Request interrupted by user for tool use]

# Когда модель учится менять себя: как мы ловили ошибки в самоадаптирующейся архитектуре Проект **llm-analysis** — это попытка научить нейросеть не просто решать задачу классификации текста SST-2, но ещё и *самостоятельно управлять своей архитектурой*. Звучит как фантастика? На деле это долгая война с энтропией и случайными числами. ## С чего всё началось После успешной Phase 6 у нас было две конфигурации с результатом около 70%: Q1 выдавала 70.15%, Q2 с MoE-архитектурой добралась до 70.73%. Казалось бы, пик достигнут. Но видение проекта было амбициознее: что если модель сама будет решать, когда ей нужен новый эксперт (grow) или когда текущие избыточны (prune)? Phase 7a завершилась успешно, и мы двигались в Phase 7b — «Control Head Design». Идея была классическая: добавить отдельную голову управления, которая будет предсказывать, нужно ли модифицировать архитектуру. Но тут начались приключения. ## Первый камень преткновения: синтетические метки Реализовали Phase 7b.1 с энтропийным подходом. Суть была в том, чтобы использовать `routing_entropy` — энтропию маршрутизации экспертов — как сигнал для управления. Сказано — сделано. Запустили обучение... И получили **58.30% точность вместо 69.80% на базовой модели**. Полный NO-GO. Ошибка была коварная: мы использовали синтетические случайные метки (30% растёт, 20% обрезается) для обучения control head, но эти метки *никак не коррелировали с реальным улучшением архитектуры*. Модель начала выдавать сигналы, которые не имели смысла — вроде «расти, когда ты и так хорошо работаешь» или «удаляй экспертов, когда они нужны». ## Поворот: энтропия как источник истины Переделали подход в Phase 7b.2. Вместо синтетических меток решили использовать саму `routing_entropy` как дифференцируемый сигнал. Ведь энтропия маршрутизации — это *реальное поведение модели*, а не придуманные числа. Создали три новых файла: полный план стратегии, `expert_manager.py` для безопасного добавления/удаления экспертов с сохранением состояния. Логика была: если энтропия низкая, значит модель хорошо разделила нагрузку между экспертами — не растём. Если энтропия высокая, нужен новый голос в ансамбле. ## Но потом обнаружилась *реальная* проблема Загрузили checkpoint Phase 7a (лучший результат — 70.73%), запустили обучение с control head... и модель стартовала с точностью 8.95% вместо ожидаемых 70%. Это была красная лампочка. Начали копать. Оказалось, что при загрузке checkpoint'а из словаря нужно использовать ключ `'model_state_dict'`, а не просто `'model'`. Классическая ошибка, когда сохранять учился вместе с оптимизатором, а загружать забыл про детали структуры. Чинили. Потом ещё раз запустили. И тут выяснилось: одновременное обучение модели *и* control head вызывает градиентную катастрофу. Точность падает, entropy-сигналы становятся шумом. ## Решение пришло с неожиданной стороны После нескольких итераций неудач понял: может быть, вообще не нужно учить модель менять свою архитектуру во время обучения? Может быть, архитектура должна быть *заморожена*? Phase 7b.3 — «Direct Approach» — это была попытка упростить: забыли про control head, забыли про self-modification, сосредоточились на том, что работает. Оказалось, что 12 экспертов, найденные в Phase 7a, — это уже оптимум. Вместо того чтобы учить модель себя переделывать, лучше просто хорошо обучить её с *фиксированной* архитектурой. Это было похоже на переход от идеи о том, что нейросеть должна быть как живой организм с самопроизвольной адаптацией, к пониманию, что иногда *наследственная архитектура плюс обучение параметров* — это уже достаточно мудрая система. ## Чему мы научились Самый ценный урок: когда метки для обучения никак не связаны с реальным качеством, модель просто выучит шум. Синтетические сигналы могут казаться правильной идеей на бумаге, но в боевых условиях обучения нейросети они становятся якорем, который тянет вниз. Второй урок: не каждая красивая идея — это хорошая идея в ML. Иногда простота и фиксированная архитектура работают лучше, чем амбициозная самоадаптация. Третий урок: checkpoint'ы — это хитрые штуки. Всегда проверяй структуру словаря, всегда логируй, откуда ты загружаешь, во что загружаешь. Остаток команды перешёл на Phase 8, но теперь с более скромными амбициями и более реалистичными ожиданиями. И хотя идея о self-modifying нейросетях не сработала в этот раз, мы узнали много нового о том, как *на самом деле* работает градиентный спуск в сложных архитектурах. --- 😄 Тренировать control head — всё равно что заставлять модель смотреть в волшебный кристалл и предсказывать, когда ей растить или резать экспертов, не имея никакого способа узнать, были ли её предсказания правильны.

#claude#ai#python#git#api#security
Разработка: llm-analisis
13 февр. 2026 г.
Новая функцияspeech-to-text

Когда пороги T5 упираются в потолок качества

# Когда оптимизация упирается в стену: история о порогах T5 Работаю над **speech-to-text** проектом уже несколько спринтов. Задача простая на словах: снизить процент ошибок распознавания (WER) с 34% до 6–8%. Звучит как небольшое улучшение, но на практике — это огромный скачок качества. Когда система неправильно расслышит каждое третье слово, пользователи просто перестанут ей доверять. Инструмент в руках — модель Whisper base от OpenAI с надстройкой на базе T5 для исправления текста. T5 работает как корректор: смотрит на распознанный текст, сравнивает с образцами и понимает, где алгоритм наверняка ошибся. Вот только настройки T5 были довольно мягкие: пороги сходства текста 0.8 и 0.85. Может, нужно сделать строже? **Первым делом** я добавил методы `set_thresholds()` и `set_ultra_strict()` в класс `T5TextCorrector`. Идея была хороша: позволить менять чувствительность фильтра на лету. Включил "ультра-строгий" режим с порогами 0.9 и 0.95 — почти идеальное совпадение текстов. Потом запустил **comprehensive benchmark**. Проверил четыре подхода: - **Базовый + улучшенный T5 (0.8/0.85)**: 34.0% WER за 0.52 сек — это наша текущая реальность ✓ - **Ультра-строгий T5 (0.9/0.95)**: 34.9% WER, 0.53 сек — хуже примерно на один процент - **Beam search с пятью лучами + T5**: 42.9% WER за 0.71 сек — катастрофа, качество упало в три раза - **Только база без T5**: 35.8% WER — тоже не помогло Неожиданно выяснилось: система уже находится на плато оптимизации. Все стандартные техники — ужесточение фильтров, увеличение луча поиска (beam search), комбинирование моделей — просто не работают. Мы выжали максимум из текущей архитектуры. **Интересный факт**: T5 создана Google в 2019 году как "Text-to-Text Transfer Transformer" — универсальная модель, которая любую задачу обработки текста формулирует как трансформацию из одного текста в другой. Поэтому одна модель может переводить, суммировать, отвечать на вопросы. Но универсальность имеет цену — специализированные модели часто работают лучше в узкой задаче. Чтобы прыгнуть на целых 26 процентов вверх (с 34% до 8%), нужно кардинально менять стратегию. Переходить на более мощную Whisper medium? Но это превысит бюджет времени отклика. Обучать свою модель на отраслевых данных? Требует месяцев работы. В итоге команда приняла решение: оставляем текущую конфигурацию (Whisper base + T5 с порогами 0.8/0.85) как оптимальную. Это лучшее соотношение качества и скорости. Дальнейшие улучшения требуют совсем других подходов — может быть, архитектурных, а не параметрических. Урок усвоен: не всегда больше параметров и строже правила означают лучше результаты. Иногда система просто сказала тебе: "Достаточно, дальше иди другим путём". 😄 *Почему разработчик попал в плато оптимизации? Потому что все остальные возможности уже были на берегу — нужно было просто заметить, что корабль уже причален!*

#git#commit#python#security
Разработка: speech-to-text
13 февр. 2026 г.
Обучениеspeech-to-text

Микротюнинг алгоритма: как сэкономить гигабайты памяти

# Когда микротюнинг алгоритма экономит гигабайты памяти Работаю над проектом speech-to-text, и вот типичная история: всё кажется работающим, но стоишь перед выбором — либо система пожирает память и отзывается медленно, либо производит мусор вместо текста. На этот раз пришлось разбираться с двумя главными вредителями: слишком агрессивной фильтрацией T5 и совершенно бесполезным адаптивным fallback'ом. Начну с того, что случилось. Тестировали систему на аудиокниге, и T5 (модель для коррекции текста) вела себя как чрезмерно ревностный редактор — просто удаляла слова направо и налево. Результат? Потеря 30% текста при попытке поднять качество. Это был провал: WER (Word Error Rate) показывал 28,4%, а сохранялось всего 70% исходного текста. Представьте, вы слушаете аудиокнигу, а система вам отдаёт её в сокращённом виде. Первым делом залез в `text_corrector_t5.py` и посмотрел на пороги схожести слов. Там стояли скромные значения: 0,6 для одиночных слов и 0,7 для фраз. Я поднял их до 0,80 и 0,85 соответственно. Звучит как небольшое изменение? На самом деле это означало: «T5, удаляй слово только если ты ОЧЕНЬ уверена, а не если просто подозреваешь». И вот что получилось — WER упал до 3,9%, а сохранение текста прыгнуло на 96,8%. Это был уже другой уровень. Но это был только первый фронт войны. Вторым врагом оказался **adaptive_model_fallback** — механизм, который должен был срабатывать, когда основная модель барахлит, и переключаться на резервную. Звучит логично, но на практике? Тестировали на синтетических деградированных аудио — отлично, WER 0,0%. На реальных данных (TTS аудиокниги в чистом виде) — хуже базовой линии: 34,6% вместо 31,9%. На шумных записях — 43,6%, никакого улучшения. Получилось, что адаптивный fallback был как дорогой зонтик, который вообще не спасает от дождя, но при этом весит килограмм и занимает место в рюкзаке. Я отключил его по умолчанию в `config.py`, выставив `adaptive_model_fallback: bool = False`. Код оставил — вдруг когда-нибудь появятся реальные микрофонные записи, где это сработает, но пока это просто груз. **Интересный факт**: задача выбора порога схожести в NLP похожа на тюнинг гитары — сдвигаешь колок на миллиметр, и звук либо поёт, либо звенит. Только вместо уха здесь работаешь с метриками и надеешься, что улучшение на тестовом наборе не рухнет на боевых данных. В итоге система стала на 86% точнее на аудиокнигах, освободилась от 460 МБ ненужной памяти и ускорилась на 0,3 секунды. Всё это из-за двух небольших изменений пороговых значений и одного отключённого флага. Результаты зафиксировал в `BENCHMARK_RESULTS.md` — полная таблица тестов, чтобы потом никто не начинал возвращать fallback обратно. Урок такой: иногда микротюнинг работает лучше, чем архитектурные перестройки. Иногда лучшее решение — просто выключить то, что не работает, вместо того чтобы его развивать. 😄 Что общего у T5 и подросткового возраста? Оба требуют очень точных параметров, иначе начинают удалять всё подряд.

#git#commit#python#security
Разработка: speech-to-text
13 февр. 2026 г.
Новая функцияC--projects-ai-agents-voice-agent

Voice Agent на FastAPI и Next.js: от идеи к продакшену

# Голос вместо текста: как собрать Voice Agent с нуля на FastAPI и Next.js Проект **Voice Agent** начинался как амбициозная идея: приложение, которое понимает речь, общается по голосу и реагирует в реальном времени. Ничего необычного для 2025 года, казалось бы. Но когда встал вопрос архитектуры — монорепозиторий с разделением Python-бэкенда и Next.js-фронтенда, отдельный обработчик голоса, система аутентификации и асинхронный чат с потоковым UI, — осознал: нужно не просто писать код, а выстраивать систему. Первым делом разобрался с бэкендом. Выбор был между Django REST и FastAPI. FastAPI выиграл благодаря асинхронности из коробки и простоте работы с WebSocket и Server-Sent Events. Версия 0.115 уже вышла с улучшениями для продакшена, и вместе с **sse-starlette 2** она идеально подходила для потокового общения. Начал с классического: настройка проекта, структура папок, переменные окружения через `load_dotenv()`. Важный момент — в Python-бэкенде приходилось быть очень внимательным с импортами: из-за специфики монорепо легко запутаться в пути до модулей, поэтому сразу завел привычку валидировать импорты через `python -c 'from src.module import Class'` после каждого изменения. Потом понадобилась аутентификация. Не сложная система, но надежная: JWT-токены, refresh-логика, интеграция с TMA SDK на фронтенде (это была особенность — приложение работает как мини-приложение в Telegram). На фронтенде поднял Next.js 15 с React 19, и здесь выскочила неожиданная беда: **Tailwind CSS v4** полностью переписал синтаксис конфигурации. Вместо привычного JavaScript-объекта — теперь **CSS-first подход** с `@import`. Монорепо с Turbopack в Next.js еще больше усложнял ситуацию: приходилось добавлять `turbopack.root` в `next.config.ts` и явно указывать `base` в `postcss.config.mjs`, иначе сборщик терялся в корне проекта. Интересный момент: FastAPI 0.115 получил встроенные улучшения для middleware и CORS — это было критично для взаимодействия фронтенда и бэкенда через потоковые запросы. Оказалось, многие разработчики всё ещё пытаются использовать старые схемы с простыми HTTP-ответами для голосовых данных, но streaming с SSE — это совсем другой уровень эффективности. Бэкенд отправляет куски данных по мере их готовности, фронтенд их тут же отображает, юзер не висит, дожидаясь полного ответа. Система валидации стала ключом к стабильности. На бэкенде — проверка импортов и тесты перед коммитом. На фронтенде — `npm build` перед каждым мерджем. Завел привычку писать в **ERROR_JOURNAL.md** каждую ошибку, которая повторялась: это предотвратило много дублирования проблем. В итоге получилась система, где голос идет с клиента, бэкенд его обрабатывает через FastAPI endpoints, генерирует ответ, отправляет его потоком обратно, а React UI отображает в реальном времени. Просто, но изящно. Дальше — добавление более умных агентов и интеграция с внешними API, но фундамент уже крепкий. Если Java работает — не трогай. Если не работает — тоже не трогай, станет хуже. 😄

#claude#ai#python#javascript#git#api#security
Разработка: ai-agents-voice-agent
11 февр. 2026 г.
Исправлениеspeech-to-text

Спасли T5 от урезания: оптимизация вместо потерь

# Как спасить качество моделей при урезании весов: история одной миссии за день Проект **speech-to-text** встал перед классической дилеммой: нужно было уменьшить размер модели и отказаться от Т5, но при этом *не потерять* качество распознавания. Задача казалась невыполнимой — обычно урезание весов модели приводит к заметному проседанию точности. Началось всё с очень конкретного вопроса: какие вообще есть способы сохранить качество, если мы идём на компромисс с размером? Я сел за исследование. ## Первый поворот: CTranslate2 Гугление выявило интересный инструмент — **CTranslate2 4.6.3**, который я знал раньше как фреймворк для ускорения seq2seq-моделей. Там есть встроенный `TransformersConverter`, способный конвертировать T5 в оптимизированный формат. И вот что важно: конвертация даёт ускорение в **2–4 раза** без потери качества. Это не уменьшение модели, это её оптимизация под боевое железо. Первым делом я проверил исходную модель — оказалось, что она T5-base (d_model=768, 12 слоёв), а не огромный T5-large. Это хорошая новость: потенциал оптимизации есть. ## Погружение в детали Когда ты начинаешь работать с конвертерами моделей, выясняется множество мелочей. Нужно было разобраться, как именно `TransformersConverter` копирует файлы модели, особенно стоит ли добавлять `added_tokens` для SentencePiece-токенайзера, который T5 использует. Пришлось лезть в исходники faster-whisper — там тоже работают с конвертированными моделями. По ходу наткнулся на забавную проблему с кодировкой cp1251 в тестах, пришлось переделывать тесты для корректной работы с Unicode. Интересный исторический факт: когда в 1940-х годах создавали первые программируемые компьютеры на основе математических абстракций, никто не предполагал, что спустя 80 лет мы будем заниматься микро-оптимизациями моделей языка. История вычислений шла от самых амбициозных идей — создать мыслящую машину — к вполне прикладным задачам, но они требуют той же глубины понимания системы. ## Неожиданный результат Проверив API `translate_batch` в `ctranslate2.Translator` и убедившись, что SentencePiece токенайзер работает с конвертированными моделями из коробки, я получил полную картину. CTranslate2 здесь действует как оптимизирующий слой: модель становится *компактнее* для инференса (благодаря квантизации и переколяции весов), *быстрее* работает, но при этом сохраняет всё качество оригинального T5. Получилось так: вместо того чтобы искать ненадёжные способы урезания модели, мы использовали инструмент, которой *именно для этого* спроектирован. CTranslate2 оптимизирует модели не наугад, а следуя best practices машинного обучения. ## Что дальше План ясен: конвертируем T5 через `TransformersConverter`, проверяем качество на тестовых данных (оно не должно просесть), деплоим оптимизированную версию. Задача из категории "невозможное" стала "вполне решаемо". Когда стоишь перед технической задачей, которая кажется неразрешимой — часто решение уже кто-то написал. Нужно просто знать, где искать. --- Почему архитектор модели пошёл в продуктивный отпуск? 😄 Потому что ему нужно было время на *рефакторинг* своей жизни!

#claude#ai#api#security
11 февр. 2026 г.