Android 適用的 AI Edge RAG 指南

AI Edge RAG SDK 提供基本元件,可使用 LLM 推論 API 建構擷取擴增生成 (RAG) 管道。RAG 管道可讓 LLM 存取使用者提供的資料,包括最新、私密或特定領域的資訊。有了 RAG 提供的資訊檢索功能,LLM 就能針對特定用途生成更準確且符合情境的回覆。

本指南將逐步說明如何使用 AI Edge RAG SDK,透過 LLM Inference API 實作範例應用程式。本指南著重於建構 RAG 管道,如要進一步瞭解如何使用 LLM Inference API,請參閱 Android 適用的 LLM Inference 指南

您可以在 GitHub 上找到完整的範例應用程式。如要開始使用,請先建構應用程式、讀取使用者提供的資料 (sample_context.txt),然後向 LLM 詢問與文字檔中資訊相關的問題。

執行範例應用程式

本指南會參考 Android 適用的 RAG 基本文字生成應用程式範例。您可以將範例應用程式做為自己 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 模型時相同的研究成果和技術。這個模型包含 10 億個參數和開放權重。

下載 Gemma-3 1B

從 Hugging Face 下載 Gemma-3 1B 後,將模型推送至裝置:

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 嵌入器和 Gecko 嵌入器。

使用 Gecko 嵌入器設定

根據預設,範例應用程式會設定為使用 Gecko 嵌入器 (GeckoEmbeddingModel),並在裝置上完整執行模型。

下載 Gecko 110m-en

Gecko 嵌入器提供浮點和量化模型,並有多個版本,適用於不同序列長度。詳情請參閱 Gecko 模型資訊卡

型號規格會顯示在型號檔案名稱中。例如:

  • Gecko_256_f32.tflite:支援最多 256 個權杖序列的浮點模型。
  • Gecko_1024_quant.tflite:量化模型,最多支援 1024 個權杖的序列。

序列長度是模型可嵌入的區塊大小上限。舉例來說,如果傳送給 Gecko_256_f32.tflite 模型的區塊超過序列長度,模型會嵌入前 256 個符記,並截斷區塊的其餘部分。

將權杖化模型 (sentencepiece.model) 和 Gecko 嵌入器推送至裝置:

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

嵌入模型與 CPU 和 GPU 皆相容。根據預設,範例應用程式會設定為使用 GPU 上的 Gecko 模型擷取嵌入。

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

使用 Gemini Embedder 設定

Gemini Embedder (GeminiEmbedder) 會使用 Gemini Cloud API 建立嵌入。這需要 Google Gemini API 金鑰才能執行應用程式,您可以從 Google Gemini API 設定頁面取得金鑰。

在 Google AI Studio 中取得 Gemini API 金鑰

RagPipeline.kt 中新增 Gemini API 金鑰,並將 COMPUTE_EMBEDDINGS_LOCALLY 設為 false:

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 程式庫。將這項依附元件新增至 Android 應用程式的 build.gradle 檔案:

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> 標記。然後為每個區塊建立嵌入。在實際工作應用程式中,區塊大小是重要的考量因素。如果區塊太大,向量就不會包含足夠的具體資訊,因此無法派上用場;如果區塊太小,向量就不會包含足夠的脈絡資訊。

範例應用程式會透過 RagPipeline.kt 中的 memorizeChunks 函式處理分塊。

嵌入

應用程式提供兩種文字嵌入路徑:

  • Gecko 嵌入器:使用 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,也就是向量資料庫中每個向量的長度。

鏈結

RAG SDK 提供鏈結,可將多個 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
    }