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

ערכת ה-SDK של AI Edge RAG מספקת את הרכיבים הבסיסיים לבניית צינור (pipeline) של Retrieval Augmented Generation‏ (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: חילוץ הטמעה של טקסט מבוסס-ענן באמצעות 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.

אפליקציית הדוגמה משתמשת ב-Retrieval and Inference 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
    }