תחילת השימוש ב-Prompt API

בדף הזה נסביר איך:

  • הגדרת הפרויקט לשימוש ב-Prompt API
  • הזנת קלט של טקסט בלבד וקבלת תשובה
  • לספק קלט של תמונה עם קלט טקסט קשור ולקבל תשובה

פרטים נוספים על Prompt API זמינים במסמכי העיון של Kotlin ‏ (com.google.mlkit.genai.prompt) ו-Java ‏ (com.google.mlkit.genai.prompt.java,‏ com.google.mlkit.genai.prompt).

[אופציונלי] בדיקת ההנחיה באמצעות מודל Gemma 3n

לפני ההטמעה, כדאי לבדוק את ההנחיה ב-AI Studio באמצעות מודל Gemma 3n E4B. הפלט של Gemma 3n צפוי להיות דומה מאוד לפלט של nano-v3.

הגדרת הפרויקט

מוסיפים את ML Kit Prompt API כתלות בהגדרה של build.gradle:

implementation("com.google.mlkit:genai-prompt:1.0.0-alpha1")

הטמעה של מודל גנרטיבי

כדי להטמיע את הקוד בפרויקט, פועלים לפי השלבים הבאים:

  • יוצרים אובייקט generativeModel:

    Kotlin

    // Get a GenerativeModel instance
    val generativeModel = Generation.getClient()
    

    Java

    // Get a GenerativeModel instance
    GenerativeModelFutures generativeModelFutures = GenerativeModelFutures
        .from(Generation.INSTANCE.getClient());
    
  • בודקים אם Gemini Nano הוא AVAILABLE, DOWNLOADABLE או UNAVAILABLE. לאחר מכן, מורידים את התכונה אם אפשר להוריד אותה:

    Kotlin

    val status = generativeModel.checkStatus()
    when (status) {
        FeatureStatus.UNAVAILABLE -> {
            // Gemini Nano not supported on this device or device hasn't fetched the latest configuration to support it
        }
    
        FeatureStatus.DOWNLOADABLE -> {
            // Gemini Nano can be downloaded on this device, but is not currently downloaded
            generativeModel.download().collect { status ->
                when (status) {
                    is DownloadStatus.DownloadStarted ->
                        Log.d(TAG, "starting download for Gemini Nano")
    
                    is DownloadStatus.DownloadProgress ->
                        Log.d(TAG, "Nano ${status.totalBytesDownloaded} bytes downloaded")
    
                    DownloadStatus.DownloadCompleted -> {
                        Log.d(TAG, "Gemini Nano download complete")
                        modelDownloaded = true
                    }
    
                    is DownloadStatus.DownloadFailed -> {
                        Log.e(TAG, "Nano download failed ${status.e.message}")
                    }
                }
            }
        }
    
        FeatureStatus.DOWNLOADING -> {
            // Gemini Nano currently being downloaded
        }
    
        FeatureStatus.AVAILABLE -> {
            // Gemini Nano currently downloaded and available to use on this device
        }
    }
    

    Java

    ListenableFuture<Integer> status = generativeModelFutures.checkStatus();
    Futures.addCallback(generativeModelFutures.checkStatus(), new FutureCallback<>() {
        @Override
        public void onSuccess(Integer featureStatus) {
            switch (featureStatus) {
                case FeatureStatus.AVAILABLE - > {
                    // Gemini Nano currently downloaded and available to use on this device
                }
                case FeatureStatus.UNAVAILABLE - > {
                    // Gemini Nano not supported on this device or device hasn't fetched the latest configuration to support it
                }
                case FeatureStatus.DOWNLOADING - > {
                    // Gemini Nano currently being downloaded
                }
                case FeatureStatus.DOWNLOADABLE - > {
                    generativeModelFutures.download(new DownloadCallback() {
                        @Override
                        public void onDownloadStarted(long l) {
                            Log.d(TAG, "starting download for Gemini Nano");
                        }
                        @Override
                        public void onDownloadProgress(long l) {
                            Log.d(TAG, "Nano " + l + " bytes downloaded");
                        }
                        @Override
                        public void onDownloadCompleted() {
                            Log.d(TAG, "Gemini Nano download complete");
                        }
                        @Override
                        public void onDownloadFailed(@NonNull GenAiException e) {
                            Log.e(TAG, "Nano download failed: " + e.getMessage());
                        }
                    });
                }
            }
        }
        @Override
        public void onFailure(@NonNull Throwable t) {
            // Failed to check status
        }
    }, ContextCompat.getMainExecutor(context));
    
    

הזנת קלט של טקסט בלבד

Kotlin

val response = generativeModel.generateContent("Write a 3 sentence story about a magical dog.")

Java

GenerateContentResponse response = generativeModelFutures.generateContent(
  new GenerateContentRequest.Builder(
    new TextPart("Write a 3 sentence story about a magical dog."))
  .build())
  .get();

אפשר גם להוסיף פרמטרים אופציונליים:

Kotlin

val response = generativeModel.generateContent(
    generateContentRequest(
        TextPart("Write a 3 sentence story about a magical dog."),
    ) {
        // Optional parameters
        temperature = 0.2f
        topK = 10
        candidateCount = 3
    },
)

Java

GenerateContentRequest.Builder requestBuilder =
        new GenerateContentRequest.Builder(
                new TextPart("Write a 3 sentence story about a magical dog."));
requestBuilder.setTemperature(.2f);
requestBuilder.setTopK(10);
requestBuilder.setCandidateCount(3);

GenerateContentResponse response =
        generativeModelFutures.generateContent(requestBuilder.build()).get();

מידע נוסף על הפרמטרים האופציונליים זמין במאמר הגדרות אופציונליות.

הזנת קלט מולטי-מודאלי (תמונה וטקסט)

מאגדים תמונה וקלט טקסט יחד בפונקציה generateContentRequest() עם הנחיית טקסט שהיא שאלה או פקודה שקשורות לתמונה:

Kotlin

val response = generativeModel.generateContent(
    generateContentRequest(ImagePart(bitmap), TextPart(textPrompt)) {
        // optional parameters
        ...
    },
)

Java

GenerateContentResponse response = generativeModelFutures.generateContent(
    new GenerateContentRequest.Builder(
        new ImagePart(bitmap),
        new TextPart("textPrompt"))
    // optional parameters
    .build())
.get();

עיבוד תוצאת ההסקה

  • מריצים את ההסקה ומאחזרים את התוצאה. אתם יכולים לבחור לחכות עד שהתוצאה המלאה תהיה מוכנה, או להזרים את התשובה בזמן שהיא נוצרת, גם בהנחיות טקסט בלבד וגם בהנחיות מולטימודאליות.

    • השיטה הזו משתמשת בהסקת מסקנות לא רציפה, שבה המערכת מאחזרת את כל התוצאה ממודל הבינה המלאכותית לפני שהיא מחזירה את התוצאה:

    Kotlin

    // Call the AI model to generate content and store the complete
    // in a new variable named 'response' once it's finished
    val response = generativeModel.generateContent("Write a 3 sentence story about a magical dog")
    

    Java

    GenerateContentResponse response = generativeModelFutures.generateContent(
            new GenerateContentRequest.Builder(
                    new TextPart("Write a 3 sentence story about a magical dog."))
                    .build())
            .get();
    
    • קטעי הקוד הבאים הם דוגמאות לשימוש בהסקת מסקנות בזמן אמת, שבה התוצאה מתקבלת בחלקים בזמן שהיא נוצרת:

    Kotlin

    // Streaming inference
    var fullResponse = ""
    generativeModel.generateContentStream("Write a 3 sentence story about a magical dog").collect { chunk ->
        val newChunkReceived = chunk.candidates[0].text
        print(newChunkReceived)
        fullResponse += newChunkReceived
    }
    

    Java

    // Streaming inference
    StringBuilder fullResponse = new StringBuilder();
    generativeModelFutures.generateContent(new GenerateContentRequest.Builder(
        (new TextPart("Write a 3 sentence story about a magical dog"))).build(),
            chunk -> {
                Log.d(TAG, chunk);
                fullResponse.append(chunk);
            });
    

מידע נוסף על הסקת מסקנות בסטרימינג ובלי סטרימינג זמין במאמר בנושא סטרימינג לעומת אי-סטרימינג.

אופטימיזציה של זמן האחזור

כדי לבצע אופטימיזציה לקריאה הראשונה של ההסקה, האפליקציה יכולה לקרוא ל-warmup(). הפעולה הזו טוענת את Gemini Nano לזיכרון ומאתחלת רכיבי זמן ריצה.

הגדרות אופציונליות

בכל GenerateContentRequest, אפשר להגדיר את הפרמטרים האופציונליים הבאים:

  • temperature : שולט במידת האקראיות בבחירת האסימון.
  • seed : מאפשר יצירת תוצאות יציבות ודטרמיניסטיות.
  • topK : שליטה באקראיות ובגיוון של התוצאות.
  • candidateCount : בקשה למספר התגובות הייחודיות שהוחזרו. שימו לב: יכול להיות שהמספר המדויק של התשובות לא יהיה זהה למספר שמופיע ב-candidateCount, כי המערכת מסירה באופן אוטומטי תשובות כפולות.
  • maxOutputTokens : הגדרת המספר המקסימלי של טוקנים שאפשר ליצור בתשובה.

הנחיות נוספות להגדרת תצורות אופציונליות זמינות במאמר GenerateContentRequest.

תכונות נתמכות ומגבלות

  • הקלט צריך להיות באורך של פחות מ-4,000 טוקנים (או בערך 3,000 מילים באנגלית). מידע נוסף זמין במאמר בנושא countTokens.
  • מומלץ להימנע מתרחישי שימוש שדורשים פלט ארוך (יותר מ-256 טוקנים).
  • ב-AICore יש מכסת הסקה לכל אפליקציה. מידע נוסף זמין במאמר בנושא מכסה לכל אפליקציה.
  • השפות הבאות אומתו לשימוש ב-Prompt API:
    • אנגלית
    • קוריאנית

בעיות נפוצות בהגדרה

ממשקי ה-API של GenAI ב-ML Kit מסתמכים על אפליקציית Android AICore כדי לגשת ל-Gemini Nano. כשמגדירים מכשיר חדש (כולל איפוס), או כשמאפסים את אפליקציית AICore (למשל, מוחקים את הנתונים, מסירים את ההתקנה ואז מתקינים מחדש), יכול להיות שלאפליקציית AICore לא יהיה מספיק זמן לסיים את האתחול (כולל הורדת ההגדרות האחרונות מהשרת). כתוצאה מכך, יכול להיות שממשקי ה-API של ML Kit GenAI לא יפעלו כמצופה. ריכזנו כאן הודעות שגיאה נפוצות שמוצגות במהלך ההגדרה והסבר איך לטפל בהן:

דוגמה להודעת שגיאה איך לטפל בבעיה
הפעולה של AICore נכשלה עם סוג השגיאה 4-CONNECTION_ERROR וקוד השגיאה 601-BINDING_FAILURE: שירות AICore נכשל בקישור. זה יכול לקרות כשמתקינים את האפליקציה באמצעות ממשקי ה-API של ML Kit GenAI מיד אחרי הגדרת המכשיר, או כשמסירים את ההתקנה של AICore אחרי התקנת האפליקציה. עדכון של אפליקציית AICore ואז התקנה מחדש של האפליקציה אמורים לפתור את הבעיה.
הפעולה של AICore נכשלה עם סוג השגיאה 3-PREPARATION_ERROR וקוד השגיאה 606-FEATURE_NOT_FOUND: התכונה ... לא זמינה. יכול להיות שהמצב הזה קורה כי AICore לא סיים להוריד את ההגדרות האחרונות. כשהמכשיר מחובר לאינטרנט, העדכון מתבצע בדרך כלל תוך כמה דקות עד כמה שעות. הפעלה מחדש של המכשיר יכולה להאיץ את העדכון.

שימו לב שאם טוען האתחול של המכשיר לא נעול, תוצג גם השגיאה הזו – ה-API הזה לא תומך במכשירים עם טועני אתחול לא נעולים.
הפעולה של AICore נכשלה עם סוג השגיאה 1-DOWNLOAD_ERROR וקוד השגיאה 0-UNKNOWN: התכונה ... נכשלה עם סטטוס הכשל 0 והשגיאה esz: UNAVAILABLE: Unable to resolve host ... משאירים את החיבור לרשת, מחכים כמה דקות ומנסים שוב.