Vertex AI Gemini API을 API 제공업체로 사용하는 경우에만 사용할 수 있습니다. |
Firebase AI Logic SDK를 사용하여 앱에서 Vertex AI Gemini API를 호출하면 이미지, PDF, 동영상, 오디오와 같은 멀티모달 입력을 기반으로 텍스트를 생성하도록 Gemini 모델에 프롬프트를 표시할 수 있습니다.
입력의 텍스트가 아닌 부분 (예: 미디어 파일)의 경우 선택적으로 Cloud Storage for Firebase를 사용하여 요청에 파일을 포함할 수 있습니다. 이 기능에 관해 알아야 할 사항은 다음과 같습니다.
Vertex AI Gemini API을 사용하는 경우 텍스트 생성과 채팅 등 모든 멀티모달 요청과 함께 Cloud Storage for Firebase을 사용할 수 있습니다. 이 가이드의 예에서는 기본적인 텍스트 및 이미지 입력을 보여줍니다.
요청 입력에서 파일의 MIME 유형과 Cloud Storage for Firebase URL(항상
gs://
로 시작)을 지정합니다. 이러한 값은 Cloud Storage 버킷에 업로드된 파일에 자동으로 할당되는 메타데이터입니다.지원되는 파일 형식 및 URL을 사용해야 합니다.
이 솔루션 가이드에서는 Cloud Storage for Firebase를 설정하고, 앱에서 Cloud Storage for Firebase 버킷에 파일을 업로드한 다음, Gemini API에 대한 멀티모달 요청에 파일의 MIME 유형과 Cloud Storage for Firebase URL을 포함하는 방법을 설명합니다.
코드 예시를 확인하시겠어요? 또는 이미 Cloud Storage for Firebase를 설정했고 멀티모달 요청과 함께 사용할 준비가 되었나요?
앱에서 Cloud Storage for Firebase을 사용하는 이유는 무엇인가요?
Cloud Storage for Firebase는 Google Cloud Storage와 동일한 빠르고 안전하며 확장 가능한 인프라를 사용하여 블롭과 파일을 저장하며, 클라이언트 SDK는 모바일 앱과 웹 앱을 위해 특별히 빌드됩니다.
Firebase AI Logic SDK의 경우 최대 요청 크기는 20MB입니다. 요청이 너무 크면 HTTP 413 오류가 표시됩니다. 파일 크기로 인해 총 요청 크기가 20MB를 초과하는 경우 Cloud Storage for Firebase URL을 사용하여 멀티모달 요청에 파일을 포함하세요. 하지만 파일이 작은 경우 인라인 데이터로 직접 전달할 수 있습니다(인라인 데이터로 제공된 파일은 전송 중에 base64로 인코딩되어 요청 크기가 증가함).
Cloud Storage for Firebase 사용의 추가 이점은 다음과 같습니다.
최종 사용자가 앱에서 Cloud Storage for Firebase 버킷으로 이미지를 직접 업로드하도록 할 수 있으며, 파일의 MIME 유형과 Cloud Storage for Firebase URL (파일의 식별자)을 지정하기만 하면 멀티모달 프롬프트에 해당 이미지를 포함할 수 있습니다.
최종 사용자가 이미지를 제공해야 하는 경우, 특히 네트워크 품질이 좋지 않거나 불안정한 경우 시간을 절약하고 대역폭을 줄일 수 있습니다.
- 파일 업로드 또는 다운로드가 중단되면 Cloud Storage for Firebase SDK는 중단된 지점에서 작업을 자동으로 다시 시작합니다.
- 최종 사용자가 앱에서 필요할 때마다 (예: 새로운 멀티모달 요청에서) 동일한 파일을 업로드하지 않아도 업로드된 파일을 여러 번 사용할 수 있습니다.
승인된 사용자만 파일을 업로드, 다운로드 또는 삭제할 수 있도록 하는 Firebase Security Rules를 사용하여 Cloud Storage for Firebase에 저장된 파일에 대한 최종 사용자 액세스를 제한할 수 있습니다.
Firebase 또는 Google Cloud에서 버킷의 파일에 액세스할 수 있으므로 Google Cloud Storage API를 사용하여 이미지 필터링이나 동영상 트랜스코딩과 같은 서버 측 처리를 유연하게 수행할 수 있습니다.
지원되는 파일 및 URL 유형은 무엇인가요?
Firebase AI Logic SDK와 함께 Cloud Storage for Firebase URL을 사용하려는 경우 파일 및 URL에 대한 요구사항은 다음과 같습니다.
파일은 멀티모달 요청의 입력 파일 요구사항을 충족해야 합니다. 여기에는 MIME 유형 및 파일 크기와 같은 요구사항이 포함됩니다.
파일은 Cloud Storage for Firebase 버킷에 저장되어야 합니다(즉, 버킷은 Firebase Security Rules과 같은 Firebase 서비스에서 액세스할 수 있음). Firebase 콘솔에서 버킷을 볼 수 있다면 Cloud Storage for Firebase 버킷입니다.
Cloud Storage for Firebase 버킷은 앱을 등록한 것과 동일한 Firebase 프로젝트에 있어야 합니다.
파일의 Cloud Storage for Firebase URL은 모든 Google Cloud Storage URL이 구성되는 방식인
gs://
로 시작해야 합니다.파일의 URL은 '브라우저' URL (예: 인터넷에서 찾은 이미지의 URL)일 수 없습니다.
또한 버킷의 Firebase Security Rules이 파일에 대한 적절한 액세스를 허용해야 합니다. 예를 들면 다음과 같습니다.
공개 규칙이 있는 경우 모든 사용자 또는 클라이언트가 파일에 액세스할 수 있습니다.
강력한 규칙 (권장)이 있는 경우 Firebase는 제공된 URL을 사용하여 호출이 진행되기 전에 로그인한 사용자 또는 클라이언트가 파일에 액세스할 수 있는지 확인합니다.
Firebase AI Logic에서 Cloud Storage for Firebase URL 사용
Vertex AI Gemini API을 API 제공업체로 사용하는 경우에만 사용할 수 있습니다. |
1단계: Cloud Storage for Firebase 설정
Cloud Storage for Firebase 설정에 관한 자세한 안내는 시작 가이드(iOS+ | Android | 웹 | Flutter | Unity)를 참고하세요.
해야 할 주요 작업은 다음과 같습니다.
Firebase 프로젝트에서 Cloud Storage for Firebase 버킷을 만들거나 가져옵니다.
이 버킷에 Firebase Security Rules을 적용합니다. Rules를 사용하면 승인된 최종 사용자의 액세스를 제한하여 파일을 보호할 수 있습니다.
앱에 Cloud Storage for Firebase 클라이언트 라이브러리를 추가합니다.
이 작업을 건너뛸 수 있지만, 항상 요청에 MIME 유형 및 URL 값을 명시적으로 포함해야 합니다.
2단계: 버킷에 파일 업로드
Cloud Storage 문서에서 버킷에 파일을 업로드하는 다양한 방법을 모두 알아볼 수 있습니다. 예를 들어 카메라의 사진 및 동영상과 같은 최종 사용자 기기의 로컬 파일을 업로드할 수 있습니다. 자세히 알아보기: iOS+ | Android | 웹 | Flutter | Unity
버킷에 파일을 업로드하면 Cloud Storage에서 파일에 다음 두 가지 정보를 자동으로 적용합니다. 이 가이드의 다음 단계에 표시된 대로 요청에 이러한 값을 포함해야 합니다.
MIME 유형: 파일의 미디어 유형입니다 (예:
image/png
). 업로드 중에 MIME 유형이 자동으로 감지되고 해당 메타데이터가 버킷의 객체에 적용됩니다. 하지만 업로드 중에 MIME 유형을 선택적으로 지정할 수 있습니다.Cloud Storage for Firebase URL: 파일의 고유 식별자입니다. URL은
gs://
로 시작해야 합니다.
3단계: 멀티모달 요청에 파일의 MIME 유형과 URL 포함
버킷에 저장된 파일이 있으면 요청에 MIME 유형과 URL을 포함할 수 있습니다. 이 예에서는 비스트리밍 generateContent
요청을 보여주지만 스트리밍 및 채팅이 포함된 URL을 사용할 수도 있습니다.
요청에 파일을 포함하려면 다음 옵션 중 하나를 사용하면 됩니다.
옵션 2: MIME 유형과 URL을 명시적으로 포함
옵션 1: 스토리지 참조를 사용하여 MIME 유형과 URL 포함
이 예시를 시도하기 전에 Firebase AI Logic SDK 시작 가이드를 완료해야 합니다. |
버킷에 파일을 업로드한 직후 요청에 파일을 즉시 포함 (스토리지 참조를 통해)하려면 이 옵션을 사용하세요. 호출에는 MIME 유형과 Cloud Storage for Firebase URL이 모두 필요합니다.
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 = generativeModel.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 = { 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 유형과 Cloud Storage for Firebase URL의 값을 알고 있고 멀티모달 요청에 명시적으로 포함하려는 경우 이 옵션을 사용합니다. 이 호출에는 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 = generativeModel.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 = { 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.");