Este tutorial demonstra como acessar a API Gemini diretamente do seu App Android usando o SDK cliente da IA do Google para Android. Você pode usar isso SDK do cliente se você não quiser trabalhar diretamente com APIs REST ou código do lado do servidor (como Python) para acessar modelos do Gemini no seu app Android.
Neste tutorial, você aprenderá a fazer o seguinte:
- Configurar seu projeto, incluindo a chave de API
- Gerar texto com base em uma entrada somente de texto
- Gerar texto com base em entradas de texto e imagem (multimodal)
- Criar conversas em várias interações (chat)
- Usar o streaming para interações mais rápidas
Além disso, este tutorial contém seções sobre casos de uso avançados (como de contagem de tokens), bem como as opções para o controle da geração de conteúdo.
Tente acessar o Gemini no dispositivo
O SDK cliente para Android descrito neste tutorial permite que você acesse o Modelos do Gemini Pro executados nos servidores do Google. Para casos de uso que envolvem processamento de dados sensíveis, disponibilidade off-line ou economia de custos para fluxos de usuários usados com frequência, acesse o Gemini Nano que é executado no dispositivo. Para mais detalhes, consulte a Tutorial do Android (no dispositivo).
Pré-requisitos
Este tutorial presume que você já sabe usar o Android Studio para desenvolver apps Android.
Para concluir este tutorial, verifique se o ambiente de desenvolvimento e O app Android atende aos seguintes requisitos:
- Android Studio (versão mais recente)
- O app Android precisa ser direcionado ao nível 21 da API ou mais recente.
Criar o projeto
Antes de chamar a API Gemini, você precisa configurar seu projeto Android, que inclui a configuração da sua chave de API, a adição de dependências do SDK ao seu projeto e inicializar o modelo.
Configurar sua chave de API
Para usar a API Gemini, você precisa de uma chave de API. Se você ainda não tiver uma, criar uma chave no Google AI Studio.
Proteger sua chave de API
É altamente recomendável não verificar uma chave de API na sua versão.
de controle de acesso. Em vez disso, armazene-o em um arquivo local.properties
.
(localizado no diretório raiz do seu projeto, mas excluído do controle
controle) e, em seguida, use o
Plug-in Secrets Gradle para Android
para ler sua chave de API como uma variável de configuração do build.
Kotlin
// Access your API key as a Build Configuration variable
val apiKey = BuildConfig.apiKey
Java
// Access your API key as a Build Configuration variable
String apiKey = BuildConfig.apiKey;
Todos os snippets neste tutorial usam essa prática recomendada. Além disso, se você
quiser ver a implementação do plug-in Secrets Gradle, consulte a
app de exemplo
para esse SDK ou usar a versão de pré-lançamento mais recente do Android Studio Iguana, que tem uma
Modelo da API Gemini Starter
(que inclui o arquivo local.properties
para você começar).
Adicionar a dependência do SDK ao seu projeto
No arquivo de configuração Gradle do módulo (nível do app) (como
<project>/<app-module>/build.gradle.kts
), adicione a dependência SDK da IA do Google para Android:Kotlin
dependencies { // ... other androidx dependencies // add the dependency for the Google AI client SDK for Android implementation("com.google.ai.client.generativeai:generativeai:0.9.0") }
Java
Para Java, é preciso adicionar mais duas bibliotecas.
dependencies { // ... other androidx dependencies // add the dependency for the Google AI client SDK for Android implementation("com.google.ai.client.generativeai:generativeai:0.9.0") // Required for one-shot operations (to use `ListenableFuture` from Guava Android) implementation("com.google.guava:guava:31.0.1-android") // Required for streaming operations (to use `Publisher` from Reactive Streams) implementation("org.reactivestreams:reactive-streams:1.0.4") }
Sincronize o projeto do Android com os arquivos do Gradle.
Inicializar o modelo generativo
Antes de fazer chamadas de API, você precisa inicializar o modelo generativo:
Kotlin
val generativeModel = GenerativeModel(
// The Gemini 1.5 models are versatile and work with most use cases
modelName = "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
apiKey = BuildConfig.apiKey
)
Java
Para Java, você também precisa inicializar o objeto GenerativeModelFutures
.
// Use a model that's applicable for your use case
// The Gemini 1.5 models are versatile and work with most use cases
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
/* apiKey */ BuildConfig.apiKey);
// Use the GenerativeModelFutures Java compatibility layer which offers
// support for ListenableFuture and Publisher APIs
GenerativeModelFutures model = GenerativeModelFutures.from(gm);
Ao especificar um modelo, observe o seguinte:
Use um modelo específico para seu caso de uso (por exemplo,
gemini-1.5-flash
) é para entrada multimodal). Neste guia, as instruções para cada de implementação lista o modelo recomendado para cada caso de uso.
Implemente casos de uso comuns
Agora que seu projeto está configurado, você pode usar a API Gemini para implementar diferentes casos de uso:
- Gerar texto com base em uma entrada somente de texto
- Gerar texto com base em entradas de texto e imagem (multimodal)
- Criar conversas em várias interações (chat)
- Usar o streaming para interações mais rápidas
Gerar texto com base em uma entrada somente de texto
Quando a entrada do comando incluir apenas texto, use um modelo Gemini 1.5 ou o
Modelo Gemini 1.0 Pro com generateContent
para gerar uma saída de texto:
Kotlin
generateContent()
é uma função de suspensão e precisa ser
chamados de um escopo de corrotina. Se você não conhece as corrotinas, leia
Corrotinas do Kotlin no Android.
val generativeModel = GenerativeModel(
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
modelName = "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
apiKey = BuildConfig.apiKey
)
val prompt = "Write a story about a magic backpack."
val response = generativeModel.generateContent(prompt)
print(response.text)
Java
Observe que generateContent()
retorna um ListenableFuture
. Se
não estiver familiarizado com essa API, consulte a documentação do Android sobre
Como usar um ListenableFuture
.
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
/* apiKey */ BuildConfig.apiKey);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);
Content content = new Content.Builder()
.addText("Write a story about a magic backpack.")
.build();
Executor executor = // ...
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
String resultText = result.getText();
System.out.println(resultText);
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Gerar texto com base em entradas de texto e imagem (multimodal)
O Gemini fornece vários modelos que podem processar entradas multimodais (modelos Gemini 1.5) para que você possa inserir texto e imagens. Não se esqueça de confira os requisitos de imagem para comandos.
Quando a entrada do comando incluir texto e imagens, use um modelo Gemini 1.5 com
generateContent
para gerar a saída de texto:
Kotlin
generateContent()
é uma função de suspensão e precisa ser
chamados de um escopo de corrotina. Se você não conhece as corrotinas, leia
Corrotinas do Kotlin no Android.
val generativeModel = GenerativeModel(
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
modelName = "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
apiKey = BuildConfig.apiKey
)
val image1: Bitmap = // ...
val image2: Bitmap = // ...
val inputContent = content {
image(image1)
image(image2)
text("What's different between these pictures?")
}
val response = generativeModel.generateContent(inputContent)
print(response.text)
Java
Observe que generateContent()
retorna um ListenableFuture
. Se
não estiver familiarizado com essa API, consulte a documentação do Android sobre
Como usar um ListenableFuture
.
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
/* apiKey */ BuildConfig.apiKey);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);
Bitmap image1 = // ...
Bitmap image2 = // ...
Content content = new Content.Builder()
.addText("What's different between these pictures?")
.addImage(image1)
.addImage(image2)
.build();
Executor executor = // ...
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
String resultText = result.getText();
System.out.println(resultText);
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Criar conversas de várias interações (chat)
Com o Gemini, você pode criar conversas em formato livre em vários turnos. O
O SDK simplifica o processo ao gerenciar o estado da conversa, portanto, ao contrário do que
com generateContent
, não é necessário armazenar o histórico de conversas
você mesmo.
Para criar uma conversa de vários turnos (como um chat), use um modelo Gemini 1.5 ou o
Gemini 1.0 Pro e inicialize a conversa chamando startChat()
.
Em seguida, use sendMessage()
para enviar uma nova mensagem de usuário, que também anexará o
e a resposta ao histórico de chat.
Há duas opções possíveis para role
associadas ao conteúdo em um
conversa:
user
: o papel que fornece os comandos. Esse valor é o padrão parasendMessage
.model
: o papel que fornece as respostas. Esse papel pode ser usado chamandostartChat()
com ashistory
existentes.
Kotlin
generateContent()
é uma função de suspensão e precisa ser
chamados de um escopo de corrotina. Se você não conhece as corrotinas, leia
Corrotinas do Kotlin no Android.
val generativeModel = GenerativeModel(
// The Gemini 1.5 models are versatile and work with multi-turn conversations (like chat)
modelName = "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
apiKey = BuildConfig.apiKey
)
val chat = generativeModel.startChat(
history = listOf(
content(role = "user") { text("Hello, I have 2 dogs in my house.") },
content(role = "model") { text("Great to meet you. What would you like to know?") }
)
)
chat.sendMessage("How many paws are in my house?")
Java
Observe que generateContent()
retorna um ListenableFuture
. Se
não estiver familiarizado com essa API, consulte a documentação do Android sobre
Como usar um ListenableFuture
.
// The Gemini 1.5 models are versatile and work with multi-turn conversations (like chat)
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
/* apiKey */ BuildConfig.apiKey);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);
// (optional) Create previous chat history for context
Content.Builder userContentBuilder = new Content.Builder();
userContentBuilder.setRole("user");
userContentBuilder.addText("Hello, I have 2 dogs in my house.");
Content userContent = userContentBuilder.build();
Content.Builder modelContentBuilder = new Content.Builder();
modelContentBuilder.setRole("model");
modelContentBuilder.addText("Great to meet you. What would you like to know?");
Content modelContent = userContentBuilder.build();
List<Content> history = Arrays.asList(userContent, modelContent);
// Initialize the chat
ChatFutures chat = model.startChat(history);
// Create a new user message
Content.Builder userMessageBuilder = new Content.Builder();
userMessageBuilder.setRole("user");
userMessageBuilder.addText("How many paws are in my house?");
Content userMessage = userMessageBuilder.build();
Executor executor = // ...
// Send the message
ListenableFuture<GenerateContentResponse> response = chat.sendMessage(userMessage);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
String resultText = result.getText();
System.out.println(resultText);
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Use o streaming para interações mais rápidas
Por padrão, o modelo retorna uma resposta após a conclusão de toda a geração de desenvolvimento de software. Para ter interações mais rápidas, não espere resultado e, em vez disso, usar streaming para lidar com resultados parciais.
O exemplo abaixo mostra como implementar o streaming com
generateContentStream
para gerar texto com base em um comando de entrada de texto e imagem.
Kotlin
generateContentStream()
é uma função de suspensão e precisa ser
chamados de um escopo de corrotina. Se você não conhece as corrotinas, leia
Corrotinas do Kotlin no Android.
val generativeModel = GenerativeModel(
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
modelName = "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
apiKey = BuildConfig.apiKey
)
val image1: Bitmap = // ...
val image2: Bitmap = // ...
val inputContent = content {
image(image1)
image(image2)
text("What's the difference between these pictures?")
}
var fullResponse = ""
generativeModel.generateContentStream(inputContent).collect { chunk ->
print(chunk.text)
fullResponse += chunk.text
}
Java
Os métodos de streaming em Java neste SDK retornam um tipo Publisher
.
da tabela Fluxos reativos
biblioteca.
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
/* apiKey */ BuildConfig.apiKey);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);
Bitmap image1 = // ...
Bitmap image2 = // ...
Content content = new Content.Builder()
.addText("What's different between these pictures?")
.addImage(image1)
.addImage(image2)
.build();
Publisher<GenerateContentResponse> streamingResponse =
model.generateContentStream(content);
StringBuilder outputContent = new StringBuilder();
streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
@Override
public void onNext(GenerateContentResponse generateContentResponse) {
String chunk = generateContentResponse.getText();
outputContent.append(chunk);
}
@Override
public void onComplete() {
System.out.println(outputContent);
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
}
});
É possível usar uma abordagem semelhante para casos de uso de entrada somente de texto e chat:
Kotlin
generateContentStream()
é uma função de suspensão e precisa ser
chamados de um escopo de corrotina. Se você não conhece as corrotinas, leia
Corrotinas do Kotlin no Android.
// Use streaming with text-only input
generativeModel.generateContentStream(inputContent).collect { chunk ->
print(chunk.text)
}
// Use streaming with multi-turn conversations (like chat)
val chat = generativeModel.startChat()
chat.sendMessageStream(inputContent).collect { chunk ->
print(chunk.text)
}
Java
Os métodos de streaming em Java neste SDK retornam um tipo Publisher
.
da tabela Fluxos reativos
biblioteca.
// Use streaming with text-only input
Publisher<GenerateContentResponse> streamingResponse =
model.generateContentStream(inputContent);
StringBuilder outputContent = new StringBuilder();
streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
@Override
public void onNext(GenerateContentResponse generateContentResponse) {
String chunk = generateContentResponse.getText();
outputContent.append(chunk);
}
@Override
public void onComplete() {
System.out.println(outputContent);
}
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
}
// ... other methods omitted for brevity
});
// Use streaming with multi-turn conversations (like chat)
ChatFutures chat = model.startChat(history);
Publisher<GenerateContentResponse> streamingResponse =
chat.sendMessageStream(inputContent);
StringBuilder outputContent = new StringBuilder();
streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
@Override
public void onNext(GenerateContentResponse generateContentResponse) {
String chunk = generateContentResponse.getText();
outputContent.append(chunk);
}
@Override
public void onComplete() {
System.out.println(outputContent);
}
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
}
// ... other methods omitted for brevity
});
Implementar casos de uso avançados
Os casos de uso comuns descritos na seção anterior deste tutorial ajudam a se familiarizar com o uso da API Gemini. Esta seção descreve algumas casos de uso que podem ser considerados mais avançados.
Chamadas de função
A chamada de função facilita o recebimento de saídas de dados estruturados de modelos generativos. Você pode usar essas saídas para chamar outras APIs e retornar os dados de resposta relevantes ao modelo. Em outras palavras, a chamada de função ajuda você conecta modelos generativos a sistemas externos para que o conteúdo gerado inclui as informações mais atualizadas e precisas. Saiba mais na tutorial sobre chamada de função.
Contar tokens
Ao usar prompts longos, pode ser útil contar os tokens antes de enviar
conteúdo ao modelo. Os exemplos a seguir mostram como usar countTokens()
.
para diversos casos de uso:
Kotlin
countTokens()
é uma função de suspensão e precisa ser
chamados de um escopo de corrotina. Se você não conhece as corrotinas, leia
Corrotinas do Kotlin no Android.
// For text-only input
val (totalTokens) = generativeModel.countTokens("Write a story about a magic backpack.")
// For text-and-image input (multi-modal)
val multiModalContent = content {
image(image1)
image(image2)
text("What's the difference between these pictures?")
}
val (totalTokens) = generativeModel.countTokens(multiModalContent)
// For multi-turn conversations (like chat)
val history = chat.history
val messageContent = content { text("This is the message I intend to send")}
val (totalTokens) = generativeModel.countTokens(*history.toTypedArray(), messageContent)
Java
Observe que countTokens()
retorna um ListenableFuture
. Se
não estiver familiarizado com essa API, consulte a documentação do Android sobre
Como usar um ListenableFuture
.
Content text = new Content.Builder()
.addText("Write a story about a magic backpack.")
.build();
Executor executor = // ...
// For text-only input
ListenableFuture<CountTokensResponse> countTokensResponse = model.countTokens(text);
Futures.addCallback(countTokensResponse, new FutureCallback<CountTokensResponse>() {
@Override
public void onSuccess(CountTokensResponse result) {
int totalTokens = result.getTotalTokens();
System.out.println("TotalTokens = " + totalTokens);
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
// For text-and-image input
Bitmap image1 = // ...
Bitmap image2 = // ...
Content multiModalContent = new Content.Builder()
.addImage(image1)
.addImage(image2)
.addText("What's different between these pictures?")
.build();
ListenableFuture<CountTokensResponse> countTokensResponse = model.countTokens(multiModalContent);
// For multi-turn conversations (like chat)
List<Content> history = chat.getChat().getHistory();
Content messageContent = new Content.Builder()
.addText("This is the message I intend to send")
.build();
Collections.addAll(history, messageContent);
ListenableFuture<CountTokensResponse> countTokensResponse = model.countTokens(history.toArray(new Content[0]));
Opções para controlar a geração de conteúdo
É possível controlar a geração de conteúdo configurando parâmetros de modelo e usando configurações de segurança.
Configurar parâmetros do modelo
Cada comando que você envia ao modelo inclui valores de parâmetros que controlam como o modelo gera uma resposta. O modelo pode gerar diferentes resultados para diferentes valores de parâmetros. Saiba mais sobre Parâmetros do modelo.
Kotlin
val config = generationConfig {
temperature = 0.9f
topK = 16
topP = 0.1f
maxOutputTokens = 200
stopSequences = listOf("red")
}
val generativeModel = GenerativeModel(
// The Gemini 1.5 models are versatile and work with most use cases
modelName = "gemini-1.5-flash",
apiKey = BuildConfig.apiKey,
generationConfig = config
)
Java
GenerationConfig.Builder configBuilder = new GenerationConfig.Builder();
configBuilder.temperature = 0.9f;
configBuilder.topK = 16;
configBuilder.topP = 0.1f;
configBuilder.maxOutputTokens = 200;
configBuilder.stopSequences = Arrays.asList("red");
GenerationConfig generationConfig = configBuilder.build();
// The Gemini 1.5 models are versatile and work with most use cases
GenerativeModel gm = new GenerativeModel(
"gemini-1.5-flash",
BuildConfig.apiKey,
generationConfig
);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);
Usar as configurações de segurança
É possível usar as configurações de segurança para ajustar a probabilidade de receber respostas que pode ser considerado nocivo. Por padrão, as configurações de segurança bloqueiam conteúdo com tamanho e/ou alta probabilidade de ser um conteúdo não seguro em todas as dimensões. Aprender Saiba mais sobre as Configurações de segurança.
Veja como definir uma configuração de segurança:
Kotlin
val generativeModel = GenerativeModel(
// The Gemini 1.5 models are versatile and work with most use cases
modelName = "gemini-1.5-flash",
apiKey = BuildConfig.apiKey,
safetySettings = listOf(
SafetySetting(HarmCategory.HARASSMENT, BlockThreshold.ONLY_HIGH)
)
)
Java
SafetySetting harassmentSafety = new SafetySetting(HarmCategory.HARASSMENT,
BlockThreshold.ONLY_HIGH);
// The Gemini 1.5 models are versatile and work with most use cases
GenerativeModel gm = new GenerativeModel(
"gemini-1.5-flash",
BuildConfig.apiKey,
null, // generation config is optional
Collections.singletonList(harassmentSafety)
);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);
Também é possível definir mais de uma configuração de segurança:
Kotlin
val harassmentSafety = SafetySetting(HarmCategory.HARASSMENT, BlockThreshold.ONLY_HIGH)
val hateSpeechSafety = SafetySetting(HarmCategory.HATE_SPEECH, BlockThreshold.MEDIUM_AND_ABOVE)
val generativeModel = GenerativeModel(
// The Gemini 1.5 models are versatile and work with most use cases
modelName = "gemini-1.5-flash",
apiKey = BuildConfig.apiKey,
safetySettings = listOf(harassmentSafety, hateSpeechSafety)
)
Java
SafetySetting harassmentSafety = new SafetySetting(HarmCategory.HARASSMENT,
BlockThreshold.ONLY_HIGH);
SafetySetting hateSpeechSafety = new SafetySetting(HarmCategory.HATE_SPEECH,
BlockThreshold.MEDIUM_AND_ABOVE);
// The Gemini 1.5 models are versatile and work with most use cases
GenerativeModel gm = new GenerativeModel(
"gemini-1.5-flash",
BuildConfig.apiKey,
null, // generation config is optional
Arrays.asList(harassmentSafety, hateSpeechSafety)
);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);
A seguir
Design de prompt é o processo de criação de prompts que extraem a resposta desejada dos modelos de linguagem. Escrever solicitações bem estruturadas é uma parte essencial para garantir respostas precisas e de alta qualidade de um modelo de linguagem. Saiba mais sobre as práticas recomendadas para a criação de comandos.
O Gemini oferece diversas variações de modelos para atender às necessidades de diferentes usos casos, como tipos de entrada e complexidade, implementações para chat ou outros tarefas de linguagem de caixas de diálogo e restrições de tamanho. Saiba mais sobre os modelos do Gemini disponíveis.
O SDK cliente para Android descrito neste tutorial permite que você acesse o Modelos do Gemini Pro executados nos servidores do Google. Para casos de uso que envolvem processamento de dados sensíveis, disponibilidade off-line ou economia de custos para fluxos de usuários usados com frequência, acesse o Gemini Nano que é executado no dispositivo. Para mais detalhes, consulte a Tutorial do Android (no dispositivo).