Crea app di agenti AI efficaci, con stato e end-to-end in Java con ADK, AlloyDB e Gemini.

Crea app di agenti di IA E2E potenti e con stato in Java con ADK, AlloyDB e Gemini.

Informazioni su questo codelab

subjectUltimo aggiornamento: mag 28, 2025
account_circleScritto da: Author: Abirami Sukumaran

1. Panoramica

In diversi settori, la ricerca contestuale è una funzionalità fondamentale che costituisce il cuore delle applicazioni. La generazione di risultati avanzata è un fattore chiave di questa evoluzione tecnologica fondamentale da un po' di tempo, grazie ai suoi meccanismi di recupero basati sull'IA generativa. I modelli generativi, con le loro ampie finestre di contesto e la straordinaria qualità dell'output, stanno trasformando l'IA. La RAG fornisce un modo sistematico per inserire il contesto nelle applicazioni e negli agenti di IA, basandoli su database strutturati o informazioni provenienti da vari media. Questi dati contestuali sono fondamentali per la chiarezza della verità e l'accuratezza dell'output, ma quanto sono precisi questi risultati? La tua attività dipende in gran parte dall'accuratezza di queste corrispondenze contestuali e dalla pertinenza? Allora questo progetto fa al caso tuo.

Ora immagina se potessimo sfruttare la potenza dei modelli generativi e creare agenti interattivi in grado di prendere decisioni autonome basate su queste informazioni fondamentali per il contesto e fondate sulla verità. È quello che stiamo per creare oggi. Stiamo per creare un'app di agenti AI end-to-end utilizzando Agent Development Kit basato su RAG avanzata in AlloyDB per un'applicazione di analisi dei brevetti.

Patent Analysis Agent aiuta l'utente a trovare brevetti pertinenti al contesto del testo di ricerca e, su richiesta, fornisce una spiegazione chiara e concisa e dettagli aggiuntivi, se necessario, per un brevetto selezionato. Vuoi scoprire come si fa? Iniziamo.

Obiettivo

L'obiettivo è semplice. Consentire a un utente di cercare brevetti in base a una descrizione testuale e poi ottenere una spiegazione dettagliata di un brevetto specifico dai risultati di ricerca, il tutto utilizzando un agente AI creato con Java ADK, AlloyDB, Vector Search (con indici avanzati), Gemini e l'intera applicazione di cui è stato eseguito il deployment in modalità serverless su Cloud Run.

Cosa creerai

In questo lab imparerai a:

  1. Crea un'istanza AlloyDB e carica i dati del set di dati pubblico dei brevetti
  2. Implementare la ricerca vettoriale avanzata in AlloyDB utilizzando le funzionalità di valutazione ScaNN e Recall
  3. Creare un agente utilizzando Java ADK
  4. Implementare la logica lato server del database in Cloud Functions serverless Java
  5. Esegui il deployment e il test dell'agente in Cloud Run

Il seguente diagramma rappresenta il flusso di dati e i passaggi coinvolti nell'implementazione.

c22563ace65a6930.png

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

Requisiti

  • Un browser, ad esempio Chrome o Firefox
  • Un progetto Google Cloud con la fatturazione abilitata.

2. Prima di iniziare

Crea un progetto

  1. Nella console Google Cloud, nella pagina di selezione del progetto, seleziona o crea un progetto Google Cloud.
  2. Verifica che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è attivata in un progetto .
  3. Utilizzerai Cloud Shell, un ambiente a riga di comando in esecuzione in Google Cloud. Fai clic su Attiva Cloud Shell nella parte superiore della console Google Cloud.

Immagine del pulsante Attiva Cloud Shell

  1. Una volta connesso a Cloud Shell, verifica di aver già eseguito l'autenticazione e che il progetto sia impostato sul tuo ID progetto utilizzando il seguente comando:
gcloud auth list
  1. Esegui il seguente comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto.
gcloud config list project
  1. Se il progetto non è impostato, utilizza il seguente comando per impostarlo:
gcloud config set project <YOUR_PROJECT_ID>
  1. Abilita le API richieste. Puoi utilizzare un comando gcloud nel terminale 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

L'alternativa al comando gcloud è tramite la console cercando ciascun prodotto o utilizzando questo link.

Consulta la documentazione per i comandi e l'utilizzo di gcloud.

3. Configurazione del database

In questo lab utilizzeremo AlloyDB come database per i dati dei brevetti. Utilizza i cluster per contenere tutte le risorse, come database e log. Ogni cluster ha un'istanza principale che fornisce un punto di accesso ai dati. Le tabelle conterranno i dati effettivi.

Creiamo un cluster, un'istanza e una tabella AlloyDB in cui verrà caricato il set di dati dei brevetti.

Crea un cluster e un'istanza

  1. Esplora la pagina AlloyDB nella console Cloud. Un modo semplice per trovare la maggior parte delle pagine in Cloud Console è cercarle utilizzando la barra di ricerca della console.
  2. Seleziona CREA CLUSTER in quella pagina:

f76ff480c8c889aa.png

  1. Viene visualizzata una schermata come quella riportata di seguito. Crea un cluster e un'istanza con i seguenti valori (assicurati che i valori corrispondano nel caso in cui stia clonando il codice dell'applicazione dal repository):
  • cluster id: "vector-cluster"
  • password: "alloydb"
  • PostgreSQL 15 / ultima versione consigliata
  • Regione: "us-central1"
  • Networking: "default"

538dba58908162fb.png

  1. Quando selezioni la rete predefinita, viene visualizzata una schermata come quella riportata di seguito.

Seleziona CONFIGURA CONNESSIONE.
7939bbb6802a91bf.png

  1. Da qui, seleziona "Utilizza un intervallo IP allocato automaticamente" e Continua. Dopo aver esaminato le informazioni, seleziona CREA CONNESSIONE. 768ff5210e79676f.png
  2. Una volta configurata la rete, puoi continuare a creare il cluster. Fai clic su CREA CLUSTER per completare la configurazione del cluster come mostrato di seguito:

e06623e55195e16e.png

Assicurati di modificare l'ID istanza (che puoi trovare al momento della configurazione del cluster / dell'istanza) in

vector-instance. Se non puoi modificarlo, ricordati di utilizzare l'ID istanza in tutti i riferimenti futuri.

Tieni presente che la creazione del cluster richiede circa 10 minuti. Al termine dell'operazione, dovresti visualizzare una schermata che mostra la panoramica del cluster appena creato.

4. Importazione dati

Ora è il momento di aggiungere una tabella con i dati del negozio. Vai ad AlloyDB, seleziona il cluster principale e poi AlloyDB Studio:

847e35f1bf8a8bd8.png

Potresti dover attendere il completamento della creazione dell'istanza. Una volta completata la procedura, accedi ad AlloyDB utilizzando le credenziali che hai creato durante la creazione del cluster. Utilizza i seguenti dati per l'autenticazione in PostgreSQL:

  • Nome utente : "postgres"
  • Database : "postgres"
  • Password : "alloydb"

Una volta eseguita l'autenticazione in AlloyDB Studio, i comandi SQL vengono inseriti nell'editor. Puoi aggiungere più finestre di Editor utilizzando il segno Più a destra dell'ultima finestra.

91a86d9469d499c4.png

Inserisci i comandi per AlloyDB nelle finestre dell'editor, utilizzando le opzioni Esegui, Formatta e Cancella, se necessario.

Attivare le estensioni

Per creare questa app, utilizzeremo le estensioni pgvector e google_ml_integration. L'estensione pgvector ti consente di archiviare ed eseguire ricerche di incorporamenti vettoriali. L'estensione google_ml_integration fornisce le funzioni che utilizzi per accedere agli endpoint di previsione di Vertex AI per ottenere le previsioni in SQL. Attiva queste estensioni eseguendo i seguenti DDL:

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

Se vuoi controllare le estensioni che sono state attivate nel tuo database, esegui questo comando SQL:

select extname, extversion from pg_extension;

Creare una tabella

Puoi creare una tabella utilizzando l'istruzione DDL riportata di seguito in 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 colonna abstract_embeddings consente di archiviare i valori vettore del testo.

Concedi autorizzazione

Esegui l'istruzione riportata di seguito per concedere l'esecuzione alla funzione "embedding":

GRANT EXECUTE ON FUNCTION embedding TO postgres;

Concedi il RUOLO Utente Vertex AI all'account di servizio AlloyDB

Nella console IAM di Google Cloud, concedi all'account di servizio AlloyDB (che ha il seguente aspetto: service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com) l'accesso al ruolo "Utente Vertex AI". PROJECT_NUMBER avrà il numero del progetto.

In alternativa, puoi eseguire il comando seguente dal terminale 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"

Carica i dati dei brevetti nel database

Come set di dati utilizzeremo i set di dati pubblici di Google Patents su BigQuery. Utilizzeremo AlloyDB Studio per eseguire le query. I dati provengono da questo file insert_scripts.sql e lo eseguiremo per caricare i dati del brevetto.

  1. Nella console Google Cloud, apri la pagina AlloyDB.
  2. Seleziona il cluster appena creato e fai clic sull'istanza.
  3. Nel menu di navigazione di AlloyDB, fai clic su AlloyDB Studio. Accedi con le tue credenziali.
  4. Apri una nuova scheda facendo clic sull'icona Nuova scheda a destra.
  5. Copia l'istruzione di query insert dallo script insert_scripts.sql sopra indicato nell'editor. Puoi copiare 10-50 istruzioni INSERT per una rapida dimostrazione di questo caso d'uso.
  6. Fai clic su Esegui. I risultati della query vengono visualizzati nella tabella Risultati.

5. Creare incorporamenti per i dati dei brevetti

Innanzitutto, testiamo la funzione di embedding eseguendo la seguente query di esempio:

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

Dovrebbe restituire il vettore di incorporamenti, che ha la forma di un array di valori float, per il testo di esempio nella query. Ha il seguente aspetto:

25a1d7ef0e49e91e.png

Aggiorna il campo del vettore abstract_embeddings

Esegui la seguente DML per aggiornare gli abstract dei brevetti nella tabella con gli embedding corrispondenti:

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

6. Eseguire una ricerca vettoriale

Ora che la tabella, i dati e gli incorporamenti sono pronti, eseguiamo la ricerca vettoriale in tempo reale per il testo di ricerca dell'utente. Per verificare, esegui la query riportata di seguito:

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

In questa query,

  1. Il testo cercato dall'utente è: "Analisi del sentiment".
  2. Lo stiamo convertendo in embedding nel metodo embedding() utilizzando il modello: text-embedding-005.
  3. "<=>" indica l'utilizzo del metodo di distanza SIMILARITÀ COSENO.
  4. Stiamo convertendo il risultato del metodo di embedding in tipo di vettore per renderlo compatibile con i vettori archiviati nel database.
  5. LIMIT 10 indica che selezioniamo le 10 corrispondenze più strette del testo di ricerca.

AlloyDB porta la ricerca vettoriale RAG a un livello superiore:

Sono state introdotte diverse novità. Due di questi, incentrati sugli sviluppatori, sono:

  1. Filtro in linea
  2. Valutatore del richiamo

Filtro in linea

In precedenza, in qualità di sviluppatore, dovevi eseguire la query di ricerca vettoriale e occuparti del filtro e del recupero. Lo strumento di ottimizzazione delle query di AlloyDB effettua delle scelte su come eseguire una query con filtri. Il filtro in linea è una nuova tecnica di ottimizzazione delle query che consente all'ottimizzatore delle query AlloyDB di valutare sia le condizioni di filtro dei metadati sia la ricerca di vettori, sfruttando sia gli indici di vettori sia gli indici delle colonne dei metadati. In questo modo, il rendimento del richiamo è aumentato, consentendo agli sviluppatori di sfruttare ciò che AlloyDB ha da offrire immediatamente.

Il filtro in linea è ideale per i casi con una selettività media. Quando AlloyDB esegue ricerche nell'indice vettoriale, calcola le distanze solo per i vettori che corrispondono alle condizioni di filtro dei metadati (i filtri funzionali in una query di solito gestiti nella clausola WHERE). In questo modo, le prestazioni di queste query migliorano notevolmente, completando i vantaggi del filtro post o pre.

  1. Installa o aggiorna l'estensione pgvector
CREATE EXTENSION IF NOT EXISTS vector WITH VERSION '0.8.0.google-3';

Se l'estensione pgvector è già installata, esegui l'upgrade all'estensione del vettore alla versione 0.8.0.google-3 o successiva per ottenere le funzionalità di valutazione del richiamo.

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

Questo passaggio deve essere eseguito solo se l'estensione vettoriale è <0.8.0.google-3.

Nota importante:se il numero di righe è inferiore a 100, non è necessario creare l'indice ScaNN perché non verrà applicato a un numero inferiore di righe. In questo caso, salta i passaggi che seguono.

  1. Per creare indici ScaNN, installa l'estensione alloydb_scann.
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
  1. Innanzitutto, esegui la query di ricerca vettoriale senza l'indice e senza il filtro in linea abilitato:
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;

Il risultato dovrebbe essere simile al seguente:

6989de0fc3f0f753.png

  1. Esegui Explain Analyze (senza indice né filtro in linea):

908dcf87c7f00ed4.png

Il tempo di esecuzione è di 2,4 ms

  1. Creiamo un indice regolare sul campo num_claims in modo da poter applicare un filtro in base a questo campo:
CREATE INDEX idx_patents_data_num_claims ON patents_data (num_claims);
  1. Creiamo l'indice ScaNN per la nostra applicazione di ricerca di brevetti. Esegui quanto segue da AlloyDB Studio:
CREATE INDEX patent_index ON patents_data 
USING scann (abstract_embeddings cosine)
WITH (num_leaves=32);

Nota importante : (num_leaves=32) si applica al nostro set di dati totale con più di 1000 righe. Se il numero di righe è inferiore a 100, non è necessario creare un indice in quanto non verrà applicato per un numero inferiore di righe.

  1. Imposta il filtro in linea attivato nell'indice ScaNN:
SET scann.enable_inline_filtering = on
  1. Ora eseguiamo la stessa query con il filtro e la ricerca vettoriale:
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

Come puoi vedere, il tempo di esecuzione è notevolmente ridotto per la stessa ricerca di vettori. Il filtro in linea integrato nell'indice ScaNN in Vector Search ha reso tutto ciò possibile.

A questo punto, valutiamo il recupero per questa ricerca vettoriale abilitata a ScaNN.

Valutatore del richiamo

Il richiamo nella ricerca di similarità è la percentuale di istanze pertinenti recuperate da una ricerca, ovvero il numero di veri positivi. Si tratta della metrica più comune utilizzata per misurare la qualità della ricerca. Una fonte di perdita del richiamo deriva dalla differenza tra la ricerca del vicino più prossimo approssimativa (ANN) e la ricerca del vicino più prossimo esatto (KNN). Gli indici vettoriali come ScaNN di AlloyDB implementano algoritmi ANN, consentendo di velocizzare la ricerca vettoriale su set di dati di grandi dimensioni in cambio di un piccolo compromesso in termini di richiamo. Ora AlloyDB ti offre la possibilità di misurare questo compromesso direttamente nel database per le singole query e di assicurarti che sia stabile nel tempo. Puoi aggiornare i parametri di query e indice in base a queste informazioni per ottenere risultati e prestazioni migliori.

Puoi trovare il richiamo per una query vettoriale su un indice vettoriale per una determinata configurazione utilizzando la funzione evaluate_query_recall. Questa funzione ti consente di ottimizzare i parametri per ottenere i risultati di recupero delle query vettoriali che preferisci. Il richiamo è la metrica utilizzata per la qualità della ricerca ed è definita come la percentuale dei risultati restituiti oggettivamente più vicini ai vettori di query. La funzione evaluate_query_recall è attiva per impostazione predefinita.

Nota importante:

Se nei passaggi successivi riscontri un errore di autorizzazione negata nell'indice HNSW, per il momento salta l'intera sezione relativa alla valutazione del richiamo. Potrebbe essere dovuto a restrizioni di accesso, dato che è stato appena rilasciato al momento della documentazione di questo codelab.

  1. Imposta il flag Enable Index Scan sull'indice ScaNN e sull'indice HNSW:
SET scann.enable_indexscan = on
SET hnsw.enable_index_scan = on
  1. Esegui la seguente query in 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 funzione evaluate_query_recall riceve la query come parametro e restituisce il relativo richiamo. Sto utilizzando la stessa query utilizzata per controllare il rendimento come query di input della funzione. Ho aggiunto SCaNN come metodo di indicizzazione. Per altre opzioni di parametro, consulta la documentazione.

Il recupero per questa query di ricerca vettoriale che abbiamo utilizzato:

c98f38fbe6a0b6c5.png

Vedo che il valore RECALL è 70%. Ora posso utilizzare queste informazioni per modificare i parametri dell'indice, i metodi e i parametri di query e migliorare il recupero per questa ricerca vettoriale.

Ho modificato il numero di righe nel set di risultati impostandolo su 7 (in precedenza 10) e ho notato un RECALL leggermente migliorato, ovvero l'86%.

c12f7b92b8481ceb.png

Ciò significa che in tempo reale posso variare il numero di corrispondenze che i miei utenti possono vedere per migliorare la pertinenza delle corrispondenze in base al contesto di ricerca degli utenti.

Bene. È ora di eseguire il deployment della logica di database e passare all'agente.

7. Trasferisci la logica del database sul web in modo serverless

Vuoi portare questa app sul web? Procedi nel seguente modo:

  1. Vai a Funzioni Cloud Run nella console Google Cloud per CREARE una nuova funzione Cloud Run o utilizza il link: https://console.cloud.google.com/functions/add.
  2. Seleziona l'ambiente come "Funzione Cloud Run". Fornisci il nome della funzione "patent-search" e scegli la regione "us-central1". Imposta l'autenticazione su "Consenti chiamate non autenticate" e fai clic su AVANTI. Scegli Java 17 come runtime e Editor incorporato per il codice sorgente.
  3. Per impostazione predefinita, il punto di ingresso viene impostato su "gcfv2.HelloHttpFunction". Sostituisci il codice segnaposto in HelloHttpFunction.java e pom.xml della tua funzione Cloud Run con il codice di "PatentSearch.java" e "pom.xml", rispettivamente. Modifica il nome del file della classe in PatentSearch.java.
  4. Ricorda di sostituire il segnaposto ************* e le credenziali di connessione AlloyDB con i tuoi valori nel file Java. Le credenziali AlloyDB sono quelle che abbiamo utilizzato all'inizio di questo codelab. Se hai utilizzato valori diversi, modificali nel file Java.
  5. Fai clic su Esegui il deployment.

PASSAGGIO IMPORTANTE:

Una volta eseguito il deployment, per consentire alla funzione Cloud di accedere all'istanza del database AlloyDB, creeremo il connettore VPC.

Una volta completato il deployment, dovresti essere in grado di vedere le funzioni nella console di Cloud Run Functions di Google Cloud. Cerca la funzione appena creata (ricerca-brevetti), fai clic su di essa, poi su MODIFICA E EFFETTUA IL DEPLOY DI NUOVE REVISIONI (identificata dall'icona MODIFICA (penna) nella parte superiore della console Cloud Run Functions) e modifica quanto segue:

  1. Vai alla scheda Networking:

828cd861864d99ea.png

  1. Seleziona "Connettiti a un VPC per il traffico in uscita" e poi "Utilizza connettori di accesso VPC serverless".
  2. Nelle impostazioni del menu a discesa Rete, fai clic sul menu a discesa Rete e seleziona l'opzione "Aggiungi nuovo connettore VPC" (se non hai già configurato quello predefinito) e segui le istruzioni visualizzate nella finestra di dialogo visualizzata:

6559ccfd10e597f2.png

  1. Fornisci un nome per il connettore VPC e assicurati che la regione corrisponda a quella dell'istanza. Lascia il valore della rete predefinito e imposta la subnet come intervallo IP personalizzato con l'intervallo IP 10.8.0.0 o un valore simile disponibile.
  2. Espandi IMPOSTAZIONI DI SCALING DEL DISPLAY e assicurati che la configurazione sia impostata esattamente come segue:

199b0ccd80215004.png

  1. Fai clic su CREA. Questo connettore dovrebbe essere ora elencato nelle impostazioni di uscita.
  2. Seleziona il connettore appena creato.
  3. Scegli di instradare tutto il traffico attraverso questo connettore VPC.
  4. Fai clic su AVANTI e poi su ESEGUI IL DEPLOY.
  5. Una volta eseguito il deployment della funzione Cloud aggiornata, dovresti vedere l'endpoint generato. Copialo e sostituiscilo nel seguente comando:
PROJECT_ID=$(gcloud config get-value project)

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

È tutto. È così semplice eseguire una ricerca vettoriale di somiglianza contestuale avanzata utilizzando il modello di incorporamenti sui dati di AlloyDB.

8. Creiamo l&#39;agente con Java ADK

Per prima cosa, iniziamo con il progetto Java nell'editor.

  1. Vai al terminale Cloud Shell

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

  1. Autorizza quando richiesto
  2. Passa all'editor di Cloud Shell facendo clic sull'icona dell'editor nella parte superiore della console di Cloud Shell

f913b886324e5196.png

  1. Nella console di Cloud Shell Editor, crea una nuova cartella e assegnale il nome "adk-agents"

Fai clic su Crea nuova cartella nella directory principale della tua cloud shell, come mostrato di seguito:

94c9804697614a94.png

Assegna il nome "adk-agents":

37445dc1fe08f74c.png

  1. Crea la seguente struttura di cartelle e i file vuoti con i nomi corrispondenti nella struttura riportata di seguito:
adk-agents/
 └—— pom.xml
 └—— src/
     └—— main/
         └—— java/
             └—— agents/
                 └—— App.java
  1. Apri il repo GitHub in una scheda separata e copia il codice sorgente dei file App.java e pom.xml.
  2. Se hai aperto l'editor in una nuova scheda utilizzando l'icona "Apri in una nuova scheda" nell'angolo in alto a destra, puoi aprire il terminale nella parte inferiore della pagina. Puoi aprire l'editor e il terminale in parallelo, il che ti consente di operare liberamente.
  3. Una volta clonato, torna alla console dell'editor di Cloud Shell
  4. Poiché abbiamo già creato la funzione Cloud Run, non devi copiare i file della funzione Cloud Run dalla cartella del repository.

Iniziare a utilizzare l'SDK Java ADK

È abbastanza semplice. Innanzitutto, devi assicurarti che nel passaggio di clonazione siano inclusi i seguenti elementi:

  1. Aggiungi dipendenze:

Includi gli elementi google-adk e google-adk-dev (per l'interfaccia utente web) in 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>

Assicurati di fare riferimento a pom.xml dal repository di origine, in quanto sono necessarie altre dipendenze e configurazioni per l'esecuzione dell'applicazione.

  1. Configura il progetto:

Assicurati che la versione Java (è consigliata 17 o versioni successive) e le impostazioni del compilatore Maven siano configurate correttamente in pom.xml. Puoi configurare il progetto in modo che segua la struttura riportata di seguito:

adk-agents/
 └—— pom.xml
 └—— src/
     └—— main/
         └—— java/
             └—— agents/
                 └—— App.java
  1. Definizione dell'agente e dei relativi strumenti (App.java):

Ed è qui che entra in gioco la magia dell'SDK Java ADK. Definiamo il nostro agente, le sue funzionalità (istruzioni) e gli strumenti che può utilizzare.

Qui puoi trovare una versione semplificata di alcuni snippet di codice della classe dell'agente principale. Per il progetto completo, consulta il repository del progetto qui.

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

Componenti chiave del codice Java ADK evidenziati:

  1. LlmAgent.builder(): API Fluent per la configurazione dell'agente.
  2. .instruction(...): fornisce il prompt e le linee guida di base per l'LLM, incluso quando utilizzare quale strumento.
  3. FunctionTool.create(App.class, "methodName"): registra facilmente i metodi Java come strumenti che l'agente può richiamare. La stringa del nome del metodo deve corrispondere a un metodo statico pubblico effettivo.
  4. @Schema(description = ...): annota i parametri dello strumento, aiutando l'LLM a capire quali input si aspetta ogni strumento. Questa descrizione è fondamentale per la selezione accurata degli strumenti e il completamento dei parametri.
  5. InvocationContext ctx: viene passato automaticamente ai metodi dello strumento, consentendo l'accesso allo stato della sessione (ctx.session().state()), alle informazioni utente e altro ancora.
  6. .outputKey("patents"): quando uno strumento restituisce dati, ADK può memorizzarli automaticamente nello stato della sessione sotto questa chiave. In questo modo explainPatent può accedere ai risultati di getPatents.
  7. VECTOR_SEARCH_ENDPOINT: questa è una variabile che contiene la logica funzionale di base per le domande e le risposte contestuali per l'utente nel caso d'uso di ricerca di brevetti.
  8. Azione da svolgere: devi impostare un valore dell'endpoint di cui è stato eseguito il deployment aggiornato dopo aver implementato il passaggio della funzione Java Cloud Run della sezione precedente.
  9. searchTool: interagisce con l'utente per trovare corrispondenze di brevetti pertinenti dal punto di vista del contesto nel database dei brevetti per il testo di ricerca dell'utente.
  10. explainTool: chiede all'utente di esaminare in dettaglio un brevetto specifico. Poi riassume l'abstract del brevetto ed è in grado di rispondere ad altre domande dell'utente in base ai dettagli del brevetto di cui dispone.

Nota importante: assicurati di sostituire la variabile VECTOR_SEARCH_ENDPOINT con l'endpoint CRF di cui hai eseguito il deployment.

Utilizzo di InvocationContext per le interazioni con stato

Una delle funzionalità fondamentali per creare agenti utili è la gestione dello stato in più turni di una conversazione. InvocationContext di ADK semplifica questa operazione.

In App.java:

  1. Quando initAgent() è definito, utilizziamo .outputKey("patents"). Questo indica ad ADK che, quando uno strumento (ad esempio getPatents) restituisce dati nel relativo campo del report, questi dati devono essere memorizzati nello stato della sessione sotto la chiave "patents".
  2. Nel metodo dello strumento explainPatent, iniettiamo InvocationContext ctx:
public static Map<String, String> explainPatent(
    @Schema(description = "...") String patentId, InvocationContext ctx) {
    String previousResults = (String) ctx.session().state().get("patents");
    // ... use previousResults ...
}

In questo modo lo strumento explainPatent può accedere all'elenco di brevetti recuperato dallo strumento getPatents in un turno precedente, rendendo la conversazione coerente e con stato.

9. Test dell&#39;interfaccia a riga di comando locale

Definisci le variabili di ambiente

Dovrai esportare due variabili di ambiente:

  1. Una chiave Gemini che puoi ottenere da AI Studio:

Per farlo, vai alla pagina https://aistudio.google.com/apikey, ottieni la chiave API per il tuo progetto Google Cloud attivo in cui stai implementando questa applicazione e salvala da qualche parte:

ae2db169e6a94e4a.png

  1. Una volta ottenuta la chiave, apri il terminale Cloud Shell e vai alla nuova directory adk-agents che abbiamo appena creato eseguendo il seguente comando:
cd adk-agents
  1. Una variabile per specificare che questa volta non utilizziamo Vertex AI.
export GOOGLE_GENAI_USE_VERTEXAI=FALSE
export GOOGLE_API_KEY=AIzaSyDF...
  1. Esegui il tuo primo agente sulla CLI

Per avviare questo primo agente, utilizza il seguente comando Maven nel terminale:

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

Vedrai la risposta interattiva dell'agente nel terminale.

10. Deployment in Cloud Run

Il deployment dell'agente Java ADK in Cloud Run è simile a quello di qualsiasi altra applicazione Java:

  1. Dockerfile: crea un Dockerfile per pacchettizzare l'applicazione Java.
  2. Crea ed esegui il push dell'immagine Docker: utilizza Google Cloud Build e Artifact Registry.
  3. Puoi eseguire il passaggio precedente ed eseguire il deployment su Cloud Run con un solo comando:
gcloud run deploy --source . --set-env-vars GOOGLE_API_KEY=<<Your_Gemini_Key>>

Analogamente, devi eseguire il deployment della funzione Java Cloud Run (gcfv2.PatentSearch). In alternativa, puoi creare ed eseguire il deployment della funzione Cloud Run Java per la logica di database direttamente dalla console della funzione Cloud Run.

11. Test con l&#39;interfaccia utente web

L'ADK è dotato di un'utile interfaccia utente web per il test e il debug locale dell'agente. Quando esegui App.java localmente (ad es. mvn exec:java -Dexec.mainClass="agents.App" se configurato o semplicemente esegui il metodo main), in genere l'ADK avvia un server web locale.

L'interfaccia utente web di ADK ti consente di:

  1. Invia messaggi all'agente.
  2. Visualizza gli eventi (messaggio utente, chiamata allo strumento, risposta dello strumento, risposta LLM).
  3. Controlla lo stato della sessione.
  4. Visualizza log e tracce.

Questo è fondamentale durante lo sviluppo per comprendere in che modo l'agente elabora le richieste e utilizza i suoi strumenti. Questo presuppone che mainClass in pom.xml sia impostato su com.google.adk.web.AdkWebServer e che il tuo agente sia registrato o che tu stia eseguendo un programma di test locale che lo esponga.

Quando esegui App.java con InMemoryRunner e Scanner per l'input della console, stai testando la logica dell'agente di base. L'interfaccia utente web è un componente separato per un'esperienza di debug più visiva, spesso utilizzata quando ADK pubblica l'agente tramite HTTP.

Puoi utilizzare il seguente comando Maven dalla directory principale per avviare il server locale 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"

Spesso l'interfaccia è accessibile all'URL visualizzato dal comando precedente. Se è stato implementato in Cloud Run, dovresti essere in grado di accedervi dal link di Cloud Run di cui è stato eseguito il deployment.

Dovresti essere in grado di vedere il risultato in un'interfaccia interattiva.

Guarda il video di seguito per informazioni sul nostro agente per i brevetti di cui abbiamo eseguito il deployment:

Demo di un agente di brevetti con controllo qualità con la ricerca in linea e la valutazione del richiamo di AlloyDB.

ca7b0fc4fe571dd6.png

12. Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo post, segui questi passaggi:

  1. Nella console Google Cloud, vai alla pagina 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. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  4. Nella finestra di dialogo, digita l'ID progetto, quindi fai clic su Chiudi per eliminare il progetto.

13. Complimenti

Complimenti! Hai creato correttamente il tuo agente di analisi brevetti in Java combinando le funzionalità di ADK, https://cloud.google.com/alloydb/docs?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog, Vertex AI e Ricerca vettoriale. Inoltre, abbiamo fatto un enorme passo avanti nel rendere le ricerche di somiglianza contestuale così trasformative, efficienti e basate sul significato.

Inizia subito.

Documentazione ADK: [Link to Official ADK Java Docs]

Codice sorgente di Patent Analysis Agent: [Link al tuo repository GitHub (ora pubblico)]

Agenti di esempio Java: [link al repository adk-samples]

Unisciti alla community ADK: https://www.reddit.com/r/agentdevelopmentkit/

Buona creazione di agenti.