🚀 Pro тут:
https://t.me/iishenka_pro_bot
⭐️ Все бесплатные материалы из этого видео тут:
https://t.me/+W1SnvvkcV6A3NWMy
В этом видео мы создадим обновляемый RAG на Supabase, который сам отслеживает изменения на вашем диске и актуализируется автоматически.
🔥 Независимо от того, работаете ли вы с AI-агентами или только начинаете осваивать автоматизации в n8n, этот урок поможет вам овладеть процессом автоматической загрузки файлов для любых задач.
Следующее видео:
https://youtu.be/GNsWiOZk4KA
💡 Не забудьте поставить лайк и подписаться, чтобы не пропустить новые уроки по n8n и AI-агентам. Давайте сделаем AI-автоматизации простыми! 🙌
Тайм-коды:
01:33 - Настраиваем Метаданные
03:10 - Строим Агента
10:20 - Настраиваем Supabase для второй векторной таблицы
17:18 - Большой Тест
19:37 - Загружаем Большие Файлы
Не забудьте поставить лайк, подписаться и нажать на колокольчик, чтобы не пропустить новые видео о AI-агентах и автоматизациях!
Всем привет. Сегодня мы с вами построим обновляемый рак. Это агент, который сам следит за состоянием файлов на вашем диски. Если вы их удаляете, если вы их изменяете, агент сам замечает изменения и обновляет вашу векторную базу данных. Соответственно, он не добавляет дубликаты в вашу векторную базу данных. Он не пытается удалить её всю, а потом заново перезаписать. Он точечно определяет данные, которые были обновлены, и поддерживает их актуальное состояние. Сразу под несколькими видео, которые мы записывали раньше, были такие комментарии: "Как же держать рак в актуальном состоянии? И сегодня, наконец, мы это делаем". Имейте в виду, что мы уже делали несколько видео про рак. Сейчас следующая серия. И мы каждый раз всё усложняем и усложняем Рак для того, чтобы он мог выполнять коммерческие задачи с высоконагруженными приложениями. Поэтому обязательно подписывайтесь на канал. У нас будет ещё очень много таких видео. Обязательно поставьте лайк и обязательно же оставьте ваш комментарий, потому что так работают алгоритмы Ютуба. И хочу напомнить, что абсолютно все шаблоны NOC Mmen, которые мы создаём в видео вместе с вами, находятся в бесплатном Telegramканале. Ссылка будет в описании. А если вы хотите погрузиться глубже в тему искусственного интеллекта, участвовать в прямых дискуссиях, задавать вопросы, получать консультации, получать поддержку на вашем пути освоения искусственного интеллекта и автоматизацией, то обязательно заходите в наш проканал. Ссылка на него также будет в описании. А мы начинаем. Что нужно понимать про обновляемый рак? Краеугольное понятие во всей этой
процедуре - это метаданные. Это не очень сложно, я вам сейчас всё объясню. Каждый раз, когда мы храним а файлы в каком-то диске, это может быть Google Drive, это может быть ЯндексДиск, с Яндекс-диском чуть будет всё посложнее, у них намного менее развитая апи инфраструктура. Каждый раз, когда мы делаем какую-то манипуляцию с файлами, мы обязаны туда добавить специфические метаданные и поместить их в нашу векторную базу данных вместе с метаданными. Для чего это делается? Это очень важно. Каждый раз, когда на этом диске происходит какое-то событие, либо создание, либо обновление файла, мы сначала делаем процедуру поиска соответствующих записей в нашей векторной базе данных. То есть мы выбираем конкретные записи в векторной базе данных, которые соответствуют изменённому файлу. И после этого мы удаляем записи из векторной базы данных, которые соответствуют этому изменённому файлу. После этого мы добавляем новый метаданные файл и записываем в векторную базу данных. Для чего это всё нужно и почему это так важно? Это важно для того, чтобы мы не тратили наши ресурсы, я имею в виду ресурсы нейронки, оплату токенов для того, чтобы каждый раз перезаписывать всю нашу векторную базу данных. Представьте, что у вас там тысячи и тысячи файлов - это очень непродуктивная операция. Но если мы научимся определять точечные записи, которые нам нужно держать в актуальном состоянии, и каждый раз их обновлять, мы значительно экономим ресурсы свои нашего бизнеса. Ну давайте приступим тогда. Так как в этом видео мы будем использовать Google диск. Нам нужно проскролить вниз
раскрыть триггеры, и нас интересуют изменения в а специфической папочке. Заходим в наш первый триггер. И здесь мы должны указать по time - это время, периодичность, с которой, а, система ходит и проверяет состояние в этой папочке, в которой нас интересует. Соответственно, мы указываем every minute, да, то есть каждую минуту. Триггер он, а, изменения, которые, а, касаются конкретной папки. И здесь указываем fromlist и указываем папку на Google Драйве, которая нас интересует. Я уже создал папочку, которая называется SFSте. И, а, указываю здесь watch for, то есть это мы следим за событием, файл создан. Соответственно, как только создаётся там какой-то файл, нас интересует это событие. И аналогично мы создаём прямо дублицируем, да? Вот мы можем нажать Ctrl C, Ctrl V, задублицировали. и прямо дублицируем. Всё-всёвсё то же самое, только мы здесь следим за файл updated, да? То есть как только какой-то из файлов изменяется, этот триггер сработает. В предыдущих видео мы уже научились, что лучше с большим количеством файлов работать через лу, да? То есть мы закидываем loop, пока удаляем все ненужные ноды и связываем. То есть, если, допустим, будет изменение сразу нескольких файлов, да, или мы добавим в Google Drive сразу несколько файлов, мы хотим, чтобы мы по очереди работали по одному с этими файлами. Что такое LOOP было в предыдущих видео. А, идите посмотрите. Мы всё это подробно разбирали. Кстати, в нашей прогруппе есть систематизированные знания, короткие вырезки про все технические нюансы, как настраивать доступы в разные системы, что такое петли, что такое суbase, чем отличается векторизация от обычного, от обычной релевантной базы. Соответственно, можно туда зайти и там увидеть все-всев-все систематизированные знания, которые очень регулярно, ну, на постоянной основе обновляются и иметь к ним доступ. Соответственно, мы поставили петлю. И дальше мы добавляем ноду, которая называется Edit Fields. Да, помните, мы в прошлом видео делали похожую вещь просто через ноду код. Одно и то же. Мы здесь что делаем? Мы вот эту лупу закинем. Мы хотим привести к некоторому общему знаменателю, ну, данные, которые мы получаем из Google Драйва. Соответственно, мы можем сразу, видите, из двух триггеров получать данные, но вне зависимости от того, а куда из какого триггера прилетели эти данные, мы сразу запис запишем, что Jon ID мы хотим представить как файл ID, что M type - это тип документа. Это, кстати, нужно для будущих видео. Мы будем с вами говорить, а, про различия текстовых файлов. Если это Excel файл, если это CSV файл, таблицы, они по-разному работают. Это всё будет в следующих видео. само название файла, да, изon name мы сохраняем как файл title и URL - это, собственно, прямая ссылка на этот файл. И дальше мы добавляем ноду а Superabbase. Сразу отмечу, да, каким образом а работает подключение Google Драйва. Мы это а просматривали всё и прямо проходили в самом первом видео на этом канале. Обязательно сходите, посмотрите. То же самое касается superbate, чтобы каждый раз из видео в видео мы это не проговаривали, а можно найти это в предыдущих видео или в прогруппе. Фишка в том, что мы должны один раз настроить аккаунт в Supbase или в Google Drive. И после этого в каждом Workflow, а, в N8N мы, а, просто переиспользуем одни и те же аккаунты и совершенно, ну, больше не тратим на это время. Так как мы уже настраивали аккаунт, да, у нас есть аккаунт Suabbase. Мы его здесь, а, подключаем. И что нас интересует? Нас интересует довольно специфический кейс. Я вам сейчас всё объясню. Каждый раз, когда происходит какая-то операция, срабатывает триггер, да, то есть файл изменился либо файл добавился, мы хотим пойти в векторную базу данных, да, где мы храним в мм в нашей таблице, которая называется documents YT Now, да, я её только что создал. Кстати, сейчас мы вместе пройдём создание этой базы, потому что это чуть-чуть отличается от создания первой базы данных. Я сейчас всё покажу. Соответственно, мы хотим, а, отфильтровать эти данные по метаданные, да, в которых содержится файл ID и тот самый JSON File ID, который мы сейчас получим из Google Драйва. Давайте, чтобы это было нагляднее, я попробую сейчас прогнать тестовый а вариант. Давайте, допустим, File Created. Пробуем, да, у нас получилось. Соответственно, мы что-то получили, да? Видите, нам Google Drive отдал вот, ну, массу всего, да? Мы после этого прогнали через наш сет File ID, да, и смотрите, мы вот из всех этих всего этого страшного Джейсона забрали себе файл ID, да, и вот он наш файл ID. Файл type. Вот он наш файл type. Само название. Я только что создал файл 22. И после этого мы хотим, а, в Supase сказать: "Пойди поищи методанные". Да, давайте раскроем, чтобы это было видно. Пойди поищи метаданные, да, в которых есть вот такой файл ID. Для чего? Помните, мы в самом начале видео проговаривали. Их теперь нужно удалить, чтобы не дублицировать, но только их конкретно эти строки. И после того, как мы, а, удалили конкретные строки в векторной базе данных, мы хотим теперь забрать обновлённый файл. Да, он же обновился либо добавился. Теперь мы его забираем. Опять же, мы эту процедуру уже делали в прошлых видео, но сейчас а мы с вами посмотрим, то нам нужно, вообще говоря, Google Drive такая нода, как Downloadфайл. Соответственно, её кинули и открываем, да, и мы хотим, в принципе, давайте соединим, чтобы видеть. Давайте сейчас вот эту всю цепочку попробуем а именно верхнюю протестировать, да? То есть в тот момент, когда мы добавим какой-то файл, мы ожидаем, что а мы удалим соответствующие записи из векторной базы данных, да, если их там нет, соответственно, удалять нечего. Но нам интересно, чтобы мы пробежали всю эту цепочку и скачали файл. Я пойду сейчас в Google Drive, да, и добавлю для того, чтобы отследить всю эту историю, файл 333, да, и здесь набежу 333 маленький текст специально, чтобы мы посмотрели, как это работает. Прогоняем именно этот флоу. Смотрим, как он идёт. Идёт, идёт. Так, отлично. Почему-то он не хочет скачивать, да? У нас была, так, как я копирую, да, некоторые ноды из своего вот готового проекта, он добавляет другие одишки. Соответственно, вы тоже за этим следите, да? У нас теперь setfile ID1 это называется. Соответственно, если теперь мы протестируем шаг, да, у нас качается файл, сейчас мы его откроем, в котором есть наш контент 333. Отлично. Возвращаемся обратно к Supace, да? каким образом настраивается а табличка для того, чтобы мы хранили а наши векторы. Мы это делали уже один раз, настраивали первую свою таблицу, но настраивание каждой следующей векторной таблицы чуть-чуть отличается, и там можно споткнуться о какие-то моменты. Поэтому сейчас мы с вами создадим новую таблицу, там вторую или третью или четвёртую. Если мы пойдём
в документацию Superabase, да, то мы опять же увидим такой пункт, который называется Quickst for setting up your vector store. Да? А если мы сюда зайдём, то нам дадут SQL запрос, который нужно выполнить в своей аbase базе. И у вас создастся, во-первых, да, давайте разберёмся в деталях, вам создастся, то есть добавится extension, да, то есть некоторый, а надстройка на Superabase, который позволяет работать с векторами базами данных, да? После этого создаётся таблица документы, в который добавляется несколько полей: ID, контент, метада, метадата и сами имбединги, да? И после этого создаётся функция для поиска по этим документам. Вот тут кроется самая как бы интересный момент. Если мы первый раз проведём этот скрипт, то есть мы как мы его заберём, да, пойдём к нам в Supase, зайдём вот сюда в SQL Editor, да, и вот просто его прогоним, он у нас выполнится без проблем. Но если мы захотим себе создать следующую базу векторану, да, чтобы разделить векторы по разным nameпейсам, скажем так, там мы скажем documents 2 и прогоним, у нас будет ошибка. Почему это происходит? Во-первых, а что нужно знать? Когда мы создаём новую базу данных, мы не делаем, не создаём новый экнtion, да? То есть он у нас уже создан, и он работает со всей базой. Соответственно, нам нужно сделать такое. Мы создаём новую базу, мы должны дать новое имя, да? То есть, например, documents YT Now. Вот новое имя. Здесь всё оставляем как есть, да, как и в прошлой базе. Здесь мы должны создать ещё и функцию для поиска векторов. Это тоже не тривиально, но она должна быть уникальная, к сожалению. Ну, так сейчас работает система су у Supase, что мы должны создавать функции для каждой таблицы. Соответственно, мы даём функции новое имя, да, прошлой это было match documents, да, в оригинальной мы говорим match documents itt now, да, и прописываем здесь оставляем, оставляем, да, и здесь прописываем, что у нас теперь таблица documents white now. Ну и, собственно, здесь тоже documents white now. Мы делаем выборку оттуда, да, и, соответственно, а, делаем сортировку вот по а now. Вы, если запустите этот скрипт, у вас создастся новая таблица, и там, ну, и к ней создастся новая функция. Прекрасно. Но что мы должны знать? Если после этого мы укажем здесь таблицу documents YT Now, по умолчанию искать он будет не в ней. Я сейчас, мы сейчас дойдём до этого, пройдём по этому моменту. Пока мы научились скачивать файл, который, который у нас обновлённый, либо новый, да, и как только мы его научились скачивать, да, мы должны его добавить в Superabase векторную базу данных. Мы опять же идём, да, сюда добавля сюда пишем Superbase, Superbase vector Store накидываем, а сюда. И здесь нас интересует adds to vector store, да? Соответственно, я накинул. Вот. И у нас будет операция Insert Documents, да? И нам интересно, а как раз работать с нашей новой таблицей, да, мы только что создали Docum YT Now. И самое важное, нам, помните, мы создавали функцию для поиска по этим данным, да, мы а добавляем query name раз ту самую функцию match documents YT now, да? То есть мы её указали вот здесь, вот она. Соответственно, мы её указываем и в самой ноде Superabase. Всё. Дальше мы добавляем нашу нейронку, да, для имбедингов. Мы опять же всё это делали в прошлых видео. Посмотрите, здесь всё максимально а типично. Добавляем парсер. Здесь в парсере мы указываем бинарник, да, потому что мы получили сейчас себе бинарник на вход, да, всё оставляем. И, соответственно, к парсеру добавляем а текст spпitter. Мы опять же объясняли и проговаривали, что такое текст spпitter в прошлых видео. А, идите посмотрите. Тут, в принципе, уже мы несколько раз проговаривали. Вот. А определить chunй пока оставим всё по умолчанию. Это что значит? Что по сути, если мы сейчас прогоним, а всю ветку, да, по идее весь контент из файла должен записаться в векторную базу данных. Мы сейчас прямо откроем нашу векторную базу данных, соответствующую таблицу, да? Идём в таблицы. Вот у нас она совершенно пустая, видите? Documents YT now, да? Если мы сейчас прогоняем этот workflow, смотрим, как он отрабатывает, работает, закончился. Что, что мы можем увидеть? Что мы определили, что был добавлен файл 333, да, у которого был контент, там был маленький контент 333, да, но сейчас в этой базе данных, если мы её обновим, смотрите, содержится контент 333. А, и самое интересное сейчас про методданные. Помните, мы обсуждали, насколько же важно добавить э эти метаданные. Если мы вернёмся в наш data loader, да, мы а должны будем здесь добавить options. То есть мы нажмём здесь а add option, да, и добавим метаданные. И вот эта краеугольная штука. Мы хотим запомнить в этих методданных файл ID. То есть я прописываю, я хочу, чтобы там остался файл ID. И туда я записываю реальный файл ID из нашей ноды set file ID. Да, только единички везде прокидываем, не забываем. Мы указали file ID, мы указали файл title. Это значит, что в этой базе должно это всё сохраниться. Если мы сейчас ещё раз прогоним, прогоняем ещё раз. И здесь сразу происходит, а, две больших вещи. Давайте обновим нашу базу и обратим внимание. Создалась вторая запись. Да, этого не должно было случиться. Почему это случилось? В первый раз, когда мы прогоняли, у нас, обратите внимание, мы открываем метаданные, да, и здесь прописан только source - это blob, да, и blob type - это, ну, собственно, сам m type этого документа. А во второй раз здесь уже намного больше информации. Смотрите, файл ID. И здесь записано именно ID из Google Драйва, да? Здесь написан файл title, то есть само название этого файла. Это значит, что сейчас мы записали намного больше информации, по которой мы в последующем можем искать релевантные записи в векторной базе данных. Это что значит? Если мы сейчас удалим, да, старую нашу базу, старый старую нашу запись, например, и оставим только запись, где уже есть все методные, и прогоним наш а путь ещё раз, то, по идее, следующая запись не должна создаться, потому что мы по методанным найдём релевантный файл, да? релевантные записи в векторной базе данных. Сначала их удалим и потом перезапишем. Соответственно, количество записей должно остаться одна. Давайте попробуем. Смотрим, смотрим. Как идёт, идёт. Так, закончился workflow. Обновляем. Смотрите, запись осталась одна. Соответственно, мы сейчас получили подтверждение, что мы делаем всё правильно. Так, ну что, настало время протестировать наш Flow. Давайте
прямо несколько файлов добавим, да, в наш Google Drive и посмотрим, каким образом будет этот Flow отрабатывать, какие записи в базе будут оставаться, какие будут удаляться. Соответственно, если я сейчас пойду, создам новый файл, который называется 111, да, сохраню и прогоню этот флоу, да, в нашей базе должна создаться одна строка, в принципе, только с а с этой записью. Вот у нас 111, да, контент, а, наши метаданные 111. Прекрасно. Что будет, если я создам ещё один файл, да, скажем, 22, да, создался файл. И если мы прогоним ещё раз этот флоу, тактактак, прошли, прошли. Так, смотрим, что у нас создалось в базе данных. Отлично, у нас создался, а, контент 222, да, и здесь указано, что это прилетело нам из файлов 222. И теперь самый интересный тест. А что будет, если мы сейчас внесём какие-то изменения в файл 111, да? То есть у нас по идее в базе не долж не должен создаться дубликат, у нас должна обновиться только конкретная строчка либо набор строчек, которые соответствуют конкретному файлу. Соответственно, мы идём в Google Drive, да, заходим сюда и пишем, то есть обновляем контент как-то. То есть мы прямо побольше написали, да, сохранили. И сейчас самый ответственный момент, да, мы идём и тестируем, как отрабатывает файл updated нода. Соответственно, она должна определить, что был изменён только один файл и внести изменения в конкретные записи в векторной базе данных. Пробуем. Так, тактак. определил. Смотрим, что же он нас определил. Он определил, что были изменения в файле 111, соответственно, и пошёл потом пошёл в векторную базу данных и внёс новые файлы, да, но предварительно он должен был удалить запись от старого файла. Идём сюда, обновляемся. Прекрасно. Смотрите, у нас также и осталось две записи, да? И одна из них соответствует файлу 111. контент уже обновлённый, то есть теперь наш рак готов работать с этой базой. И обновляется, его знания обновляются, а, нашего агента полностью автоматически. Я знаю, что вы часто
пишите в комментариях, что почему же такие простые примеры, такие простые файлы, что если что-то побольше. Поэтому я сейчас просто возьму, очищу базу знаний для того, чтобы было чистый эксперимент. Теперь я готов сюда закинуть несколько файлов. Но для того, чтобы мы прямо посмотрели, как это работает, я хочу пойти сюда и активировать этот флоу. Это значит, что каждую минуту а наша наш workflow будет смотреть в эту папку и должен, по идее, определить все пять файлов, которые а сюда закинулись. Соответственно, я нажимаю сюда а этот свичер, да, делаю этот флоу активным, и в этот момент он уже начинает ожидать файлы в диске. Я беру, добавляю пять файлов в диск, всё, наши даже шесть файлов добавились, и теперь мы должны подождать. Соответственно, через минуту здесь должен появиться execution, да? То есть сейчас вот он должен в 15:43 быть или в 15:44. А я сейчас поставлю видео на паузу и как только Ага. даже и не нужно ждать. Смотрите, пошёл цикл. Пошёл цикл, да, он должен определить, что там шесть новых файлов, соответственно, идёт ex Так, первый прошёл. Так, да, второй прошёл. Так, интересно. Очень интересно. Смотрите, он шесть раз прогнал нам наш цикл. Это значит, что по идее в нашей базе должны появиться релевантные записи вот этой фигурации файлов. Например, да, нас интересует там intrродаction. Мы видим, что тут техническая информация, это документация для нашей компании какая-то, да, должна появиться соответствующая запись, да, в базе данных. Идём сюда, обновляемся. Отлично. Смотрите, у нас есть наши чанки, да? И у нас есть везде метод данные, откуда же он забирал эти, а, эти функции. Теперь самое интересное. Мы идём в наш файл и меняем, допустим, что-то только в одном файле. Допустим, в том же Introductions, да? Мы здесь, а, нажимаем там Enter 1 1. Теперь, если мы вернёмся сюда опять в Executions, да, то в течение минуты он должен определить, что было изменение какое-то в файле, в конкретном файле, и провести только вот эти изменения. должен удалить все релевантные записи только этому файлу и, а, записать новые данные. Я сейчас поставлю опять же видео на паузу, может быть это будет через минуту, и продолжим, когда начнётся эта процедура. Так, мы видим, что у нас в очереди есть, да? Отлично. Только что прошла процедура, и мы можем, а, удостовериться, с каким же файлом была манипуляция, да? Мы можем нажать сюда, увидеть, что это было copy of introduction, да? А он так и назывался, copy of introduction, да? Мы сначала удалили все релевантные, только релевантные copy of introduction записи и потом залили новые записи только для этого файла. Все остальные файлы мы не трогали, всю остальную векторную базу мы не трогали. Для нас это произошло максимально дёшево, максимально точечно. На этом всё на сегодня. Как я уже сказал, мы развиваем наш рак. Да и будут ещё видео про рак. Усложняем и усложняем эту историю. Лайк, подписка, проверьте. Вот этот шаблон будет в бесплатной Telegram-группе. Обязательно то залетайте, забирайте шаблон, экспериментируйте и идите в нашу прогруппу. Также там живое общение, там усложнённые кейсы, там очень много всего интересного. До встречи.