Руководство: Начало работы с Gemini API


Этот учебник демонстрирует, как получить доступ к API Gemini непосредственно из вашего приложения Android, используя Google AI Client SDK для Android. Вы можете использовать этот клиент SDK, если вы не хотите работать напрямую с API REST или кодом на стороне сервера (например, Python) для доступа к моделям Gemini в вашем приложении Android.

В этом уроке вы узнаете, как сделать следующее:

Кроме того, этот урок содержит разделы о расширенных вариантах использования (например, подсчет токенов ), а также опции для управления генерацией контента .

Подумайте о доступе к Близнецам на устройстве

Клиент SDK для Android, описанный в этом уроке, позволяет вам получить доступ к моделям Gemini Pro, которые работают на серверах Google . Для вариантов использования, которые включают обработку конфиденциальных данных, доступность в автономном режиме или для экономии затрат для часто используемых пользовательских потоков, вы можете рассмотреть возможность доступа к Nano Gemini, который работает на устройстве . Для получения более подробной информации обратитесь к учебному пособию Android (On-Device) .

Предварительные условия

Этот учебник предполагает, что вы знакомы с использованием Android Studio для разработки приложений Android.

Чтобы завершить этот урок, убедитесь, что ваша среда разработки и приложение для Android соответствует следующим требованиям:

  • Android Studio (последняя версия)
  • Ваше приложение для Android должно нацелиться на уровень API 21 или выше.

Настройте свой проект

Прежде чем вызывать API Gemini, вам необходимо настроить свой проект Android, который включает настройку клавиши API, добавление зависимостей SDK в ваш проект Android и инициализацию модели.

Установите свой ключ API

Чтобы использовать API Gemini, вам понадобится ключ API. Если у вас его еще нет, создайте ключ в Google AI Studio.

Получить ключ API

Закрепите свой ключ API

Настоятельно рекомендуется, чтобы вы не проверяли ключ API в системе управления версиями. Вместо этого вы должны сохранить его в файле local.properties (который находится в корневом каталоге вашего проекта, но исключен из управления версией), а затем использовать плагин Secrets Gradle для Android , чтобы прочитать ваш ключ API в качестве переменной конфигурации сборки.

Котлин

// Access your API key as a Build Configuration variable
val apiKey = BuildConfig.apiKey

Джава

// Access your API key as a Build Configuration variable
String apiKey = BuildConfig.apiKey;

Все фрагменты в этом уроке используют эту лучшую практику. Кроме того, если вы хотите увидеть реализацию плагина Secrets Gradle, вы можете просмотреть приложение для этого SDK или использовать последний предварительный просмотр Android Studio Iguana, который имеет шаблон стартера Gemini API (который включает в себя файл local.properties , чтобы получить ты начал).

Добавьте зависимость SDK в свой проект

  1. В вашем модуле (App-Level) Файл конфигурации Gradle (например, <project>/<app-module>/build.gradle.kts ) добавьте зависимость для Google AI SDK для Android:

    Котлин

    dependencies {
      // ... other androidx dependencies
    
      // add the dependency for the Google AI client SDK for Android
      implementation("com.google.ai.client.generativeai:generativeai:0.6.0")
    }
    

    Джава

    Для Java вам нужно добавить две дополнительные библиотеки.

    dependencies {
        // ... other androidx dependencies
    
        // add the dependency for the Google AI client SDK for Android
        implementation("com.google.ai.client.generativeai:generativeai:0.6.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")
    }
    
  2. Синхронизируйте ваш проект Android с Gradle Files.

Инициализировать генеративную модель

Прежде чем вы сможете сделать какие -либо вызовы API, вам необходимо инициализировать генеративную модель:

Котлин

val generativeModel = GenerativeModel(
    // Use a model that's applicable for your use case (see "Implement basic use cases" below)
    modelName = "MODEL_NAME",
    // Access your API key as a Build Configuration variable (see "Set up your API key" above)
    apiKey = BuildConfig.apiKey
)

Джава

Для Java вам также необходимо инициализировать объект GenerativeModelFutures .

// Use a model that's applicable for your use case (see "Implement basic use cases" below)
GenerativeModel gm = new GenerativeModel(/* modelName */ "MODEL_NAME",
// 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);

При указании модели обратите внимание на следующее:

  • Используйте модель, специфичную для вашего варианта использования (например, gemini-pro-vision предназначена для мультимодального входа). В этом руководстве в инструкциях для каждой реализации перечислена рекомендуемая модель для каждого варианта использования.

Реализовать общие варианты использования

Теперь, когда ваш проект настроен, вы можете изучить использование Gemini API для реализации различных вариантов использования:

Создать текст из ввода только текста

Когда ввод подсказки включает только текст, используйте модель gemini-pro с generateContent для генерации вывода текста:

Котлин

Обратите внимание, что generateContent() является подвесной функцией и должна быть вызвана из прицела. Если вы не знакомы с Coroutines, прочитайте Kotlin Coroutines на Android .

val generativeModel = GenerativeModel(
    // For text-only input, use the gemini-pro model
    modelName = "gemini-pro",
    // 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)

Джава

Обратите внимание, что generateContent() возвращает ListenableFuture . Если вы не знакомы с этим API, см. Документацию Android об использовании ListenableFuture .

// For text-only input, use the gemini-pro model
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-pro",
// 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);

Создать текст с ввода текста и изображения (мультимодальный)

Gemini предоставляет мультимодальную модель ( gemini-pro-vision ), так что вы можете ввести как текст, так и изображения. Обязательно ознакомьтесь с требованиями к изображениям для подсказок .

Когда ввод приглашения включает в себя как текст, так и изображения, используйте модель gemini-pro-vision с generateContent для генерации вывода текста:

Котлин

Обратите внимание, что generateContent() является подвесной функцией и должна быть вызвана из прицела. Если вы не знакомы с Coroutines, прочитайте Kotlin Coroutines на Android .

val generativeModel = GenerativeModel(
    // For text-and-images input (multimodal), use the gemini-pro-vision model
    modelName = "gemini-pro-vision",
    // 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)

Джава

Обратите внимание, что generateContent() возвращает ListenableFuture . Если вы не знакомы с этим API, см. Документацию Android об использовании ListenableFuture .

// For text-and-images input (multimodal), use the gemini-pro-vision model
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-pro-vision",
// 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);

Создайте многократные разговоры (чат)

Используя Gemini, вы можете строить разговоры в произвольной форме, состоящие из нескольких ходов. SDK упрощает процесс, управляя состоянием разговора, поэтому, в отличие от generateContent , вам не нужно хранить историю разговора самостоятельно.

Чтобы создать многообразие разговора (например, чат), используйте модель gemini-pro и инициализируйте чат, позвонив startChat() . Затем используйте sendMessage() , чтобы отправить новое пользовательское сообщение, которое также добавит сообщение и ответ на историю чата.

Есть два возможных варианта role , связанных с содержанием в разговоре:

  • user : роль, которая предоставляет подсказки. Это значение является по умолчанию для вызовов sendMessage .

  • model : роль, которая обеспечивает ответы. Эта роль может быть использована при вызове startChat() с существующей history .

Котлин

Обратите внимание, что generateContent() является подвесной функцией и должна быть вызвана из прицела. Если вы не знакомы с Coroutines, прочитайте Kotlin Coroutines на Android .

val generativeModel = GenerativeModel(
    // For text-only input, use the gemini-pro model
    modelName = "gemini-pro",
    // 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?")

Джава

Обратите внимание, что generateContent() возвращает ListenableFuture . Если вы не знакомы с этим API, см. Документацию Android об использовании ListenableFuture .

// For text-only input, use the gemini-pro model
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-pro",
// 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 userMessage = new Content.Builder()
    .setRole("user")
    .addText("How many paws are in my house?")
    .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);

Используйте потоковую передачу для более быстрых взаимодействий

По умолчанию модель возвращает ответ после завершения всего процесса генерации. Вы можете достичь более быстрых взаимодействий, не ожидая всего результата, и вместо этого использовать потоковую передачу для обработки частичных результатов.

В следующем примере показано, как реализовать потоковую передачу с помощью generateContentStream для генерации текста из подсказки ввода текста и изображения.

Котлин

Обратите внимание, что generateContentStream() является функцией приостановки и должна быть вызвана из прицела. Если вы не знакомы с Coroutines, прочитайте Kotlin Coroutines на Android .

val generativeModel = GenerativeModel(
    // For text-and-image input (multimodal), use the gemini-pro-vision model
    modelName = "gemini-pro-vision",
    // 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 в этом SDK возвращают тип Publisher из библиотеки реактивных потоков .

// For text-and-images input (multimodal), use the gemini-pro-vision model
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-pro-vision",
// 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);

final String[] fullResponse = {""};

streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
    @Override
    public void onNext(GenerateContentResponse generateContentResponse) {
        String chunk = generateContentResponse.getText();
        fullResponse[0] += chunk;
    }

    @Override
    public void onComplete() {
        System.out.println(fullResponse[0]);
    }

    @Override
    public void onError(Throwable t) {
        t.printStackTrace();
    }

    @Override
    public void onSubscribe(Subscription s) { }
});

Вы можете использовать аналогичный подход для ввода только текста и вариантов использования чата:

Котлин

Обратите внимание, что generateContentStream() является функцией приостановки и должна быть вызвана из прицела. Если вы не знакомы с Coroutines, прочитайте Kotlin Coroutines на 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 в этом SDK возвращают тип Publisher из библиотеки реактивных потоков .

// Use streaming with text-only input
Publisher<GenerateContentResponse> streamingResponse =
    model.generateContentStream(inputContent);

final String[] fullResponse = {""};

streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
    @Override
    public void onNext(GenerateContentResponse generateContentResponse) {
        String chunk = generateContentResponse.getText();
        fullResponse[0] += chunk;
    }

    @Override
    public void onComplete() {
        System.out.println(fullResponse[0]);
    }

    // ... other methods omitted for brevity
});
// Use streaming with multi-turn conversations (like chat)
ChatFutures chat = model.startChat(history);

Publisher<GenerateContentResponse> streamingResponse =
    chat.sendMessageStream(inputContent);

final String[] fullResponse = {""};

streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
    @Override
    public void onNext(GenerateContentResponse generateContentResponse) {
        String chunk = generateContentResponse.getText();
        fullResponse[0] += chunk;
    }

    @Override
    public void onComplete() {
        System.out.println(fullResponse[0]);
    }

    // ... other methods omitted for brevity
});

Внедрить расширенные варианты использования

Общие варианты использования, описанные в предыдущем разделе этого учебника, помогают вам понять API Gemini. В этом разделе описываются некоторые варианты использования, которые можно считать более продвинутыми.

Вызов функции

Функциональный вызов облегчает вам структурированные выходные данные из генеративных моделей. Затем вы можете использовать эти выходы для вызова других API и вернуть соответствующие данные ответа в модель. Другими словами, функциональный вызов помогает вам подключить генеративные модели к внешним системам, чтобы сгенерированный контент включал самую современную и точную информацию. Узнайте больше в функции, вызову обучения .

Считайте токены

При использовании длинных подсказок может быть полезно подсчитать токены перед отправкой какого -либо контента в модель. Следующие примеры показывают, как использовать countTokens() для различных вариантов использования:

Котлин

Обратите внимание, что countTokens() является подвесной функцией и должна быть вызвана из прицела. Если вы не знакомы с Coroutines, прочитайте Kotlin Coroutines на 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)

Джава

Обратите внимание, что countTokens() возвращает ListenableFuture . Если вы не знакомы с этим API, см. Документацию Android об использовании 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]));

Параметры для контроля генерации контента

Вы можете управлять генерацией содержания, настраивая параметры модели и с помощью настройки безопасности.

Настройте параметры модели

Каждое приглашение, которое вы отправляете в модель, включает значения параметров, которые управляют тем, как модель генерирует ответ. Модель может генерировать различные результаты для разных значений параметров. Узнайте больше о параметрах модели .

Котлин

val config = generationConfig {
    temperature = 0.9f
    topK = 16
    topP = 0.1f
    maxOutputTokens = 200
    stopSequences = listOf("red")
}

val generativeModel = GenerativeModel(
    modelName = "MODEL_NAME",
    apiKey = BuildConfig.apiKey,
    generationConfig = config
)

Джава

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();

GenerativeModel gm = new GenerativeModel(
    "MODEL_NAME",
    BuildConfig.apiKey,
    generationConfig
);

GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Используйте настройки безопасности

Вы можете использовать настройки безопасности, чтобы скорректировать вероятность получения ответов, которые можно считать вредными. По умолчанию настройки безопасности блокируют содержание со средней и/или высокой вероятностью быть небезопасным содержанием во всех измерениях. Узнайте больше о настройках безопасности .

Вот как установить одну настройку безопасности:

Котлин

val generativeModel = GenerativeModel(
    modelName = "MODEL_NAME",
    apiKey = BuildConfig.apiKey,
    safetySettings = listOf(
        SafetySetting(HarmCategory.HARASSMENT, BlockThreshold.ONLY_HIGH)
    )
)

Джава

SafetySetting harassmentSafety = new SafetySetting(HarmCategory.HARASSMENT,
    BlockThreshold.ONLY_HIGH);

GenerativeModel gm = new GenerativeModel(
    "MODEL_NAME",
    BuildConfig.apiKey,
    null, // generation config is optional
    Collections.singletonList(harassmentSafety)
);

GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Вы также можете установить более одного настройки безопасности:

Котлин

val harassmentSafety = SafetySetting(HarmCategory.HARASSMENT, BlockThreshold.ONLY_HIGH)

val hateSpeechSafety = SafetySetting(HarmCategory.HATE_SPEECH, BlockThreshold.MEDIUM_AND_ABOVE)

val generativeModel = GenerativeModel(
    modelName = "MODEL_NAME",
    apiKey = BuildConfig.apiKey,
    safetySettings = listOf(harassmentSafety, hateSpeechSafety)
)

Джава

SafetySetting harassmentSafety = new SafetySetting(HarmCategory.HARASSMENT,
    BlockThreshold.ONLY_HIGH);

SafetySetting hateSpeechSafety = new SafetySetting(HarmCategory.HATE_SPEECH,
    BlockThreshold.MEDIUM_AND_ABOVE);

GenerativeModel gm = new GenerativeModel(
    "MODEL_NAME",
    BuildConfig.apiKey,
    null, // generation config is optional
    Arrays.asList(harassmentSafety, hateSpeechSafety)
);

GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Что дальше

  • Проектирование подсказок — это процесс создания подсказок, которые вызывают желаемый ответ от языковых моделей. Написание хорошо структурированных подсказок является важной частью обеспечения точных и качественных ответов языковой модели. Узнайте о лучших практиках для быстрого написания .

  • Gemini предлагает несколько вариантов модели для удовлетворения потребностей различных вариантов использования, таких как типы вводов и сложность, реализации для чата или другие языковые задачи диалоговых языков и ограничения размера. Узнайте о доступных моделях Близнецов .

  • Gemini предлагает варианты для запроса ограничения на ограничение ставки . Предел скорости для моделей Gemini Pro составляет 60 запросов в минуту (обороты).

  • Клиент SDK для Android, описанный в этом уроке, позволяет вам получить доступ к моделям Gemini Pro, которые работают на серверах Google . Для вариантов использования, которые включают обработку конфиденциальных данных, доступность в автономном режиме или для экономии средств для часто используемых пользовательских потоков, вы можете рассмотреть возможность доступа к Nano Gemini, который работает на грани . Для получения более подробной информации обратитесь к учебному пособию Android (On-Device) .