📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

How to Build Realtime Voice RAG Agents with ADK Web UI and File Search

Yeyu Lab20:31

Transcription

Здравствуйте и добро пожаловать обратно в Yeyu Lab! Сегодня мы рассмотрим, как использовать фреймворк ADK от Google для создания помощника поиска документов в реальном времени, который позволяет пользователям загружать PDF-файлы, задавать вопросы с помощью голосового взаимодействия в реальном времени с указанием источников. И самое главное, разработка очень проста. Итак, вот в чем дело: Google только что выпустил два инструмента, которые делают создание такой системы намного проще, чем раньше. Во-первых, это инструмент File Search, который представляет собой полностью управляемую RAG-систему, куда вы просто загружаете документы, а он автоматически обрабатывает разбиение на части, встраивания и поиск. Во-вторых, это фреймворк ADK и его компонент расширенного веб-интерфейса, который представляет собой встроенный интерфейс, предоставляющий вам чат в текстовом виде, голосовое взаимодействие, взаимодействие с камерой, загрузку файлов и другие опции с инструментами отладки, которые освобождают вас от написания какого-либо фронтенд-кода. Итак, сегодня я покажу вам, как объединить эти инструменты для создания готовой к производству RAG-помощника. Мы начнем с базового агента, добавим обработку загрузки файлов, интегрируем поиск документов и закончим голосовым взаимодействием по этому документу. К концу у вас будет система, в которой пользователи смогут загрузить PDF, нажать на микрофон и задать вопросы вроде "Что в документе?" — и все это примерно за 500 строк Python. Прежде чем мы начнем, я хочу, чтобы вы сначала увидели живую демонстрацию. Хорошо, давайте посмотрим живую демонстрацию. Это интерфейс встроенного веб-интерфейса ADK. Так что нам не нужно заниматься его разработкой; мы просто сосредоточимся на бэкенде. Итак, здесь вы можете увидеть, что у нас есть "RAG Agent", что является названием нашей папки. На самом деле, в этой папке у нас есть несколько агентов, которые я опишу позже. Итак, здесь первое, что нам нужно сделать, это загрузить один файл и использовать этот файл для голосового взаимодействия. Итак, сначала давайте загрузим локальный файл. Я выберу локальный файл из интернета под названием "Руководство бегуна для игры в Нью-Йоркском марафоне в этом году". Итак, я хочу спросить что-нибудь об этом дне марафона. Итак, давайте загрузим немедленно. Хорошо. Модель, агент, сказал: "Хорошо, я начну с проверки загруженных файлов", и он перечислит все загруженные файлы в системе. "Итак, я вижу, что загруженный документ PDF уже проиндексирован, так что теперь вы можете задать вопрос о нем." Итак, это стратегия экономии затрат: каждый раз, когда я загружаю PDF-файл, он проверяет, проиндексирован ли он и загружен ли он в хранилище Gemini. Если да, то он просто использует существующий индекс для взаимодействия. Теперь я собираюсь спросить что-нибудь голосом об этой марафонской игре. Нажмем кнопку микрофона. (Демонстрация использования приложения) Хорошо, отлично. Какие у вас есть вопросы по загруженному документу? Итак, можете ли вы рассказать мне общее резюме этого документа? Хорошо, загруженный документ — это руководство бегуна для Нью-Йоркского марафона TCS. Он охватывает важную информацию, такую как номера гонок, что взять с собой, детали старта и финиша, а также мероприятия после гонки. В нем упоминается, что Tata Consultancy Services является титульным спонсором, и освещается маршрут через все пять районов, начиная со Статен-Айленда и заканчивая Центральным парком. Руководство также рассказывает о таких вещах, как безопасность, транспорт и где забрать свою сумку после гонки. Всю эту информацию можно найти в uploaded_document.pdf. Итак, можете ли вы описать весь маршрут этой игры? Хорошо. Маршрут марафона проходит через все пять районов Нью-Йорка. Он начинается на Статен-Айленде у подножия моста Верраццано-Нарроуз. Затем проходит через Бруклин, Квинс и Бронкс, прежде чем завершиться в Центральном парке Манхэттена. Эта информация находится в uploaded_document.pdf. Хорошо. Итак, если я бегун этой игры, когда и где мне следует быть готовым в этот день? Хорошо, если вы участвуете в Нью-Йоркском марафоне TCS, вам нужно отправиться в Форт-Уодсворт на Статен-Айленде, это стартовая зона. Что касается времени, то есть расписание старта, и время в пути варьируется. Например, автобус до Мидтаун-Манхэттена занимает около 90 минут, а автобус до Нью-Джерси — около 60 минут, не считая времени на проверку безопасности. Помните, что в стартовую зону допускаются только бегуны с гоночным номером, и все проходят проверку безопасности. Более подробную информацию можно найти в uploaded_document.pdf. Эм, кажется, весь рабочий процесс работает. Мы перейдем к следующему этапу, чтобы объяснить, что произошло внутри этого бэкенда. И также вы можете увидеть трассировку вызовов функций, события, произошедшие во время разговора, исторические сессии, которые мы создали. Хорошо. Итак, прежде чем говорить о разработке, сначала позвольте мне показать вам, что делает File Search. Это недавно выпущенный Google Gemini API, который представляет собой управляемый RAG-конвейер, встроенный в фреймворк модели Gemini. Используя API, вы можете создавать, хранить, загружать документы, а он обрабатывает все под капотом, включая разбиение на части, встраивания с использованием модели встраивания Gemini Embedding 001 и векторный поиск, а также поиск. Все это в одной коробке. Модель ценообразования интересна. Хранение бесплатно. Встраивания во время запроса бесплатны. Вы платите только один раз при первом индексировании файла, это 0,15 доллара за миллион токенов. И если вы посмотрите на документацию File Search, вы найдете, что код очень прост. Когда вам нужно загрузить в хранилище File Search, когда вы импортируете файлы или добавляете некоторые конфигурации разбиения на части и File Search в хранилищах. Это очень просто, всего несколько строк кода. Теперь давайте поговорим о веб-интерфейсе ADK. Внутри ADK, который называется Agent Development Kit, вы можете определить агента, запустить веб-интерфейс, и вы получите полный интерфейс текстового чата, потоковой передачи голоса, ввода с камеры, загрузки файлов, просмотрщик состояния сессии и отладчик трассировки. Если вы хотите попробовать это немедленно, вы можете перейти к его документации, чтобы увидеть краткое руководство. Убедитесь, что вы установили google-genai-adk с помощью pip, и вы можете создать новый проект, вызвав adk create. Давайте попробуем быстро в моей текстовой папке. adk create my_project. Он спросит, какую модель вы собираетесь использовать для корневого агента. Я выбираю одну, Gemini 2.5 Flash, и я выбираю одну для моделей Google AI, и я собираюсь ввести поддельный API-ключ. И теперь он создан. Давайте проверим в текстовой папке. Есть папка my_project, включающая файл agent.py. Он просто создает очень, очень простой агент без каких-либо конкретных функций, и .env для хранения вашего секретного ключа и API-ключа для этого проекта. Хорошо, если у нас это есть в папке проекта, мы теперь можем запустить adk web. О, есть еще один предыдущий проект, который работает. Так что я закрою его. Эм, теперь я открою этот снова. Хорошо, он работает. И теперь локальная веб-страница. Это веб-интерфейс ADK, который подключен к нашей группе агентов my_project. Хорошо. Если я использую действительный API-ключ, то я могу печатать, чтобы говорить с моделью. Итак, если вы сравните процесс создания веб-приложения Lexi, вам понадобится сервер FastAPI. Вам понадобятся обработчики WebSocket, если вы используете аудиосвязь, и вам нужно будет кодировать и декодировать аудио, как мы делали для предыдущих проектов, если вы смотрели мои предыдущие видео. Так что, и вам также нужно управлять управлением сессиями и пользовательским фронтендом с дизайном UI и CSS. Итак, эта команда adk предоставляет вам все это. Итак, теперь давайте просто заглянем в код, чтобы увидеть, как реализовано наше приложение для поиска документов в реальном времени, которое включает RAG-систему, а также голосовое взаимодействие в реальном времени. Я построил всех агентов под rag_agent, и вы увидите, что там есть стандартный файл agent.py. Мы включаем трех агентов, которых мы разработали для нашей системы. Давайте разберем роль каждого агента. Итак, первый агент, который мы назвали FileManagerAgent, обрабатывает загрузку файлов. Итак, когда используется кнопка загрузки UI, файл поступает в виде встроенных данных в части сообщения. Этот агент имеет два инструмента. Один — ListFileTool, который используется для проверки того, что доступно в его хранилище, а другой — IndexFileTool, который предназначен для загрузки в хранилище File Search. Он не должен использовать живую модель. Он должен использовать стандартную модель Gemini 2.5 Flash. А затем у нас есть инструкции, которые направляют модель придерживаться задачи выполнять только операции, связанные с файлами. И второй агент, под названием SearchAssistantAgent, который является нашим ключевым агентом, использующим модель Gemini 2.5 Flash Native Audio Preview для взаимодействия с живым аудио, чтобы отвечать на запросы из хранилища File Search, и у него есть SearchTool, который используется для вызова семантического поиска в векторном хранилище, которое управляется Gemini API для инструментов File Search. И последний — RootAgent, который использует пользовательский базовый агент или RAG-оркестратор, который обнаруживает загрузку файлов и направляет вопрос поисковому помощнику, который должен отвечать на голосовые запросы. Сам по себе инструментов нет; это просто логика координации. Итак, вот диаграмма рабочего процесса системы, которая показывает, как эти агенты координируют работу друг с другом. Итак, из веб-интерфейса ADK у вас есть ввод текста, ввод с микрофона и кнопка загрузки, а также отправка. Итак, когда что-то поступает, RAG-оркестратор, который является нашим пользовательским базовым агентом, работает над фильтрацией и оркестрацией того, с каким агентом следует взаимодействовать. Итак, когда есть файл, он переходит в блоки загрузки файлов, управляемые FileManagerAgent, асинхронно работая с инструментом списка файлов и индексирования файлов для выполнения чистого поиска файлов, который не ищет содержимое. Он просто ищет наличие документа, а когда есть текстовый вопрос, он переходит к поисковому помощнику и использует инструмент SearchDocs для поиска существующих документов для запроса, для поиска, для цитирования. И если есть голосовой ввод, он проверит загрузки в сессии. Если есть сессия загрузки, он вызовет FileManager для выполнения списка и индекса. После этого он выполнит поиск помощника в живом стиле для выполнения семантического поиска в текущем хранилище, и все эти инструменты превратятся в текстовый ответ от ИИ пользователю. Как только файл загружен, он покажет преобразованное имя файла. Если на вопрос дан ответ, он скажет: "На основе точного документа ответ такой-то", и укажет источник этого ответа. Теперь давайте посмотрим, как это реализовано по одному. Первое — это реализация оркестратора в файле orchestrator.py. Мы определяем новый класс под названием RAGOrchestrator, унаследованный от BaseAgent, который используется только для пользовательского агента для выполнения пользовательских действий, выходящих за рамки предустановленной функциональности. Итак, ключевым моментом здесь являются встроенные данные, которые проверяют последнее сообщение на наличие сообщений о загрузке файлов или ключевых слов, таких как "upload" или "index", которые доставляются UI на фронтенде. Если они найдены, он будет направлен к файловому менеджеру для выполнения файловых операций; в противном случае он будет направлен к поисковому помощнику для выполнения прямого семантического поиска по существующему документу. Вся интеграция UI выполняется автоматически. Итак, когда пользователь нажимает кнопку загрузки и выбирает PDF или другой тип файла, он появляется как часть встроенных данных с файлами по MIME-типу. Оркестратор обнаруживает это и направляет соответствующим образом. Вот почему нам нужен пользовательский агент для выполнения этого, потому что исходный агент не может выполнять такие логические операции. Хорошо. Теперь давайте подключим все к Gemini File Search. Нам нужны три инструмента: ListFiles, IndexFiles и SearchDocuments. Итак, я открою файл file_upload_handler.py, чтобы увидеть эти функции. Эм, сначала мы видим list_uploaded_files. Этот инструмент проверяет, какие файлы доступны для индексирования. Здесь мы проверяем историю сессии. Итак, почему мы это делаем? Потому что файл, загруженный через кнопку UI, поступает как встроенные данные, если вы помните, которые не сохраняются автоматически как артефакты. Поэтому нам нужно извлечь их из событий сессии и перечислить. Во-вторых, нам нужен index_uploaded_file, который является инструментом, загружающим файл в хранилище индексирования File Search. Здесь мы создаем хранилище File Search, вызывая Gemini File Search API. Когда происходит первая загрузка, мы проверяем дубликаты с помощью файла file_store_config.json здесь и откладываем операцию загрузки до завершения. В этом JSON-файле мы записываем историю файловых операций. Теперь перейдем к файлу file_search_tool.py, чтобы увидеть определение окончательного инструмента SearchDocumentTool, который обрабатывает запросы к хранилищу File Search, используя Gemini API инструментов File Search. Здесь вы видите, что модель, которую мы используем, — это Gemini 2.5 Flash, а не I-модель, потому что мы хотим, чтобы она была достаточно точной для генерации ответов при поиске файлов. Когда функция обработчика завершена, инструмент завершен. Теперь мы можем создать агента для использования инструмента поиска. Итак, здесь, в определении этого агента, поскольку он хорошо отвечает голосом, мы просим в инструкциях использовать естественный, дружелюбный стиль речи для общения с пользователями, и мы даем пример того, как отвечать и что нужно включить, а также строго просим модель вызывать этот инструмент для ответа на вопросы пользователей, когда это связано с документом. Итак, в основном, теперь текстовое взаимодействие по загруженному документу работает. Итак, поскольку мы собираемся реализовать не только RAG-систему текстовой модели, но и RAG-систему с голосовым взаимодействием. Поэтому нам также придется реализовать голосовое взаимодействие на основе пользовательского агента. Итак, давайте вернемся к файлу оркестратора. Чтобы найти, что у нас есть переопределенная функция run_live_implement, которая точно определена для режима живого голоса, потому что изначально оркестратор имеет только run_async_implementation, который обрабатывает только текстовый режим. Итак, голосовой режим требует переопределения run_live_implementation. Итак, теперь логика оркестрации становится такой: если обнаружено событие загрузки, он запустит FileManager в асинхронном текстовом режиме для их индексирования, затем запустит поискового помощника в живом режиме для ответов на вопросы. Итак, это все для этого бэкенд-кода. Определенно, вам не придется управлять большим количеством рабочих процессов. Вам нужно только позаботиться об агентах, инструментах и их операциях. Итак, опять же, весь исходный код вы можете найти в моем репозитории GitHub для ваших экспериментов или настройки. Я думаю, что платформа ADK с системой веб-интерфейса имеет довольно большой потенциал для расширения для реальных проектов агентов. На этом все на сегодня. Если у вас есть дальнейшие вопросы или идеи, пожалуйста, оставьте их в комментариях ниже. Спасибо за просмотр. Увидимся в следующем видео.