Le SDK AI Edge RAG fournit les composants fondamentaux pour créer un pipeline de génération augmentée par récupération (RAG) avec l'API LLM Inference. Un pipeline RAG permet aux LLM d'accéder aux données fournies par l'utilisateur, qui peuvent inclure des informations mises à jour, sensibles ou spécifiques à un domaine. Grâce aux fonctionnalités de récupération d'informations supplémentaires de RAG, les LLM peuvent générer des réponses plus précises et plus contextuelles pour des cas d'utilisation spécifiques.
Ce guide vous explique comment implémenter une application exemple de base à l'aide de l'API LLM Inference avec le SDK AI Edge RAG. Il se concentre sur la création d'un pipeline RAG. Pour en savoir plus sur l'utilisation de l'API LLM Inference, consultez le guide LLM Inference for Android.
L'exemple d'application complet est disponible sur
GitHub.
Pour commencer, compilez l'application, lisez les données fournies par l'utilisateur
(sample_context.txt),
et posez des questions au LLM concernant les informations contenues dans le fichier texte.
Exécuter l'application exemple
Ce guide fait référence à un exemple d'application de génération de texte de base avec RAG pour Android. Vous pouvez utiliser l'application exemple comme point de départ pour votre propre application Android ou vous y référer lorsque vous modifiez une application existante.
L'application est optimisée pour les appareils haut de gamme tels que les Pixel 8, Pixel 9, S23 et S24. Connectez un appareil Android à votre poste de travail et assurez-vous d'avoir la dernière version d'Android Studio. Pour en savoir plus, consultez le guide de configuration d'Android.
Télécharger le code de l'application
Les instructions suivantes vous montrent comment créer une copie locale de l'exemple de code à l'aide de l'outil de ligne de commande git.
Clonez le dépôt git à l'aide de la commande suivante :
git clone https://github.com/google-ai-edge/ai-edge-apis
Après avoir créé une version locale de l'exemple de code, vous pouvez importer le projet dans Android Studio et exécuter l'application.
Télécharger un modèle
L'application exemple est configurée pour utiliser Gemma-3 1B. Gemma-3 1B fait partie de la famille Gemma de modèles ouverts, légers et à la pointe de la technologie, basés sur la recherche et la technologie utilisées pour créer les modèles Gemini. Le modèle contient 1 milliard de paramètres et des pondérations ouvertes.
Après avoir téléchargé Gemma-3 1B depuis Hugging Face, transférez le modèle sur votre appareil :
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
Vous pouvez également utiliser d'autres modèles avec l'application exemple, mais cela peut nécessiter des étapes de configuration supplémentaires.
Configurer un embedder
L'embedder prend des fragments de texte à partir des données fournies par l'utilisateur et les transforme en représentations numériques vectorisées qui capturent leur signification sémantique. Le LLM fait référence à ces embeddings pour identifier les vecteurs pertinents et intègre les fragments les plus pertinents d'un point de vue sémantique dans la sortie générée.
L'application exemple est conçue pour fonctionner avec deux embedders : l'embedder Gemini et l'embedder Gecko.
Configurer avec l'embedder Gecko
Par défaut, l'application exemple est configurée pour utiliser l'embedder Gecko (GeckoEmbeddingModel) et exécute le modèle entièrement sur l'appareil.
L'embedder Gecko est disponible en tant que modèles flottants et quantifiés, avec plusieurs versions pour différentes longueurs de séquence. Pour en savoir plus, consultez la fiche de modèle Gecko.
Les spécifications du modèle se trouvent dans le nom de fichier du modèle. Exemple :
Gecko_256_f32.tflite: modèle flottant qui accepte des séquences de 256 jetons maximum.Gecko_1024_quant.tflite: modèle quantifié qui accepte des séquences de 1 024 jetons maximum.
La longueur de la séquence correspond à la taille maximale des fragments que le modèle peut intégrer. Par exemple, si un fragment qui dépasse la longueur de la séquence est transmis au modèle Gecko_256_f32.tflite, le modèle intégrera les 256 premiers jetons et tronquera le reste du fragment.
Transférez le modèle de tokenisation (sentencepiece.model) et l'embedder Gecko sur votre appareil :
adb push sentencepiece.model /data/local/tmp/sentencepiece.model
adb push Gecko_256_f32.tflite /data/local/tmp/gecko.tflite
Le modèle d'embedding est compatible avec les processeurs et les GPU. Par défaut, l'application exemple est configurée pour extraire les embeddings avec le modèle Gecko sur le GPU.
companion object {
...
private const val USE_GPU_FOR_EMBEDDINGS = true
}
Configurer avec l'embedder Gemini
L'embedder Gemini (GeminiEmbedder) crée des embeddings à l'aide de l'API Gemini Cloud. Pour exécuter l'application, vous avez besoin d'une clé API Google Gemini, que vous pouvez obtenir sur la page de configuration de l'API Google Gemini.
Obtenir une clé API Gemini dans Google AI Studio
Ajoutez votre clé API Gemini et définissez COMPUTE_EMBEDDINGS_LOCALLY sur "false" dans
RagPipeline.kt :
companion object {
...
private const val COMPUTE_EMBEDDINGS_LOCALLY = false
private const val GEMINI_API_KEY = "<API_KEY>"
}
Fonctionnement
Cette section fournit des informations plus détaillées sur les composants du pipeline RAG de l'application. Vous pouvez afficher la majeure partie du code dans RagPipeline.kt.
Dépendances
Le SDK RAG utilise la bibliothèque com.google.ai.edge.localagents:localagents-rag.
Ajoutez cette dépendance au fichier build.gradle de votre application Android :
dependencies {
...
implementation("com.google.ai.edge.localagents:localagents-rag:0.1.0")
implementation("com.google.mediapipe:tasks-genai:0.10.22")
}
Données fournies par l'utilisateur
Les données fournies par l'utilisateur dans l'application sont un fichier texte nommé
sample_context.txt,
qui est stocké dans le répertoire assets. L'application prend des fragments du fichier texte, crée des embeddings de ces fragments et fait référence aux embeddings lors de la génération du texte de sortie.
L'extrait de code suivant se trouve dans MainActivity.kt :
class MainActivity : ComponentActivity() {
lateinit var chatViewModel: ChatViewModel
...
chatViewModel.memorizeChunks("sample_context.txt")
...
}
Fragmentation
Pour plus de simplicité, le
sample_context.txt
fichier inclut des balises <chunk_splitter> que l'application exemple utilise pour créer des
fragments. Des embeddings sont ensuite créés pour chaque fragment. Dans les applications de production, la taille des fragments est un élément clé à prendre en compte. Lorsqu'un fragment est trop volumineux, le vecteur ne contient pas suffisamment de spécificité pour être utile. Lorsqu'il est trop petit, il ne contient pas suffisamment de contexte.
L'application exemple gère la fragmentation via la memorizeChunks
fonction dans
RagPipeline.kt.
Embedding
L'application propose deux méthodes pour l'embedding de texte :
- Embedder Gecko: extraction locale (sur l'appareil) d'embeddings de texte avec le modèle Gecko.
- Embedder Gemini: extraction d'embeddings de texte dans le cloud avec l'API Generative Language Cloud.
L'application exemple sélectionne l'embedder en fonction de l'intention de l'utilisateur de calculer les embeddings localement ou via Google Cloud. L'extrait de code suivant se trouve dans 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
)
}
Base de données
L'application exemple utilise SQLite (SqliteVectorStore) pour stocker les embeddings de texte. Vous pouvez également utiliser la base de données DefaultVectorStore pour le stockage de vecteurs non persistants.
L'extrait de code suivant se trouve dans RagPipeline.kt :
private val config = ChainConfig.create(
mediaPipeLanguageModel, PromptBuilder(QA_PROMPT_TEMPLATE1),
DefaultSemanticTextMemory(
SqliteVectorStore(768), embedder
)
)
L'application exemple définit la dimension d'embedding sur 768, ce qui correspond à la longueur de chaque vecteur dans la base de données vectorielle.
Chaîne
Le SDK RAG fournit des chaînes, qui combinent plusieurs composants RAG dans un seul pipeline. Vous pouvez utiliser des chaînes pour orchestrer des modèles de récupération et de requête. L'API est basée sur l' interface Chain.
L'application exemple utilise la chaîne de récupération et d'inférence. L'extrait de code suivant se trouve dans RagPipeline.kt :
private val retrievalAndInferenceChain = RetrievalAndInferenceChain(config)
La chaîne est appelée lorsque le modèle génère des réponses :
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
}