Das AI Edge RAG SDK bietet die grundlegenden Komponenten zum Erstellen einer Retrieval Augmented Generation-Pipeline (RAG) mit der LLM Inference API. Eine RAG-Pipeline ermöglicht LLMs den Zugriff auf von Nutzern bereitgestellte Daten, die aktualisierte, vertrauliche oder domänenspezifische Informationen enthalten können. Mit den zusätzlichen Funktionen zum Abrufen von Informationen aus RAG können LLMs genauere und kontextbezogene Antworten für bestimmte Anwendungsfälle generieren.
In dieser Anleitung wird eine grundlegende Implementierung einer Beispielanwendung mit der LLM Inference API und dem AI Edge RAG SDK beschrieben. Der Schwerpunkt dieser Anleitung liegt auf dem Erstellen einer RAG-Pipeline. Weitere Informationen zur Verwendung der LLM Inference API finden Sie in der Anleitung LLM Inference for Android.
Die vollständige Beispielanwendung finden Sie auf
GitHub.
Erstellen Sie zuerst die Anwendung, lesen Sie die von Nutzern bereitgestellten Daten
(sample_context.txt),
und stellen Sie dem LLM Fragen zu den Informationen in der Textdatei.
Beispielanwendung ausführen
In dieser Anleitung wird eine Beispielanwendung für die grundlegende Textgenerierung mit RAG für Android verwendet. Sie können die Beispielanwendung als Ausgangspunkt für Ihre eigene Android-Anwendung verwenden oder sie als Referenz beim Ändern einer vorhandenen Anwendung nutzen.
Die Anwendung ist für High-End-Geräte wie das Pixel 8, Pixel 9, S23 und S24 optimiert. Verbinden Sie ein Android-Gerät mit Ihrer Workstation und prüfen Sie, ob Sie die aktuelle Version von Android Studio verwenden. Weitere Informationen finden Sie in der Android-Einrichtungs anleitung.
Anwendungscode herunterladen
In der folgenden Anleitung wird beschrieben, wie Sie mit dem Befehlszeilentool „git“ eine lokale Kopie des Beispielcodes erstellen.
Klonen Sie das Git-Repository mit dem folgenden Befehl:
git clone https://github.com/google-ai-edge/ai-edge-apis
Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie das Projekt in Android Studio importieren und die Anwendung ausführen.
Modell herunterladen
Die Beispielanwendung ist für die Verwendung von Gemma-3 1B konfiguriert. Gemma-3 1B gehört zur Gemma-Familie von einfachen, hochmodernen offenen Modellen, die auf derselben Forschung und Technologie basieren, die auch für die Erstellung der Gemini-Modelle verwendet werden. Das Modell enthält 1B Parameter und offene Gewichtungen.
Nachdem Sie Gemma-3 1B von Hugging Face heruntergeladen haben, übertragen Sie das Modell auf Ihr Gerät:
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
Sie können auch andere Modelle mit der Beispielanwendung verwenden. Dazu sind jedoch möglicherweise zusätzliche Konfigurationsschritte erforderlich.
Embedder einrichten
Der Embedder nimmt Textblöcke aus den von Nutzern bereitgestellten Daten und wandelt sie in vektorisierte numerische Darstellungen um, die die semantische Bedeutung erfassen. Das LLM verwendet diese Einbettungen, um relevante Vektoren zu identifizieren, und fügt die semantisch relevantesten Blöcke in die generierte Ausgabe ein.
Die Beispielanwendung ist für die Verwendung mit zwei Embeddern konzipiert: dem Gemini Embedder und dem Gecko Embedder.
Mit dem Gecko Embedder einrichten
Standardmäßig ist die Beispielanwendung für die Verwendung des Gecko Embedders (GeckoEmbeddingModel) konfiguriert und führt das Modell vollständig auf dem Gerät aus.
Der Gecko Embedder ist als Float- und quantisiertes Modell mit mehreren Versionen für unterschiedliche Sequenzlängen verfügbar. Weitere Informationen finden Sie auf der Modellkarte für Gecko.
Die Modellspezifikationen finden Sie im Modellnamen. Beispiel:
Gecko_256_f32.tflite: Float-Modell, das Sequenzen mit bis zu 256 Tokens unterstützt.Gecko_1024_quant.tflite: Quantisiertes Modell, das Sequenzen mit bis zu 1024 Tokens unterstützt.
Die Sequenzlänge ist die maximale Blockgröße, die das Modell einbetten kann. Wenn dem Modell Gecko_256_f32.tflite beispielsweise ein Block übergeben wird, der die Sequenzlänge überschreitet, bettet das Modell die ersten 256 Tokens ein und schneidet den Rest des Blocks ab.
Übertragen Sie das Tokenizer-Modell (sentencepiece.model) und den Gecko Embedder auf Ihr Gerät:
adb push sentencepiece.model /data/local/tmp/sentencepiece.model
adb push Gecko_256_f32.tflite /data/local/tmp/gecko.tflite
Das Einbettungsmodell ist mit CPUs und GPUs kompatibel. Standardmäßig ist die Beispielanwendung so konfiguriert, dass Einbettungen mit dem Gecko-Modell auf der GPU extrahiert werden.
companion object {
...
private const val USE_GPU_FOR_EMBEDDINGS = true
}
Mit dem Gemini Embedder einrichten
Der Gemini Embedder (GeminiEmbedder) erstellt Einbettungen mit der Gemini Cloud API. Für die Ausführung der Anwendung ist ein Google Gemini API-Schlüssel erforderlich, den Sie auf der Einrichtungsseite der Google Gemini API erhalten.
Gemini API-Schlüssel in Google AI Studio abrufen
Fügen Sie Ihren Gemini API-Schlüssel hinzu und setzen Sie COMPUTE_EMBEDDINGS_LOCALLY in
RagPipeline.kt auf „false“:
companion object {
...
private const val COMPUTE_EMBEDDINGS_LOCALLY = false
private const val GEMINI_API_KEY = "<API_KEY>"
}
Funktionsweise
In diesem Abschnitt finden Sie detailliertere Informationen zu den RAG-Pipelinekomponenten der Anwendung. Den größten Teil des Codes finden Sie unter RagPipeline.kt.
Abhängigkeiten
Das RAG SDK verwendet die Bibliothek com.google.ai.edge.localagents:localagents-rag.
Fügen Sie diese Abhängigkeit der Datei build.gradle Ihrer Android-Anwendung hinzu:
dependencies {
...
implementation("com.google.ai.edge.localagents:localagents-rag:0.1.0")
implementation("com.google.mediapipe:tasks-genai:0.10.22")
}
Von Nutzern bereitgestellte Daten
Die von Nutzern bereitgestellten Daten in der Anwendung sind eine Textdatei mit dem Namen
sample_context.txt,
die im assets Verzeichnis gespeichert ist. Die Anwendung nimmt Textblöcke aus der Textdatei, erstellt Einbettungen dieser Blöcke und verwendet die Einbettungen, um Ausgabetext zu generieren.
Das folgende Code-Snippet finden Sie in MainActivity.kt:
class MainActivity : ComponentActivity() {
lateinit var chatViewModel: ChatViewModel
...
chatViewModel.memorizeChunks("sample_context.txt")
...
}
Chunking
Zur Vereinfachung enthält die
sample_context.txt
Datei die Tags <chunk_splitter>, die von der Beispielanwendung zum Erstellen von
Blöcken verwendet werden. Anschließend werden für jeden Block Einbettungen erstellt. In Produktionsanwendungen ist die Größe der Blöcke ein wichtiger Faktor. Wenn ein Block zu groß ist, ist der Vektor nicht spezifisch genug, um nützlich zu sein. Wenn er zu klein ist, enthält er nicht genügend Kontext.
Die Beispielanwendung verarbeitet das Chunking über die memorizeChunks
Funktion in
RagPipeline.kt.
Einbettung
Die Anwendung bietet zwei Möglichkeiten für die Texteinbettung:
- Gecko Embedder: Lokale (auf dem Gerät) Extraktion von Texteinbettungen mit dem Gecko-Modell.
- Gemini Embedder: Cloudbasierte Extraktion von Texteinbettungen mit der Generative Language Cloud API.
Die Beispielanwendung wählt den Embedder danach aus, ob der Nutzer Einbettungen lokal oder über Google Cloud berechnen möchte. Das folgende Code-Snippet finden Sie in 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
)
}
Datenbank
Die Beispielanwendung verwendet SQLite (SqliteVectorStore) zum Speichern von Texteinbettungen. Sie können die Datenbank DefaultVectorStore auch für die nichtflüchtige Vektorspeicherung verwenden.
Das folgende Code-Snippet finden Sie in RagPipeline.kt:
private val config = ChainConfig.create(
mediaPipeLanguageModel, PromptBuilder(QA_PROMPT_TEMPLATE1),
DefaultSemanticTextMemory(
SqliteVectorStore(768), embedder
)
)
Die Beispielanwendung legt die Einbettungsdimension auf 768 fest. Dies bezieht sich auf die Länge jedes Vektors in der Vektordatenbank.
Kette
Das RAG SDK bietet Ketten, die mehrere RAG-Komponenten zu einer einzigen Pipeline kombinieren. Mit Ketten können Sie Abruf- und Abfragemodelle orchestrieren. Die API basiert auf der Chain Schnittstelle.
Die Beispielanwendung verwendet die Kette „Retrieval and Inference“. Das folgende Code-Snippet finden Sie in RagPipeline.kt:
private val retrievalAndInferenceChain = RetrievalAndInferenceChain(config)
Die Kette wird aufgerufen, wenn das Modell Antworten generiert:
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
}