О практической работе
1. Обзор
В различных отраслях контекстный поиск является важнейшей функциональностью, которая формирует сердце и центр их приложений. Дополненная генерация поиска уже довольно давно является ключевым драйвером этой важной технологической эволюции с ее механизмами поиска на основе генеративного ИИ. Генеративные модели с их большими контекстными окнами и впечатляющим качеством вывода преобразуют ИИ. RAG обеспечивает систематический способ внедрения контекста в приложения и агенты ИИ, заземляя их в структурированных базах данных или информации из различных носителей. Эти контекстные данные имеют решающее значение для ясности истины и точности вывода, но насколько точны эти результаты? Ваш бизнес в значительной степени зависит от точности этих контекстных соответствий и релевантности? Тогда этот проект вас пощекочет!
Теперь представьте, если бы мы могли взять силу генеративных моделей и создать интерактивных агентов, которые способны принимать автономные решения, подкрепленные такой контекстно-критической информацией и основанные на истине; это то, что мы собираемся создать сегодня. Мы собираемся создать сквозное приложение агента ИИ, используя Agent Development Kit на базе передового RAG в AlloyDB для приложения патентного анализа.
Patent Analysis Agent помогает пользователю находить патенты, соответствующие контексту поиска, и по запросу предоставляет четкое и краткое объяснение и дополнительные сведения, если требуется, для выбранного патента. Готовы увидеть, как это делается? Давайте погрузимся!
Цель
Цель проста. Позвольте пользователю искать патенты на основе текстового описания, а затем получать подробное объяснение конкретного патента из результатов поиска, и все это с помощью агента ИИ, созданного с помощью Java ADK, AlloyDB, Vector Search (с расширенными индексами), Gemini и всего приложения, развернутого без сервера в Cloud Run.
Что вы построите
В рамках этой лабораторной работы вы:
- Создайте экземпляр AlloyDB и загрузите данные из набора данных Patents Public Dataset.
- Реализуйте расширенный поиск векторов в AlloyDB с использованием функций ScaNN и Recall eval
- Создать агента с помощью Java ADK
- Реализуйте логику сервера базы данных в Java Serverless Cloud Functions
- Разверните и протестируйте агент в Cloud Run
На следующей диаграмме представлен поток данных и этапы реализации.
High level diagram representing the flow of the Patent Search Agent with AlloyDB & ADK
Требования
2. Прежде чем начать
Создать проект
- В Google Cloud Console на странице выбора проекта выберите или создайте проект Google Cloud.
- Убедитесь, что для вашего проекта Cloud включена функция выставления счетов. Узнайте, как проверить, включена ли функция выставления счетов для проекта .
- Вы будете использовать Cloud Shell , командную среду, работающую в Google Cloud. Нажмите Activate Cloud Shell в верхней части консоли Google Cloud.
- После подключения к Cloud Shell вы проверяете, что вы уже аутентифицированы и что проекту присвоен ваш идентификатор проекта, с помощью следующей команды:
gcloud auth list
- Выполните следующую команду в Cloud Shell, чтобы подтвердить, что команда gcloud знает о вашем проекте.
gcloud config list project
- Если ваш проект не настроен, используйте следующую команду для его настройки:
gcloud config set project <YOUR_PROJECT_ID>
- Включите требуемые API. Вы можете использовать команду gcloud в терминале Cloud Shell:
gcloud services enable alloydb.googleapis.com compute.googleapis.com cloudresourcemanager.googleapis.com servicenetworking.googleapis.com run.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com aiplatform.googleapis.com
Альтернативой команде gcloud является поиск каждого продукта через консоль или использование этой ссылки .
Информацию о командах и использовании gcloud см. в документации .
3. Настройка базы данных
В этой лабораторной работе мы будем использовать AlloyDB в качестве базы данных для патентных данных. Она использует кластеры для хранения всех ресурсов, таких как базы данных и журналы. Каждый кластер имеет первичный экземпляр , который обеспечивает точку доступа к данным. Таблицы будут хранить фактические данные.
Давайте создадим кластер, экземпляр и таблицу AlloyDB, куда будет загружен набор данных по патентам.
Создать кластер и экземпляр
- Перейдите на страницу AlloyDB в Cloud Console. Самый простой способ найти большинство страниц в Cloud Console — воспользоваться строкой поиска консоли.
- Выберите СОЗДАТЬ КЛАСТЕР на этой странице:
- Вы увидите экран, подобный показанному ниже. Создайте кластер и экземпляр со следующими значениями (убедитесь, что значения совпадают, если вы клонируете код приложения из репозитория):
- идентификатор кластера : "
vector-cluster
" - пароль : "
alloydb
" - PostgreSQL 15 / последняя рекомендуемая версия
- Регион : "
us-central1
" - Сетевое взаимодействие : "
default
"
- При выборе сети по умолчанию вы увидите экран, подобный показанному ниже.
Выберите НАСТРОЙКА ПОДКЛЮЧЕНИЯ .
- Оттуда выберите « Использовать автоматически выделенный диапазон IP-адресов » и «Продолжить». После просмотра информации выберите «СОЗДАТЬ ПОДКЛЮЧЕНИЕ».
- После настройки сети вы можете продолжить создание кластера. Нажмите CREATE CLUSTER , чтобы завершить настройку кластера, как показано ниже:
Обязательно измените идентификатор экземпляра (который вы можете найти во время настройки кластера/экземпляра) на
vector-instance
. Если вы не можете его изменить, не забудьте использовать идентификатор вашего экземпляра во всех последующих ссылках.
Обратите внимание, что создание кластера займет около 10 минут. После успешного завершения вы должны увидеть экран, на котором будет показан обзор вашего кластера, который вы только что создали.
4. Прием данных
Теперь пришло время добавить таблицу с данными о магазине. Перейдите в AlloyDB, выберите основной кластер, а затем AlloyDB Studio:
Возможно, вам придется подождать, пока ваш экземпляр не будет создан. После этого войдите в AlloyDB, используя учетные данные, которые вы создали при создании кластера. Используйте следующие данные для аутентификации в PostgreSQL:
- Имя пользователя: "
postgres
" - База данных: "
postgres
" - Пароль: "
alloydb
"
После успешной аутентификации в AlloyDB Studio, команды SQL вводятся в редакторе. Вы можете добавить несколько окон редактора, используя плюс справа от последнего окна.
Команды для AlloyDB вы будете вводить в окнах редактора, используя при необходимости параметры «Выполнить», «Форматировать» и «Очистить».
Включить расширения
Для создания этого приложения мы будем использовать расширения pgvector
и google_ml_integration
. Расширение pgvector позволяет хранить и искать векторные вложения. Расширение google_ml_integration предоставляет функции, которые вы используете для доступа к конечным точкам прогнозирования Vertex AI для получения прогнозов в SQL. Включите эти расширения, запустив следующие DDL:
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
Если вы хотите проверить расширения, включенные в вашей базе данных, выполните следующую команду SQL:
select extname, extversion from pg_extension;
Создать таблицу
Вы можете создать таблицу с помощью приведенного ниже оператора DDL в AlloyDB Studio:
CREATE TABLE patents_data ( id VARCHAR(25), type VARCHAR(25), number VARCHAR(20), country VARCHAR(2), date VARCHAR(20), abstract VARCHAR(300000), title VARCHAR(100000), kind VARCHAR(5), num_claims BIGINT, filename VARCHAR(100), withdrawn BIGINT, abstract_embeddings vector(768)) ;
Столбец abstract_embeddings позволит хранить векторные значения текста.
Предоставить разрешение
Выполните приведенный ниже оператор, чтобы предоставить разрешение на выполнение функции «встраивания»:
GRANT EXECUTE ON FUNCTION embedding TO postgres;
Предоставьте учетную запись службы AlloyDB роль пользователя Vertex AI.
Из консоли Google Cloud IAM предоставьте учетной записи службы AlloyDB (которая выглядит так: service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com) доступ к роли «Пользователь Vertex AI». PROJECT_NUMBER будет содержать номер вашего проекта.
В качестве альтернативы вы можете выполнить следующую команду из терминала Cloud Shell:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
Загрузить данные патентов в базу данных
В качестве нашего набора данных будут использоваться общедоступные наборы данных Google Patents на BigQuery. Для выполнения запросов мы будем использовать AlloyDB Studio. Данные берутся в файл insert_scripts.sql
, и мы запустим его для загрузки данных патентов.
- В консоли Google Cloud откройте страницу AlloyDB .
- Выберите только что созданный кластер и щелкните экземпляр.
- В меню навигации AlloyDB нажмите AlloyDB Studio . Войдите, используя свои учетные данные.
- Откройте новую вкладку, нажав на значок «Новая вкладка» справа.
- Скопируйте оператор запроса
insert
из скриптаinsert_scripts.sql
, упомянутого выше, в редактор. Вы можете скопировать 10-50 операторов вставки для быстрой демонстрации этого варианта использования. - Нажмите Выполнить . Результаты вашего запроса появятся в таблице результатов .
5. Создание вложений для данных патентов
Сначала давайте протестируем функцию внедрения, выполнив следующий пример запроса:
SELECT embedding('text-embedding-005', 'AlloyDB is a managed, cloud-hosted SQL database service.');
Это должно вернуть вектор вложений, который выглядит как массив чисел с плавающей точкой, для образца текста в запросе. Выглядит так:
Обновите векторное поле abstract_embeddings
Запустите приведенный ниже DML-код, чтобы обновить аннотации патентов в таблице с соответствующими вложениями:
UPDATE patents_data set abstract_embeddings = embedding( 'text-embedding-005', abstract);
6. Выполнить поиск вектора
Теперь, когда таблица, данные, вложения готовы, давайте выполним векторный поиск в реальном времени для текста пользовательского поиска. Вы можете проверить это, выполнив запрос ниже:
SELECT id || ' - ' || title as title FROM patents_data ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
В этом запросе
- Пользователь искал текст: «Анализ настроений».
- Мы преобразуем его во встраивание в методе embedding(), используя модель: text-embedding-005.
- «<=>» представляет собой использование метода расстояния КОСИНУСНОГО ПОДОБИЯ.
- Мы преобразуем результат метода внедрения в векторный тип, чтобы сделать его совместимым с векторами, хранящимися в базе данных.
- LIMIT 10 означает, что мы выбираем 10 наиболее близких совпадений искомого текста.
AlloyDB выводит Vector Search RAG на новый уровень:
Введено много новых вещей. Две из них ориентированы на разработчиков:
- Встроенная фильтрация
- Оценщик отзывов
Встроенная фильтрация
Раньше, как разработчик, вам приходилось выполнять запрос поиска векторов и иметь дело с фильтрацией и отзывом. Оптимизатор запросов AlloyDB делает выбор относительно того, как выполнять запрос с фильтрами. Встроенная фильтрация — это новый метод оптимизации запросов, который позволяет оптимизатору запросов AlloyDB оценивать как условия фильтрации метаданных, так и векторный поиск, используя как векторные индексы, так и индексы в столбцах метаданных. Это увеличило производительность отзыва, позволяя разработчикам использовать преимущества того, что AlloyDB может предложить из коробки.
Встроенная фильтрация лучше всего подходит для случаев со средней селективностью. Поскольку AlloyDB выполняет поиск по индексу вектора, он вычисляет расстояния только для векторов, которые соответствуют условиям фильтрации метаданных (ваши функциональные фильтры в запросе, обычно обрабатываемые в предложении WHERE). Это значительно повышает производительность для этих запросов, дополняя преимущества пост-фильтра или предварительного фильтра .
- Установите или обновите расширение pgvector
CREATE EXTENSION IF NOT EXISTS vector WITH VERSION '0.8.0.google-3';
Если расширение pgvector уже установлено, обновите расширение вектора до версии 0.8.0.google-3 или более поздней, чтобы получить возможности оценщика отзыва.
ALTER EXTENSION vector UPDATE TO '0.8.0.google-3';
Этот шаг необходимо выполнить только в том случае, если расширение вашего вектора <0.8.0.google-3.
Важное примечание: Если количество строк меньше 100, вам не нужно будет создавать индекс ScaNN изначально, поскольку он не будет применяться для меньшего количества строк. В этом случае пропустите следующие шаги.
- Для создания индексов ScaNN установите расширение soliddb_scann.
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
- Сначала запустите векторный поисковый запрос без индекса и без включенного встроенного фильтра:
SELECT id || ' - ' || title as title FROM patents_data
WHERE num_claims >= 15
ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
Результат должен быть похож на:
- Запустите Explain Analyze для него: (без индекса и встроенной фильтрации)
Время выполнения 2,4 мс.
- Давайте создадим обычный индекс по полю num_claims, чтобы иметь возможность фильтровать по нему:
CREATE INDEX idx_patents_data_num_claims ON patents_data (num_claims);
- Давайте создадим индекс ScaNN для нашего приложения поиска патентов. Запустите следующее из вашей студии AlloyDB:
CREATE INDEX patent_index ON patents_data
USING scann (abstract_embeddings cosine)
WITH (num_leaves=32);
Важное примечание: (num_leaves=32)
применяется к нашему общему набору данных с 1000+ строками. Если количество строк меньше 100, вам не нужно будет создавать индекс изначально, поскольку он не будет применяться для меньшего количества строк.
- Включите встроенную фильтрацию в индексе ScaNN:
SET scann.enable_inline_filtering = on
- Теперь давайте выполним тот же запрос с фильтром и векторным поиском:
SELECT id || ' - ' || title as title FROM patents_data
WHERE num_claims >= 15
ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
Как вы можете видеть, время выполнения значительно сократилось для того же поиска векторов. Индекс ScaNN, встроенный в Inline Filtering, в поиске векторов сделал это возможным!!!
Теперь давайте оценим полноту для векторного поиска с использованием ScaNN.
Оценщик отзывов
Полнота в поиске по сходству — это процент релевантных экземпляров, которые были извлечены из поиска, т. е. количество истинно положительных результатов. Это наиболее распространенная метрика, используемая для измерения качества поиска. Одним из источников потери полноты является разница между приблизительным поиском ближайшего соседа, или aNN, и k (точным) поиском ближайшего соседа, или kNN. Векторные индексы, такие как ScaNN от AlloyDB, реализуют алгоритмы aNN, позволяя ускорить векторный поиск в больших наборах данных в обмен на небольшой компромисс в полноте. Теперь AlloyDB предоставляет вам возможность измерять этот компромисс непосредственно в базе данных для отдельных запросов и гарантировать его стабильность с течением времени. Вы можете обновлять параметры запроса и индекса в ответ на эту информацию, чтобы добиться лучших результатов и производительности.
Вы можете найти отзыв для векторного запроса по векторному индексу для заданной конфигурации с помощью функции estimate_query_recall . Эта функция позволяет вам настраивать параметры для достижения желаемых результатов отзыва векторного запроса. Отзыв — это метрика, используемая для качества поиска, и определяется как процент возвращенных результатов, которые объективно ближе всего к векторам запроса. Функция estimate_query_recall включена по умолчанию.
Важное примечание:
Если вы столкнулись с ошибкой отказа в доступе на индексе HNSW на следующих этапах, пропустите весь этот раздел оценки отзыва на данный момент. Это может быть связано с ограничениями доступа на данном этапе, поскольку он только что был выпущен на момент документирования этой кодовой лаборатории.
- Установите флаг «Включить сканирование индекса» для индекса ScaNN и индекса HNSW:
SET scann.enable_indexscan = on
SET hnsw.enable_index_scan = on
- Выполните следующий запрос в AlloyDB Studio:
SELECT
*
FROM
evaluate_query_recall($$
SELECT
id || ' - ' || title AS title,
abstract
FROM
patents_data
where num_claims >= 15
ORDER BY
abstract_embeddings <=> embedding('text-embedding-005',
'sentiment analysis')::vector
LIMIT 25 $$,
'{"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10}',
ARRAY['scann']);
Функция estimate_query_recall принимает запрос в качестве параметра и возвращает его отзыв. Я использую тот же запрос, который я использовал для проверки производительности в качестве входного запроса функции. Я добавил SCaNN в качестве метода индекса. Для получения дополнительных параметров см. документацию .
Для этого запроса поиска векторов мы использовали следующие данные:
Я вижу, что RECALL составляет 70%. Теперь я могу использовать эту информацию для изменения параметров индекса, методов и параметров запроса и улучшить свою полноту для этого поиска вектора!
Я изменил количество строк в результирующем наборе до 7 (ранее было 10) и вижу немного улучшенный показатель RECALL, т.е. 86%.
Это означает, что в режиме реального времени я могу изменять количество совпадений, которые видят мои пользователи, чтобы повысить релевантность совпадений в соответствии с контекстом поиска пользователей.
Ну что ж! Пришло время развернуть логику базы данных и перейти к агенту!!!
7. Перенести логику базы данных на веб-сервер без использования
Готовы вывести это приложение в Интернет? Выполните следующие действия:
- Перейдите в раздел Cloud Run Functions в Google Cloud Console, чтобы СОЗДАТЬ новую функцию Cloud Run, или используйте ссылку: https://console.cloud.google.com/functions/add .
- Выберите Environment как " Cloud Run function ". Укажите имя функции " patent-search " и выберите Region как " us-central1 ". Установите Authentication на " Allow unauthenticated invocations " и нажмите NEXT. Выберите Java 17 как среду выполнения и Inline Editor для исходного кода.
- По умолчанию он установит Entry Point на " gcfv2.HelloHttpFunction ". Замените код-заполнитель в HelloHttpFunction.java и pom.xml вашей Cloud Run Function на код из " PatentSearch.java " и " pom.xml " соответственно. Измените имя файла класса на PatentSearch.java.
- Не забудьте изменить заполнитель ************* и учетные данные подключения AlloyDB на ваши значения в файле Java. Учетные данные AlloyDB — это те, которые мы использовали в начале этой кодовой лаборатории. Если вы использовали другие значения, пожалуйста, измените их в файле Java.
- Нажмите «Развернуть» .
ВАЖНЫЙ ШАГ:
После развертывания, чтобы разрешить облачной функции доступ к нашему экземпляру базы данных AlloyDB, мы создадим соединитель VPC.
После того, как вы настроитесь на развертывание, вы должны увидеть функции в консоли Google Cloud Run Functions. Найдите недавно созданную функцию (patent-search), щелкните по ней, затем щелкните EDIT AND DEPLOY NEW REVISIONS (обозначается значком EDIT (ручка) в верхней части консоли Cloud Run Functions) и измените следующее:
- Перейдите на вкладку «Сеть»:
- Выберите « Подключиться к VPC для исходящего трафика », а затем выберите « Использовать коннекторы Serverless VPC Access ».
- В раскрывающемся списке «Сеть» выберите «Настройки», щелкните раскрывающийся список «Сеть» и выберите опцию « Добавить новый коннектор VPC » (если вы еще не настроили коннектор по умолчанию ), затем следуйте инструкциям, которые вы увидите в появившемся диалоговом окне:
- Введите имя для VPC Connector и убедитесь, что регион совпадает с вашим экземпляром. Оставьте значение Network по умолчанию и установите Subnet как Custom IP Range с диапазоном IP 10.8.0.0 или чем-то похожим, что доступно.
- Разверните ПОКАЗАТЬ НАСТРОЙКИ МАСШТАБИРОВАНИЯ и убедитесь, что у вас установлена следующая конфигурация:
- Нажмите «СОЗДАТЬ» , и этот коннектор должен появиться в настройках выхода.
- Выберите только что созданный соединитель.
- Выберите маршрутизацию всего трафика через этот VPC-коннектор.
- Нажмите ДАЛЕЕ , а затем РАЗВЕРНУТЬ .
- После развертывания обновленной функции облака вы должны увидеть сгенерированную конечную точку. Скопируйте ее и замените в следующей команде:
PROJECT_ID=$(gcloud config get-value project)
curl -X POST <<YOUR_ENDPOINT>> \
-H 'Content-Type: application/json' \
-d '{"search":"Sentiment Analysis"}'
Вот и все! Вот так просто выполнить расширенный поиск вектора контекстного сходства с использованием модели Embeddings на данных AlloyDB.
8. Давайте создадим агента с помощью Java ADK
Для начала давайте начнем с проекта Java в редакторе.
- Перейдите в Cloud Shell Terminal.
https://shell.cloud.google.com/?fromcloudshell=true&show=ide%2Cterminal
- Авторизуйтесь при появлении соответствующего запроса
- Переключитесь в Cloud Shell Editor, щелкнув значок редактора в верхней части консоли Cloud Shell.
- В консоли лендинга Cloud Shell Editor создайте новую папку и назовите ее «adk-agents»
Нажмите «Создать новую папку» в корневом каталоге вашего Cloud Shell, как показано ниже:
Назовите его «adk-agents»:
- Создайте следующую структуру папок и пустые файлы с соответствующими именами файлов в приведенной ниже структуре:
adk-agents/
└—— pom.xml
└—— src/
└—— main/
└—— java/
└—— agents/
└—— App.java
- Откройте репозиторий github в отдельной вкладке и скопируйте исходный код файлов App.java и pom.xml.
- Если вы открыли редактор в новой вкладке с помощью значка «Открыть в новой вкладке» в правом верхнем углу, вы можете открыть терминал в нижней части страницы. Вы можете открыть редактор и терминал параллельно, что позволит вам работать свободно.
- После клонирования вернитесь в консоль Cloud Shell Editor.
- Поскольку мы уже создали функцию Cloud Run, вам не нужно копировать файлы функции Cloud Run из папки репозитория .
Начало работы с ADK Java SDK
Это довольно просто. В первую очередь вам нужно убедиться, что на этапе клонирования учтены следующие моменты:
- Добавить зависимости:
Включите артефакты google-adk и google-adk-dev (для веб-интерфейса) в ваш pom.xml.
<!-- The ADK core dependency -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk</artifactId>
<version>0.1.0</version>
</dependency>
<!-- The ADK dev web UI to debug your agent -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk-dev</artifactId>
<version>0.1.0</version>
</dependency>
Обязательно укажите ссылку на pom.xml из исходного репозитория, так как для запуска приложения необходимы другие зависимости и конфигурации.
- Настройте свой проект:
Убедитесь, что ваша версия Java (рекомендуется 17+) и параметры компилятора Maven правильно настроены в вашем pom.xml. Вы можете настроить свой проект в соответствии со следующей структурой:
adk-agents/
└—— pom.xml
└—— src/
└—— main/
└—— java/
└—— agents/
└—— App.java
- Определение агента и его инструментов (App.java):
Вот где сияет магия ADK Java SDK. Мы определяем нашего агента, его возможности (инструкции) и инструменты, которые он может использовать.
Найдите упрощенную версию нескольких фрагментов кода основного класса агента здесь. Для полного проекта обратитесь к репозиторию проекта здесь .
// App.java (Simplified Snippets)
package agents;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.BaseAgent;
import com.google.adk.agents.InvocationContext;
import com.google.adk.tools.Annotations.Schema;
import com.google.adk.tools.FunctionTool;
// ... other imports
public class App {
static FunctionTool searchTool = FunctionTool.create(App.class, "getPatents");
static FunctionTool explainTool = FunctionTool.create(App.class, "explainPatent");
public static BaseAgent ROOT_AGENT = initAgent();
public static BaseAgent initAgent() {
return LlmAgent.builder()
.name("patent-search-agent")
.description("Patent Search agent")
.model("gemini-2.0-flash-001") // Specify your desired Gemini model
.instruction(
"""
You are a helpful patent search assistant capable of 2 things:
// ... complete instructions ...
""")
.tools(searchTool, explainTool)
.outputKey("patents") // Key to store tool output in session state
.build();
}
// --- Tool: Get Patents ---
public static Map<String, String> getPatents(
@Schema(name="searchText",description = "The search text for which the user wants to find matching patents")
String searchText) {
try {
String patentsJson = vectorSearch(searchText); // Calls our Cloud Run Function
return Map.of("status", "success", "report", patentsJson);
} catch (Exception e) {
// Log error
return Map.of("status", "error", "report", "Error fetching patents.");
}
}
// --- Tool: Explain Patent (Leveraging InvocationContext) ---
public static Map<String, String> explainPatent(
@Schema(name="patentId",description = "The patent id for which the user wants to get more explanation for, from the database")
String patentId,
@Schema(name="ctx",description = "The list of patent abstracts from the database from which the user can pick the one to get more explanation for")
InvocationContext ctx) { // Note the InvocationContext
try {
// Retrieve previous patent search results from session state
String previousResults = (String) ctx.session().state().get("patents");
if (previousResults != null && !previousResults.isEmpty()) {
// Logic to find the specific patent abstract from 'previousResults' by 'patentId'
String[] patentEntries = previousResults.split("\n\n\n\n");
for (String entry : patentEntries) {
if (entry.contains(patentId)) { // Simplified check
// The agent will then use its instructions to summarize this 'report'
return Map.of("status", "success", "report", entry);
}
}
}
return Map.of("status", "error", "report", "Patent ID not found in previous search.");
} catch (Exception e) {
// Log error
return Map.of("status", "error", "report", "Error explaining patent.");
}
}
public static void main(String[] args) throws Exception {
InMemoryRunner runner = new InMemoryRunner(ROOT_AGENT);
// ... (Session creation and main input loop - shown in your source)
}
}
Выделены основные компоненты кода Java ADK:
- LlmAgent.builder(): Fluent API для настройки вашего агента.
- .instruction(...): предоставляет основные подсказки и рекомендации для LLM, включая информацию о том, когда использовать тот или иной инструмент.
- FunctionTool.create(App.class, "methodName"): легко регистрирует ваши методы Java как инструменты, которые агент может вызывать. Строка имени метода должна соответствовать реальному публичному статическому методу.
- @Schema(description = ...): Аннотирует параметры инструмента, помогая LLM понять, какие входные данные ожидает каждый инструмент. Это описание имеет решающее значение для точного выбора инструмента и заполнения параметров.
- InvocationContext ctx: автоматически передается в методы инструмента, предоставляя доступ к состоянию сеанса (ctx.session().state()), информации о пользователе и многому другому.
- .outputKey("patents"): Когда инструмент возвращает данные, ADK может автоматически сохранять их в состоянии сеанса под этим ключом. Вот как ExplainPatent может получить доступ к результатам из GetPatents.
- VECTOR_SEARCH_ENDPOINT: Это переменная, которая содержит основную функциональную логику для контекстных вопросов и ответов для пользователя в сценарии использования патентного поиска.
- Элемент действия здесь: вам необходимо установить обновленное значение развернутой конечной точки после реализации шага Java Cloud Run Function из предыдущего раздела.
- searchTool : помогает пользователю находить в патентной базе данных соответствующие контексту совпадения патентов по тексту поиска пользователя.
- ExplainTool : Это запрашивает у пользователя конкретный патент для глубокого погружения. Затем он суммирует реферат патента и может ответить на дополнительные вопросы пользователя на основе имеющихся у него данных о патенте.
Важное примечание: обязательно замените переменную VECTOR_SEARCH_ENDPOINT на развернутую вами конечную точку CRF.
Использование InvocationContext для взаимодействия с сохранением состояния
Одной из важнейших функций для создания полезных агентов является управление состоянием в нескольких поворотах разговора. InvocationContext ADK делает это простым.
В нашем App.java:
- Когда initAgent() определен, мы используем .outputKey("patents"). Это сообщает ADK, что когда инструмент (например, getPatents) возвращает данные в поле отчета, эти данные должны быть сохранены в состоянии сеанса под ключом "patents".
- В методе инструмента ExplainPatent мы внедряем InvocationContext ctx:
public static Map<String, String> explainPatent(
@Schema(description = "...") String patentId, InvocationContext ctx) {
String previousResults = (String) ctx.session().state().get("patents");
// ... use previousResults ...
}
Это позволяет инструменту ExplainPatent получить доступ к списку патентов, полученному инструментом GetPatents на предыдущем этапе, что делает разговор связным и последовательным.
9. Локальное тестирование CLI
Определить переменные среды
Вам необходимо экспортировать две переменные среды:
- Ключ Gemini, который вы можете получить в AI Studio:
Для этого перейдите по ссылке https://aistudio.google.com/apikey и получите ключ API для вашего активного проекта Google Cloud, в котором вы реализуете это приложение, и сохраните ключ где-нибудь:
- Получив ключ, откройте Cloud Shell Terminal и перейдите в новый каталог, который мы только что создали adk-agents, выполнив следующую команду:
cd adk-agents
- Переменная, указывающая, что на этот раз мы не используем Vertex AI.
export GOOGLE_GENAI_USE_VERTEXAI=FALSE
export GOOGLE_API_KEY=AIzaSyDF...
- Запустите своего первого агента в CLI
Чтобы запустить этот первый агент, используйте следующую команду Maven в терминале:
mvn compile exec:java -DmainClass="agents.App"
Вы увидите интерактивный ответ агента на своем терминале.
10. Развертывание в облаке Run
Развертывание агента ADK Java в Cloud Run аналогично развертыванию любого другого приложения Java:
- Dockerfile: создайте Dockerfile для упаковки вашего Java-приложения.
- Сборка и отправка образа Docker: используйте Google Cloud Build и Artifact Registry.
- Вы можете выполнить вышеуказанный шаг и выполнить развертывание в Cloud Run всего одной командой:
gcloud run deploy --source . --set-env-vars GOOGLE_API_KEY=<<Your_Gemini_Key>>
Аналогично, вы развернете свою Java Cloud Run Function (gcfv2.PatentSearch). В качестве альтернативы вы можете создать и развернуть Java Cloud Run Function для логики базы данных непосредственно из консоли Cloud Run Function.
11. Тестирование с помощью веб-интерфейса
ADK поставляется с удобным веб-интерфейсом для локального тестирования и отладки вашего агента. Когда вы запускаете App.java локально (например, mvn exec:java -Dexec.mainClass="agents.App", если настроено, или просто запускаете метод main), ADK обычно запускает локальный веб-сервер.
Веб-интерфейс пользователя ADK позволяет:
- Отправляйте сообщения своему агенту.
- Просматривайте события (сообщение пользователя, вызов инструмента, ответ инструмента, ответ LLM).
- Проверьте состояние сеанса.
- Просмотр журналов и трассировок.
Это бесценно во время разработки для понимания того, как ваш агент обрабатывает запросы и использует свои инструменты. Это предполагает, что ваш mainClass в pom.xml установлен на com.google.adk.web.AdkWebServer и ваш агент зарегистрирован в нем, или вы запускаете локальный тестовый раннер, который это показывает.
При запуске App.java с его InMemoryRunner и Scanner для ввода с консоли вы тестируете логику основного агента. Веб-интерфейс — это отдельный компонент для более визуального отладочного опыта, часто используемый, когда ADK обслуживает вашего агента через HTTP.
Для запуска локального сервера SpringBoot можно использовать следующую команду Maven из корневого каталога:
mvn compile exec:java -Dexec.args="--adk.agents.source-dir=src/main/java/ --logging.level.com.google.adk.dev=TRACE --logging.level.com.google.adk.demo.agents=TRACE"
Интерфейс часто доступен по URL, который выводит команда выше. Если это Cloud Run deployed , вы должны иметь возможность получить к нему доступ по ссылке Cloud Run deployed.
Результат вы сможете увидеть в интерактивном интерфейсе.
Посмотрите видео ниже о нашем патентном агенте:
12. Очистить
Чтобы избежать списания средств с вашего аккаунта Google Cloud за ресурсы, использованные в этой публикации, выполните следующие действия:
- В консоли Google Cloud перейдите по адресу https://console.cloud.google.com/cloud-resource-manager?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog
- https://console.cloud.google.com/cloud-resource-manager?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=страница блога.
- В списке проектов выберите проект, который вы хотите удалить, и нажмите Удалить .
- В диалоговом окне введите идентификатор проекта, а затем нажмите «Завершить работу» , чтобы удалить проект.
13. Поздравления
Поздравляем! Вы успешно создали своего агента анализа патентов на Java, объединив возможности ADK, https://cloud.google.com/alloydb/docs?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog , Vertex AI и Vector Search, а также сделали огромный шаг вперед в том, чтобы сделать контекстный поиск по сходству настолько преобразующим, эффективным и действительно осмысленным.
Начните сегодня!
Документация ADK: [Ссылка на официальную документацию ADK Java]
Исходный код агента анализа патентов: [Ссылка на ваш (теперь общедоступный) репозиторий GitHub]
Примеры агентов Java: [ссылка на репозиторий adk-samples]
Присоединяйтесь к сообществу ADK: https://www.reddit.com/r/agentdevelopmentkit/
Удачного агентского строительства!