1. Introduzione
I modelli di IA generativa si distinguono per comprendere e rispondere al linguaggio naturale. Ma cosa succederebbe se avessi bisogno di output precisi e prevedibili per attività critiche come la standardizzazione degli indirizzi? I modelli generativi tradizionali a volte possono fornire risposte diverse in momenti diversi per gli stessi prompt, il che potrebbe causare incoerenze. È qui che spicca la funzionalità di chiamata di funzione di Gemini, che ti consente di controllare in modo deterministico gli elementi della risposta dell'IA.
Questo codelab illustra questo concetto con il caso d'uso di completamento degli indirizzi e standardizzazione. A questo scopo, creeremo una funzione Cloud Functions Java che esegue le seguenti attività:
- Accetta le coordinate di latitudine e longitudine
- Chiama l'API Geocoding di Google Maps per ottenere gli indirizzi corrispondenti
- Utilizza la funzionalità di chiamata di funzione di Gemini 1.0 Pro per standardizzare e riassumere in modo deterministico questi indirizzi in un formato specifico di cui abbiamo bisogno
Iniziamo.
2. Chiamate di funzione di Gemini
La chiamata di funzione di Gemini si distingue nell'era dell'IA generativa perché ti consente di combinare la flessibilità dei modelli linguistici generativi con la precisione della programmazione tradizionale.
Ecco le attività che devi completare per implementare la chiamata di funzione di Gemini:
- Definisci le funzioni: descrivi le funzioni in modo chiaro. Le descrizioni devono includere le seguenti informazioni:
- Il nome della funzione, ad esempio
getAddress
. - I parametri previsti dalla funzione, ad esempio
latlng
come stringa. - Il tipo di dati restituiti dalla funzione, ad esempio un elenco di stringhe di indirizzi.
- Creare strumenti per Gemini: descrizioni delle funzioni dei pacchetti sotto forma di specifica API in strumenti. Pensa a uno strumento come a uno strumento specializzato che Gemini può utilizzare per comprendere la funzionalità dell'API.
- Orchestra le API utilizzando Gemini: quando invii un prompt a Gemini, questo può analizzare la tua richiesta e riconoscere dove può utilizzare gli strumenti che hai fornito. Gemini agisce quindi da agente di orchestrazione intelligente svolgendo le seguenti attività:
- Genera i parametri API necessari per chiamare le funzioni definite. Gemini non chiama l'API per tuo conto. Devi chiamare l'API in base ai parametri e alla firma che la chiamata di funzione di Gemini ha generato per te.
- Gemini elabora i risultati fornendo i risultati delle chiamate API alla loro generazione e incorpora informazioni strutturate nella risposta finale. Puoi trattare queste informazioni come preferisci per la tua domanda.
L'immagine seguente mostra il flusso di dati, i passaggi previsti dall'implementazione e il proprietario di ogni passaggio, ad esempio applicazione, LLM o API:
Cosa creerai
Creerai ed eseguirai il deployment di una funzione Cloud Functions Java che fa quanto segue:
- Indica le coordinate di latitudine e longitudine.
- Chiama l'API Geocoding di Google Maps per ottenere gli indirizzi corrispondenti.
- Utilizza la funzionalità di chiamata di funzione Gemini 1.0 Pro per standardizzare e riassumere in modo deterministico questi indirizzi in un formato specifico.
3. Requisiti
4. Prima di iniziare
- Nella pagina del selettore dei progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.
- Assicurati che la fatturazione sia abilitata per il tuo progetto Google Cloud. Scopri come controllare se la fatturazione è abilitata per un progetto.
- Attiva Cloud Shell dalla console Google Cloud. Per ulteriori informazioni, vedi Utilizzare Cloud Shell.
- Se il progetto non è configurato, utilizza il comando seguente per configurarlo:
gcloud config set project <YOUR_PROJECT_ID>
- In Cloud Shell, imposta le seguenti variabili di ambiente:
export GCP_PROJECT=<YOUR_PROJECT_ID>
export GCP_REGION=us-central1
- Abilita le API Google Cloud necessarie eseguendo questi comandi in Cloud Shell:
gcloud services enable cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com logging.googleapis.com storage-component.googleapis.com cloudaicompanion.googleapis.com aiplatform.googleapis.com
- Apri l'editor di Cloud Shell, fai clic su Estensioni e installa l'estensione Gemini + Google Cloud Code.
5. Implementazione della funzione Cloud Functions
- Avvia l'editor di Cloud Shell.
- Fai clic su Cloud Code ed espandi la sezione Cloud Functions.
- Fai clic sull'icona Crea funzione (+).
- Nella finestra di dialogo Crea nuova applicazione, seleziona l'opzione Java: Hello World.
- Fornisci un nome per il progetto nel relativo percorso, ad esempio GeminiFunctionCalling.
- Fai clic su Explorer per visualizzare la struttura del progetto, quindi apri il file pom.xml. La seguente immagine mostra la struttura del progetto:
- Aggiungi le dipendenze necessarie all'interno del tag
<dependencies>... </dependencies>
nel filepom.xml
. Puoi accedere all'interopom.xml
dal repository GitHub di questo progetto. Copia il file pom.xml da lì nel filepom.xml
del progetto corrente che stai modificando. - Copia la classe
HelloWorld.java
dal link GeminiFunctionCalling GitHub. Devi aggiornareAPI_KEY
eproject_id
rispettivamente con la tua chiave API di geocodifica e con l'ID progetto Google Cloud.
6. Comprendere le chiamate di funzione utilizzando la classe HelloWorld.java
Input del prompt
In questo esempio, il prompt di input è il seguente: Qual è l'indirizzo per il valore latitudine/longitudine 40.714224,-73.961452.
Di seguito è riportato lo snippet di codice corrispondente al prompt di input nel file:
String promptText = "What's the address for the latlong value '" + latlngString + "'?"; //40.714224,-73.961452
Specifica API
In questo esempio viene utilizzata l'API Reverse Geocoding. Di seguito è riportata la specifica dell'API:
/* Declare the function for the API to invoke (Geo coding API) */
FunctionDeclaration functionDeclaration =
FunctionDeclaration.newBuilder()
.setName("getAddress")
.setDescription("Get the address for the given latitude and longitude value.")
.setParameters(
Schema.newBuilder()
.setType(Type.OBJECT)
.putProperties(
"latlng",
Schema.newBuilder()
.setType(Type.STRING)
.setDescription("This must be a string of latitude and longitude coordinates separated by comma")
.build())
.addRequired("latlng")
.build())
.build();
Orchestra il prompt con Gemini
L'input del prompt e la specifica dell'API vengono inviati a Gemini:
// Add the function to a "tool"
Tool tool = Tool.newBuilder()
.addFunctionDeclarations(functionDeclaration)
.build();
// Invoke the Gemini model with the use of the tool to generate the API parameters from the prompt input.
GenerativeModel model = GenerativeModel.newBuilder()
.setModelName(modelName)
.setVertexAi(vertexAI)
.setTools(Arrays.asList(tool))
.build();
GenerateContentResponse response = model.generateContent(promptText);
Content responseJSONCnt = response.getCandidates(0).getContent();
La risposta da questo è il file JSON dei parametri orchestrati nell'API. Di seguito è riportato un output di esempio:
role: "model"
parts {
function_call {
name: "getAddress"
args {
fields {
key: "latlng"
value {
string_value: "40.714224,-73.961452"
}
}
}
}
}
Passa il seguente parametro all'API Reverse Geocoding
: "latlng=40.714224,-73.961452"
Abbina il risultato orchestrato al formato "latlng=VALUE"
.
Richiamare l'API
Di seguito è riportata la sezione del codice che richiama l'API:
// Create a request
String url = API_STRING + "?key=" + API_KEY + params;
java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
// Send the request and get the response
java.net.http.HttpResponse<String> httpresponse = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString());
// Save the response
String jsonResult = httpresponse.body().toString();
La stringa jsonResult
contiene la risposta dell'API Geocoding inversa. Di seguito è riportata una versione formattata dell'output:
"...277 Bedford Ave, Brooklyn, NY 11211, USA; 279 Bedford Ave, Brooklyn, NY 11211, USA; 277 Bedford Ave, Brooklyn, NY 11211, USA;..."
Elaborare la risposta dell'API e preparare il prompt
Il seguente codice elabora la risposta dall'API e prepara il prompt con istruzioni su come elaborare la risposta:
// Provide an answer to the model so that it knows what the result
// of a "function call" is.
String promptString =
"You are an AI address standardizer for assisting with standardizing addresses accurately. Your job is to give the accurate address in the standard format as a JSON object containing the fields DOOR_NUMBER, STREET_ADDRESS, AREA, CITY, TOWN, COUNTY, STATE, COUNTRY, ZIPCODE, LANDMARK by leveraging the address string that follows in the end. Remember the response cannot be empty or null. ";
Content content =
ContentMaker.fromMultiModalData(
PartMaker.fromFunctionResponse(
"getAddress",
Collections.singletonMap("address", formattedAddress)));
String contentString = content.toString();
String address = contentString.substring(contentString.indexOf("string_value: \"") + "string_value: \"".length(), contentString.indexOf('"', contentString.indexOf("string_value: \"") + "string_value: \"".length()));
List<SafetySetting> safetySettings = Arrays.asList(
SafetySetting.newBuilder()
.setCategory(HarmCategory.HARM_CATEGORY_HATE_SPEECH)
.setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH)
.build(),
SafetySetting.newBuilder()
.setCategory(HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT)
.setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH)
.build()
);
Richiama Gemini e restituisci l'indirizzo standardizzato
Il seguente codice passa l'output elaborato del passaggio precedente come prompt a Gemini:
GenerativeModel modelForFinalResponse = GenerativeModel.newBuilder()
.setModelName(modelName)
.setVertexAi(vertexAI)
.build();
GenerateContentResponse finalResponse = modelForFinalResponse.generateContent(promptString + ": " + address, safetySettings);
System.out.println("promptString + content: " + promptString + ": " + address);
// See what the model replies now
System.out.println("Print response: ");
System.out.println(finalResponse.toString());
String finalAnswer = ResponseHandler.getText(finalResponse);
System.out.println(finalAnswer);
La variabile finalAnswer
ha l'indirizzo standardizzato in formato JSON. Di seguito è riportato un output di esempio:
{"replies":["{ \"DOOR_NUMBER\": null, \"STREET_ADDRESS\": \"277 Bedford Ave\", \"AREA\": \"Brooklyn\", \"CITY\": \"New York\", \"TOWN\": null, \"COUNTY\": null, \"STATE\": \"NY\", \"COUNTRY\": \"USA\", \"ZIPCODE\": \"11211\", \"LANDMARK\": null} null}"]}
Ora che hai capito come funziona la chiamata di funzione di Gemini con il caso d'uso di standardizzazione degli indirizzi, puoi procedere con il deployment della funzione Cloud Functions.
7. Deployment e test
- Se hai già creato il progetto GeminiFunctionCalling e implementato la funzione Cloud Functions, vai al passaggio 2. Se non hai creato il progetto, vai al terminale Cloud Shell e clona questo repository:
git clone
https://github.com/AbiramiSukumaran/GeminiFunctionCalling - Vai alla cartella del progetto:
cd GeminiFunctionCalling
- Esegui questa istruzione per creare ed eseguire il deployment della funzione Cloud Functions:
gcloud functions deploy gemini-fn-calling --gen2 --region=us-central1 --runtime=java11 --source=. --entry-point=cloudcode.helloworld.HelloWorld --trigger-http
Di seguito è riportato il formato URL dopo il deployment: https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/gemini-fn-calling
- Testa la funzione Cloud Functions eseguendo questo comando dal terminale:
gcloud functions call gemini-fn-calling --region=us-central1 --gen2 --data '{"calls":[["40.714224,-73.961452"]]}'
Di seguito è riportata una risposta a un prompt di esempio casuale: '{"replies":["{ "DOOR_NUMBER": "277", "STREET_ADDRESS": "Bedford Ave", "AREA": null, "CITY": "Brooklyn", "TOWN": null, "COUNTY": "Kings County", "STATE": "NY", "COUNTRY": "USA", "ZIPCODE": "11211", "LANDMARK": null}}```"]}'
8. Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo post, segui questi passaggi:
- Nella console Google Cloud, vai alla pagina Gestisci risorse.
- Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
- Nella finestra di dialogo, digita l'ID progetto, quindi fai clic su Chiudi per eliminare il progetto.
- Se vuoi conservare il progetto, salta i passaggi precedenti ed elimina la funzione Cloud Functions accedendo a Cloud Functions e, nell'elenco delle funzioni, seleziona la funzione che vuoi eliminare e fai clic su ELIMINA.
9. Complimenti
Complimenti Hai utilizzato con successo la funzionalità di chiamata di funzione di Gemini in un'applicazione Java e hai trasformato un'attività di IA generativa in un processo deterministico e affidabile. Per saperne di più sui modelli disponibili, consulta la documentazione del prodotto LLM Vertex AI.