Интересно посмотреть дым от сожжённых офисных кресел
Видеомонтаж кадров боевой работы от бойца, девушки-добровольца ЦСН "Барс-Сармат", позывной "Форель". (с) https://t.me/rogozin_do/7269
Видеомонтаж кадров боевой работы от бойца, девушки-добровольца ЦСН "Барс-Сармат", позывной "Форель". (с) https://t.me/rogozin_do/7269
Я — дата-инженер. По роду деятельности пишу много SQL, но в какой-то момент захотелось чего-то более осязаемого. Хотелось делать проекты, которые можно «потрогать руками» и которыми можно делиться. Так я немного углубился в веб-разработку и возникла идея сделать сервис, который бы генерировал образовательный контент с помощь AI. Так появился AI Tutor — если красиво завернуть, то это платформа, которая объединяет онлайн-обучение и нейросети. Сервис помогает авторам и ученикам создавать и проходить курсы, генерирует контент с помощью LLM, проверяет знания и сопровождает обучающегося в виде виртуального тьютора. В общем и целом - условно бесплатно, а если пользователь подключит свой gpt-аккаунт, то сам будет определять, сколько он может генерировать контента.
Изначально идея была простой: загрузил список тем — получил структурированный курс с лекциями и заданиями. Но в процессе проект быстро оброс новыми функциями и стал куда интереснее.
На сегодня в сервисе есть два режима создания курсов.1. AI-режим (быстрый старт)
Вы вводите название курса или список тем — AI сам:
предлагает структуру (модули и уроки),
генерирует содержание уроков,
создаёт проверочные задания.
Подходит для быстрого запуска MVP или чернового наброска.
Вы полностью контролируете структуру курса:
добавляете модули и уроки вручную,
загружаете свои тексты, заметки,
используете AI для редактуры и дополнений.
Этот режим подходит для продуманных авторских программ.
Курс можно опубликовать — и другие пользователи найдут его в библиотеке и смогут пройти. Это работает как для авторов, так и для студентов, которые хотят делиться находками.
1. AI-помощник в уроках В каждом уроке встроен чат с нейросетью. Можно задавать уточняющие вопросы, просить объяснений — будто у вас всегда под рукой личный репетитор.
2. Проверочные задания AI сам создаёт тесты и задания, а затем даёт обратную связь — что получилось, что можно улучшить.
3. Аудиоверсии лекций Не хотите читать — слушайте! Текст превращается в речь, удобно в дороге или во время прогулки.
4. Трекер прогресса Система отмечает, какие уроки вы прошли, что осталось, и помогает отслеживать результат.
Проект написан на Django + Jinja2 Templates. Без модных SPA-фреймворков — всё максимально просто и понятно. Почему так? Потому что изначально это был учебный проект — и сработало. Плюс, я не знаком с современным фронтендом и мне было куда проще собирать костяк html самому и потом через GPT кастомить до нужных бутстрап классов, чтобы верстка смотрелась приемлемо.
Accounts — управление пользователями, токенами, AI-моделями.
Courses — AI-курсы, публичные курсы.
CreatorCourses — редактор авторских программ, которые затем можно «трансформировать» в AI-курсы.
Используются стандартные CBV (ListView, CreateView, и т.д.). Данные моделей Course, Module, Lesson, Task клонируются из Creator-программы при публикации.
По умолчанию используется Qwen2.5-32B, но пользователь может подключить свой ключ от OpenAI (например, GPT-4). Я тестировал разные модели — по качеству ± одинаково, но GPT-4 справляется примерно на 20–30% быстрее.
Промпты заранее шаблонизированы, в них просто «втыкается» пользовательский ввод.
Сначала всё работало на Raspberry Pi, который стоял дома на подоконнике. Потом начались проблемы с провайдером — и я перенёс всё в Digital Ocean. Плачу около 1000₽ в месяц, зато всё стабильно, и не нужно мутить прокси для доступа к OpenAI из РФ.
Хотелось, чтобы ответ от AI печатался прямо на экране. С stream=True и запуском через runserver + nginx всё работало. Но при переходе на Uvicorn/Gunicorn стрим ломается: данные буферизируются и выводятся разом. JS и backend одинаковые, конфиг nginx тот же — а стрима нет. Пока временное решение — просто показываю прогресс-бар.
Возможно, стоит вынести стриминг в отдельный FastAPI-сервис, как советует GPT. Пока руки не дошли.
Интеграция WYSIWYG-редактора в Creator-режим.
Авторизация через VK, Яндекс и другие платформы.
Улучшение UX/UI.
Восстановление стриминга при запуске не через runserver.
Если у кого-то нет идей для пет-проектов, то делюсь своей идеей. При разработке использован фреймворк Django + очереди задач (Celery, Redis) + периодические задачи (Celery-beat) + pyTelegramAPI (телеграм бот).
Django - архаичная шляпа, которую используют до сих пор только из-за большого комьюнити, которое так же когда-то подсело на него, потому что по большому счёту во время его появления не из чего было особо выбирать. Огромная непонятная запудренная кодовая база, если даже сравнивать с тем же Flask/FastAPI, Django - как городская сумасшедшая бабка, которая существует только благодаря своим родственникам, которая несёт дичь и чушь (это фигурально я обсираю говнокодовую базу, которая при масштабируемости действительно становится похожим на свалку непонятных объектов). Когда я решил попробовать Django в первый раз - он же был и последний, эти старые шаблоны, которые толком не дают нормальной возможности работать с JS и сторонними библиотеками, только используя непонятные костыли. Товарищи, которые лестно о нём отзываются - лишь те неудачники, которые когда-то мало-мальски нашли к нему подход, а пересаживаться на любой другой фрейм - очень сложно, потому что очень сильно не похожи (к слову, Flask и FastAPI ой как похожи по кодовой базе и паттернам). Да, Django не асинхронный, но и тот же Flask можно полностью с лёгкостью настроить под себя. О, "Flask не масштабируемый" я могу услышать, но и при всей масштабируемости и синхронности Django уже просто нет смысла его использовать.
Когда коты начинают общаться между собой, они создают целые сообщества. А мы с тобой научимся строить такие же связи в базах данных!
ForeignKey - это специальный тип поля в Django, который позволяет связать две модели между собой. Представь, что у нас есть два кота: Мурзик и Барсик. У каждого из них своя миска с едой. Чтобы каждый кот мог найти свою миску, мы создаём связь между ними.
Давайте разберёмся на пальцах (или лапках):
Когда ты создаёшь ForeignKey, ты говоришь базе данных: "Смотри, этот кот связан с этой миской"
Внутри Django происходит магия: создаётся специальное поле, которое хранит ID связанной записи
💡 От древних библиотек до современных баз данных
В стародавние времена, когда не было компьютеров, библиотекари использовали карточки для связи книг с их авторами. Теперь мы делаем то же самое, только цифровым способом!
🌟 Создание записи
🌟 Получение данных
🌟 Обновление связи
CASCADE 🐾 - Если миску удаляют, кот тоже пропадает
PROTECT 🐾 - Защищает миску от удаления, если там есть кот
SET_NULL 🐾 - Если миску удалят, кот останется без неё
SET_DEFAULT 🐾 - При удалении миски кот получает стандартную
🤔 Знаешь, почему коты любят ForeignKey? Потому что он помогает им всегда находить свои миски! Остались ли у тебя вопросы о том, как связывать модели в Django, или всё так же ясно, как утренний луч солнца на миске с кормом?
А на канале https://t.me/pytonism мы рассмотрим связь many-to-many, заходите ;)