Este tutorial demonstra como acessar a API Gemini para seu aplicativo Dart ou Flutter usando o SDK do Google AI Dart. Você pode usar esse SDK se não quiser trabalhar diretamente com APIs REST para acessar modelos do Gemini no seu app.
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 embeddings e tokens de contagem), bem como opções para controlar a geração de conteúdo.
Pré-requisitos
Neste tutorial, presume-se que você esteja familiarizado com a criação de aplicativos com o Dart.
Para concluir este tutorial, verifique se o ambiente de desenvolvimento atende aos seguintes requisitos:
- Dart 3.2.0 ou mais recente
Configurar seu projeto
Antes de chamar a API Gemini, você precisa configurar seu projeto, o que inclui configurar sua chave de API, adicionar o SDK às dependências do Pub/Sub 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, crie uma chave no Google AI Studio.
Proteger sua chave de API
Proteja sua chave de API. É altamente recomendável não incluir a chave de API diretamente no código nem verificar os arquivos que a contêm nos sistemas de controle de versões. Em vez disso, use um armazenamento de secrets para a chave de API.
Em todos os snippets deste tutorial, supomos que você esteja acessando sua chave de API como uma variável de ambiente de processo. Se você estiver desenvolvendo um app Flutter, use
String.fromEnvironment
e transmita --dart-define=API_KEY=$API_KEY
para
flutter build
ou flutter run
para compilar com a chave de API, já que o ambiente
de processo será diferente ao executar o app.
Instalar o pacote do SDK
Para usar a API Gemini no seu aplicativo, você precisa add
o
pacote google_generative_ai
no seu app Dart ou Flutter:
Dart
dart pub add google_generative_ai
Flutter
flutter pub add google_generative_ai
Inicializar o modelo generativo
Antes de fazer qualquer chamada de API, é preciso importar e inicializar o modelo generativo.
import 'dart:io';
import 'package:google_generative_ai/google_generative_ai.dart';
void main() async {
// Access your API key as an environment variable (see "Set up your API key" above)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No \$API_KEY environment variable');
exit(1);
}
// The Gemini 1.5 models are versatile and work with most use cases
final model = GenerativeModel(model: 'gemini-1.5-flash', apiKey: apiKey);
}
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 implementação listam o modelo recomendado para cada caso de uso.
Implemente casos de uso comuns
Agora que seu projeto está configurado, é possível 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
Na seção de casos de uso avançados, você encontra informações sobre a API Gemini e embeddings.
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
Gemini 1.0 Pro com generateContent
para gerar a saída de texto:
import 'dart:io';
import 'package:google_generative_ai/google_generative_ai.dart';
void main() async {
// Access your API key as an environment variable (see "Set up your API key" above)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No \$API_KEY environment variable');
exit(1);
}
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
final model = GenerativeModel(model: 'gemini-1.5-flash', apiKey: apiKey);
final content = [Content.text('Write a story about a magic backpack.')];
final response = await model.generateContent(content);
print(response.text);
}
Gerar texto com base em entradas de texto e imagem (multimodal)
O Gemini oferece vários modelos que podem processar entrada multimodal (modelos do Gemini 1.5) para que você possa inserir texto e imagens. Confira os requisitos de imagem para comandos.
Quando a entrada do comando incluir texto e imagens, use um modelo Gemini 1.5
com o método generateContent
para gerar a saída de texto:
import 'dart:io';
import 'package:google_generative_ai/google_generative_ai.dart';
void main() async {
// Access your API key as an environment variable (see "Set up your API key" above)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No \$API_KEY environment variable');
exit(1);
}
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
final model = GenerativeModel(model: 'gemini-1.5-flash', apiKey: apiKey);
final (firstImage, secondImage) = await (
File('image0.jpg').readAsBytes(),
File('image1.jpg').readAsBytes()
).wait;
final prompt = TextPart("What's different between these pictures?");
final imageParts = [
DataPart('image/jpeg', firstImage),
DataPart('image/jpeg', secondImage),
];
final response = await model.generateContent([
Content.multi([prompt, ...imageParts])
]);
print(response.text);
}
Criar conversas de várias interações (chat)
Com o Gemini, você pode criar conversas em formato livre em vários turnos. O
SDK simplifica o processo gerenciando o estado da conversa. Portanto, diferentemente de
generateContent
, não é necessário armazenar o histórico
de conversas.
Para criar uma conversa de vários turnos (como um chat), use um modelo Gemini 1.5 ou
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á a mensagem e a resposta ao histórico de chat.
Há duas opções possíveis para role
associados ao conteúdo em uma
conversa:
user
: o papel que fornece os comandos. Esse valor é o padrão para chamadassendMessage
, e a função vai gerar uma exceção se um papel diferente for transmitido.model
: o papel que fornece as respostas. Esse papel pode ser usado ao chamarstartChat()
comhistory
.
import 'dart:io';
import 'package:google_generative_ai/google_generative_ai.dart';
Future<void> main() async {
// Access your API key as an environment variable (see "Set up your API key" above)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No \$API_KEY environment variable');
exit(1);
}
// The Gemini 1.5 models are versatile and work with multi-turn conversations (like chat)
final model = GenerativeModel(
model: 'gemini-1.5-flash',
apiKey: apiKey,
generationConfig: GenerationConfig(maxOutputTokens: 100));
// Initialize the chat
final chat = model.startChat(history: [
Content.text('Hello, I have 2 dogs in my house.'),
Content.model([TextPart('Great to meet you. What would you like to know?')])
]);
var content = Content.text('How many paws are in my house?');
var response = await chat.sendMessage(content);
print(response.text);
}
Use o streaming para interações mais rápidas
Por padrão, o modelo retorna uma resposta após concluir todo o processo de geração. Para ter interações mais rápidas, não espere o resultado todo e, em vez disso, use o streaming para processar resultados parciais.
O exemplo a seguir mostra como implementar o streaming com o
método generateContentStream
para gerar texto com base em um prompt de entrada de texto
e imagem.
// ...
final response = model.generateContentStream([
Content.multi([prompt, ...imageParts])
]);
await for (final chunk in response) {
print(chunk.text);
}
// ...
Você pode usar uma abordagem semelhante para casos de uso de entrada somente de texto e chat.
// Use streaming with text-only input
final response = model.generateContentStream(content);
// Use streaming with multi-turn conversations (like chat)
final response = chat.sendMessageStream(content);
Implementar casos de uso avançados
Os casos de uso comuns descritos na seção anterior deste tutorial ajudam você a se familiarizar com o uso da API Gemini. Esta seção descreve alguns casos de uso que podem ser considerados mais avançados.
Chamadas de função
A chamada de função facilita a geração de saídas de dados estruturados de modelos generativos. Depois, use 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ê a conectar modelos generativos a sistemas externos, para que o conteúdo gerado inclua as informações mais atualizadas e precisas. Saiba mais no tutorial sobre chamada de função.
Usar embeddings
Embedding é uma técnica usada para representar informações como uma lista de números de ponto flutuante em uma matriz. Com o Gemini, é possível representar textos (palavras, frases e blocos de texto) em forma vetorial, facilitando a comparação e o contraste de embeddings. Por exemplo, dois textos que compartilham um assunto ou sentimento semelhante precisam ter embeddings semelhantes, que podem ser identificados por meio de técnicas de comparação matemática, como a semelhança de cossenos.
Use o modelo embedding-001
com o método embedContent
(ou o método batchEmbedContent
) para gerar embeddings. O exemplo abaixo
gera um embedding para uma única string:
final model = GenerativeModel(model: 'embedding-001', apiKey: apiKey);
final content = Content.text('The quick brown fox jumps over the lazy dog.');
final result = await model.embedContent(content);
print(result.embedding.values);
Contar tokens
Ao usar prompts longos, pode ser útil contar os tokens antes de enviar qualquer conteúdo para o modelo. Os exemplos abaixo mostram como usar countTokens()
em vários casos de uso:
// For text-only input
final tokenCount = await model.countTokens(Content.text(prompt));
print('Token count: ${tokenCount.totalTokens}');
// For text-and-image input (multimodal)
final tokenCount = await model.countTokens([
Content.multi([prompt, ...imageParts])
]);
print('Token count: ${tokenCount.totalTokens}');
// For multi-turn conversations (like chat)
final prompt = Content.text(message);
final allContent = [...chat.history, prompt];
final tokenCount = await model.countTokens(allContent);
print('Token count: ${tokenCount.totalTokens}');
Opções para controlar a geração de conteúdo
É possível controlar a geração de conteúdo definindo parâmetros do modelo e usando as configurações de segurança.
Transmitir generationConfig
ou safetySettings
para um método de solicitação de modelo (como generateContent
) vai substituir totalmente o objeto de configuração
com o mesmo nome transmitido em getGenerativeModel
.
Configurar parâmetros do modelo
Cada comando que você envia ao modelo inclui valores de parâmetro que controlam como o modelo gera uma resposta. O modelo pode gerar diferentes resultados para diferentes valores de parâmetros. Saiba mais sobre os parâmetros do modelo. A configuração é mantida durante o ciclo de vida da instância do modelo.
final generationConfig = GenerationConfig(
stopSequences: ["red"],
maxOutputTokens: 200,
temperature: 0.9,
topP: 0.1,
topK: 16,
);
final model = GenerativeModel(
// The Gemini 1.5 models are versatile and work with most use cases
model: 'gemini-1.5-flash',
apiKey: apiKey,
generationConfig: generationConfig,
);
Usar as configurações de segurança
Use as configurações de segurança para ajustar a probabilidade de receber respostas que possam ser consideradas prejudiciais. Por padrão, as configurações de segurança bloqueiam conteúdo com probabilidade média e/ou alta de não ser seguro em todas as dimensões. Saiba mais sobre as Configurações de segurança.
Veja como definir uma configuração de segurança:
final safetySettings = [
SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high)
];
final model = GenerativeModel(
// The Gemini 1.5 models are versatile and work with most use cases
model: 'gemini-1.5-flash',
apiKey: apiKey,
safetySettings: safetySettings,
);
Também é possível definir mais de uma configuração de segurança:
final safetySettings = [
SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high),
SafetySetting(HarmCategory.hateSpeech, HarmBlockThreshold.high),
];
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 modelo para atender às necessidades de diferentes casos de uso, como tipos de entrada e complexidade, implementações para chat ou outras tarefas de linguagem de caixas de diálogo e restrições de tamanho. Saiba mais sobre os modelos do Gemini disponíveis.