כשאתם קוראים ל-Gemini API מהאפליקציה באמצעות SDK של Vertex AI in Firebase, אתם יכולים לבקש ממודל Gemini ליצור טקסט על סמך קלט רב-מודלי. הנחיות מרובה-מצבים יכולות לכלול כמה מודלים (או סוגי קלט), כמו טקסט עם תמונות, קובצי PDF, סרטונים ואודיו.
בחלקים של הקלט שאינם טקסט (כמו קובצי מדיה), אפשר להשתמש ב-Cloud Storage for Firebase כדי לכלול קבצים בבקשה. באופן כללי, זה מה שצריך לדעת על התכונה הזו:
אפשר להשתמש ב-Cloud Storage for Firebase בכל בקשה עם כמה מודלים (כמו יצירת טקסט וצ'אט). בדוגמאות במדריך הזה מוצגת קלט בסיסי של טקסט ותמונה.
צריך לציין את סוג ה-MIME של הקובץ ואת כתובת ה-URL שלו מסוג Cloud Storage for Firebase (שתמיד מתחילה ב-
gs://
) בקלט הבקשה. הערכים האלה הם מטא-נתונים שמוקציים באופן אוטומטי לכל קובץ שמעלים לקטגוריה Cloud Storage.צריך להשתמש בסוג קובץ וכתובת URL נתמכים.
במדריך הפתרון הזה מוסבר איך להגדיר את Cloud Storage for Firebase, להעלות קובץ לקטגוריה (bucket) 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 לאחסון blobs וקובצי, וערכות ה-SDK של הלקוח שלו מיועדות במיוחד לאפליקציות לנייד ולאינטרנט.
ב-SDK של Vertex AI in Firebase, גודל הבקשה המקסימלי הוא 20MB. אם הבקשה גדולה מדי, תופיע שגיאת HTTP 413. אם גודל הקובץ יגרום לגודל הבקשה הכולל לחרוג מ-20MB, צריך להשתמש בכתובת 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 של Vertex AI in Firebase:
כשמשתמשים ב-SDKs של Vertex AI in Firebase, הקובץ צריך לעמוד בדרישות של קובצי קלט לבקשות עם כמה מודלים. הדרישות האלה כוללות, למשל, סוג MIME וגודל הקובץ.
הקובץ צריך להיות מאוחסן בקטגוריה (bucket) מסוג 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 של הקטגוריה צריך לאפשר גישה מתאימה לקובץ. לדוגמה:
אם יש לכם כללים ציבוריים, כל משתמש או לקוח יכול לגשת לקובץ ולספק את כתובת ה-URL שלו בקריאה באמצעות Vertex AI in Firebase SDK. יש להשתמש בסוגים האלה של כללים רק כדי להתחיל לעבוד ובשלבי האב-טיפוס המוקדמים (אלא אם הקבצים מיועדים להיות קבצים שיהיו נגישים לכולם).
אם יש לכם כללים חזקים (מומלץ מאוד), מערכת Firebase תבדוק שלמשתמש או ללקוח שמחוברים לחשבון יש גישה מספקת לקובץ לפני שהיא תאפשר להפעלה להמשיך עם כתובת ה-URL שסופקה.
שימוש בכתובות URL מסוג Cloud Storage for Firebase עם Vertex AI in Firebase
שלב 1: מגדירים את Cloud Storage for Firebase
הוראות מפורטות להגדרת Cloud Storage for Firebase מפורטות במדריך למתחילים: iOS+ | Android | אינטרנט | Flutter
אלה המשימות ברמה גבוהה שצריך לבצע:
יוצרים או מייבאים קטגוריה מסוג Cloud Storage for Firebase בפרויקט Firebase.
מחילים את Firebase Security Rules על הקטגוריה הזו. Rules יעזרו לכם לאבטח את הקבצים על ידי הגבלת הגישה למשתמשי קצה מורשים.
מוסיפים לאפליקציה את ספריית הלקוח של Cloud Storage for Firebase.
שימו לב שאפשר לדלג על המשימה הזו, אבל אם תעשו זאת תצטרכו תמיד לכלול במפורש את סוג ה-MIME ואת ערכי כתובות ה-URL בבקשות.
שלב 2: מעלים קובץ לקטגוריה
במסמכי העזרה של Cloud Storage מפורטות כל הדרכים להעלאת קבצים לקטגוריה. לדוגמה, אפשר להעלות קבצים מקומיים ממכשיר של משתמש הקצה, כמו תמונות וסרטונים מהמצלמה. מידע נוסף: iOS+ | Android | אינטרנט | Flutter
כשאתם מעלים קובץ לקטגוריה, Cloud Storage מחיל עליו באופן אוטומטי את שני פרטי המידע הבאים. תצטרכו לכלול את הערכים האלה בבקשה (כפי שמתואר בשלב הבא במדריך הזה).
סוג MIME: זהו סוג המדיה של הקובץ (לדוגמה,
image/png
). אנחנו ננסה לזהות את סוג ה-MIME באופן אוטומטי במהלך ההעלאה ולהחיל את המטא-נתונים האלה על האובייקט בקטגוריה. עם זאת, אפשר לציין את סוג ה-MIME במהלך ההעלאה.כתובת ה-URL של Cloud Storage for Firebase: זהו מזהה ייחודי של הקובץ. כתובת ה-URL חייבת להתחיל ב-
gs://
.
שלב 3: כוללים את סוג ה-MIME ואת כתובת ה-URL של הקובץ בבקשה רב-מודאלית
אחרי שמאחסנים קובץ בקטגוריה, אפשר לכלול את סוג ה-MIME ואת כתובת ה-URL שלו בבקשה. חשוב לזכור שבדוגמאות האלה מוצגת בקשה מסוג generateContent
ללא סטרימינג, אבל אפשר גם להשתמש בכתובות URL עם סטרימינג וצ'אט.
כדי לכלול את הקובץ בבקשה, אפשר להשתמש באחת מהאפשרויות הבאות:
אפשרות 1: הוספת סוג ה-MIME וכתובת ה-URL באמצעות הפניה ל-Storage
השתמשו באפשרות הזו אם העליתם את הקובץ לקטגוריה זה עתה ואתם רוצים לכלול את הקובץ (דרך הפניה ל-Storage) בבקשה באופן מיידי. בקריאה נדרשים גם סוג ה-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 הזה הן פונקציות השהיה (suspend) וצריך לקרוא להן מהיקף של פונקציית אירוע (coroutine).// 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);
אפשרות 2: כוללים את סוג ה-MIME ואת כתובת ה-URL באופן מפורש
משתמשים באפשרות הזו אם אתם יודעים את הערכים של סוג ה-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 הזה הן פונקציות השהיה (suspend) וצריך לקרוא להן מהיקף של פונקציית אירוע (coroutine).// 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);