מדריך RAG של AI Edge ל-Android

ערכת ה-SDK של AI Edge RAG מספקת את הרכיבים הבסיסיים לבניית צינור (pipeline) של שליפה מוגברת גנרטיבית (RAG) באמצעות LLM Inference API. צינור RAG מספק למודלים של LLM גישה לנתונים שסופקו על ידי משתמשים, שיכולים לכלול מידע מעודכן, רגיש או ספציפי לתחום. היכולות הנוספות של RAG לאחזור מידע מאפשרות למודלים של שפה גדולה ליצור תשובות מדויקות יותר שמתחשבות בהקשר, במקרים ספציפיים של שימוש.

במדריך הזה מוסבר איך לבצע הטמעה בסיסית של אפליקציה לדוגמה באמצעות LLM Inference API עם AI Edge RAG SDK. המדריך הזה מתמקד בבניית צינור עיבוד נתונים של RAG. מידע נוסף על השימוש ב-LLM Inference API זמין במדריך בנושא LLM Inference ל-Android.

אפשר למצוא את האפליקציה המלאה לדוגמה ב-GitHub. כדי להתחיל, צריך לבנות את האפליקציה, לקרוא את הפרטים שהמשתמשים סיפקו (sample_context.txt) ולשאול את מודל ה-LLM שאלות שקשורות למידע בקובץ הטקסט.

הרצת האפליקציה לדוגמה

במדריך הזה אנחנו מתייחסים לדוגמה של אפליקציה בסיסית ליצירת טקסט עם RAG ל-Android. אתם יכולים להשתמש באפליקציה לדוגמה כנקודת התחלה לאפליקציית Android משלכם, או להיעזר בה כשאתם משנים אפליקציה קיימת.

האפליקציה מותאמת למכשירים מתקדמים כמו Pixel 8, ‏ Pixel 9,‏ S23 ו-S24. מחברים מכשיר Android לתחנת העבודה ומוודאים שיש לכם גרסה עדכנית של Android Studio. מידע נוסף זמין במדריך ההגדרה של Android.

הורדת קוד האפליקציה

בהוראות הבאות מוסבר איך ליצור עותק מקומי של קוד הדוגמה באמצעות כלי שורת הפקודה של Git.

משכפלים את מאגר ה-Git באמצעות הפקודה הבאה:

git clone https://github.com/google-ai-edge/ai-edge-apis

אחרי שיוצרים גרסה מקומית של קוד הדוגמה, אפשר לייבא את הפרויקט ל-Android Studio ולהריץ את האפליקציה.

הורדת מודל

אפליקציית הדוגמה מוגדרת לשימוש ב-Gemma-3 1B. ‫Gemma-3 1B הוא חלק ממשפחת Gemma של מודלים קלים ומתקדמים בקוד פתוח, שנבנו על בסיס אותם מחקרים וטכנולוגיות ששימשו ליצירת מודלים של Gemini. המודל מכיל מיליארד פרמטרים ומשקלים פתוחים.

הורדת Gemma-3 1B

אחרי שמורידים את Gemma-3 1B מ-Hugging Face, מעבירים את המודל למכשיר:

cd ~/Downloads
tar -xvzf gemma3-1b-it-int4.tar.gz
$ adb shell rm -r /data/local/tmp/llm/ # Remove any previously loaded models
$ adb shell mkdir -p /data/local/tmp/llm/
$ adb push output_path /data/local/tmp/llm/model_version.task

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

הגדרת כלי להטמעה

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

אפליקציית הדוגמה מיועדת לעבוד עם שני מפעילים: Gemini embedder ו-Gecko embedder.

הגדרה באמצעות Gecko embedder

כברירת מחדל, אפליקציית הדוגמה מוגדרת לשימוש ב-Gecko embedder ‏(GeckoEmbeddingModel), והיא מפעילה את המודל באופן מלא במכשיר.

Download Gecko 110m-en

המודל להטמעה של Gecko זמין כמודלים של float ושל quantized, עם כמה גרסאות לאורכים שונים של רצפים. מידע נוסף זמין בכרטיס המודל של Gecko.

מפרטי המודל מופיעים בשם הקובץ של המודל. לדוגמה:

  • Gecko_256_f32.tflite: מודל float שתומך ברצפים של עד 256 אסימונים.
  • Gecko_1024_quant.tflite: מודל שעבר קוונטיזציה ותומך ברצפים של עד 1,024 טוקנים.

אורך הרצף הוא גודל הצ'אנק המקסימלי שהמודל יכול להטמיע. לדוגמה, אם מעבירים למודל Gecko_256_f32.tflite מקטע שחורג מאורך הרצף, המודל יטמיע את 256 הטוקנים הראשונים ויקצץ את שאר המקטע.

מעבירים את מודל הטוקנייזר (sentencepiece.model) ואת Gecko embedder למכשיר:

adb push sentencepiece.model /data/local/tmp/sentencepiece.model
adb push Gecko_256_f32.tflite /data/local/tmp/gecko.tflite

מודל ההטמעה תואם גם למעבד (CPU) וגם למעבד גרפי (GPU). כברירת מחדל, אפליקציית הדוגמה מוגדרת לחילוץ הטמעות באמצעות מודל Gecko ב-GPU.

companion object {
  ...
  private const val USE_GPU_FOR_EMBEDDINGS = true
}

הגדרה באמצעות Gemini Embedder

הכלי Gemini Embedder‏ (GeminiEmbedder) יוצר הטבעות באמצעות Gemini Cloud API. כדי להריץ את האפליקציה, צריך מפתח Google Gemini API. אפשר לקבל אותו מדף ההגדרה של Google Gemini API.

קבלת מפתח Gemini API ב-Google AI Studio

מוסיפים את מפתח Gemini API ומגדירים את COMPUTE_EMBEDDINGS_LOCALLY ל-false ב-RagPipeline.kt:

companion object {
  ...
  private const val COMPUTE_EMBEDDINGS_LOCALLY = false
  private const val GEMINI_API_KEY = "<API_KEY>"
}

איך זה עובד

בקטע הזה מופיע מידע מעמיק יותר על רכיבי צינור ה-RAG של האפליקציה. אפשר לראות את רוב הקוד ב-RagPipeline.kt.

תלויות

‫RAG SDK משתמש בספרייה com.google.ai.edge.localagents:localagents-rag. מוסיפים את יחסי התלות האלה לקובץ build.gradle של אפליקציית Android:

dependencies {
    ...
    implementation("com.google.ai.edge.localagents:localagents-rag:0.1.0")
    implementation("com.google.mediapipe:tasks-genai:0.10.22")
}

פרטים שהמשתמשים סיפקו

הנתונים שהמשתמש מספק באפליקציה הם קובץ טקסט בשם sample_context.txt, שמאוחסן בספרייה assets. האפליקציה לוקחת נתחים מקובץ הטקסט, יוצרת הטבעות של הנתחים האלה ומתייחסת להטבעות כשהיא יוצרת פלט טקסט.

קטע הקוד הבא נמצא בקובץ MainActivity.kt:

class MainActivity : ComponentActivity() {
  lateinit var chatViewModel: ChatViewModel
...
    chatViewModel.memorizeChunks("sample_context.txt")
...
}

חלוקה לחלקים

כדי לפשט את התהליך, קובץ sample_context.txt כולל תגי <chunk_splitter> שהאפליקציה לדוגמה משתמשת בהם כדי ליצור נתחים. לאחר מכן נוצרים וקטורים לכל חלק. באפליקציות בסביבת הייצור, גודל החלקים הוא שיקול חשוב. כשחלק גדול מדי, הווקטור לא מכיל מספיק פרטים כדי להיות שימושי, וכשהוא קטן מדי, הוא לא מכיל מספיק הקשר.

אפליקציית הדוגמה מטפלת בחלוקה לקטעים באמצעות הפונקציה memorizeChunks ב-RagPipeline.kt.

הטמעה

האפליקציה מציעה שתי דרכים להטמעת טקסט:

  • Gecko embedder: חילוץ הטמעה של טקסט מקומי (במכשיר) באמצעות מודל Gecko.
  • Gemini Embedder: חילוץ הטמעה של טקסט מבוסס-Cloud באמצעות Generative Language Cloud API.

אפליקציית הדוגמה בוחרת את המטמיע בהתאם לכוונה של המשתמש לחשב הטמעות באופן מקומי או דרך Google Cloud. קטע הקוד הבא מופיע בקובץ RagPipeline.kt:

private val embedder: Embedder<String> = if (COMPUTE_EMBEDDINGS_LOCALLY) {
  GeckoEmbeddingModel(
    GECKO_MODEL_PATH,
    Optional.of(TOKENIZER_MODEL_PATH),
    USE_GPU_FOR_EMBEDDINGS,
    )
  } else {
    GeminiEmbedder(
      GEMINI_EMBEDDING_MODEL,
      GEMINI_API_KEY
      )
  }

מסד נתונים

אפליקציית הדוגמה משתמשת ב-SQLite ‏ (SqliteVectorStore) כדי לאחסן הטבעות של טקסט. אפשר גם להשתמש במסד הנתונים DefaultVectorStore לאחסון וקטורי לא קבוע.

קטע הקוד הבא מופיע בקובץ RagPipeline.kt:

private val config = ChainConfig.create(
    mediaPipeLanguageModel, PromptBuilder(QA_PROMPT_TEMPLATE1),
    DefaultSemanticTextMemory(
        SqliteVectorStore(768), embedder
    )
)

באפליקציה לדוגמה, ממד ההטמעה מוגדר ל-768, שמתייחס לאורך של כל וקטור במסד הנתונים הווקטורי.

Chain

ערכת ה-SDK של RAG מספקת שרשראות שמשלבות כמה רכיבי RAG לצינור אחד. אפשר להשתמש בשרשרות כדי לתזמן אחזור של מודלים ושאילתות. ה-API מבוסס על ממשק Chain.

באפליקציה לדוגמה נעשה שימוש בשרשרת של שליפה והסקת מסקנות. קטע הקוד הבא מופיע בקובץ RagPipeline.kt:

private val retrievalAndInferenceChain = RetrievalAndInferenceChain(config)

השרשרת מופעלת כשהמודל יוצר תשובות:

suspend fun generateResponse(
    prompt: String,
    callback: AsyncProgressListener<LanguageModelResponse>?
): String =
    coroutineScope {
        val retrievalRequest =
            RetrievalRequest.create(
                prompt,
                RetrievalConfig.create(2, 0.0f, TaskType.QUESTION_ANSWERING)
            )
        retrievalAndInferenceChain.invoke(retrievalRequest, callback).await().text
    }