Panduan RAG AI Edge untuk Android

AI Edge RAG SDK menyediakan komponen dasar untuk membuat pipeline Retrieval-Augmented Generation (RAG) dengan LLM Inference API. Pipeline RAG memberi LLM akses ke data yang disediakan pengguna, yang dapat mencakup informasi yang diperbarui, sensitif, atau khusus domain. Dengan kemampuan pengambilan informasi tambahan dari RAG, LLM dapat menghasilkan respons yang lebih akurat dan sesuai konteks untuk kasus penggunaan tertentu.

Panduan ini akan memandu Anda melalui penerapan dasar aplikasi contoh menggunakan LLM Inference API dengan AI Edge RAG SDK. Panduan ini berfokus pada membangun pipeline RAG. Untuk mengetahui informasi selengkapnya tentang penggunaan LLM Inference API, lihat panduan LLM Inference untuk Android.

Anda dapat menemukan contoh aplikasi lengkap di GitHub. Untuk memulai, buat aplikasi, baca data yang diberikan pengguna (sample_context.txt), dan ajukan pertanyaan kepada LLM terkait informasi dalam file teks.

Menjalankan aplikasi contoh

Panduan ini merujuk pada contoh aplikasi pembuatan teks dasar dengan RAG untuk Android. Anda dapat menggunakan aplikasi contoh sebagai titik awal untuk aplikasi Android Anda sendiri, atau merujuknya saat mengubah aplikasi yang sudah ada.

Aplikasi ini dioptimalkan untuk perangkat kelas atas seperti Pixel 8, Pixel 9, S23, dan S24. Hubungkan perangkat Android ke workstation Anda dan pastikan Anda memiliki Android Studio versi terbaru. Untuk mengetahui informasi selengkapnya, lihat panduan penyiapan Android.

Mendownload kode aplikasi

Petunjuk berikut menunjukkan cara membuat salinan lokal contoh kode menggunakan alat command line git.

Clone repositori git menggunakan perintah berikut:

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

Setelah membuat versi lokal kode contoh, Anda dapat mengimpor project ke Android Studio dan menjalankan aplikasi.

Mendownload model

Aplikasi contoh dikonfigurasi untuk menggunakan Gemma-3 1B. Gemma-3 1B adalah bagian dari keluarga model terbuka yang ringan dan canggih Gemma, yang dibangun dari riset dan teknologi yang sama dengan yang digunakan untuk membuat model Gemini. Model ini berisi 1B parameter dan bobot terbuka.

Download Gemma-3 1B

Setelah mendownload Gemma-3 1B dari Hugging Face, kirim model ke perangkat Anda:

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

Anda juga dapat menggunakan model lain dengan aplikasi contoh, tetapi mungkin memerlukan langkah-langkah konfigurasi tambahan.

Menyiapkan penyemat

Embedder mengambil potongan teks dari data yang disediakan pengguna dan mengubahnya menjadi representasi numerik tervektor yang menangkap makna semantiknya. LLM merujuk pada embedding ini untuk mengidentifikasi vektor yang relevan, dan menggabungkan potongan yang paling relevan secara semantik dalam output yang dihasilkan.

Aplikasi contoh dirancang untuk berfungsi dengan dua penyemat, penyemat Gemini dan penyemat Gecko.

Menyiapkan dengan penyemat Gecko

Secara default, aplikasi contoh dikonfigurasi untuk menggunakan embedder Gecko (GeckoEmbeddingModel), dan menjalankan model sepenuhnya di perangkat.

Download Gecko 110m-en

Penyematan Gecko tersedia sebagai model float dan terkuantisasi, dengan beberapa versi untuk panjang urutan yang berbeda. Untuk mengetahui informasi selengkapnya, lihat kartu model Gecko.

Spesifikasi model dapat ditemukan di nama file model. Contoh:

  • Gecko_256_f32.tflite: Model float yang mendukung urutan hingga 256 token.
  • Gecko_1024_quant.tflite: Model terkuantisasi yang mendukung urutan hingga 1.024 token.

Panjang urutan adalah ukuran potongan maksimum yang dapat disematkan oleh model. Misalnya, model Gecko_256_f32.tflite meneruskan potongan yang melebihi panjang urutan, model akan menyematkan 256 token pertama dan memotong sisa potongan.

Kirim model tokenizer (sentencepiece.model) dan penyemat Gecko ke perangkat Anda:

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

Model penyematan kompatibel dengan CPU dan GPU. Secara default, aplikasi contoh dikonfigurasi untuk mengekstrak penyematan dengan model Gecko di GPU.

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

Menyiapkan dengan Gemini Embedder

Gemini Embedder (GeminiEmbedder) membuat embedding menggunakan Gemini Cloud API. Hal ini memerlukan kunci Google Gemini API untuk menjalankan aplikasi, yang dapat Anda peroleh dari halaman penyiapan Google Gemini API.

Mendapatkan kunci Gemini API di Google AI Studio

Tambahkan kunci Gemini API Anda dan tetapkan COMPUTE_EMBEDDINGS_LOCALLY ke false di RagPipeline.kt:

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

Cara kerjanya

Bagian ini memberikan informasi yang lebih mendalam tentang komponen pipeline RAG aplikasi. Anda dapat melihat sebagian besar kode di RagPipeline.kt.

Dependensi

RAG SDK menggunakan library com.google.ai.edge.localagents:localagents-rag. Tambahkan dependensi ini ke file build.gradle aplikasi Android Anda:

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

Data yang disediakan pengguna

Data yang disediakan pengguna dalam aplikasi adalah file teks bernama sample_context.txt, yang disimpan di direktori assets. Aplikasi mengambil potongan file teks, membuat embedding potongan tersebut, dan merujuk ke embedding saat membuat teks output.

Cuplikan kode berikut dapat ditemukan di MainActivity.kt:

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

Pengelompokan

Untuk mempermudah, file sample_context.txt mencakup tag <chunk_splitter> yang digunakan aplikasi contoh untuk membuat chunk. Kemudian, embedding dibuat untuk setiap potongan. Dalam aplikasi produksi, ukuran chunk adalah pertimbangan utama. Jika potongan terlalu besar, vektor tidak cukup spesifik untuk berguna; dan jika terlalu kecil, vektor tidak cukup memuat konteks.

Aplikasi contoh menangani chunking melalui fungsi memorizeChunks di RagPipeline.kt.

Embedding

Aplikasi ini menawarkan dua jalur untuk penyematan teks:

  • Gecko embedder: Ekstraksi embedding teks lokal (di perangkat) dengan model Gecko.
  • Gemini Embedder: Ekstraksi embedding teks berbasis cloud dengan Generative Language Cloud API.

Aplikasi contoh memilih embedder berdasarkan apakah pengguna ingin menghitung embedding secara lokal atau melalui Google Cloud. Cuplikan kode berikut dapat ditemukan di 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
      )
  }

Database

Aplikasi contoh menggunakan SQLite (SqliteVectorStore) untuk menyimpan sematan teks. Anda juga dapat menggunakan database DefaultVectorStore untuk penyimpanan vektor non-persisten.

Cuplikan kode berikut dapat ditemukan di RagPipeline.kt:

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

Aplikasi contoh menetapkan dimensi embedding ke 768, yang mengacu pada panjang setiap vektor dalam database vektor.

Chain

RAG SDK menyediakan rantai, yang menggabungkan beberapa komponen RAG ke dalam satu pipeline. Anda dapat menggunakan rantai untuk mengatur pengambilan dan model kueri. API didasarkan pada antarmuka Chain.

Aplikasi contoh menggunakan rantai Pengambilan dan Inferensi. Cuplikan kode berikut dapat ditemukan di RagPipeline.kt:

private val retrievalAndInferenceChain = RetrievalAndInferenceChain(config)

Rantai dipanggil saat model menghasilkan respons:

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
    }