📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Я собрал AI сервис, который учит тебя говорить: английский через подкасты

n1kitos1:29:35

Transcription

Также перед началом установим pip install а ptic settings. Неправильно написал. Вот оно мне подсказывает. Settings. Зачем тыs нажал? Settings. А пока он устанавливается, мы начнём прописывать config, да? From bydidentic import base settings. Соответственно, это у нас класс для создания конфига. А, посмотрим, что у нас тут он предложит. Класс config. Пусть будет config. И создадим мы, наверное, вот так вот, чтобы у нас не путался. Экземпляр класса создадим. М. Так. Что я хочу? Я хочу задать, наверное, model, да? А model name, э, и сюда скопировать. Вот такую модельку мы будем с вами использовать. Open ey APK. Я предлагаю назвать просто APK, потому что у нас будет в проекте всего лишь один APK. И ещё нужно создать, наверное, base, которую мы, а, возьмём с нашего сайта. Так, AP, тактактактактак. Model. Окей. Где наш base? Опяк. Вот base наш. Копируем его. Мы будем работать через Python requests. Сейчас вот через Python request мы, наверное, будем работать. А, переходим в наш этот и base мы сюда запишем. Вот так вот. На самом деле можно работать через библиотеку какую-нибудь Openy, да, но я не знаю, не уверен, что мы А нет, возможно, мы будем работать через Openi. Наверное, лучше через Open SDK и использовать base вот этот вот. Почему? Да на самом деле всё просто. А потому что у нас банально, давайте её и установим, потому что у нас банально будет ещё использоваться лмка, через которую клиента тоже удобнее написать, гораздо удобнее написать через Open AI. А всё, confнig у нас есть. Ээ это минимальный вообще конфиг, э, который есть. И далее мы, наверное, так, выбрали мы модельку. Вот эту. Ну, на самом деле, я её взял, потому что она дешёвая, и я уверен, что она будет нормально справляться с с видосиками. Вот. Дальше я приступлю, наверное, к написанию промта для того, чтобы написать уже модуль, а, для м того, чтобы дёргать нашу спичатую текстмодельку и, возможно, модуль ещё для того, чтобы дёргать нашу обычную лмку, и попробуем прогнать наш весь пай учётом одного запроса, пока что не трогая нашу какую-нибудь там базу данных, да, или не настраивая какое-то умное общение, чаты и всё такое. Слушайте, я, короче, предлагаю прямо при вас накидать, потому что я просто скопировал из сайта Open Router вот эту вот часть. На самом деле мы её просто можем скопировать и вставить в наш код. Я хочу, чтобы это сделала ЛМКА. Поэтому попросим её сгенерируй, сгенерируй модуль для обращения к SST модельке. Т модельки спичте текст модельки используй используй следующую структуру и всё. Пусть генерирует нам модуль. Вот он нам, соответственно, должен генерировать. Я единственное бы поменял тут modele. Я бы поменял бы, наверное, stt model name, потому что всё-таки у нас будет ещё одна. А это будет LLM model name. Model name. Давайте её напишем и пока что оставим просто str. А я не знаю пока что, что там будет. Пока ещё не думал, наверное, какой-то квен. Вот. А сейчас смотрим, что он там нам добавил. Так, какой-то рид det детект аудиоформат. Что-то он нам написал. Ага, он ещё продублировал нам текст. Так, хорошо. Сейчас тогда будем проверять, работает ли эта история или нет. From config settings. Хорошо. В темпе у нас лежит ли файлик? Лежит. Давайте его попробуем и отправить. Auds. Ага. Ну давайте. print print transcribite audio аудио pass у нас будет темп кстати у нас даже подсказывает как его правильно назвать отлично что ещё мы должны передать str is in in audio. Да пусть будет. Ну давайте попробуем вызвать наш файлик. Для этого мы пропишем Python. STT client.pi. Посмотрим, что он у нас выдаст. А он у нас упал. Упал с ошибкой. Какой? Identic errors base settings. Не смог что-то импортнуть. Мне кажется, проблемка в LM model name сейчас. Давайте вот так вот. А, смотрите, мы там STT model name используем. А, мне кажется, просто такого нету у нас, да? М, что сечасчас. Мне кажется, в этом проблемка. STT model name угу. From config import settings. Давайте ещё раз. А, base setting has been moved to the pidentic settings package. Ага, мы, значит, может быть, что-то не так написали в конфиге. Ага, мы написали, нужно from settings. Вот так вот нужно написать. И тогда я тут верну LLM model name. Я подумал, мало ли, он возмущается на это. Сохраним. Мм, сохраним. И вот этот модуль тоже сохраним. И давайте повторно его запустим. Ждём ответ. И вот нам пришёл ответ enable to access filly. However, if prov describe the content audio I can certainly help you on the center please share the details and I will do my best to assist you. А, короче, он не может проанализировать чётко файл, потому что, по всей видимости, ну, мы его слушали, да, он, по-моему, был пустой. Давайте попробуем просто другое видео на Ютубе скачать и прогнать ещё раз наш пайплайн. Давайте удалим эту папочку. переместить в корзину. Я сейчас быстренько, быстренько я сейчас скачаю любое видео. Э, итак, я нашёл ссылочку на другое видео. А вот это видео, мм, там должен быть уже звук появиться, поэтому давайте прогоним наш экстрактор ещё раз. А, мы упали с ошибкой. If you earn it a bot. Вот как разтаки, что я говорил. Нам нужны. Вот мы попались на кукисы. Вот. А что это значит? Нам говорит, что YouTube хочет убедиться, что мы не бот, потому что мы, по всей видимости, с какого-то непонятного адреса э ходим в YouTube. Вот. И, соответственно, он нам предлагает это как-то исправить. Сейчас я тогда покажу, как это исправляется. То есть нам необходимо зайти в какой-то браузер. Давайте пусть это будет этот браузер. И в режиме инкогнита. Так. Аэ тут я не особо пользуюсь этим браузером, если честно, поэтому аэ сейчас посмотрим. Ну и где тут режим инкогнито? Ну вот вот вот вот вот так вот. Давайте откроем YouTube в режиме инкогнито. Тут у меня уже открывается этот. Войдём в аккаунт. Так. Итак, я просто вошёл в аккаунт в свой на Google аккаунте. Дальше, что мы хотим сделать? Мы хотим воспользоваться расширением getook txt. Его можно скачать просто в этом же браузере. А, и что мы хотим? Export current site. Так, что, что тебе не так? Curentй. Я надеюсь, что он скачал. Да, мы скачали. Я случайно он не очень корректно UАка отображала. Мы получили в кукисы. Это просто на самом деле ксистичный файл, который выглядит вот так вот. Э, дальше мы этот файл должны переместить в корень нашего проекта. Давайте это и сделаем. Переходим в наш вискодик и перемещаем этот файлик сюда. Всё, этот файлик у нас находится здесь. И теперь мы заново можем попробовать загрузить наш PayP. Давайте попробуем, всё ли сработает. Я думаю, да. Да, всё сработает. Как вы видите, а загрузка началась. Это достаточно легко фиксится, потому что сейчас YouTube знает, где кто к нему конкретно ходит. Проверим папочку temp. Да, появляются файлы, всё корректно конвертируется. Сейчас ждём, а пока у нас это всё добро сконвертируется. А, по всей видимости, он скачивает старую ссылку. Я, видимо, не сохранил, да, новую ссылку. Я перезапустил бы ещё раз бы процесс, потому что я скачиваю не тот ролик, если честно. Давайте ещё раз удалим папочку. Там должен быть маленький ролик. Вот. И ещё раз запустим наш экстрактор. Всё должно пройти быстро, потому что там быстрый достаточно ролик. Всё, мы получили наш 3 файлик. Проверим звук. >> Да, есть какой-то какой-то звук. Теперь запустим нашего сети- клиента. Он запускается вот так вот. И ждём, смотрим, что нам ответит. А, да, точно, мы же захардкодили файлик. Скопируем название файлика и перейдём в нашего клиента. И потому что мы тут захардкодили, да, название. У нас поменялось название, поэтому давайте поменяем ещё раз. И запустим наш файлик. Посмотрим, как у нас это работает. Так, а один know what? We can continue. Ага. То есть он просто дал нам расшифровку этого файлика. Сейчас давайте послушаем. Не знал я, что не знали. >> Угу. Не знал я, что не знали. Это он на английском почему-то это нам перевёл. Ээ, можно ли тут указать промт? М, давайте скажем ему, а, отправь расшифровку на русском языке. Сохраним и повторно запустим наш пайплайн. А давайте, я надеюсь, что он ответит уже на русском. Нет, к сожалению, он отвечает на английском. М. Странно, я вроде как сохранил эту штуку. То есть сейчас секундочку, давайте посмотрим. Промт формат инpдиотекст. Возможно, эта модель не поддерживает русский язык, в принципе. А потому что мы, соответственно, не поменяли промт. Поменяли промт не там мы поменяли. Надо было вот здесь поменять промт. Давайте тут поменяем. Ещё раз сохраним и ещё раз попробуем запустить. Сейчас должно уже работать. Что я всё-таки думаю, что Микстралин, ну, поддерживает 100% русский язык. Мм. Угу. Да, не знал я, что не знали вы, кому и кто был в роли главы. Главы с меня как бы певец такой себе, да. Главное, что мы получили расшифровку и понимаем, что наш пайплайн работает. Вот. Фактически на данном этапе у нас есть уже а наш экстрактор Ютуба. То есть наш модуль, который собирает файлик, да? Сейчас мы тут оп вот так вот удалим, чтобы у нас всё красиво было. У нас есть наш клиент, который вызывает с пичтуте текст модельку. И что нам остаётся сделать? Нам нужно прикрутить модуль лылки, которая у нас будет непосредственно получать в контекст эту расшифровку и уже сможет отвечать на какие-то вопросы согласно этой расшифровке. Давайте приступим к его написанию. Итак, я накидал вот такой промт. Объяснил, что мы делаем клиент, который будет обращаться к нашей нейронке. Скал, где взять переменные для корректного оформления модуля в конфиге, да, как они называются. Но на самом деле этого можно не делать. Там сам агент залезет и посмотрит. А скинул ему сдкашку с сайта, дабы лишний раз не переживать, что что-то накосячится с сайта. В openрутере есть апии. А-э, и там прямо есть код, который рассказывает, как именно обращаться к этой модели. Вот написал, что мы будем передавать в нашего клиента это системный проomт memory, то есть память предыдущее сообщения, да, ид - это новое сообщение. Кстати, пока записывал ролик, вышла на днях GPT 5.5, её добавили в этот, поэтому сейчас проверим, как она работает. Запускаем агента. Мм, вот я пока ещё подумаю, что нам ещё надо. Ну, естественно, нам нужно это всё как-то, ну, у нас нету, во-первых, базы данных. Сейчас будем поднимать БДку, в которой, я уже говорил, будут храничится таблички с метаданными, да? Во-вторых, нам нужно организовать вот эти все сессии, э, чатики, да, то есть синхронизовать видео, а видеоэдишник синхронизовать с определённой сессией. И также ещё табличку с messages, да, оформить. Вот это сейчас всё будем делать. Что нам ещё понадобится после поднятия бдшки? Если у нас будет храниться расшифровка, также у нас будут храниться статусы по сессиям. А, в принципе, да, наверное, всё. Ну, то есть у нас будет суперпростая система собрата. Сейчас у нас тут что-то unexpected status 403. Это что, я типа без випенки хожу, что ли? Давайте подключим пенку и попробуем сейчас ещё раз отправить запрос. 5.5. Всё нормально. Так, а сейчас, а сейчас, да, не забывайте подрубать в бен, как вы заметили, может что-то непонятное произойти. Всё, вернусь тогда, как увидим готовый модуль. Итак, вот у нас появился модуль. А давайте будем разбираться, что у нас написал наш агент. Мм, функция клиента. Пусть так будет. На самом деле не обязательно. Можно один раз просто задать ээ класс какой-то. с клиентом, да, open и всё будет хорошо. Сделал так, на самом деле, не принципиально. Дальше функция, которая возвращает хедеры эроутера. Это вообще, ну, нам не нужно для MVP, потому что, ну, у нас нету никакого-то сайта, да, и у нас нету никакого-то имени. То есть это абсолютно бесполезная информация. А дальше вот эта вот штука у нас, что она делает? Она у нас создаёт Jon в формате RL Assistance Content Edit и сохранищ Reasoning Details. Давайте reasoning details мы уберём. А в формате сохранения памяти почему бы и нет? Пусть будет. У нас функция, которая будет сохранять память. Это хорошо. А так смотрим, что у нас тут. System prompt message memory может быть Ne. Хорошо. И возвращать она у нас будет ээ она у нас будет тапle. Она у нас будет возвращать tle. Давайте посмотрим, что это за tнт assistant response, то есть ответ ассистента и список из memory распакованный. User message assistant message. Хорошо, сейчас посмотрим тогда, что у нас там. Этот изначально тут заголовочки вот эти берём, которые мы стёрли, да? Угу. Так, посмотрим, что она формирует user message. Собирается у нас сообщение RL system prompt memory и user message. И вызывается моделька со включённым reason. Да, это хорошо. А assistant response парсится, получается этот, и возвращает текст объекта. текст и обновлённую память. В общем, всё понятно. У нас, соответственно, что что происходит, да? У нас получаем мы ответ ассистента из этого парсим, да, и ээ сохраняем его в память, то есть assistant message, да, и непосредственно возвращаем мы а ответ, если он был получен или ничего. Вот это, соответственно, если у нас тут выкинется нан или я не помню, что там может прилететь. Вот. И, соответственно, это первое значение кортеджа. Второе значение кортежа - это список из памяти, э, сообщения этого пользователя и сообщение нашего непосредственно агента. И заметим, что тут сообщение агента, оно у нас будет в формате вот таком. То есть это будет жечик, roll system и content и ответ. Супер простой модуль. Всё, у нас в принципе он есть. Аа я надеюсь, понятно, что происходит, да, обращение к ЛНК каким образом? Давайте теперь, э, что мы хотим дальше сделать? Мы хотим дальше заняться базой данных. То есть, ээ, мы получили мы вот такой птришный файлик, да, и мы же до этого вызывали, когда лмку, помните, да, у нас в терминале была история вызова, то есть у нас оно никуда не сохранялось. При этом, ну, мы не хотим, наверное, 10 раз прогонять по одному и тому же тексту нашу спичатую текстмодельку. Во-первых, потому что это бессмысленно. То есть, если можете один раз сохранить и повторно обращаться, да? Во-вторых, это невыгодно. Ну, то есть ээ моделька на порядок, моделька спич текст работает, стоит её работа на порядок дороже, чем тексту текст моделька, поэтому выгоднее, конечно, сохранять эту историю. Эээ, я предлагаю сейчас ээ заниматься уже следующим модулем. А, это база данных. Сейчас я накидаю пром для того, чтобы у нас агент написал этот модуль. Далее, а потом будем разбираться, что он там написал. Итак, я попросил реализовать нейронку, написать промт. А вот что мы получаем. Ты Python разработчик, нужно реализовать бла-бла-бла. Описываем, что делает весь проект, сервис наш, да? Что мы хотим хранить? Только тут не видео, да? Мы хотим хранить, а аудио в скобочках MP3 файлик. А точнее, мы даже хотим не аудио хранить, а раз разшифровку MP3 файлика текстовую. Угу. Чат сессии, сообщение диалога. Создать файл dB.p. А говорим, что мы хотим использовать Seclite 3, то есть это встроенная обычная библиотека, да? Не будем сейчас разбираться с алхимией и с вот этим вот всем. Я думаю, это лишнее, когда нам хватит обычно SEQ Lite, да, Sequite это БДшка, которая живёт у вас в локально. То есть она нигде отдельно не поднимается, она как бы у вас запускается, а, с помощью питона. То есть это супер- супер такая игрушечная база данных, но она фактически помогает познакомиться с самим механизмом, да, когда вы будете использовать там какой-нибудь пасгрю, а, не знаю, что там ещё использовать, там хайвы всякие кликхаусы, ну, вот эти вот все продовые бдшки, там принцип работы будет абсолютно тот же самый. Единственное, это всё будет просто в другом масштабе и чуть другие инструменты будут использоваться. Вот. Но смысл использования он будет один и тот же. Вот. Ну и пишем, что код должен быть простым и всё такое. Кстати, заметил, что в 5.5 появился контекстное окно. Вот показывает, сколько контекста занято, да, и что у нас кодекс будет автоматически сжимать контекст. Отлично. Закидываем промт. А ждём, надеемся и верим на лучшее. Потом будем разбирать, что он нам сделал, и удалять лишнее, либо добавлять что-то. Итак, вот у нас появился файлик с нашей даты, database, с нашей Securite. Давайте посмотрим сразу, что нагенерировала Неронка. И мне уже бросается в глаза вот этот вот эта переменная. Я предлагаю её вынести сразу в конфиг наш и обозвать её DB Pass, только маленькими буквами для красоты. DB Pass. Отлично. И в таком случае мы должны тут импортнуть а config config и вместо DBP pass мы должны везде прописать config то dp pass. Так, что у нас там? Мы не сохранили, что ли? Так, DB пас сохранить. Сейчас должно обновиться. Я надеюсь, что всё нормально. Или у нас config? А, у нас settings, потому что называется from config import settings. Немножко замечтался. settings DB pass и давайте посмотрим ещё где-то был. Вроде нигде не было. Вроде нигде не подсвечивается. Отлично. Что за функция? Функция создаёт соединение с датой, с базой данных. Потому что у нас базы данных работают через соединение. То есть мы сначала должны подключиться к базе данных, а после чего мы, а, можем с ней работать, выполнять какие-то команды. А-э, вот насчёт этой функции, я думаю, понятно. Ну, внутри, на самом деле, что у нас происходит? Устанавливается соединение. Мм, после этого мы используем эта штука вроде как позволяет обращаться к строке как дикту, то есть, чтобы мы не писали э-э по индексу, мы можем обращаться по ключикам, вроде как это оно. И, соответственно, это это не не непосредственно э ограничение. То есть мы говорим, что мы не можем создавать message без session, то есть ну не получится создать сообщение, если оно не привязано к сессию. и можно каскадно удалять. А далее это у нас происходит инициализация наших, э, дбшек. Мм, у нас тут, соответственно, просто написан сырой сикль запрос. Я думаю, не стоит останавливаться на синтаксель запроса. При желании можно увидеть, что у нас тут есть, да, это там, а, если мы говорим про табличку, а, videos, то она будет содержать айдишник, уникальный YouTube, э, путь до аудио, transрипt и дату создания, но это, соответственно, не обязательно. Вот аналогичная табличка для чатсессий и для messages, да, ну, там, на самом деле, не принципиально важно, что именно он добавил. Мы с этим потом, наверное, будем разбираться. А после этого м после этого у нас что идёт? Save video transcript, да, соответственно, функция, которая просто сохраняет наше видео плюс transcript. Куда оно будет у нас сохранять? Давайте посмотрим. Мм, оно будет выполняться. Арт videos. Э, что происходит, да? Insert into - это, соответственно, вставить в дбшку. Ну, мы будем вставлять просто в табличку видео наш, э, транскрипt. Вот. А, соответственно, как-то так. Дальше у нас будет get video, то есть достаёт видео по айдишнику, выполняется просто команда select, которая достаёт из дата баз, из датаabase, да, из базы данных соответственно видео по айдишнику. Дальше создание мм чат-сессии. То есть это фактически просто создаёт новую сессию, да, которую мы, а, в которую мы будем добавлять ээ ну что у нас тут происходит, да? Вставляем в табличку чат сессии. видео айдишник, названия, какие-то значения. Ну, соответственно, создаётся сессия, в которую будут отлетать наши месседжи. Вот. И возвращает айдишник, соответственно, сессии. Дальше get chat session. А что это такое? М, select from chat session. Мы просто получаем чат-сессию подишнику. В принципе, тут всё. Дальше add message соответственно возвращает у нас она что будет делать message просто будет добавлять сообщения, да, по названию, наверное, так. Insert into messages значения какие-то, да? А сейчас секунду я там, может быть, что-то наговорил не то повыше. Create chat session. Она у нас не вставляет туда сообщение, она у нас просто создаёт сессию, то есть, ээ, видео и титул, ээ с, короче, получается туда два значения, которые поставляются вот под вопросики. А это у нас не вставляется месседжи. Messengдж у нас вставляется вот в этой функции. Вот. А дальше что у нас? Get messages получить все, заселектить все сообщения из по какой-то сессии. Вот. Мм. Мм, в принципе, тут всё, наверное. А, и listть, соответственно, все чаты, которые у нас есть. Вот. Давайте посмотрим про Reasoning Details. Вот в этом мне не нравится reasoning Details, если честно. Давайте её уберём. Ну, потому что зачем нам reasoning в нашей этой самой мы не собираемся ничего анализировать. И reasoning details я бы, в принципе, убрал. Так, извиняюсь. А, вот так вот. Отлично. Где-то ещё будут у насing details, наверное, нет. М, всё, в принципе, у нас загружен модуль, который у нас может непосредственно работать с базой данных, которая будет подниматься при ээ инициализации, да? То есть, когда мы прописываем ЕДБ, у нас создаются вот эти вот базы данных. Они у нас будут создаваться, аэ, где они у нас будут создаваться? В DBпаs. DBP у нас из конфига мы помним, что это storage, database, DB. Вот тут вот они они у нас будут, соответственно, создаваться в этом файлике. Вот. Эээ, как-то так, наверное. Я думаю, тут всё должно быть понятно, что происходит. Я, в принципе, постарался рассказать про все функции за конкретным синтаксисом, если вы не понимаете там синтаксис CQэля или там ещё чего-то. На самом деле это, ну, не суть важно, потому что в реальной разработке, ну, я там тоже супер не помню, как сеQL запрос большой какой-то написать, да, я, ну, вижу, ну, знаю основные команды, там inсёр in, да, понимаю, что это там вставить в а табличку, в название таблички chat sessions, что-то мы конкретно вставляем, да, вот вот это там create table, например, да, ну, создать табличку, если if not exist, если не существует там и название таблички messages, да, и дальше какие поля мы конкретно туда вставляем. Вот, наверное, как-то так. С конкретными синтаксисами не думаю смысла смысла нет заморачиваться, его как-то разжёвывать. Вот смысл всего, я надеюсь, этого модуля понятен. После чего у нас фактически, что у нас уже есть на данном этапе, да? На данном этапе у нас есть экстрактор, то есть наш модуль, который ходит и скачивает видео. У нас есть спичный текст клиент, который при надобности всё расшифровывает красиво. После этого у нас есть lm клиент, который у нас уже будет взаимодействовать непосредственно с нашим спичайте текст расшифровочкой, которая прилетает, да, и сообщением, который попадает туда. У нас есть модуль database, наш модуль, который у нас хранит, то есть кэширует запросы пользователя для того, чтобы мы, а, непосредственно использовали расшифровку, которую мы до этого как-то сделали, да, она у нас куда-то сохранилась, куда-то упала. И вот мы ей будем непосредственно пользоваться. Мм, и всё остаётся нам сделать, наверное, помимо опишки самой, да, то есть как мы будем взаимодействовать с нашим проектом, мы напишем простую опишку. Э, у нас остался оркестратор, то есть нам остался файлик, который у нас а это всё взаимодействие настроит, то есть пропишет всю логику, когда ходить сюда, когда сюда, откуда что делать. И сейчас, наверное, я напишу промт для составления вот этого оркестратора, который у нас непосредственно это всё соберёт в единую кучу, и мы сможем уже попользоваться и посмотреть, пощупать, как это всё будет работать. Итак, ребят, прошла, наверное, где-то неделька, а спустя того, как я вернулся к продолжению написания проекта. Для вас там секунда, да, я отходил вот на недельку примерно, а сейчас освежил память, вспомнил, что мы писали, на чём мы остановились. Мы остановились на том, чтобы написать, соответственно, оркестратора, да, для нашего проекта. и апишку. Сейчас я накидал промт, который поправит некоторые баги, которые у нас там были. Баг, который я нашёл, он там был детейс, который мы сериализовали. Я сейчас не помню уже, где это было. Ну, короче, там где-то передаётся details, которую мы не задали, и мы её пытаемся сериализовать, и это очень-очень плохо. А вот я попросил это в промте, чтобы мы это исправили. А сейчас, секунду. Вот есть какой-то details. Можем её попробовать сейчас найти. Вот мы тут какие-то details запрашиваем, да, а потом вот тут вот формируем. А details мы везде на самом деле отключали. То есть я бы поэтому вообще бы отсюда рининг. Ну ладно, пусть пусть оно будет. Я думаю, это просто пустая штука будет и всё. Хотя нет, убираем details. И сейчас перейдём к Details. Я бы убрал быails и просто бы не передавал бы сюда. Сейчас так вот сделаем, потому что это просто лишнее всё. А 1 2три Теперь три вопросика. А я надеюсь, теперь будет нормально. В общем-то, мы на самом деле сами справились детей. Ну, в общем, это был баг, который нужно показать. Плюс попросил создать

файлик вот этот вот archestration.pi. Вот. И всё. Вызываем а нашего ассистента. Проверим. Я надеюсь, что у меня пинка включена и он всё отработает. Так, на всякий случай. А про скопировать уже нельзя. Я к вам вернусь, когда он, соответственно, сделает своё дело.

Итак, агент у нас отработал. Он создал файликrator оркестратор.pйлик db там 10 строчек накинул. Давайте начнём разбирать с нашего оркестратора. Фактически он тут просто импортирует все функции с нашего модуля и а пишет функцию, которая, соответственно, очищает у нас папочку temp, да? А давайте посмотрим, где он её использует. Он её использует в самом конце. М. Это, наверное, не есть ОК, потому что он у нас использует её после ST, то есть когда мы отправляем наши модельки. Если у нас ST упадёт, то у нас темп папочка останется. На самом деле лучше бы её переместить, но это сейчас не принципиально. Заострять на этом не будем. А, и вот он собрал весь пайплайн. В принципе, лёгкий, да. Получаем видео, если у нас видео уже есть, да? А, а видео - это у нас мы получаем видео из, а, get video by ur. Можем сразу перейти к определению для того, чтобы разобраться. Это как раз-таки, мне кажется, то, что написал, а, непосредственно файлики DB. Это функция, которая просто у нас селектит видео из нашей таблички videos, да, если оно есть, соответственно, и возвращает. Если Nн, то, ну, видео не нашлось в базе данных. Если нашлось, то, соответственно, у нас оно вернёт этот словарик. Да, который у нас преобразуется после вот такой вот словарик. А так, дальше возвращаемся обратно. А вот, соответственно, извлекаем аудио, а после этого отправляем на transcript. После этого save transcript выполняется функция. То есть сохраняем наш транскриптик и возвращается видео айдишник. Вот. А как-то так.

Сейчас, наверное, мы напишем, что мы что мы сделаем. А я бы хотел бы ещё поправить. На самом деле у нас тут был, я нашёл ещё один с с этими details. Я бы reasoning details убрал, потому что мы её нигде вообще не используем. И ещё есть такая штука, как м в табличку. Мм, что я хотел сказать-то? А вот тут вот я бы, наверное, а что я хотел сказать? У нас YouTube, он должен быть уникальным, а я бы добавил сюда. Вот. Ну, это обезопасить, чтобы у нас не было никогда дублей, а по YouTube урлам. Вот всё-таки потому что мы же тянем из БДшки потом по урлу и нужно, чтобы он был уникальным. Вот, в принципе, ещё можно, конечно, аудио путь удалить, потому что мы его нигде, а, наверное, не используем. Давайте проверим ещё аудио, чтобы его везде почистить. Ага, аудиопуть. Так, мы в save video transcript передаём аудиопуть. Аудиопас мы просто так сейчас из download в транскрипt. Transриpt мы передаём аудиопуть. Блин, я чуть запутался, если честно. Аа я бы Нет, всё, всё дальше всё нормально идёт. Нам просто из вот этой вот таблички, да, нам не нужно хранить аудиопуть по конкретному видео, потому что, ну, мы аудиопуть у нас попадает в папочку темп. которая чистится. То есть она потом удаляется. Вот. И я бы вот тут вот аудиопуть ээ в видео я бы не вставлял бы, а потому что он попросту не нужен. То есть я бы и не передавал бы сюда бы аудиопуть и сейв. Вот эту вот функцию я бы проверил. А, да, мы и не передаём аудиопуть, то есть он нигде не используется, поэтому всё мы корректно удалили. Вот, в принципе, такие правки.

А я сейчас предлагаю что сделать? Я сейчас предлагаю у нас мейна нету, да? М, я сейчас предлагаю написать main.pi, в котором мы будем поднимать опишку. Вот я чуть подробнее расскажу, что такое апишка, как она выглядит. точнее, даже ничуть подробнее расскажу, лучше просто посмотреть, как это всё выглядит, как это всё работает, то есть как работают полноценные приложения, сервисы, да, если мало ли вы до этого не писали что-то своё, либо не видели, как это работает, то сейчас тогда я приступлю к написанию промта, который у нас забабахает опишку, и мы уже непосредственно поднимем это всё нашем компьютере и сможем попользоваться, я надеюсь, нашим сервисом, который мы так долго старательно писали.

Итак, я написал вот такой промт, в котором я ему описал, что нам нужно сделать. Э-э, это что у нас уже есть. На самом деле это можно не писать, потому что у него есть контекст ad. Нужно написать файлик. И я попросил написать файлик requirements.txt, в котором он соберёт все наши зависимости, аэ, которые используются в проекте, да, все библиотеки. Дальше мы хотим написать, создадим простую, простую, но чистую структуру апии, в которую мы поместим routers.p - это наши ручки. И, э, напишем main. Пай, как точка входа в наше приложение, через которое мы будем, соответственно, поднимать наш фастафйвок. Вот. И дальше я ему просто ниже написал ручки, которые у нас должны быть, да, это загрузка видео endpint 1. Дальше endpoint 2 - это создать чат. Аэ, что там дальше ещё у нас есть? NPPint 3, сообщение в чат отправить. А, и вот как-то так, наверное. То есть, ээ, три основные ручки, которые у нас будут. В начале, по-моему, я описывал ручек чуть больше, но начнём с этих и если что, потом при необходимости попросим добавить ещё что-нибудь нашего агента. Вот я, в принципе, запускаю и вернусь, когда он что-то что-то нам напишет. И уже посмотрим, что он написал, что будем исправлять, что оставим.

Итак, посмотрим, посмотрим, что он у нас написал. Мм. Так. Давайте смотрим. Э, он у нас написал, мы перешли в папочку AP Routers. Тут на самом деле всё создаёт роутер. Ээ дальше он пишет, а ручки upload видео. Что, что тут происходит? Процес видео. То есть мы передаём а туда нашу наши данные и он, соответственно, всё запускает. М процесс процесс видео, да, процесс нашей обработки это из нашего оркестратора функция. А дальше старт чат ручка, да? То есть начать чат ээ возвращает session ID для того, чтобы понимать, в какой сессии мы сейчас находимся, да, чтобы была какая-то память нашего диалога. И отправить сообщение. Наша самая большая ручка, да, мы, а, передаём дату, которую мы распашиваем вот таким образом. на самом деле не лучшая не лучший э формат парсинга, потому что у нас мм мало ли такого ключика там нету, например. Ну, короче, в общем, это вот эта вот часть написана очень хрупко через всё, что мы через ключики. А как минимум лучше писать это через метод get, который, а, в случае, если по такому ключу отсутствует значение, да, то он непосредственно вернёт Nн, да, и у нас как минимум приложение может не упасть. То есть мы как-то это можем обработать. То есть вот такой формат, он очень-очень хрупкий. А, а в идеале лучше это писать, конечно, через через классы, через атрибуты класса, но я, э, не уверен, что мы мм будем это делать. Я бы, наверное, попросил бы его сейчас переписать вот эту часть, чтобы мы это всё красиво получали через метод get, как минимум. Вот. Дальше что мы получает? Дальше он получает анса и возвращает у нас анса. Короче, в общем-то, такие три простые ручки. который мы его попросили написать. И посмотрим, что у нас в мейне. Ага, мей у нас совсем худот. Даже запускается, запускать мы будем нашу программу через Uborn, а не через main й. А это мы тоже, конечно, исправим. Давай его сразу попросим это сделать тогда при вас. А исправь справь в ручках получение получение необходимых необходимых полей полей из дета безопасно через метод get плюс а перепиши main чтобы мы чтобы я мог запускать запускать его через Python main. P в терминале и поднимался в фаст апе. Я думаю, это будет очень-очень быстро. Он всё это исправит. Вот сейчас попросим это сделать. Думает. Агага. Закроем. Так, сейчас закрывать пока ничего не будем. Давайте, он быстренько всё должен сделать. А, подождём. Да, проверить. Всё готово. Открываем роутер. Смотрим. Получают эти атрибуты через get. А вот тут вот system промт я бы его чутка бы поправил, потому что мне не нравится, как он выглядит. Так, лучше чуть. Вот он получает через get, да? Угу. И вот он вот получает через get. Всё, он поправил. В принципе, хорошо. Стало лучше, действительно. И теперь посмотрим в main. Вот. И равно он запускает это всё. И теперь мы можем запустить, давайте попробуем запустить наш. Python main.p у нас сработал db pass. Что-то с DB pass у нас произошло. Modfields require db pass is not min. Короче, что-то нам надо открыть сейчас наш. А где у нас эти лежат? Я забыл. Короче, какая-то подентик схема не сработала. Это, скорее всего, конфиг. DB pass у нас тут. О'кей. А в каком файлике мы ломаемся? LM model fields require type annotation if pass. Что у нас тут? Так, сейчас я, короче, я сейчас туплю. Я лучше сейчас вернусь. Секунду. Оказывается, у нас пойдентик обязательно аннотация типов. И не хватало вот этой вот этой вот этой вот писюльки, чтобы у нас всё корректно отработало. Вот. А поэтому сейчас всё должно запуститься адекватно, да? У нас запускается наш фаста. А вот и сейчас посмотрим, как он выглядит. То есть ээ вот сюда мы перейдём. А, обновим страничку. И мы видим, да, мы попадаем, переходя по адресу из непосредственно вот этому, да, UVCorn running on, вот на вот этом вот HTTP, а у нас мы попадаем вот на такую страничку, и у нас detail not found. Ну, на самом деле всё правильно, потому что у нас мы ничего не задавали нашей главной страничке. Чтобы перейти и видеть наши ручки, нам нужно перейти на вкладочку docs. И тут мы попадаем на такой swagger UI, да? Это, то есть, фактически встроенная юайка у нашего фастапе. Вот. А что она нам показывает? Ну, тут у нас это просто удобная, а, usеer интерфейс удобный, да, который позволяет взаимодействовать с непосредственно нашими ручками, да. Можем вот посмотреть все тут есть, все наши ручки, которые а мы задавали до этого. Вот. А что мы хотим сделать? Да, видео, да, давайте, наверное, попробуем, а, соответственно, загрузить наше видео. Сейчас я найду, а, ссылочку и, соответственно, сейчас, в общем, я сейчас подготовлюсь, вернусь и мы с вами протыкаем все наши ручки, которые у нас с вами получились.

Итак, я нашёл видеоролик, который мы будем пробовать загружать в нашу системку, и мы будем пробовать общаться. Перед этим я хочу сказать, что у нас есть небольшие проблемки. А первое, ну, я, во-первых, скопировал сюда, э, ссылку на YouTube видео. А что я хочу сказать, какие есть проблемки? А, во-первых, у нас непонятно, что передавать. Вот если мы захотим передать в нашу ручку, да, мы по факту должны что передать? Ну давайте зайдём в код, посмотрим, что мы должны передать в нашу ручку, чтобы у нас она отработала корректно, да? Мы должны передать ээ YouTube, да, и ну согласитесь, что с вот такого описания непонятно, что нам передавать в эту ручку. То есть по-хорошему это нужно мм ну как бы прописать либо в качестве примера, да, вот тут вот а-а писать в качестве примера мм что мы хотим увидеть. Плюс, э, логичнее было бы, если бы мы сюда передаём только YouTube, логичнее было бы, наверное, прописать, ну, непосредственно YouTube и string вот. И YouTube у нас шёл бы вот так вот дальше, да? То есть, ну, тут как бы логично и аналогично можно с видеоиID так же самое сделать, да? У нас как бы сейчас пока простая системка. Мы опять же ничего не говорим про обработку входных данных. Мы не думаем про безопасность, про мм количество клиентов, да, и про вот нагрузку, про вот это всё. Мы сейчас пишем вообще максимально простую штуку, которая хотя бы будет запускаться и работать. А в этом случае мы можем передавать как бы через дату, да, но нам нужно понимать, что мы передаём это в формате jсончика. Мы потом настроим, а, мы потом настроим непосредственно наш формат м примерчики. Вот. И я пока что хочу такие базовые больше как моменты а передавать, да? То есть, ну, тут мы запомнили, да, что видео мы передаём просто ссылку на YouTube видео. В сюда мы передаём циферку, да, то есть, чтобы получить нашу сессию, чатик, да, и в качестве сессии мы будем общаться вот передавая всё-таки уже джейсончик. У нас, по-моему, там был в STT клиенте у нас был такой не очень приятный промт, да, в котором мы просили отправь расшифровку на русском языке, да? Давайте просто отправим а send. Всё, поменяем чуть promptт, а, чтобы у нас приводилось на английском языке и попробуем воспользоваться нашим, а, сервером. Опять же запускаем pythonmain.pie. Наш сервер запустился. Перезагружаем странице страничку и видим, что у нас уже тут достаточно приятнее, да? То есть мы понимаем, что YouTube нам нужен. Я его сохранил в конфиге. На самом деле теперь можно поменять, потому что изначально я планировал передавать, а сейчас мы его поменяем чутка. Угу. Вот так. Отлично. Передаём мы YouTube передаём. Нажимаем execute. Ждём. Наша система сейчас, соответственно, отрабатывает internal server error. 403 ошибка. Давайте кое-что проверим. FM есть. А давайте попробуем перезапустить наш терминал. Ctrl G. Ждём, пока появится VНФ. Угу. Венф появился. Добавляем в пас наш FFM. Проверяем, что он в пасе. Отлично. Запускаем pythonmain.p. А, странно. Очень странно, что упал. Сейчас ещё раз просто проверим, перезагрузим наш этот йout. Смотрим. Я не думаю, что что-то поменяется, да, потому что у нас Давайте посмотрим. Sign into confirm. You are not a bot. Угу. Наш наши кукисы, по всей видимости, которые у нас вот тут вот, они а устарели. Да, странно. Я не я сейчас я подумаю, по всейдимости придётся обновить кукисы. Вот. Очень странно, потому что до этого буквально у меня всё было о'кей. Давайте попробуем ещё раз экзекнуться. Может быть, через пару запросов пройдёт. Так вот, вроде бы начало проходить сейчас. И мы сейчас должны, да, и мы получили видео один. То есть мы заметим, да, что у нас, а, сейчас это отработало, но до этого там три, три-четыре раза мы упали с ошибкой. То есть кукисы, они всё-таки не очень надёжные, и по-хорошему нужно проводить авторизацию. Но в итоге мы добились того, что мы получили а расшифровку этого видео, да, мы потом будем думать над надёжностью, то есть как это пофиксить. А дальше что мы хотим? Мы хотим создать сессию. А сессия один создана. передали. У нас появилась сессия. Отлично. И теперь мы вот сюда мы хотим что передавать? Давайте смотреть в наш код. Что мы хотим передавать в наш файлик? Ой, в нашу ручку. Это Jonчик с полями Session ID и message. Session ID. У нас это который Session ID, который мы получили, это единичка. И message, а поле с именем message, он у нас будет непосредственно наш месдж, да? А давайте что-то спросим. Tell me about this video. What is the main topic? Ну, спросим, да, типа, какая какая какая тема вообще видео, которого мы тебе отправили. Знак вопроса сейчас ещё на клавиатуре нашёл. Execut. Смотрим, что нам придёт. Тут чуть подольше подождём, потому что тут идёт отправка лмки. Вот она ещё не самая быстрая. То есть мы ходим по опишке к не самой быстрой лмке, которая ещё плюс должна сгенерировать какой-то текст. И там ещё не задано вроде как, сколько текста она может сгенерировать. То есть может прийти достаточно большой жирный ответ, но мы ждём. Да, вот пришёл такой достаточно большой ответ. Смотрим, что она ответила. А-а, и она отвечает, что вы типа предоставили транскрипцию короткого разговора, подкастного разговора. Да, мой ответ будет базироваться на этом транскрипте. А основной топик - это бриф, повседневный, ежедневный английский диалог между двумя спикерами. Да. А дальше я не вижу смысла переводить, в принципе, вы всё видите. То есть ответ Лымки есть. А давайте попробуем а в рамках этой сессии ещё что-то спросить. А-а, ну по факту у нас же должно помнить, да, ээ диалог наша ЛМКА. Проверим это вот. А у меня я не мастер английского, к сожалению, но давайте, типа, о чём был последний мой вопрос? Вот my вот из myус previous question воз да не а was my previous question about вроде так это пишется давайте спросим посмотрим помнит ли наша лмка о чём был мой Мой предыдущий вопрос. А понятно, что сейчас это всё не очень удобно выглядит. Это всё не очень удобно выглядит, потому что это всё апишка. То есть это мы фактически взаимодействуем с бэкэндом через суперпростую юайку от ээ фаast. Swager UI называется. Вот. И, естественно, по-хорошему, надо прикручивать какую-то красивую мордочку. Можно прикрутить, да, чтобы мы не тыкались вот так вот, не передавали S ID, да, там всякие вот эти истории. А это всё было. А сейчас О, он нам прямо скопировал, да, прямо наш вопрос. Супер. Мы понимаем, что он всё помнит. Вот наш вопрос предыдущий. То есть мы создали чат бота, которого будет в контексте наши предыдущие а сообщения. И это это очень круто. То есть это на самом деле уже работающая штука. Э, осталось, как я уже сказал, её закрутить в какую-то простую Uюку, которую можно навайп-кодеть. Я, к сожалению, вообще не разбираюсь в фронте, да, там всякие джаваскрипты, э-э, я не знаю даже на чём, на Реакте, на View пишут сейчас фронт вообще без понятия, если честно. А вот знаю, единственное, на Питоне есть Streamlit, такая мм библиотека либо, да, которая позволяет накидать какую-то простую юку, как учата GPT. В принципе, можно с этим побаловаться. А вот, но я бы, наверное, побаловался бы. Вообще, на самом деле, достаточно долгий видеоролик. Я бы, наверное, оставил это пока что в таком виде. То есть это супер- супер сырое MVP. Я думаю, что если, э, ну, будут какие-то будет какой-то интерес к этой к этому сервису, то я обязательно продолжу. завернуть в суперкрасивую юайку какую-то, да, ну не прямо суперкрасивую, но что-то корректное, и а мы сможем продолжить ээ разрабатывать именно этот сервис. Он а потенциал есть хороший. Вот. И в принципе мне нравится, как это работает теоретически. Вот. А практически, как видите, эта тоже штука работает. Не всегда стабильно, потому что есть проблема с кукисами, да, которую тоже, ну, по-хорошему, надо решить, чтобы пользователь не сидел и там не дрочил пять попыток, чтобы спросить у нашей системы что-то, да. Вот. А, ну, точнее, не спросить, а загрузить видео. А, с тем, как уже у нас внутри будет работать со всем этим. И сори, как у нас хранится это всё, да? То есть вы можете спросить: "А где у нас вообще, как понимает у нас система, что у нас всё есть?" У нас есть файлик database, в котором у нас хранятся все наши сообщения. Можем зайти сюда и посмотреть. Вот у нас тут хранится папочка messages, да? А в которой у нас есть айдишник, айдишник сессии, usзеер, наш вопрос и created, то есть время, когда мы спросили. Есть ответ ассистента такой же. И вот вот эта история вся, она хранится вот тут вот. А-а просто на самом деле с, я так понимаю, стам всем табличкам и видео с которое у нас хранится. У нас хранится, как говорили мы, YouTube, Transcript и Creative супер простая табличка, что ещё нужно, как говорится, для счастья, да, и сессии у нас хранится а сессия по определённому видео. Сессий, как мы помним, может быть несколько. То есть, если мы захотим создать ещё одну сессию по видосику, да, то у нас появится тут вторая запись, у которой будет там session ID уже будет два, а видео ID может быть тот же видео, да, потому что мы хотим ещё раз обсудить это видео, но там может быть в другом контексте, да, например, ну, и наши мессесенджерист я уже показал. То есть всё это хранится у нас в сиклайте нашей, которая фактически является файликом на нашем компьютере, да, и сервер, который у нас запущен, да, то есть в фастапе наш фреймворк, он у нас запущен также в нашем компьютере. То есть всё это работает локально. На самом деле есть огромный потенциал. Если этот видосик сервис реально зайдёт, то бахнуть это всё на какой-то докер, на удалённый сервис, может быть, на ВМКУ какую-нибудь, да? А показать, как деплоить приложение. Де плоить я умею и прикрутить какой-то простой фронт. Вот к этому наверное как-то так. Вот это всё, что я хотел сказать по этому сервису. В общем, давайте подводить итог. За этот ролик мы с нуля собрали полноценный сервис подcast speaking coach, да, или как его можно назвать. То есть штука, которая решает конкретную задачу, да? Вы смотрите подкаст на английском, потом можете обсудить его синьору сетью, которая уже знает весь контекст. Понятно, что он получился не идеальным, а он получился супер-спер простым. Но цель этого видеоролика была, на самом деле, вас познакомить с тем, как пишутся такие базовые сервисы, а как они запускаются и как выглядит код внутри этих сервисов. А далее это исключительно доработка отдельных модулей, да, взять тот же пример с кукисами. На самом деле, если не особо заморачиваться, то можно просто написать какой-то, а, декоратор, да, который у нас будет просить наш код там 10 раз совершать 10 попыток запросов, да, по умолчанию. Вот. И там с какого-то и надеяться, что там за 10 раз у нас проблемы с падением нашего сервиса сервера не возникнет, да, что мы сможем достучаться до Ютуба. Вот как это у нас было на видосе, что мы там раза с пятого, да, по-моему, а, смогли запустить транскрипцию видео. Вот, можно так сделать, а можно написать какую-то адекватную авторизацию через Google или ещё через какой-то сервис, да, там по телефону, может быть, в общем, а написать авторизацию и, ну, естественно, в полноценных сервисах пишется авторизация, удентификация и вот эта вот вся история, да, которая фиксит вот эту проблему с куками, с тем, что к Ютубу пытается достучаться какой-то непонятный, а, неизвестный человек. Вот. А что мы сделали по факту, да, в нашем сервисе? Мы научились забирать видео с YouTube через Python, разобрались, как это вообще работает под капотом, почему там нужны вот эти кукисы, да, какие есть ограничения. Дальше мы вытащили из видеоадио, прогнали через спичествую текстмодельку и получили полноценную расшифровку. После этого мы всё аккуратно сохранили в Seclite, чтобы не гонять одну и ту же дорогую транскрипцию по 10 раз. И в итоге поверх этого собрали чат-логику, да, то есть сессия, память, взаимодействие слм, чтобы можно было реально общаться по подкасту, а не просто, ну, каждый раз кидать заново расшифровку и просить м что-то что-то попробовать, да. И это на самом деле э ключевой момент, да, мы не сделали просто запрос GPT, а собрали маленькую, но полноценную систему с пайплайном, хранением данным, оркестрации и разделением на модуле. А вот что можно сделать дальше, я уже, наверное, рассказал, да, это веб-интерфейс, это добавить нормальный менеджмент сессий, прикрутить кэширование какое-то поу мнению, вынести обработку видеофон, в целом, довести до состояния, когда этим реально можно пользоваться обычному юзеру каждый день. И самое важное, вы сейчас понимаете, как такие штуки вообще собираются, да? Не одним каким-то промтом в кодекс или в clд, а через избиние на части и нормальную инженерку. То есть вы продумываете каждый модуль, вы понимаете, как у вас что работает, да, где у вас слабые места, что бы прикрутить и вот такие вот вещи. Если вам зашёл такой формат, где мы не просто что-то обсуждаем, а реально собираем систему с нуля, обязательно пишите. Это, на самом деле, мотивирует снимать подобные видосы, потому что вот я сейчас потратил очень много времени написание этого сервиса, и непонятно, да, зайдёт ли такой формат, будет ли интересно людям это смотреть и стоит ли вообще дальше продолжать раскручивать этот сервис или это всё ушло в молоко. Вот. И я, да, и мне на самом деле такой формат очень нравится. Я бы хотел продолжить развиваться в эту сторону и возможно развию этот проект в будущем до более какой-то продовой версии. Вот на этом заканчиваем. Напоминаю, что ссылочка на мой Telegram-канал находится в описании, где я разбираю реальные кейсы с работы, где я делюсь какими-то своими фичами, инсайтами по прохождению собеседований, просто какие-то интересные штуки в сфере AILM нейронок. Вот на этом заканчиваем. Спасибо, что досмотрели, и погнали дальше делать ещё более интересные штуки. Всем удачи. M.