1. Introdução
Você gosta de ler livros, mas tem dificuldade em escolher um entre tantas opções? Imagine ter um app com tecnologia de IA que recomenda a leitura perfeita e oferece um resumo conciso com base no gênero escolhido, apresentando um pouco da essência do livro. Neste codelab, vou mostrar como criar um app assim usando o BigQuery e o Cloud Functions com tecnologia do Gemini.
Visão geral do projeto
Nosso caso de uso foca estes quatro componentes principais:
- Banco de dados de livros: o vasto conjunto de dados públicos do BigQuery de livros arquivados da Internet vai servir como nosso catálogo abrangente.
- Mecanismo de resumo de IA: o Cloud Functions, equipado com o modelo de linguagem Gemini Pro, vai gerar resumos práticos de acordo com os pedidos dos usuários.
- Integração com o BigQuery: uma função remota no BigQuery que chama a função do Cloud para entregar resumos e temas de livros sob demanda.
- Interface do usuário: um app da Web hospedado no Cloud Run que vai oferecer um aplicativo da Web para que os usuários vejam os resultados.
Vamos dividir a implementação em três codelabs:
Codelab 1: usar o Gemini para criar uma função do Cloud em Java para um aplicativo do Gemini.
Codelab 2: use o Gemini para criar aplicativos de IA generativa somente de SQL com o BigQuery.
Codelab 3: use o Gemini para criar um aplicativo da Web em Java do Spring Boot que interage com o BigQuery.
2. Use o Gemini para criar um app de IA generativa sem servidor na função Java Cloud
O que você vai criar
Você vai criar um
- Aplicativo do Cloud Functions em Java que implementa o Gemini 1.0 Pro para receber um comando específico como entrada na forma de matriz JSON e retorna uma resposta (valor JSON rotulado como "replies").
- Você vai realizar as etapas de criação e implantação com a ajuda do Gemini
3. Requisitos
- Use um navegador, como o Chrome ou o Firefox.
- Tenha um projeto do Google Cloud com o faturamento ativado.
Confira abaixo os pré-requisitos:
Criar seu projeto
- No console do Google Cloud, na página de seletor de projetos, selecione ou crie um projeto do Google Cloud.
- Confira se o faturamento está ativado para seu projeto do Cloud. Saiba como verificar se o faturamento está ativado em um projeto.
Ativar o Cloud Shell
- Você vai usar o Cloud Shell, um ambiente de linha de comando executado no Google Cloud que vem pré-carregado com bq:
No console do Cloud, clique em Ativar o Cloud Shell no canto superior direito:
- Depois de se conectar ao Cloud Shell, você vai ver que sua conta já está autenticada e que o projeto está configurado com seu ID do projeto. Execute o seguinte comando no Cloud Shell para confirmar se a conta está autenticada:
gcloud auth list
- Execute o comando a seguir no Cloud Shell para confirmar se o comando gcloud sabe sobre seu projeto.
gcloud config list project
- Se o projeto não estiver definido, use este comando:
gcloud config set project <YOUR_PROJECT_ID>
Consulte a documentação para ver o uso e os comandos gcloud.
4. Como ativar o Gemini para Google Cloud e as APIs necessárias
Ativar o Gemini
- Acesse o Gemini para Google Cloud no Marketplace para ativar a API. Também é possível usar o seguinte comando:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- Acesse a página do Gemini e clique em "Iniciar conversa".
Importante: siga as etapas 1 e 2 deste codelab para começar a usar o Gemini e ativá-lo no ambiente de desenvolvimento integrado do Cloud Shell, respectivamente.
Ativar outras APIs necessárias
Como podemos fazer isso? Vamos perguntar para o Gemini. Mas, antes disso, não se esqueça:
LLMs não são determinísticos. Por isso, ao testar esses comandos, a resposta que você recebe pode ser diferente das mostradas na captura de tela.
Para acessar o console de conversa no Gemini, clique no ícone "Abrir Gemini" no canto superior direito, ao lado da barra de pesquisa no console do Google Cloud.
Digite esta pergunta na seção "Insira um comando aqui":
How do I enable the cloud functions api using a gcloud command?
Você receberá uma resposta semelhante a:
gcloud services enable cloudfunctions.googleapis.com
Copie (use o ícone de cópia na parte de cima do snippet de comando) e execute isso no terminal do Cloud Shell para ativar o Cloud Functions. Faça o mesmo para o Cloud Run, porque precisamos dos dois para criar e implantar o Cloud Functions:
gcloud services enable \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com
5. Como preparar um modelo do Cloud Functions com o Gemini
Neste ponto, suponho que você já tenha ativado o Gemini no seu ambiente de desenvolvimento integrado do Cloud Shell.
Para abrir o editor do Cloud Shell, clique no ícone "Abrir editor" no canto superior direito do terminal do Cloud Shell. Geralmente, prefiro abrir o terminal e o editor em duas guias paralelas para escrever o código em uma e desenvolver em outra.
Depois de abrir o editor, confira se o logotipo do Gemini no canto inferior direito do console do editor está ativo (e não cancelado). Verifique também se o projeto do Google Cloud no canto inferior esquerdo aponta para o projeto ativo em que você quer trabalhar. Se estiverem inativos, clique neles, autorize, selecione o projeto do Google Cloud que você quer apontar e faça a ativação.
Quando ambos estiverem ativos, clique no nome do projeto no canto inferior esquerdo. Na lista pop-up chamada "Cloud Code", role para baixo até "Novo aplicativo".
Nessa lista, selecione o aplicativo do Cloud Functions. Na lista exibida, selecione Java:
Na lista resultante, digite o nome do projeto "duetai-gemini-calling" em vez de helloworld e clique em OK.
Oba! Você inicializou um aplicativo simples do Cloud Functions em Java com o Gemini e não fez muito mais do que ativar e definir configurações, concorda?
Esta deve ser a estrutura do projeto:
Agora você já pode implantar a função. Mas não foi por isso que começamos. Vamos criar a implementação da API Gemini Pro nesta função do Cloud usando o SDK Java.
Agora vamos criar a funcionalidade para nosso caso de uso, que é invocar o modelo Gemini Pro nesta função do Cloud. Para isso, você pode adicionar mais comandos e desenvolver seu código incrementalmente com o Gemini ou escrever a lógica por conta própria. Vou combinar as duas opções.
6. Adicione dependências
No console de chat do Gemini (aquele no Cloud Code Editor no painel à esquerda), digite o seguinte comando:
what is the maven dependency for com.google.cloud.vertexai library
Estou pedindo especificamente o pacote com.google.cloud.vertexai porque é o que estou usando no meu código-fonte, onde implemento o código de invocação do Gemini.
Recebi este resultado:
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-vertexai</artifactId>
<version>0.1.0</version>
</dependency>
Copie e cole no arquivo pom.xml, antes da tag </dependencies>. Substitua a versão por 0.1.0. Você pode remover a tag <version> se estiver usando a BOM do Spring Cloud GCP para gerenciar os números de versão do spring-cloud-gcp.
A seção de dependência vai ficar assim:
Atualize os números de versão, se necessário, para corresponder ao exemplo acima. Também incluí outra dependência:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10</version>
</dependency>
7. Modificar o ponto de entrada da função e o nome da classe
- Navegue até o arquivo "launch.json" na pasta ".vscode". Edite o nome da função de "function-hello-world" para "function-gemini-calling".
- Atualize o valor de entryPoint de "cloudcode.helloworld.HelloWorld para cloudcode.bookshelf.Bookshelf.
- Agora navegue até o arquivo de classe Java "HelloWorld.java". Mude o nome do pacote para "package cloudcode.bookshelf". No erro que aparece, clique na lâmpada amarela e na opção "Move HelloWorld.java" para "package cloudcode.bookshelf".
- Atualize o nome da classe para Bookshelf e, no erro exibido, clique na pequena lâmpada amarela e selecione "Renomear arquivo como Bookshelf.java". Selecione essa opção.
8. Criar o método que chama o Gemini Pro
Vamos implementar essa funcionalidade na classe Bookshelf.java. Substitua o Bookshelf.java pelo código abaixo:
package cloudcode.bookshelf;
import java.io.BufferedWriter;
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.GenerationConfig;
import com.google.cloud.vertexai.generativeai.preview.GenerativeModel;
import com.google.cloud.vertexai.generativeai.preview.ResponseHandler;
import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import java.util.LinkedHashMap;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
public class Bookshelf implements HttpFunction {
private static final Gson gson = new Gson();
@Override
public void service(HttpRequest request, HttpResponse response) throws Exception {
BufferedWriter writer = response.getWriter();
// Get the request body as a JSON object.
JsonObject requestJson = new Gson().fromJson(request.getReader(), JsonObject.class);
JsonArray calls_array = requestJson.getAsJsonArray("calls");
JsonArray calls = (JsonArray) calls_array.get(0);
String context = calls.get(0).toString().replace("\"", "");
//Invoke Gemini model
String raw_result = callGemini(context);
raw_result = raw_result.replace("\n","");
String trimmed = raw_result.trim();
List<String> result_list = Arrays.asList(trimmed);
Map<String, List<String>> stringMap = new LinkedHashMap<>();
stringMap.put("replies", result_list);
// Serialization
String return_value = gson.toJson(stringMap);
writer.write(return_value);
}
public String callGemini(String context) throws IOException{
String res = "";
try (VertexAI vertexAi = new VertexAI("REPLACE_WITH_YOUR_PROJECT_ID", "us-central1"); ) {
GenerationConfig generationConfig =
GenerationConfig.newBuilder()
.setMaxOutputTokens(2048)
.setTemperature(0.4F)
.setTopK(32)
.setTopP(1)
.build();
GenerativeModel model = new GenerativeModel("gemini-pro", generationConfig, vertexAi);
GenerateContentResponse response = model.generateContent(context);
res = ResponseHandler.getText(response);
}catch(Exception e){
System.out.println(e);
}
return res;
}
}
Essa classe espera uma entrada na estrutura JSON, como abaixo:
{ "calls": [["YOUR_PROMPT_HERE"]] }
Ele retorna uma resposta como esta:
(Json) Map<String, List<String>> {"replies": ["response"]}
Teste a opção de chat do Gemini no editor do Cloud Shell no painel à esquerda para explicar o código. Se preferir, selecione todo o código, clique na lâmpada amarela no canto superior esquerdo da seleção e escolha a opção "Explicar".
9. Implante a Função do Cloud
Agora que a função do Cloud está pronta, vamos perguntar ao Gemini como implantá-la. Acesse a conversa do Gemini no editor do Cloud Code e digite o seguinte:
How to deploy this Cloud Function with a gcloud command?
Recebi a seguinte resposta:
Agora eu queria investigar mais. Então, pedi para o Gemini me dar o comando completo de implantação de funções do gcloud. A resposta é mostrada abaixo:
Agora não posso dizer se você vai receber a mesma resposta, mas achei interessante ver que ele traz mais alguns detalhes para minha surpresa, como mostra a imagem abaixo:
Formato do corpo da solicitação:
e
Formato da resposta:
Agora, vamos implantar a função executando o comando gcloud que o Gemini nos deu. Para isso, precisamos abrir o terminal do Cloud Shell. Abra https://console.cloud.google.com em uma nova guia e verifique se o projeto certo está selecionado. Para abrir o terminal do Cloud Shell, clique no ícone "Ativar o Cloud Shell" no canto superior direito do console e use o comando abaixo para verificar se você está na pasta de projeto correta:
cd duetai-gemini-calling
Seguido pelo comando abaixo:
gcloud functions deploy bookshelf --runtime java17 --trigger-http --entry-point cloudcode.bookshelf.Bookshelf --allow-unauthenticated
Ele vai perguntar "Permitir invocações não autenticadas da nova função [bookshelf]?" Diga "y" e pressione Enter. Depois disso, algumas perguntas, se aplicável, e a função Cloud sem servidor será implantada com o URL implantado: https://us-central1-*******.cloudfunctions.net/bookshelf.
Agora, vamos invocar o Cloud Functions implantado e testá-lo.
Observação: se você pular a pergunta "Permitir invocações não autenticadas" ou selecionar "N", não será possível acessar o resultado das Funções do Cloud e você vai receber uma mensagem de "erro de permissões" sem conceder outras configurações do IAM. Então preste atenção nisso.
10. Chamar a função do Cloud implantada
Vamos perguntar para o Gemini. Eu inseri o comando
How to call the deployed cloud function?
Recebi o resultado abaixo: (Você pode ou não receber a mesma resposta. Sinta-se à vontade para brincar com o comando e conferir a diferença nas respostas).
Faça perguntas específicas no chat sobre formas alternativas de invocar a função implantada, chamá-la usando o comando gcloud etc. Enviei o comando abaixo:
how to call the deployed cloud function using gcloud
Recebi a resposta abaixo:
É possível usar essa resposta ("comando "gcloud functions call") no terminal com ajustes para que ela funcione no nosso cenário. Como alternativa, tente transmitir os parâmetros no próprio comando e conferir se você consegue receber a chamada detalhada de funções do gcloud em resposta:
gcloud functions call bookshelf --region=us-central1 --gen2 --data '{"calls":[["Hello! This is my test prompt."]]}'
Confira meu resultado:
11. Limpar
É possível excluir o Cloud Functions criado anteriormente clicando no botão "EXCLUIR" na página de detalhes do Cloud Functions.
12. Parabéns
Você criou, implantou e testou uma função do Cloud em Java para chamar o Gemini 1.0 Pro usando o Gemini. Este aplicativo usa a solicitação de entrada relacionada à recomendação de livros com o resumo e o tema dos livros.