GenAI Rewriting API

בעזרת GenAI Rewriting API של ML Kit, תוכלו לעזור למשתמשים לשכתב באופן אוטומטי הודעות בצ'אט או קטעי תוכן קצרים בסגנון או בנימה שונים.

יכול להיות שמשתמשים ירצו לקבל הצעות לשכתוב של תוכן במקרים הבאים:

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

יכולות עיקריות

ה-API של GenAI Rewriting ב-ML Kit יכול לשכתב קטעי תוכן קצרים באחד מהסגנונות הבאים:

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

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

תוצאות לדוגמה

קלט סגנון השכתוב פלט
רוצה שניפגש כדי שנוכל לדבר על זה? מקצועי רוצה שניפגש שוב כדי להמשיך לדון בנושא?
אשמח לקבל את חברתך במפגש לא רשמי בביתי בשבת בערב קיצור רוצה להצטרף אליי למפגש לא רשמי בבית שלי בשבת בערב?
האירוע בוצע בהצלחה גרסה מורחבת האירוע היה הצלחה מסחררת, ועמד בכל הציפיות שלנו.
אשמח לשתות איתך קפה בקרוב המרה לאמוג'י אשמח לשתות איתך קפה ☕ בקרוב 👋.
שליחת הדוח עד סוף היום ידידותי יש לך אפשרות לשלוח את הדוח עד סוף היום?
היי, דרושה לי העבודה הזו בהקדם האפשרי מקצועי עליך לספק את המסמך המבוקש בהקדם האפשרי.
הפרויקט לא מתקדם לפי לוח הזמנים ניסוח מחדש יש צורך לבצע התאמה בלוחות הזמנים של הפרויקט כדי לעמוד בלוחות הזמנים המקוריים

תחילת העבודה

כדי להתחיל להשתמש ב-GenAI Rewriting API, מוסיפים את התלות הזו לקובץ ה-build של הפרויקט.

implementation("com.google.mlkit:genai-rewriting:1.0.0-beta1")

לאחר מכן יוצרים מופע של הלקוח Rewriter עם האפשרויות הנדרשות, בודקים אם תכונות המודל הנדרשות במכשיר זמינות (ומורידים אותן אם צריך), מכינים את טקסט הקלט כבקשה, מריצים את תהליך הכתיבה מחדש כדי לקבל הצעות ומשתחררים מהמשאבים.

Kotlin

val textToRewrite = "The event was successful"

// Define task with selected input and output format
val rewriterOptions = RewriterOptions.builder(context)
    // OutputType can be one of the following: ELABORATE, EMOJIFY, SHORTEN,
    // FRIENDLY, PROFESSIONAL, REPHRASE
    .setOutputType(RewriterOptions.OutputType.ELABORATE)
    // Refer to RewriterOptions.Language for available languages
    .setLanguage(RewriterOptions.Language.ENGLISH)
    .build()
val rewriter = Rewriting.getClient(rewriterOptions)

suspend fun prepareAndStartRewrite() {
    // Check feature availability, status will be one of the following:
    // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
    val featureStatus = rewriter.checkFeatureStatus().await()

    if (featureStatus == FeatureStatus.DOWNLOADABLE) {
        // Download feature if necessary.
        // If downloadFeature is not called, the first inference request will
        // also trigger the feature to be downloaded if it's not already
        // downloaded.
        rewriter.downloadFeature(object : DownloadCallback {
            override fun onDownloadStarted(bytesToDownload: Long) { }

            override fun onDownloadFailed(e: GenAiException) { }

            override fun onDownloadProgress(totalBytesDownloaded: Long) {}

            override fun onDownloadCompleted() {
                startRewritingRequest(textToRewrite, rewriter)
            }
        })
    } else if (featureStatus == FeatureStatus.DOWNLOADING) {
        // Inference request will automatically run once feature is
        // downloaded.
        // If Gemini Nano is already downloaded on the device, the
        // feature-specific LoRA adapter model will be downloaded
        // quickly. However, if Gemini Nano is not already downloaded,
        // the download process may take longer.
        startRewritingRequest(textToRewrite, rewriter)
    } else if (featureStatus == FeatureStatus.AVAILABLE) {
        startRewritingRequest(textToRewrite, rewriter)
    }
}

suspend fun startRewritingRequest(text: String, rewriter: Rewriter) {
    // Create task request
    val rewritingRequest = RewritingRequest.builder(text).build()

    // Start rewriting request with non-streaming response
    // More than 1 result may be returned. If multiple suggestions are
    // returned, results will be sorted by descending confidence.
    val rewriteResults =
        rewriter.runInference(rewritingRequest).await().results

    // You can also start a streaming request
    // rewriter.runInference(rewritingRequest) { newText ->
    //    // Show new text in UI
    // }
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
rewriter.close()

Java

String textToRewrite = "The event was successful";

// Define task with required input and output format
RewriterOptions rewriterOptions =
    RewriterOptions.builder(context)
        // OutputType can be one of the following: ELABORATE,
        // EMOJIFY, SHORTEN, FRIENDLY, PROFESSIONAL, REPHRASE
        .setOutputType(RewriterOptions.OutputType.ELABORATE)
        // Refer to RewriterOptions.Language for available
        // languages
        .setLanguage(RewriterOptions.Language.ENGLISH)
        .build();
Rewriter rewriter = Rewriting.getClient(rewriterOptions);

void prepareAndStartRewrite()
    throws ExecutionException, InterruptedException {
    // Check feature availability, status will be one of the
    // following: UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
    try {
        int featureStatus = rewriter.checkFeatureStatus().get();
        if (featureStatus == FeatureStatus.DOWNLOADABLE) {
            // Download feature if necessary.
            // If downloadFeature is not called, the first inference
            // request will also trigger the feature to be downloaded
            // if it's not already downloaded.
            rewriter.downloadFeature(
                new DownloadCallback() {
                    @Override
                    public void onDownloadCompleted() {
                        startRewritingRequest(textToRewrite, rewriter);
                    }

                    @Override
                    public void onDownloadFailed(GenAIException e) {}

                    @Override
                    public void onDownloadProgress(
                        long totalBytesDownloaded) {}

                    @Override
                    public void onDownloadStarted(long bytesDownloaded) {}
                });
        } else if (featureStatus == FeatureStatus.DOWNLOADING) {
            // Inference request will automatically run once feature is
            // downloaded.
            // If Gemini Nano is already downloaded on the device, the
            // feature-specific LoRA adapter model will be downloaded
            // quickly. However, if Gemini Nano is not already downloaded,
            // the download process may take longer.
            startRewritingRequest(textToRewrite, rewriter);
        } else if (featureStatus == FeatureStatus.AVAILABLE) {
            startRewritingRequest(textToRewrite, rewriter);
        }
    } catch (ExecutionException | InterruptedException e) {
        e.printStackTrace();
    }
}

void startRewritingRequest(String text, Rewriter rewriter) {
    // Create task request
    RewritingRequest rewritingRequest =
        RewritingRequest.builder(text).build();

    try {
        // Start rewriting request with non-streaming response
        // More than 1 result may be returned. If multiple
        // suggestions are returned, results will be sorted by
        // descending confidence.
        rewriter.runInference(rewritingRequest).get().getResults();

        // You can also start a streaming request
        // rewriter.runInference(rewritingRequest, newText -> {
        //     // Show new text in UI
        // });
    } catch (ExecutionException | InterruptedException e) {
        e.printStackTrace();
    }
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
rewriter.close();

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

GenAI Rewriting API תומך בשפות הבאות: אנגלית, יפנית, צרפתית, גרמנית, איטלקית, ספרדית וקוריאנית. השפות מוגדרות בקובץ RewriterOptions.Language. הקלט צריך להכיל פחות מ-256 אסימונים.

הזמינות של תצורת התכונה הספציפית (שצוינה על ידי RewriterOptions) עשויה להשתנות בהתאם לתצורה של המכשיר הספציפי ולמודלים שהורדתם למכשיר.

הדרך הבטוחה ביותר למפתחים לוודא שתכונה מסוימת של ה-API נתמכת במכשיר עם RewriterOptions המבוקש היא לבצע קריאה ל-method‏ checkFeatureStatus(). השיטה הזו מספקת את הסטטוס המוחלט של זמינות התכונה במכשיר בזמן הריצה.

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

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

דוגמה להודעת שגיאה איך מטפלים
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: Feature ... failed with failure status 0 and error esz: UNAVAILABLE: Unable to resolve host ... שומרים על החיבור לרשת, ממתינים כמה דקות ומנסים שוב.