1. Introdução
Os modelos de IA generativa são notáveis em entender e responder à linguagem natural. Mas e se você precisar de resultados precisos e previsíveis para tarefas críticas como a padronização de endereços? Os modelos generativos tradicionais podem, às vezes, fornecer respostas diferentes em momentos distintos para os mesmos comandos, o que pode levar a inconsistências. É aí que o recurso de chamada de função do Gemini se destaca, permitindo que você controle deterministamente os elementos da resposta da IA.
Este codelab ilustra esse conceito com o caso de uso de preenchimento de endereço e padronização. Para isso, vamos criar uma função do Cloud em Java que realiza as seguintes tarefas:
- Usa coordenadas de latitude e longitude
- Chama a API Geocoding do Google Maps para receber endereços correspondentes
- Usa o recurso de chamada de função do Gemini 1.0 Pro para padronizar e resumir de maneira determinista esses endereços em um formato específico necessário.
Vamos ao que interessa!
2. Chamada de função do Gemini
A chamada de função do Gemini se destaca na era da IA generativa porque permite combinar a flexibilidade dos modelos de linguagem generativa com a precisão da programação tradicional.
Confira as tarefas que você precisa concluir para implementar a chamada de função do Gemini:
- Definir funções: descreva as funções com clareza. As descrições precisam incluir as seguintes informações:
- O nome da função, como
getAddress
. - Os parâmetros que a função espera, por exemplo,
latlng
como uma string. - O tipo de dados que a função retorna, como uma lista de strings de endereço.
- Criar ferramentas para o Gemini: agrupe descrições de funções na forma de especificação da API em ferramentas. Pense em uma ferramenta como uma caixa de ferramentas especializada que o Gemini pode usar para entender a funcionalidade de uma API.
- Orquestrar APIs usando o Gemini: quando você envia um comando ao Gemini, ele pode analisar sua solicitação e reconhecer onde pode usar as ferramentas fornecidas. O Gemini atua como um orquestrador inteligente, realizando as seguintes tarefas:
- Gera os parâmetros de API necessários para chamar suas funções definidas. O Gemini não chama a API em seu nome. Chame a API com base nos parâmetros e na assinatura que a chamada de função do Gemini gerou para você.
- O Gemini processa os resultados alimentando os resultados das chamadas de API de volta na geração e incorpora informações estruturadas na resposta final. É possível processar essas informações da maneira que você quiser para seu aplicativo.
A imagem abaixo mostra o fluxo de dados, as etapas envolvidas na implementação e o proprietário de cada etapa, como aplicativo, LLM ou API:
O que você vai criar
Você criará e implantará uma função do Cloud em Java que faz o seguinte:
- Usa coordenadas de latitude e longitude.
- Chama a API Geocoding do Google Maps para receber os endereços correspondentes.
- Usa o recurso de chamada de função do Gemini 1.0 Pro para padronizar e resumir de forma determinista esses endereços em um formato específico.
3. Requisitos
4. Antes de começar
- No console do Google Cloud, na página de seletor de projetos, selecione ou crie um projeto do Google Cloud.
- Verifique se o faturamento está ativado para seu projeto do Google Cloud. Saiba como verificar se o faturamento está ativado em um projeto.
- Ative o Cloud Shell no console do Google Cloud. Para mais informações, consulte Usar o Cloud Shell.
- Se o projeto não estiver definido, use o seguinte comando para configurá-lo:
gcloud config set project <YOUR_PROJECT_ID>
- No Cloud Shell, defina as seguintes variáveis de ambiente:
export GCP_PROJECT=<YOUR_PROJECT_ID>
export GCP_REGION=us-central1
- Execute os comandos a seguir no Cloud Shell para ativar as APIs do Google Cloud necessárias:
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
- Abra o editor do Cloud Shell, clique em Extensões e instale a extensão Gemini + Google Cloud Code.
5. Implementar a função do Cloud
- Inicie o editor do Cloud Shell
- Clique em Cloud Code e expanda a seção Cloud Functions.
- Clique no ícone Criar função (+).
- Na caixa de diálogo Create New Application, selecione a opção Java: Hello World.
- Dê um nome ao projeto no caminho dele, como GeminiFunctionCalling.
- Clique em Explorer para ver a estrutura do projeto e abra o arquivo pom.xml. A imagem abaixo mostra a estrutura do projeto:
- Adicione as dependências necessárias na tag
<dependencies>... </dependencies>
no arquivopom.xml
. Você pode acessar todo opom.xml
no repositório do GitHub deste projeto. Copie o pom.xml de lá para o arquivopom.xml
do projeto atual que você está editando. - Copie a classe
HelloWorld.java
do link GeminiFunctionCalling github. AtualizeAPI_KEY
eproject_id
com sua chave de API de geocodificação e o ID do projeto do Google Cloud, respectivamente.
6. Entender a chamada de função usando a classe HelloWorld.java
Entrada do comando
Neste exemplo, este é o comando de entrada: What's the address for the latlong value 40.714224,-73.961452.
Confira a seguir o snippet de código correspondente ao comando de entrada no arquivo:
String promptText = "What's the address for the latlong value '" + latlngString + "'?"; //40.714224,-73.961452
Especificação da API
A API Reverse Geocoding é usada neste exemplo. Confira a seguir a especificação da 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();
Orquestrar o comando com o Gemini
A entrada do comando e a especificação da API são enviadas ao 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();
A resposta são os parâmetros orquestrados JSON para a API. Confira um exemplo de saída:
role: "model"
parts {
function_call {
name: "getAddress"
args {
fields {
key: "latlng"
value {
string_value: "40.714224,-73.961452"
}
}
}
}
}
Transmita o seguinte parâmetro para a API Reverse Geocoding
: "latlng=40.714224,-73.961452"
Combine o resultado orquestrado com o formato "latlng=VALUE"
.
Invocar a API
Veja a seguir a seção do código que invoca a 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();
A string jsonResult
contém a resposta da API Geocoding inversa. Confira a seguir uma versão formatada da saída:
"...277 Bedford Ave, Brooklyn, NY 11211, USA; 279 Bedford Ave, Brooklyn, NY 11211, USA; 277 Bedford Ave, Brooklyn, NY 11211, USA;..."
Processar a resposta da API e preparar o comando
O código abaixo processa a resposta da API e prepara o comando com instruções:
// 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()
);
Invocar o Gemini e retornar o endereço padronizado
O código abaixo transmite a saída processada da etapa anterior como um comando para o 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);
A variável finalAnswer
tem o endereço padronizado no formato JSON. Confira abaixo um exemplo de saída:
{"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}"]}
Agora que você entendeu como a chamada de função do Gemini funciona com o caso de uso de padronização de endereços, é hora de implantar a função do Cloud.
7. Implantar e testar
- Se você já criou o projeto GeminiFunctionCalling e implementou a função do Cloud, prossiga para a etapa 2. Se você não criou o projeto, acesse o terminal do Cloud Shell e clone este repositório:
git clone
https://github.com/AbiramiSukumaran/GeminiFunctionCalling - Navegue até a pasta do projeto:
cd GeminiFunctionCalling
- Execute a seguinte instrução para criar e implantar a função do Cloud:
gcloud functions deploy gemini-fn-calling --gen2 --region=us-central1 --runtime=java11 --source=. --entry-point=cloudcode.helloworld.HelloWorld --trigger-http
Este é o formato do URL após a implantação: https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/gemini-fn-calling
- Execute o comando a seguir no terminal para testar a função do Cloud:
gcloud functions call gemini-fn-calling --region=us-central1 --gen2 --data '{"calls":[["40.714224,-73.961452"]]}'
Veja a seguir uma resposta para um comando de amostra aleatório: '{"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. Limpar
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados nesta postagem, siga estas etapas:
- No console do Google Cloud, acesse a página Gerenciar recursos.
- Na lista de projetos, selecione o projeto que você quer excluir e clique em "Excluir".
- Na caixa de diálogo, digite o ID do projeto e clique em "Encerrar" para excluí-lo.
- Se quiser manter seu projeto, pule as etapas acima e exclua a função do Cloud. Para isso, acesse o Cloud Functions e, na lista de funções, marque a que você quer excluir e clique em EXCLUIR.
9. Parabéns
Parabéns! Você usou o recurso de chamada de função do Gemini em um aplicativo Java e transformou uma tarefa de IA generativa em um processo determinista e confiável. Para saber mais sobre os modelos disponíveis, consulte a documentação do produto LLM da Vertex AI.