Créez des applications d'agent d'IA puissantes, avec état et de bout en bout en Java avec ADK, AlloyDB et Gemini.

1. Présentation

Dans différents secteurs, la recherche contextuelle est une fonctionnalité essentielle qui constitue le cœur de leurs applications. La génération augmentée de récupération est un moteur clé de cette évolution technologique cruciale depuis un certain temps, avec ses mécanismes de récupération optimisés par l'IA générative. Les modèles génératifs, avec leurs grandes fenêtres de contexte et leur qualité de sortie impressionnante, transforment l'IA. Le RAG fournit un moyen systématique d'injecter du contexte dans les applications et les agents d'IA, en les ancrant dans des bases de données structurées ou des informations provenant de divers supports. Ces données contextuelles sont essentielles pour clarifier la vérité et obtenir des résultats précis, mais dans quelle mesure ces résultats sont-ils précis ? Votre activité dépend-elle largement de la justesse de ces correspondances contextuelles et de leur pertinence ? Ce projet va vous plaire !

Imaginez maintenant que nous puissions exploiter la puissance des modèles génératifs pour créer des agents interactifs capables de prendre des décisions autonomes basées sur de telles informations contextuelles critiques et fondées sur la vérité. C'est ce que nous allons créer aujourd'hui. Nous allons créer une application d'agent d'IA de bout en bout à l'aide du kit de développement d'agent optimisé par la génération augmentée par récupération avancée dans AlloyDB pour une application d'analyse de brevets.

L'agent d'analyse des brevets aide l'utilisateur à trouver des brevets pertinents par rapport à son texte de recherche. Sur demande, il fournit une explication claire et concise, ainsi que des informations supplémentaires si nécessaire, pour un brevet sélectionné. Prêt à découvrir comment procéder ? C'est parti !

Objectif

L'objectif est simple. Permettre à un utilisateur de rechercher des brevets à partir d'une description textuelle, puis d'obtenir une explication détaillée d'un brevet spécifique à partir des résultats de recherche, le tout à l'aide d'un agent d'IA créé avec Java ADK, AlloyDB, la recherche vectorielle (avec des index avancés), Gemini et l'ensemble de l'application déployée sans serveur sur Cloud Run.

Ce que vous allez faire

Au cours de cet atelier, vous allez:

  1. Créer une instance AlloyDB et charger les données de l'ensemble de données public sur les brevets
  2. Implémenter une recherche vectorielle avancée dans AlloyDB à l'aide des fonctionnalités d'évaluation ScaNN et Recall
  3. Créer un agent à l'aide du kit de développement d'agents Java
  4. Implémenter la logique côté serveur de la base de données dans des fonctions Cloud sans serveur Java
  5. Déployer et tester l'agent dans Cloud Run

Le diagramme suivant représente le flux de données et les étapes impliquées dans l'implémentation.

c22563ace65a6930.png

High level diagram representing the flow of the Patent Search Agent with AlloyDB & ADK

Conditions requises

  • Un navigateur tel que Chrome ou Firefox
  • Un projet Google Cloud avec facturation activée.

2. Avant de commencer

Créer un projet

  1. Dans la console Google Cloud, sur la page du sélecteur de projet, sélectionnez ou créez un projet Google Cloud.
  2. Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier si la facturation est activée sur un projet .
  3. Vous allez utiliser Cloud Shell, un environnement de ligne de commande exécuté dans Google Cloud. Cliquez sur "Activer Cloud Shell" en haut de la console Google Cloud.

Image du bouton Activer Cloud Shell

  1. Une fois connecté à Cloud Shell, vérifiez que vous êtes déjà authentifié et que le projet est défini avec votre ID de projet à l'aide de la commande suivante:
gcloud auth list
  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet.
gcloud config list project
  1. Si votre projet n'est pas défini, utilisez la commande suivante pour le définir :
gcloud config set project <YOUR_PROJECT_ID>
  1. Activer les API requises. Vous pouvez utiliser une commande gcloud dans le terminal 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

Vous pouvez également rechercher chaque produit dans la console ou utiliser ce lien.

Consultez la documentation pour connaître les commandes gcloud ainsi que leur utilisation.

3. Configuration de la base de données

Dans cet atelier, nous utiliserons AlloyDB comme base de données pour les données sur les brevets. Il utilise des clusters pour stocker toutes les ressources, telles que les bases de données et les journaux. Chaque cluster dispose d'une instance principale qui fournit un point d'accès aux données. Les tables contiennent les données réelles.

Créons un cluster, une instance et une table AlloyDB dans lesquels l'ensemble de données sur les brevets sera chargé.

Créer un cluster et une instance

  1. Accédez à la page AlloyDB dans Cloud Console. Pour trouver facilement la plupart des pages de la console Cloud, recherchez-les à l'aide de la barre de recherche de la console.
  2. Sélectionnez CRÉER UN CLUSTER sur cette page:

f76ff480c8c889aa.png

  1. Un écran semblable à celui-ci s'affiche : Créez un cluster et une instance avec les valeurs suivantes (assurez-vous que les valeurs correspondent au cas où vous cloneriez le code de l'application à partir du dépôt):
  • ID de cluster: "vector-cluster"
  • password : alloydb
  • PostgreSQL 15 / dernière version recommandée
  • Région: "us-central1"
  • Networking (Réseau) : "default"

538dba58908162fb.png

  1. Lorsque vous sélectionnez le réseau par défaut, un écran semblable à celui-ci s'affiche.

Sélectionnez CONFIGURER LA CONNEXION.
7939bbb6802a91bf.png

  1. Sélectionnez ensuite Utiliser une plage d'adresses IP automatiquement allouée, puis cliquez sur "Continuer". Après avoir examiné les informations, sélectionnez "CRÉER UNE CONNEXION". 768ff5210e79676f.png
  2. Une fois votre réseau configuré, vous pouvez continuer à créer votre cluster. Cliquez sur CRÉER UN CLUSTER pour terminer la configuration du cluster, comme illustré ci-dessous:

e06623e55195e16e.png

Assurez-vous de remplacer l'ID d'instance (que vous pouvez trouver au moment de la configuration du cluster / de l'instance) par

vector-instance. Si vous ne pouvez pas le modifier, n'oubliez pas d'utiliser votre ID d'instance dans toutes les références à venir.

Notez que la création du cluster prendra environ 10 minutes. Une fois l'opération terminée, un écran présentant une vue d'ensemble du cluster que vous venez de créer devrait s'afficher.

4. Ingestion de données

Il est maintenant temps d'ajouter un tableau contenant les données sur le magasin. Accédez à AlloyDB, sélectionnez le cluster principal, puis AlloyDB Studio:

847e35f1bf8a8bd8.png

Vous devrez peut-être attendre que la création de votre instance soit terminée. Connectez-vous à AlloyDB avec les identifiants que vous avez créés lors de la création du cluster. Utilisez les données suivantes pour vous authentifier auprès de PostgreSQL:

  • Nom d'utilisateur : "postgres"
  • Base de données : "postgres"
  • Mot de passe : "alloydb"

Une fois que vous vous êtes authentifié dans AlloyDB Studio, vous pouvez saisir des commandes SQL dans l'éditeur. Vous pouvez ajouter plusieurs fenêtres de l'éditeur à l'aide du signe plus à droite de la dernière fenêtre.

91a86d9469d499c4.png

Vous allez saisir des commandes pour AlloyDB dans les fenêtres d'éditeur, en utilisant les options "Run" (Exécuter), "Format" (Mettre en forme) et "Clear" (Effacer) si nécessaire.

Activer les extensions

Pour créer cette application, nous utiliserons les extensions pgvector et google_ml_integration. L'extension pgvector vous permet de stocker et de rechercher des embeddings vectoriels. L'extension google_ml_integration fournit des fonctions que vous pouvez utiliser pour accéder aux points de terminaison de prédiction Vertex AI afin d'obtenir des prédictions en SQL. Activez ces extensions en exécutant les LDD suivantes:

CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;

Si vous souhaitez vérifier les extensions qui ont été activées dans votre base de données, exécutez cette commande SQL:

select extname, extversion from pg_extension;

Créer une table

Vous pouvez créer une table à l'aide de l'instruction LDD ci-dessous dans 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)) ;

La colonne "abstract_embeddings" permet de stocker les valeurs vectorielles du texte.

Accorder l'autorisation

Exécutez l'instruction ci-dessous pour autoriser l'exécution sur la fonction "embedding" :

GRANT EXECUTE ON FUNCTION embedding TO postgres;

Attribuer le rôle Utilisateur Vertex AI au compte de service AlloyDB

Dans la console Google Cloud IAM, accordez au compte de service AlloyDB (qui se présente sous la forme service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com) l'accès au rôle "Utilisateur Vertex AI". PROJECT_NUMBER correspond à votre numéro de projet.

Vous pouvez également exécuter la commande ci-dessous à partir du terminal 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"

Charger les données des brevets dans la base de données

Nous utiliserons les ensembles de données publics sur les brevets Google dans BigQuery comme ensemble de données. Nous allons utiliser AlloyDB Studio pour exécuter nos requêtes. Les données sont extraites de ce fichier insert_scripts.sql et nous allons l'exécuter pour charger les données sur les brevets.

  1. Dans la console Google Cloud, ouvrez la page AlloyDB.
  2. Sélectionnez le cluster que vous venez de créer, puis cliquez sur l'instance.
  3. Dans le menu de navigation AlloyDB, cliquez sur AlloyDB Studio. Connectez-vous avec vos identifiants.
  4. Ouvrez un nouvel onglet en cliquant sur l'icône Nouvel onglet à droite.
  5. Copiez l'instruction de requête insert du script insert_scripts.sql mentionné ci-dessus dans l'éditeur. Vous pouvez copier 10 à 50 instructions d'insertion pour une démonstration rapide de ce cas d'utilisation.
  6. Cliquez sur Exécuter. Les résultats de votre requête s'affichent dans la table Résultats.

5. Créer des embeddings pour les données sur les brevets

Commençons par tester la fonction d'encapsulation en exécutant l'exemple de requête suivant:

SELECT embedding('text-embedding-005', 'AlloyDB is a managed, cloud-hosted SQL database service.');

Cette commande devrait renvoyer le vecteur d'embeddings, qui ressemble à un tableau de nombres à virgule flottante, pour l'exemple de texte de la requête. Il se présente comme suit:

25a1d7ef0e49e91e.png

Mettre à jour le champ de vecteur abstract_embeddings

Exécutez la LMD ci-dessous pour mettre à jour les résumés des brevets dans le tableau avec les représentations vectorielles continues correspondantes:

UPDATE patents_data set abstract_embeddings = embedding( 'text-embedding-005', abstract);

6. Effectuer une recherche vectorielle

Maintenant que le tableau, les données et les embeddings sont prêts, effectuons la recherche vectorielle en temps réel pour le texte de recherche de l'utilisateur. Pour le vérifier, exécutez la requête ci-dessous:

SELECT id || ' - ' || title as title FROM patents_data ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;

Dans cette requête,

  1. Le texte recherché par l'utilisateur est "Analyse des sentiments".
  2. Nous le convertissons en embeddings dans la méthode embedding() à l'aide du modèle text-embedding-005.
  3. "<=>" représente l'utilisation de la méthode de distance SIMILARITY COSINE.
  4. Nous convertissons le résultat de la méthode d'embedding en type de vecteur pour le rendre compatible avec les vecteurs stockés dans la base de données.
  5. LIMIT 10 indique que nous sélectionnons les 10 correspondances les plus proches du texte de recherche.

AlloyDB fait passer la recherche vectorielle RAG au niveau supérieur:

De nombreux éléments sont introduits. Voici deux exemples de fonctionnalités destinées aux développeurs:

  1. Filtrage intégré
  2. Évaluateur de rappel

Filtrage intégré

Auparavant, en tant que développeur, vous deviez effectuer la requête de recherche vectorielle et gérer le filtrage et le rappel. L'optimiseur de requêtes AlloyDB détermine comment exécuter une requête avec des filtres. Le filtrage intégré est une nouvelle technique d'optimisation des requêtes qui permet à l'optimiseur de requêtes AlloyDB d'évaluer à la fois les conditions de filtrage des métadonnées et la recherche vectorielle, en exploitant à la fois les index vectoriels et les index sur les colonnes de métadonnées. Les performances de rappel ont ainsi augmenté, ce qui permet aux développeurs de profiter de ce que AlloyDB a à offrir dès la sortie de la boîte.

Le filtrage intégré est idéal pour les cas de sélectivité moyenne. Lorsque AlloyDB recherche dans l'index vectoriel, il ne calcule que les distances pour les vecteurs qui correspondent aux conditions de filtrage des métadonnées (vos filtres fonctionnels dans une requête sont généralement gérés dans la clause WHERE). Cela améliore considérablement les performances de ces requêtes, ce qui complète les avantages du post-filtrage ou du pré-filtrage.

  1. Installer ou mettre à jour l'extension pgvector
CREATE EXTENSION IF NOT EXISTS vector WITH VERSION '0.8.0.google-3';

Si l'extension pgvector est déjà installée, mettez-la à niveau vers la version 0.8.0.google-3 ou ultérieure pour bénéficier des fonctionnalités d'évaluation du rappel.

ALTER EXTENSION vector UPDATE TO '0.8.0.google-3';

Cette étape ne doit être exécutée que si votre extension de vecteur est inférieure à 0.8.0.google-3.

Remarque importante:Si le nombre de lignes est inférieur à 100, vous n'avez pas besoin de créer l'index ScaNN, car il ne s'applique pas à moins de lignes. Dans ce cas, ignorez les étapes suivantes.

  1. Pour créer des index ScaNN, installez l'extension alloydb_scann.
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
  1. Exécutez d'abord la requête Vector Search sans l'index et sans le filtre intégré activé:
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;

Le résultat devrait ressembler à ceci:

6989de0fc3f0f753.png

  1. Exécutez l'analyse "Explain" (Expliquer) dessus (sans indice ni filtrage intégré) :

908dcf87c7f00ed4.png

Le temps d'exécution est de 2,4 ms.

  1. Créons un indice standard sur le champ num_claims afin de pouvoir le filtrer:
CREATE INDEX idx_patents_data_num_claims ON patents_data (num_claims);
  1. Créons l'index ScaNN pour notre application de recherche de brevets. Exécutez les commandes suivantes depuis AlloyDB Studio:
CREATE INDEX patent_index ON patents_data 
USING scann (abstract_embeddings cosine)
WITH (num_leaves=32);

Remarque importante : (num_leaves=32) s'applique à l'ensemble de données total de plus de 1 000 lignes. Si le nombre de lignes est inférieur à 100, vous n'avez pas besoin de créer d'index, car il ne s'applique pas à moins de lignes.

  1. Activez le filtrage intégré dans l'index ScaNN:
SET scann.enable_inline_filtering = on
  1. Exécutons maintenant la même requête avec un filtre et Vector Search:
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;

aa54cba2b2ada2cb.png

Comme vous pouvez le constater, le temps d'exécution est considérablement réduit pour la même recherche vectorielle. Le filtrage intégré intégré à l'index ScaNN de Vector Search a rendu cela possible.

Passons maintenant à l'évaluation du rappel pour cette recherche vectorielle compatible avec ScaNN.

Évaluateur de rappel

Le rappel dans la recherche par similarité correspond au pourcentage d'instances pertinentes récupérées à partir d'une recherche, c'est-à-dire au nombre de vrais positifs. Il s'agit de la métrique la plus couramment utilisée pour mesurer la qualité de recherche. Une source de perte de rappel provient de la différence entre la recherche des plus proches voisins approximatifs (ANN) et la recherche des plus proches voisins exacts (KNN). Les index vectoriels tels que ScaNN d'AlloyDB implémentent des algorithmes de réseau de neurones artificiels, ce qui vous permet d'accélérer la recherche vectorielle sur de grands ensembles de données en échange d'un léger compromis sur le rappel. AlloyDB vous permet désormais de mesurer ce compromis directement dans la base de données pour des requêtes individuelles et de vous assurer qu'il est stable au fil du temps. Vous pouvez mettre à jour les paramètres de requête et d'index en fonction de ces informations pour obtenir de meilleurs résultats et de meilleures performances.

Vous pouvez trouver le rappel d'une requête vectorielle sur un index vectoriel pour une configuration donnée à l'aide de la fonction evaluate_query_recall. Cette fonction vous permet d'ajuster vos paramètres pour obtenir les résultats de rappel de requête vectorielle souhaités. Le rappel est la métrique utilisée pour la qualité de recherche. Il est défini comme le pourcentage des résultats renvoyés qui sont objectivement les plus proches des vecteurs de requête. La fonction evaluate_query_recall est activée par défaut.

Remarque importante :

Si vous rencontrez une erreur d'autorisation refusée sur l'index HNSW lors des étapes suivantes, ignorez toute la section Évaluation du rappel pour le moment. Il peut s'agir de restrictions d'accès à ce stade, car il vient tout juste d'être publié au moment de la documentation de cet atelier de programmation.

  1. Définissez l'indicateur "Enable Index Scan" (Activer l'analyse de l'index) sur l'index ScaNN et l'index HNSW:
SET scann.enable_indexscan = on
SET hnsw.enable_index_scan = on
  1. Exécutez la requête suivante dans 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']);

La fonction evaluate_query_recall reçoit la requête en tant que paramètre et renvoie son rappel. J'utilise la même requête que celle que j'ai utilisée pour vérifier les performances comme requête d'entrée de la fonction. J'ai ajouté SCaNN comme méthode d'indexation. Pour connaître les autres options de paramètre, consultez la documentation.

Le rappel de cette requête de recherche vectorielle que nous avons utilisée:

c98f38fbe6a0b6c5.png

Je vois que la valeur RECALL est de 70%. Je peux maintenant utiliser ces informations pour modifier les paramètres d'index, les méthodes et les paramètres de requête, et améliorer la mémorisation de cette recherche vectorielle.

J'ai modifié le nombre de lignes du jeu de résultats à 7 (au lieu de 10 précédemment) et j'observe une légère amélioration du rappel, à savoir 86%.

c12f7b92b8481ceb.png

Cela signifie que je peux modifier en temps réel le nombre de correspondances que mes utilisateurs peuvent voir pour améliorer leur pertinence en fonction du contexte de recherche des utilisateurs.

Très bien. Il est temps de déployer la logique de base de données et de passer à l'agent.

7. Transférer la logique de base de données sur le Web sans serveur

Prêt à publier cette application sur le Web ? Procédez comme suit :

  1. Accédez à Cloud Run Functions dans la console Google Cloud pour CRÉER une fonction Cloud Run ou utilisez le lien https://console.cloud.google.com/functions/add.
  2. Sélectionnez "Fonction Cloud Run" comme environnement. Indiquez le nom de la fonction patent-search et sélectionnez la région us-central1. Définissez l'authentification sur Allow unauthenticated invocations (Autoriser les appels non authentifiés), puis cliquez sur "NEXT" (SUIVANT). Choisissez Java 17 comme environnement d'exécution et l'éditeur intégré pour le code source.
  3. Par défaut, le point d'entrée est défini sur gcfv2.HelloHttpFunction. Remplacez le code d'espace réservé dans HelloHttpFunction.java et pom.xml de votre fonction Cloud Run par le code de PatentSearch.java et pom.xml, respectivement. Remplacez le nom du fichier de classe par PatentSearch.java.
  4. N'oubliez pas de remplacer l'espace réservé ************* et les identifiants de connexion AlloyDB par vos valeurs dans le fichier Java. Les identifiants AlloyDB sont ceux que nous avons utilisés au début de cet atelier de programmation. Si vous avez utilisé des valeurs différentes, veuillez les modifier dans le fichier Java.
  5. Cliquez sur Déployer.

ÉTAPE IMPORTANTE :

Une fois déployée, nous créerons le connecteur VPC pour permettre à la fonction Cloud d'accéder à notre instance de base de données AlloyDB.

Une fois le déploiement effectué, vous devriez pouvoir voir les fonctions dans la console Google Cloud Run Functions. Recherchez la fonction nouvellement créée (recherche-brevet), cliquez dessus, puis sur MODIFIER ET DÉPLOYER LA NOUVELLE RÉVISION (identifié par l'icône MODIFIER (stylo) en haut de la console Cloud Run Functions), puis modifiez les éléments suivants:

  1. Accédez à l'onglet "Networking" (Réseau) :

828cd861864d99ea.png

  1. Sélectionnez Se connecter à un VPC pour le trafic sortant, puis Utiliser des connecteurs d'accès au VPC sans serveur.
  2. Dans les paramètres du menu déroulant "Network" (Réseau), cliquez sur le menu déroulant "Network" (Réseau), puis sélectionnez l'option Add New VPC Connector (Ajouter un connecteur VPC) (si vous n'avez pas encore configuré le connecteur par défaut), puis suivez les instructions qui s'affichent dans la boîte de dialogue qui s'affiche:

6559ccfd10e597f2.png

  1. Attribuez un nom au connecteur VPC et assurez-vous que la région est la même que celle de votre instance. Laissez la valeur "Network" (Réseau) définie par défaut et définissez "Subnet" (Sous-réseau) sur "Custom IP Range" (Plage d'adresses IP personnalisée) avec la plage d'adresses IP 10.8.0.0 ou une autre plage disponible.
  2. Développez "AFFICHER LES PARAMÈTRES DE SCALING" et assurez-vous que la configuration est exactement la suivante:

199b0ccd80215004.png

  1. Cliquez sur CRÉER. Ce connecteur devrait maintenant figurer dans les paramètres de sortie.
  2. Sélectionnez le connecteur que vous venez de créer.
  3. Choisissez d'acheminer tout le trafic via ce connecteur VPC.
  4. Cliquez sur SUIVANT, puis sur DÉPLOYER.
  5. Une fois la fonction Cloud mise à jour déployée, le point de terminaison devrait être généré. Copiez-le et remplacez-le dans la commande suivante:
PROJECT_ID=$(gcloud config get-value project)

curl -X POST <<YOUR_ENDPOINT>> \
  -H 'Content-Type: application/json' \
  -d '{"search":"Sentiment Analysis"}'

Et voilà ! Il est si simple d'effectuer une recherche vectorielle de similarité contextuelle avancée à l'aide du modèle d'embeddings sur les données AlloyDB.

8. Créons l'agent avec le kit de développement d'agents Java

Commençons par le projet Java dans l'éditeur.

  1. Accédez au terminal Cloud Shell.

https://shell.cloud.google.com/?fromcloudshell=true&show=ide%2Cterminal

  1. Autoriser lorsque vous y êtes invité
  2. Activez l'éditeur Cloud Shell en cliquant sur l'icône de l'éditeur en haut de la console Cloud Shell.

f913b886324e5196.png

  1. Dans la console de l'éditeur Cloud Shell, créez un dossier et nommez-le "adk-agents".

Cliquez sur "Créer un dossier" dans le répertoire racine de votre shell cloud, comme illustré ci-dessous:

94c9804697614a94.png

Nommez-le "adk-agents":

37445dc1fe08f74c.png

  1. Créez la structure de dossiers suivante et les fichiers vides avec les noms de fichiers correspondants dans la structure ci-dessous:
adk-agents/
 └—— pom.xml
 └—— src/ 
     └—— main/
         └—— java/
             └—— agents/
                 └—— App.java
  1. Ouvrez le dépôt GitHub dans un onglet distinct, puis copiez le code source des fichiers App.java et pom.xml.
  2. Si vous avez ouvert l'éditeur dans un nouvel onglet à l'aide de l'icône "Ouvrir dans un nouvel onglet" en haut à droite, vous pouvez ouvrir le terminal en bas de la page. Vous pouvez ouvrir l'éditeur et le terminal en parallèle pour pouvoir travailler librement.
  3. Une fois le clonage effectué, revenez à la console de l'éditeur Cloud Shell.
  4. Comme nous avons déjà créé la fonction Cloud Run, vous n'avez pas besoin de copier les fichiers de la fonction Cloud Run à partir du dossier du dépôt.

Premiers pas avec le SDK Java de l'ADK

C'est assez simple. Vous devez principalement vous assurer que les éléments suivants sont couverts lors de l'étape de clonage:

  1. Ajouter des dépendances :

Incluez les artefacts google-adk et google-adk-dev (pour l'UI Web) dans votre fichier 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>

Veillez à faire référence au fichier pom.xml à partir du dépôt source, car d'autres dépendances et configurations sont nécessaires pour que l'application puisse s'exécuter.

  1. Configurez votre projet:

Assurez-vous que votre version Java (17 ou version ultérieure recommandée) et les paramètres du compilateur Maven sont correctement configurés dans votre fichier pom.xml. Vous pouvez configurer votre projet pour qu'il respecte la structure ci-dessous:

adk-agents/
 └—— pom.xml
 └—— src/ 
     └—— main/
         └—— java/
             └—— agents/
                 └—— App.java
  1. Définition de l'agent et de ses outils (App.java):

C'est là que le SDK Java de l'ADK brille. Nous définissons notre agent, ses capacités (instructions) et les outils qu'il peut utiliser.

Vous trouverez ici une version simplifiée de quelques extraits de code de la classe d'agent principale. Pour obtenir le projet complet, cliquez ici.

// 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)
    }
}

Composants clés du code Java de l'ADK mis en évidence:

  1. LlmAgent.builder(): : API Fluent permettant de configurer votre agent.
  2. .instruction(...) : fournit l'invite et les consignes de base pour le LLM, y compris quand utiliser tel ou tel outil.
  3. FunctionTool.create(App.class, "methodName") : enregistre facilement vos méthodes Java en tant qu'outils que l'agent peut appeler. La chaîne de nom de méthode doit correspondre à une méthode statique publique réelle.
  4. @Schema(description = ...) : permet d'annoter les paramètres de l'outil, ce qui aide le LLM à comprendre les entrées attendues par chaque outil. Cette description est essentielle pour sélectionner et renseigner correctement les outils et les paramètres.
  5. InvocationContext ctx:transmis automatiquement aux méthodes de l'outil, permettant d'accéder à l'état de la session (ctx.session().state()), aux informations utilisateur, etc.
  6. .outputKey("brevets") : lorsqu'un outil renvoie des données, ADK peut les stocker automatiquement dans l'état de la session sous cette clé. C'est ainsi que explainPatent peut accéder aux résultats de getPatents.
  7. VECTOR_SEARCH_ENDPOINT::variable qui contient la logique fonctionnelle de base des questions/réponses contextuelles pour l'utilisateur dans le cas d'utilisation de la recherche de brevets.
  8. Action à entreprendre: Vous devez définir une valeur de point de terminaison déployée mise à jour une fois que vous avez implémenté l'étape de la fonction Java Cloud Run de la section précédente.
  9. searchTool: permet à l'utilisateur de trouver des correspondances de brevets pertinentes dans la base de données des brevets pour le texte de recherche de l'utilisateur.
  10. explainTool: demande à l'utilisateur de sélectionner un brevet spécifique à examiner en détail. Il résume ensuite l'aperçu du brevet et peut répondre à d'autres questions de l'utilisateur en fonction des informations sur le brevet dont il dispose.

Remarque importante: Veillez à remplacer la variable VECTOR_SEARCH_ENDPOINT par votre point de terminaison CRF déployé.

Exploiter InvocationContext pour les interactions avec état

L'une des fonctionnalités essentielles pour créer des agents utiles est la gestion de l'état sur plusieurs tours d'une conversation. L'InvocationContext de l'ADK facilite cette tâche.

Dans App.java:

  1. Lorsque initAgent() est défini, nous utilisons .outputKey("patents"). Cela indique à ADK que lorsqu'un outil (comme getPatents) renvoie des données dans son champ de rapport, ces données doivent être stockées dans l'état de la session sous la clé "patents".
  2. Dans la méthode de l'outil explainPatent, nous injectons InvocationContext ctx:
public static Map<String, String> explainPatent(
    @Schema(description = "...") String patentId, InvocationContext ctx) {
    String previousResults = (String) ctx.session().state().get("patents");
    // ... use previousResults ...
}

Cela permet à l'outil explainPatent d'accéder à la liste des brevets extraite par l'outil getPatents lors d'un tour de conversation précédent, ce qui rend la conversation cohérente et avec état.

9. Tests de la CLI en local

Définir des variables d'environnement

Vous devez exporter deux variables d'environnement:

  1. Une clé Gemini que vous pouvez obtenir dans AI Studio:

Pour ce faire, accédez à https://aistudio.google.com/apikey et obtenez la clé API de votre projet Google Cloud actif dans lequel vous implémentez cette application, puis enregistrez-la quelque part:

ae2db169e6a94e4a.png

  1. Une fois que vous avez obtenu la clé, ouvrez le terminal Cloud Shell et accédez au nouveau répertoire adk-agents que nous venons de créer en exécutant la commande suivante:
cd adk-agents
  1. Variable permettant de spécifier que nous n'utilisons pas Vertex AI cette fois-ci.
export GOOGLE_GENAI_USE_VERTEXAI=FALSE
export GOOGLE_API_KEY=AIzaSyDF...
  1. Exécuter votre premier agent dans la CLI

Pour lancer ce premier agent, utilisez la commande Maven suivante dans votre terminal:

mvn compile exec:java -DmainClass="agents.App"

La réponse interactive de l'agent s'affiche dans votre terminal.

10. Déployer sur Cloud Run

Le déploiement de votre agent Java ADK sur Cloud Run est semblable à celui de n'importe quelle autre application Java:

  1. Dockerfile: créez un Dockerfile pour empaqueter votre application Java.
  2. Créer et transmettre une image Docker: utilisez Google Cloud Build et Artifact Registry.
  3. Vous pouvez effectuer l'étape ci-dessus et déployer dans Cloud Run en une seule commande:
gcloud run deploy --source . --set-env-vars GOOGLE_API_KEY=<<Your_Gemini_Key>>

De même, vous devez déployer votre fonction Java Cloud Run (gcfv2.PatentSearch). Vous pouvez également créer et déployer la fonction Java Cloud Run pour la logique de base de données directement depuis la console des fonctions Cloud Run.

11. Tester avec l'UI Web

L'ADK est fourni avec une interface utilisateur Web pratique pour tester et déboguer votre agent en local. Lorsque vous exécutez votre App.java localement (par exemple, mvn exec:java -Dexec.mainClass="agents.App" si configuré, ou simplement en exécutant la méthode principale), l'ADK démarre généralement un serveur Web local.

L'interface utilisateur Web de l'ADK vous permet d'effectuer les opérations suivantes:

  1. Envoyez des messages à votre agent.
  2. Afficher les événements (message utilisateur, appel d'outil, réponse de l'outil, réponse du LLM).
  3. Inspectez l'état de la session.
  4. Afficher les journaux et les traces

Cela est indispensable pendant le développement pour comprendre comment votre agent traite les requêtes et utilise ses outils. Cela suppose que votre mainClass dans pom.xml est définie sur com.google.adk.web.AdkWebServer et que votre agent y est enregistré, ou que vous exécutez un outil d'exécution de test local qui l'expose.

Lorsque vous exécutez votre App.java avec son InMemoryRunner et son scanner pour l'entrée de la console, vous testez la logique de base de l'agent. L'UI Web est un composant distinct qui offre une expérience de débogage plus visuelle. Elle est souvent utilisée lorsque l'ADK diffuse votre agent via HTTP.

Vous pouvez utiliser la commande Maven suivante à partir de votre répertoire racine pour lancer le serveur local SpringBoot:

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"

L'interface est souvent accessible à l'URL renvoyée par la commande ci-dessus. S'il est déployé sur Cloud Run, vous devriez pouvoir y accéder à partir du lien de déploiement Cloud Run.

Vous devriez pouvoir voir le résultat dans une interface interactive.

Regardez la vidéo ci-dessous pour découvrir notre agent spécialisé dans les brevets:

Démonstration d'un agent de brevets contrôlé par qualité avec la recherche intégrée et l'évaluation de la mémoire AlloyDB

ca7b0fc4fe571dd6.png

12. Effectuer un nettoyage

Pour éviter que les ressources utilisées dans cet article soient facturées sur votre compte Google Cloud, procédez comme suit:

  1. Dans la console Google Cloud, accédez à https://console.cloud.google.com/cloud-resource-manager?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog.
  2. https://console.cloud.google.com/cloud-resource-manager?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog.
  3. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  4. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

13. Félicitations

Félicitations ! Vous avez créé votre agent d'analyse des brevets en Java en combinant les fonctionnalités d'ADK, https://cloud.google.com/alloydb/docs?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog, Vertex AI et Vector Search. Nous avons également fait un grand pas en avant pour rendre les recherches de similarité contextuelle si transformatrices, efficaces et vraiment axées sur le sens.

Commencez dès aujourd'hui !

Documentation de l'ADK: [Link to Official ADK Java Docs]

Code source de l'agent d'analyse des brevets: [Lien vers votre dépôt GitHub (maintenant public)]

Exemples d'agents Java: [link to the adk-samples repo]

Rejoignez la communauté ADK: https://www.reddit.com/r/agentdevelopmentkit/

Bon développement !