1. Bem-vindo, desenvolvedor do Gemini!

Neste codelab, você vai aprender a criar aplicativos de IA de próxima geração em Java usando o SDK de interações do Gemini personalizado.
O que é a API Gemini Interactions?
As APIs de LLM tradicionais são sem estado e orientadas por solicitação-resposta. Para criar um assistente de chat com conversa multiturno ou um loop agêntico complexo, os desenvolvedores historicamente precisaram gerenciar o estado da conversa, o truncamento do histórico, a orquestração de chamadas de ferramentas e os loops de execução totalmente no código do aplicativo do lado do cliente.
A API Gemini Interactions transfere essa complexidade para o servidor. É uma API com estado e baseada em sessão em que a infraestrutura do Google hospeda e gerencia o gráfico de conversas. Uma única interação representa uma sessão com estado. Ao interagir com ela, a API retorna uma linha do tempo estruturada e avançada composta por etapas polimórficas, como:
ThoughtStep: o processo de raciocínio interno do modelo.ModelOutputStep: conteúdo de texto, áudio ou imagem gerado pelo modelo.ToolCallStepeToolResultStep: invocações de ferramentas iniciadas pelo sistema ou pelo modelo.UserInteractionStep: pontos em que o sistema pausa para solicitar entrada ou aprovação humana.
O que são agentes gerenciados?
Orquestrar agentes autônomos (processar loops, lógica de repetição, ambientes de execução de ferramentas e gerenciamento de estado) é notoriamente difícil.
Os agentes gerenciados são uma solução de plataforma fornecida pela API Gemini Interactions. Em vez de executar loops de agente localmente, você pode provisionar agentes especializados diretamente na infraestrutura do Google:
- Agentes integrados: agentes especializados prontos para uso, como o agente Deep Research, que realiza pesquisas na Web de várias etapas, agrega descobertas e gera relatórios abrangentes.
- Agentes gerenciados personalizados: entidades autônomas definidas por você. Você fornece instruções do sistema, anexa ferramentas (como a Pesquisa Google ou um ambiente de execução do Bash) e configura um sandbox do Cloud , um ambiente de execução seguro, isolado e em contêineres com regras de saída de rede personalizáveis (por exemplo, permitindo acesso apenas a domínios específicos, como o GitHub).
Ao usar o SDK de interações do Gemini para Java, você pode inicializar, coordenar e colaborar facilmente com esses agentes gerenciados em aplicativos Java padrão.
O que você vai aprender
- Como navegar pela nova arquitetura polimórfica baseada em
Step. - Como transmitir áudio TTS expressivo diretamente para alto-falantes.
- Como gerar músicas (MP3 + letras) com o Lyria.
- Como gerar sketchnotes visuais com o Gemini 3 Pro para imagens.
- Como orientar o agente Deep Research usando o planejamento colaborativo.
- Como provisionar um agente personalizado com regras e ferramentas de saída de rede.
O que é necessário
- Java 21 ou mais recente.
- Apache Maven.
- Um editor de texto ou ambiente de desenvolvimento integrado (IntelliJ IDEA, VS Code etc.).
- Uma chave da API Gemini (do Google AI Studio).
2. Configuração: projeto e chave de API
Criar projeto Maven
Inicialize um novo projeto Maven no terminal usando o seguinte comando:
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=gemini-interactions-demo \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.5 \
-DinteractiveMode=false
Navegue até o diretório do projeto recém-criado:
cd gemini-interactions-demo
Abra o arquivo pom.xml e configure-o:
- Atualize as propriedades da versão do Java para direcionar o Java 21:
<properties> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> </properties> - Adicione a dependência do SDK dentro do
bloco:<dependency> <groupId>io.github.glaforge</groupId> <artifactId>gemini-interactions-api-sdk</artifactId> <version>0.10.1</version> </dependency>
Configurar chave de API
Receba uma chave da API Gemini do Google AI Studio.
Defina a chave como uma variável de ambiente no terminal:
macOS / Linux:
export GEMINI_API_KEY="your_actual_api_key"
Windows (prompt de comando):
set GEMINI_API_KEY="your_actual_api_key"
3. Hello World: como navegar pela arquitetura de etapas
A API Interactions introduziu uma arquitetura de linha do tempo polimórfica baseada em etapas. Em vez de retornar uma lista simples de saídas, a API retorna uma sequência de objetos Step digitados (por exemplo, ModelOutputStep, ThoughtStep, FunctionCallStep).
Nesta etapa, você vai escrever uma interação simples para entender como extrair a saída final do modelo dessa estrutura.
Criar HelloInteractions.java
Crie o arquivo src/main/java/com/example/HelloInteractions.java com o seguinte conteúdo:
package com.example;
import io.github.glaforge.gemini.interactions.GeminiInteractionsClient;
import io.github.glaforge.gemini.interactions.model.*;
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
public class HelloInteractions {
public static void main(String[] args) {
// 1. Initialize the client
GeminiInteractionsClient client = GeminiInteractionsClient.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.build();
// 2. Build the request
ModelInteractionParams request = ModelInteractionParams.builder()
.model("gemini-3.5-flash")
.input("Explain the difference between a library and a framework in one sentence.")
.build();
// 3. Send request
Interaction response = client.create(request);
// 4. Navigate the step-based architecture to get the output
response.steps().stream()
.filter(step -> step instanceof Step.ModelOutputStep)
.map(step -> (Step.ModelOutputStep) step)
.findFirst()
.ifPresent(step -> System.out.println(step.content().get(0)));
}
}
Executar o código
Compile e execute a classe:
mvn compile exec:java -Dexec.mainClass=com.example.HelloInteractions
4. Áudio direcionável: streaming de TTS expressivo
O Gemini 3.1 Flash apresenta a conversão de texto em voz (TTS, na sigla em inglês) direcionável. Você pode controlar o ritmo, o tom e o ambiente da voz usando comandos e usar tags emocionais (como [excitedly] ou [whispers]) no meio da frase.
Nesta etapa, você vai gerar áudio expressivo e transmiti-lo diretamente para os alto-falantes.
Criar StreamingDJ.java
Crie o arquivo src/main/java/com/example/StreamingDJ.java com o seguinte conteúdo:
package com.example;
import io.github.glaforge.gemini.interactions.GeminiInteractionsClient;
import io.github.glaforge.gemini.interactions.model.*;
import io.github.glaforge.gemini.interactions.model.Config.SpeechConfig;
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
import javax.sound.sampled.*;
import java.util.Base64;
import java.util.stream.Stream;
public class StreamingDJ {
public static void main(String[] args) throws Exception {
GeminiInteractionsClient client = GeminiInteractionsClient.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.build();
// Prompt defining the voice profile and emotional tags
String prompt = """
# AUDIO PROFILE: Jaz R.
## THE SCENE: London Studio
### DIRECTOR'S NOTES
Accent: Jaz is a DJ from Brixton, London.
Style: Bouncy, energetic, high-speed delivery.
#### TRANSCRIPT
[excitedly] Yes, massive vibes in the studio!
[whispers] But keep it down, the boss is coming...
[shouting] Turn this up! Let's go!
""";
ModelInteractionParams request = ModelInteractionParams.builder()
.model("gemini-3.1-flash-tts-preview")
.input(prompt)
.responseModalities(Interaction.Modality.AUDIO)
.speechConfig(new SpeechConfig("Algenib", "en-GB"))
.stream(true) // Enable streaming
.build();
System.out.println("Streaming audio from Gemini...");
try (Stream<Events> eventStream = client.stream(request)) {
// Configure the Java Audio System for 24kHz Mono 16-bit PCM
AudioFormat format = new AudioFormat(24000, 16, 1, true, false);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try (SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info)) {
line.open(format);
line.start();
// Process the stream and play audio chunks as they arrive
eventStream.forEach(event -> {
if (event instanceof Events.StepDelta cd && cd.delta() instanceof Events.AudioDelta audioDelta) {
byte[] audioData = Base64.getDecoder().decode(audioDelta.data());
line.write(audioData, 0, audioData.length);
}
});
line.drain();
}
}
}
}
Executar o código
mvn compile exec:java -Dexec.mainClass=com.example.StreamingDJ
Ouvir a saída
Confira um exemplo de áudio do que você vai ouvir ao executar o código (usando a voz Algenib com tags emocionais):
5. Geração de música com o Lyria 3
Usando o modelo DeepMind Lyria 3, você pode gerar músicas e jingles. Ao solicitar modalidades de resposta dupla (AUDIO e TEXT), é possível recuperar o áudio gerado (MP3) e a letra da música.
Criar MusicGenerator.java
Crie o arquivo src/main/java/com/example/MusicGenerator.java com o seguinte conteúdo:
package com.example;
import io.github.glaforge.gemini.interactions.GeminiInteractionsClient;
import io.github.glaforge.gemini.interactions.model.*;
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
import io.github.glaforge.gemini.interactions.model.Content.AudioContent;
import java.nio.file.Files;
import java.nio.file.Paths;
public class MusicGenerator {
public static void main(String[] args) throws Exception {
GeminiInteractionsClient client = GeminiInteractionsClient.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.build();
ModelInteractionParams request = ModelInteractionParams.builder()
.model("models/lyria-3-clip-preview") // 30-second clip
.input("An uplifting rock song with acoustic guitars about coding in Java.")
.responseModalities(
Interaction.Modality.AUDIO,
Interaction.Modality.TEXT) // Request both MP3 and Lyrics
.build();
System.out.println("Generating music (this might take a moment)...");
Interaction response = client.create(request);
// 1. Print the lyrics (TEXT output)
System.out.println("\n--- Generated Lyrics ---");
response.steps().stream()
.filter(step -> step instanceof Step.ModelOutputStep)
.flatMap(step -> ((Step.ModelOutputStep) step).content().stream())
.filter(content -> content instanceof Content.TextContent)
.forEach(content -> System.out.println(((Content.TextContent) content).text()));
// 2. Save the MP3 (AUDIO output)
response.steps().stream()
.filter(step -> step instanceof Step.ModelOutputStep)
.flatMap(step -> ((Step.ModelOutputStep) step).content().stream())
.filter(content -> content instanceof AudioContent)
.map(content -> (AudioContent) content)
.findFirst()
.ifPresent(audio -> {
try {
Files.write(Paths.get("coding_song.mp3"), audio.data());
System.out.println("\nSuccess: Song saved to coding_song.mp3");
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
Executar o código
mvn compile exec:java -Dexec.mainClass=com.example.MusicGenerator
Ouvir a música gerada
Confira o arquivo MP3 gerado (coding_song.mp3) que contém a música e a letra:
6. Visualização com sketchnotes (Nano Banana Pro)
O Gemini 3 Pro para imagens (também conhecido como Nano Banana Pro) pode gerar imagens. Ao solicitar a modalidade IMAGE, é possível gerar infográficos, diagramas ou sketchnotes com base na entrada de texto.
Nesta etapa, você vai gerar um resumo de sketchnote de um artigo sobre agentes gerenciados e salvá-lo como um arquivo PNG.
Criar ImageGenerator.java
Crie o arquivo src/main/java/com/example/ImageGenerator.java com o seguinte conteúdo:
package com.example;
import io.github.glaforge.gemini.interactions.GeminiInteractionsClient;
import io.github.glaforge.gemini.interactions.model.*;
import io.github.glaforge.gemini.interactions.model.InteractionParams.ModelInteractionParams;
import io.github.glaforge.gemini.interactions.model.Content.ImageContent;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ImageGenerator {
public static void main(String[] args) throws Exception {
GeminiInteractionsClient client = GeminiInteractionsClient.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.build();
String articleSummary = """
Managed Agents in the Gemini API allow developers to run autonomous agents
that reason, plan, use tools, and execute code inside isolated cloud sandboxes.
The Gemini API handles the infrastructure (containers, network, runtime).
It is powered by the Antigravity agent running on Gemini 3.5 Flash.
The Java Interactions SDK supports these capabilities, utilizing a Step-based
architecture to model the execution timeline.
""";
ModelInteractionParams request = ModelInteractionParams.builder()
.model("gemini-3-pro-image-preview")
.input(String.format("""
Create a hand-drawn and hand-written sketchnote
style summary infographic, with a pure white background,
about the following information:
%s
""", articleSummary))
.responseModalities(Interaction.Modality.IMAGE) // Request IMAGE modality
.build();
System.out.println("Generating sketchnote (this might take a moment)...");
Interaction response = client.create(request);
// Save the generated image
response.steps().stream()
.filter(step -> step instanceof Step.ModelOutputStep)
.flatMap(step -> ((Step.ModelOutputStep) step).content().stream())
.filter(content -> content instanceof ImageContent)
.map(content -> (ImageContent) content)
.findFirst()
.ifPresent(image -> {
try {
Files.write(Paths.get("sketchnote.png"), image.data());
System.out.println("Success: Sketchnote saved to sketchnote.png");
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
Executar o código
mvn compile exec:java -Dexec.mainClass=com.example.ImageGenerator
Sketchnote gerado
Confira o sketchnote gerado (sketchnote.png) criado pelo modelo:

7. Agentes de direção: pesquisa detalhada colaborativa
O Deep Research é um agente avançado que pode executar tarefas de pesquisa de várias etapas. No entanto, em vez de executar imediatamente, você pode usar o planejamento colaborativo para revisar, modificar e direcionar o plano de pesquisa antes que o agente comece a coletar dados.
Você vai implementar uma conversa de várias conversas que usa o mesmo estado do lado do servidor (previousInteractionId) para refinar um plano.
Criar CollaborativeResearch.java
Crie o arquivo src/main/java/com/example/CollaborativeResearch.java com o seguinte conteúdo:
package com.example;
import io.github.glaforge.gemini.interactions.GeminiInteractionsClient;
import io.github.glaforge.gemini.interactions.model.*;
import io.github.glaforge.gemini.interactions.model.InteractionParams.AgentInteractionParams;
import io.github.glaforge.gemini.interactions.model.Config.DeepResearchAgentConfig;
import io.github.glaforge.gemini.interactions.model.Config.ThinkingSummaries;
import io.github.glaforge.gemini.interactions.model.Config.Visualization;
public class CollaborativeResearch {
public static void main(String[] args) throws Exception {
GeminiInteractionsClient client = GeminiInteractionsClient.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.build();
String agentModel = "deep-research-preview-04-2026";
// --- Phase 1: Request a Plan ---
System.out.println("Phase 1: Requesting research plan...");
AgentInteractionParams planParams = AgentInteractionParams.builder()
.agent(agentModel)
.input("Research the latest generations of Google Cloud TPUs (TPU7x and the 8th generation TPU 8t and TPU 8i).")
.agentConfig(new DeepResearchAgentConfig(
"deep-research",
ThinkingSummaries.AUTO,
Visualization.AUTO,
true // TRUE enables collaborative planning
))
.background(true)
.store(true)
.build();
Interaction planInteraction = client.create(planParams);
planInteraction = waitForCompletion(client, planInteraction.id());
System.out.println("\n--- Proposed Plan ---");
printOutputText(planInteraction);
// --- Phase 2: Refine the Plan ---
System.out.println("\nPhase 2: Refining research plan...");
AgentInteractionParams refineParams = AgentInteractionParams.builder()
.agent(agentModel)
.input("Focus on comparing the architectural, performance, and scaling differences between the TPU7x generation and the two flavors of the eighth generation: TPU 8t (optimized for training at scale) and TPU 8i (optimized for low-latency reasoning and inference).")
.agentConfig(new DeepResearchAgentConfig(
"deep-research",
ThinkingSummaries.AUTO,
Visualization.AUTO,
true // Keep collaborative planning TRUE to iterate
))
.previousInteractionId(planInteraction.id()) // Resume session
.background(true)
.store(true)
.build();
Interaction refinedInteraction = client.create(refineParams);
refinedInteraction = waitForCompletion(client, refinedInteraction.id());
System.out.println("\n--- Refined Plan ---");
printOutputText(refinedInteraction);
// --- Phase 3: Approve and Execute ---
System.out.println("\nPhase 3: Approving plan and starting deep research (this will take a few minutes)...");
AgentInteractionParams executeParams = AgentInteractionParams.builder()
.agent(agentModel)
.input("Plan looks good, execute!")
.agentConfig(new DeepResearchAgentConfig(
"deep-research",
ThinkingSummaries.AUTO,
Visualization.AUTO,
false // FALSE approves the plan and executes the research
))
.previousInteractionId(refinedInteraction.id()) // Resume session
.background(true)
.store(true)
.build();
Interaction finalReport = client.create(executeParams);
finalReport = waitForCompletion(client, finalReport.id());
System.out.println("\n--- Final Research Report ---");
printOutputText(finalReport);
}
private static Interaction waitForCompletion(GeminiInteractionsClient client, String id) throws Exception {
Interaction interaction = client.get(id);
while (interaction.status() != Interaction.Status.COMPLETED && interaction.status() != Interaction.Status.FAILED) {
Thread.sleep(5000);
interaction = client.get(id);
}
if (interaction.status() == Interaction.Status.FAILED) {
throw new RuntimeException("Interaction failed. Status: " + interaction.status());
}
return interaction;
}
private static void printOutputText(Interaction interaction) {
interaction.steps().stream()
.filter(step -> step instanceof Step.ModelOutputStep)
.flatMap(step -> ((Step.ModelOutputStep) step).content().stream())
.filter(content -> content instanceof Content.TextContent)
.forEach(content -> System.out.println(((Content.TextContent) content).text()));
}
}
Executar o código
mvn compile exec:java -Dexec.mainClass=com.example.CollaborativeResearch
Saída do relatório gerado
O agente Deep Research vai produzir um relatório abrangente e estruturado. Confira o relatório completo gerado pela execução de exemplo aqui:
Confira o relatório gerado do Deep Research (tpu_history_report.md)
8. Agentes personalizados e sandboxes do Cloud
Para tarefas complexas de desenvolvedores, você pode provisionar agentes personalizados. Você define as instruções do sistema, equipa-os com ferramentas (como execução de código/Bash) e configura o ambiente remoto (como regras de saída de rede).
Nesta etapa, você vai provisionar um agente que tenha acesso seguro à Internet para github.com e instruí-lo a clonar um repositório e analisar os arquivos de configuração dentro do sandbox do Cloud.
Criar GitHubAnalyzer.java
Crie o arquivo src/main/java/com/example/GitHubAnalyzer.java com o seguinte conteúdo:
package com.example;
import io.github.glaforge.gemini.interactions.GeminiInteractionsClient;
import io.github.glaforge.gemini.interactions.model.*;
import io.github.glaforge.gemini.interactions.model.InteractionParams.AgentInteractionParams;
import java.util.List;
public class GitHubAnalyzer {
public static void main(String[] args) throws Exception {
GeminiInteractionsClient client = GeminiInteractionsClient.builder()
.apiKey(System.getenv("GEMINI_API_KEY"))
.build();
String agentId = "github-analyzer-codelab";
// 1. Define the Custom Agent with Network Egress and Tools
Agent customAgent = Agent.builder()
.id(agentId)
.description("Clones and analyzes GitHub repos.")
.baseAgent("antigravity-preview-05-2026")
.baseEnvironment(new EnvironmentConfig(
new EnvironmentNetworkEgressAllowlist(List.of(
new AllowlistEntry("github.com") // Allow git clone over HTTPS
)),
List.of()
))
.systemInstruction("You are an architect. Clone the repo, inspect files, and write a summary.")
.tools(List.of(
new AgentTool.CodeExecution(), // Enables terminal bash execution in sandbox
new AgentTool.GoogleSearch()
))
.build();
// 2. Provision the Agent
System.out.println("Provisioning custom agent in the cloud...");
client.createAgent(customAgent);
try {
// 3. Start the Interaction
AgentInteractionParams params = AgentInteractionParams.builder()
.agent(agentId)
.input("Clone https://github.com/glaforge/gemini-interactions-api-sdk and explain its pom.xml structure.")
.environment("remote") // Crucial: Run in cloud sandbox
.build();
System.out.println("Starting clone and analysis (polling status)...");
Interaction interaction = client.create(params);
// 4. Poll for completion
while (interaction.status() != Interaction.Status.COMPLETED) {
System.out.println("Agent working... Status: " + interaction.status());
Thread.sleep(5000);
interaction = client.get(interaction.id());
}
// 5. Output the results
System.out.println("\n--- Architectural Analysis ---");
interaction.steps().stream()
.filter(step -> step instanceof Step.ModelOutputStep)
.flatMap(step -> ((Step.ModelOutputStep) step).content().stream())
.filter(content -> content instanceof Content.TextContent)
.forEach(content -> System.out.println(((Content.TextContent) content).text()));
} finally {
// 6. Clean up resources
client.deleteAgent(agentId);
System.out.println("\nCustom agent resource deleted from cloud.");
}
}
}
Executar o código
mvn compile exec:java -Dexec.mainClass=com.example.GitHubAnalyzer
Saída de análise gerada
Você pode conferir o relatório completo de análise arquitetônica produzido pelo agente personalizado após clonar o repositório aqui:
Confira a saída do GitHub Analyzer (github_analysis_report.md)
9. Parabéns!
Você concluiu o codelab e aprendeu a criar fluxos de trabalho complexos, multimodais e agênticos em Java usando o SDK de interações do Gemini.
O que você realizou:
- Navegou pela arquitetura de etapas: usou a nova arquitetura de etapas polimórficas para consultar modelos padrão.
- Transmitiu TTS expressivo: usou as notas do diretor e as tags emocionais inline para transmitir áudio em tempo real.
- Gerou músicas: gerou faixas e letras de MP3 com o Lyria 3.
- Gerou sketchnotes: criou resumos visuais usando o Gemini 3 Pro para imagens (Nano Banana Pro).
- Direcionou o Deep Research: usou o planejamento colaborativo para refinar planos de pesquisa.
- Provisionou agentes personalizados: criou ambientes de sandbox com controle de saída de rede personalizado para executar código com segurança.
Saiba mais:
- Confira o código-fonte do SDK e mais casos de teste no GitHub: glaforge/gemini-interactions-api-sdk
- Leia mais sobre padrões de design agênticos no blog de Guillaume: glaforge.dev