Как добавлять большие файлы в мультимодальные запросы и управлять файлами с помощью Cloud Storage for Firebase

Доступно, только если вы используете Agent Platform Gemini API (formerly Vertex AI) в качестве поставщика API.

При вызове Agent Platform Gemini API (formerly Vertex AI) из приложения с помощью SDK Firebase AI Logic вы можете попросить модель Gemini сгенерировать текст на основе мультимодальных входных данных, таких как изображения, PDF-файлы, видео и аудио.

Для нетекстовых частей входных данных (например, медиафайлов) вы можете использовать Cloud Storage for Firebase, чтобы включить файлы в запрос. Вот что нужно знать об этой функции:

  • Вы можете использовать Cloud Storage for Firebase с любым мультимодальным запросом (например, для генерации текста и в чате), если вы используете Agent Platform Gemini API (formerly Vertex AI). В примерах этого руководства показан базовый ввод текста и изображений.

  • В запросе необходимо указать MIME-тип файла и его URL в Cloud Storage for Firebase (всегда начинается с gs://). Эти значения представляют собой метаданные, которые автоматически присваиваются любому файлу, загруженному в сегмент Cloud Storage.

  • Используйте поддерживаемый тип файла и URL.


В этом руководстве рассказывается, как настроить Cloud Storage for Firebase, загрузить файл в корзину Cloud Storage for Firebase из приложения, а затем включить MIME-тип файла и URL Cloud Storage for Firebase в мультимодальный запрос к Gemini API.

Хотите посмотреть примеры кода? Или вы уже настроили Cloud Storage for Firebase и готовы использовать ее для мультимодальных запросов?

Перейти к примерам кода

Зачем использовать Cloud Storage for Firebase в приложении?

Cloud Storage for Firebase использует ту же быструю, безопасную и масштабируемую инфраструктуру, что и Google Cloud Storage, для хранения больших двоичных объектов и файлов, а его клиентские SDK созданы специально для мобильных и веб-приложений.

Для SDK Firebase AI Logic максимальный размер запроса составляет 20 МБ. Если запрос слишком большой, вы получите ошибку HTTP 413. Если размер файла превышает 20 МБ, используйте URL Cloud Storage for Firebase, чтобы включить файл в мультимодальный запрос. Однако если файл небольшой, вы часто можете передать его напрямую в виде встроенных данных (обратите внимание, что файл, предоставленный в виде встроенных данных, при передаче кодируется в base64, что увеличивает размер запроса).

Вот ещё несколько преимуществ Cloud Storage for Firebase:

  • Вы можете разрешить конечным пользователям загружать изображения из вашего приложения напрямую в сегмент Cloud Storage for Firebase, а затем включать эти изображения в мультимодальные запросы, просто указывая MIME-тип файла и URL Cloud Storage for Firebase (который является идентификатором файла).

  • Вы можете сэкономить время и трафик конечных пользователей, если им нужно предоставить изображения, особенно если у них плохое или нестабильное качество сети.

    • Если загрузка или скачивание файла прерывается, SDK Cloud Storage for Firebase автоматически возобновляет операцию с того места, где она была прервана.
    • Один и тот же загруженный файл можно использовать несколько раз, и конечному пользователю не придется загружать его каждый раз, когда он нужен в вашем приложении (например, в новом мультимодальном запросе).
  • Вы можете ограничить доступ конечных пользователей к файлам, хранящимся в Cloud Storage for Firebase, с помощью Firebase Security Rules, которые позволяют только авторизованным пользователям загружать, скачивать или удалять файлы.

  • Вы можете получить доступ к файлам в сегменте из Firebase или Google Cloud, что позволяет выполнять обработку на стороне сервера, например фильтрацию изображений или перекодирование видео, с помощью API Google Cloud Storage.

Какие типы файлов и URL поддерживаются?

Ниже приведены требования к файлам и URL, если вы хотите использовать URL Cloud Storage for Firebase с SDK Firebase AI Logic.

  • Файл должен соответствовать требованиям к входным файлам для мультимодальных запросов. в том числе требования к MIME-типу и размеру файла.

  • Файл должен храниться в сегменте Cloud Storage for Firebase, то есть сегменте, доступном для сервисов Firebase, таких как Firebase Security Rules. Если вы можете просматривать сегмент в консоли Firebase, значит это сегмент Cloud Storage for Firebase.

  • Сегмент Cloud Storage for Firebase должен находиться в том же проекте Firebase, в котором вы зарегистрировали приложение.

  • URL файла Cloud Storage for Firebase должен начинаться с gs://. Так создаются все URL Google Cloud Storage.

  • URL файла не может быть URL браузера (например, URL изображения, найденного в интернете).

Кроме того, Firebase Security Rules для вашего сегмента должен разрешать соответствующий доступ к файлу. Пример:

  • Если у вас есть общедоступные правила, то любой пользователь или клиент может получить доступ к файлу.

  • Если у вас настроены надежные правила (настоятельно рекомендуется), Firebase проверит, есть ли у вошедшего в систему пользователя или клиента достаточный доступ к файлу, прежде чем разрешить вызов с указанным URL.

Используйте URL-адреса Cloud Storage for Firebase с Firebase AI Logic

Доступно, только если вы используете Agent Platform Gemini API (formerly Vertex AI) в качестве поставщика API.

Шаг 1. Настройте Cloud Storage for Firebase

Подробные инструкции по настройке Cloud Storage for Firebase можно найти в руководстве по началу работы: iOS+ | Android | Web | Flutter | Unity

Вот что вам нужно будет сделать:

  1. Создайте или импортируйте сегмент Cloud Storage for Firebase в проекте Firebase.

  2. Примените к этому сегменту Firebase Security Rules. Security Rules помогают защитить файлы, ограничивая доступ к ним только авторизованными конечными пользователями.

  3. Добавьте в приложение клиентскую библиотеку для Cloud Storage for Firebase.

    Вы можете пропустить этот шаг, но тогда вам придется всегда явно указывать MIME-тип и URL в запросах.

Шаг 2. Загрузите файл в сегмент

В документации по Cloud Storage вы можете узнать обо всех способах загрузки файлов в сегмент. Например, вы можете загружать локальные файлы с устройства конечного пользователя, такие как фотографии и видео с камеры. Подробнее: iOS+ | Android | Web | Flutter | Unity

При загрузке файла в сегмент Cloud Storage автоматически добавляет к нему два элемента информации. Эти значения нужно будет включить в запрос (как показано на следующем шаге этого руководства).

  • MIME-тип. Это тип медиаконтента в файле (например, image/png). Мы автоматически попытаемся определить MIME-тип во время загрузки и применим эти метаданные к объекту в сегменте. Однако при загрузке вы можете указать MIME-тип.

  • URL Cloud Storage for Firebase – уникальный идентификатор файла. URL должен начинаться с gs://.

Шаг 3. Укажите MIME-тип и URL файла в мультимодальном запросе

После того как вы сохраните файл в сегменте, вы сможете включить его MIME-тип и URL в запрос. Обратите внимание, что в этих примерах показан запрос generateContent без потоковой передачи, но вы также можете использовать URL с потоковой передачей и чатом.

Чтобы включить файл в запрос, вы можете использовать один из следующих вариантов:

Вариант 1. Укажите MIME-тип и URL, используя ссылку на хранилище

Прежде чем попробовать этот пример, убедитесь, что вы выполнили инструкции из краткого руководства по работе с Firebase AI Logic SDK.

Используйте этот вариант, если вы только что загрузили файл в сегмент и хотите сразу же включить его в запрос (через ссылку на хранилище). Для вызова требуется MIME-тип и URL Cloud Storage for Firebase.

Swift

// Upload an image file using Cloud Storage for Firebase.
let storageRef = Storage.storage().reference(withPath: "images/image.jpg")
guard let imageURL = Bundle.main.url(forResource: "image", withExtension: "jpg") else {
  fatalError("File 'image.jpg' not found in main bundle.")
}
let metadata = try await storageRef.putFileAsync(from: imageURL)

// Get the MIME type and Cloud Storage for Firebase URL.
guard let mimeType = metadata.contentType else {
  fatalError("The MIME type of the uploaded image is nil.")
}
// Construct a URL in the required format.
let storageURL = "gs://\(storageRef.bucket)/\(storageRef.fullPath)"

let prompt = "What's in this picture?"
// Construct the imagePart with the MIME type and the URL.
let imagePart = FileDataPart(uri: storageURL, mimeType: mimeType)

// To generate text output, call generateContent with the prompt and the imagePart.
let result = try await model.generateContent(prompt, imagePart)
if let text = result.text {
  print(text)
}

Kotlin

В Kotlin методы этого SDK являются функциями приостановки и должны вызываться из области сопрограммы.
// Upload an image file using Cloud Storage for Firebase.
val storageRef = Firebase.storage.reference.child("images/image.jpg")
val fileUri = Uri.fromFile(File("image.jpg"))
try {
    val taskSnapshot = storageRef.putFile(fileUri).await()
    // Get the MIME type and Cloud Storage for Firebase file path.
    val mimeType = taskSnapshot.metadata?.contentType
    val bucket = taskSnapshot.metadata?.bucket
    val filePath = taskSnapshot.metadata?.path

    if (mimeType != null && bucket != null) {
        // Construct a URL in the required format.
        val storageUrl = "gs://$bucket/$filePath"
        // Construct a prompt that includes text, the MIME type, and the URL.
        val prompt = content {
            fileData(mimeType = mimeType, uri = storageUrl)
            text("What's in this picture?")
        }
        // To generate text output, call generateContent with the prompt.
        val response = model.generateContent(prompt)
        println(response.text)
    }
} catch (e: StorageException) {
    // An error occurred while uploading the file.
} catch (e: GoogleGenerativeAIException) {
    // An error occurred while generating text.
}

Java

В Java методы этого SDK возвращают ListenableFuture.
// Upload an image file using Cloud Storage for Firebase.
StorageReference storage = FirebaseStorage.getInstance().getReference("images/image.jpg");
Uri fileUri = Uri.fromFile(new File("images/image.jpg"));

storage.putFile(fileUri).addOnSuccessListener(taskSnapshot -> {
    // Get the MIME type and Cloud Storage for Firebase file path.
    String mimeType = taskSnapshot.getMetadata().getContentType();
    String bucket = taskSnapshot.getMetadata().getBucket();
    String filePath = taskSnapshot.getMetadata().getPath();

    if (mimeType != null && bucket != null) {
        // Construct a URL in the required format.
        String storageUrl = "gs://" + bucket + "/" + filePath;
        // Create a prompt that includes text, the MIME type, and the URL.
        Content prompt = new Content.Builder()
                .addFileData(storageUrl, mimeType)
                .addText("What's in this picture?")
                .build();

        // To generate text output, call generateContent with the prompt.
        GenerativeModelFutures modelFutures = GenerativeModelFutures.from(model);
        ListenableFuture<GenerateContentResponse> response = modelFutures.generateContent(prompt);
        Futures.addCallback(response, new FutureCallback<>() {
            @Override
            public void onSuccess(GenerateContentResponse result) {
                String resultText = result.getText();
                System.out.println(resultText);
            }

            @Override
            public void onFailure(@NonNull Throwable t) {
                t.printStackTrace();
            }
        }, executor);
    }
}).addOnFailureListener(e -> {
    // An error occurred while uploading the file.
    e.printStackTrace();
});

Web

// Upload an image file using Cloud Storage for Firebase.
const storageRef = ref(storage, "image.jpg");
const uploadResult = await uploadBytes(storageRef, file);

// Get the MIME type and Cloud Storage for Firebase URL.
// toString() is the simplest way to construct the Cloud Storage for Firebase URL
// in the required format.
const mimeType = uploadResult.metadata.contentType;
const storageUrl = uploadResult.ref.toString();

// Construct the imagePart with the MIME type and the URL.
const imagePart = { type: "fileData", fileData: { mimeType, fileUri: storageUrl }};

// To generate text output, call generateContent with the prompt and imagePart.
const result = await model.generateContent([prompt, imagePart]);
console.log(result.response.text());

Dart

// Upload an image file using Cloud Storage for Firebase.
final storageRef = FirebaseStorage.instance.ref();
final imageRef = storageRef.child("images/image.jpg");
await imageRef.putData(data);

// Get the MIME type and Cloud Storage for Firebase file path.
final metadata = await imageRef.getMetadata();
final mimeType = metadata.contentType;
final bucket = imageRef.bucket;
final fullPath = imageRef.fullPath;

final prompt = TextPart("What's in the picture?");
// Construct a URL in the required format.
final storageUrl = 'gs://$bucket/$fullPath';
// Construct the filePart with the MIME type and the URL.
final filePart = FileData(mimeType, storageUrl);
// To generate text output, call generateContent with the text and the filePart.
final response = await model.generateContent([
  Content.multi([prompt, filePart])
]);
print(response.text);

Unity

var storageRef = FirebaseStorage.DefaultInstance.GetReference("images/image.jpg");
var metadata = await storageRef.PutFileAsync(filePathToJpg);

// Get the MIME type and Cloud Storage for Firebase URL.
var mimeType = metadata.ContentType;
// Construct a URL in the required format.
var storageURL = new Uri($"gs://{storageRef.Bucket}/{storageRef.Path}");

var prompt = ModelContent.Text("What's in this picture?");
// Construct a FileData that explicitly includes the MIME type and
// Cloud Storage for Firebase URL values.
var fileData = ModelContent.FileData(mimeType, storageURL);

// To generate text output, call GenerateContentAsync with the prompt and fileData.
var response = await model.GenerateContentAsync(new [] { prompt, fileData });
UnityEngine.Debug.Log(response.Text ?? "No text in response.");

Вариант 2. Явно укажите MIME-тип и URL

Прежде чем использовать этот пример, убедитесь, что вы ознакомились с кратким руководством по началу работы с Firebase AI Logic SDK.

Используйте этот вариант, если вы знаете значения для MIME-типа и URL Cloud Storage for Firebase и хотите явно включить их в мультимодальный запрос. В вызове должны быть указаны и MIME-тип, и URL.

Swift

let prompt = "What's in this picture?"
// Construct an imagePart that explicitly includes the MIME type and
// Cloud Storage for Firebase URL values.
let imagePart = FileDataPart(uri: "gs://bucket-name/path/image.jpg", mimeType: "image/jpeg")

// To generate text output, call generateContent with the prompt and imagePart.
let result = try await model.generateContent(prompt, imagePart)
if let text = result.text {
  print(text)
}

Kotlin

В Kotlin методы этого SDK являются функциями приостановки и должны вызываться из области сопрограммы.
// Construct a prompt that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
val prompt = content {
    fileData(mimeType = "image/jpeg", uri = "gs://bucket-name/path/image.jpg")
    text("What's in this picture?")
}
// To generate text output, call generateContent with the prompt.
val response = model.generateContent(prompt)
println(response.text)

Java

В Java методы этого SDK возвращают ListenableFuture.
// Construct a prompt that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
Content prompt = new Content.Builder()
        .addFilePart("gs://bucket-name/path/image.jpg", "image/jpeg")
        .addText("What's in this picture?")
        .build();

// To generate text output, call generateContent with the prompt
GenerativeModelFutures modelFutures = GenerativeModelFutures.from(model);
ListenableFuture<GenerateContentResponse> response = modelFutures.generateContent(prompt);
Futures.addCallback(response, new FutureCallback<>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        String resultText = result.getText();
        System.out.println(resultText);
    }

    @Override
    public void onFailure(@NonNull Throwable t) {
        t.printStackTrace();
    }
}, executor);

Web

const prompt = "What's in this picture?";
// Construct an imagePart that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
const imagePart = { type: "fileData", fileData: { mimeType: "image/jpeg", fileUri: "gs://bucket-name/path/image.jpg" }};

// To generate text output, call generateContent with the prompt and imagePart.
const result = await model.generateContent([prompt, imagePart]);
console.log(result.response.text());

Dart

final prompt = TextPart("What's in the picture?");
// Construct a filePart that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
final filePart = FileData('image/jpeg', 'gs://bucket-name/path/image.jpg');
// To generate text output, call generateContent with the prompt and filePart.
final response = await model.generateContent([
  Content.multi([prompt, filePart])
]);
print(response.text);

Unity

var prompt = ModelContent.Text("What's in this picture?");
// Construct a FileData that explicitly includes the MIME type and
// Cloud Storage for Firebase URL values.
var fileData = ModelContent.FileData(
  mimeType: "image/jpeg",
  uri: new Uri("gs://bucket-name/path/image.jpg")
);

// To generate text output, call GenerateContentAsync with the prompt and fileData.
var response = await model.GenerateContentAsync(new [] { prompt, fileData });
UnityEngine.Debug.Log(response.Text ?? "No text in response.");