AI Edge RAG SDK는 LLM 추론 API를 사용하여 검색 증강 생성 (RAG) 파이프라인을 구성하는 기본 구성요소를 제공합니다. RAG 파이프라인은 업데이트된 정보, 민감한 정보 또는 도메인별 정보를 포함할 수 있는 사용자 제공 데이터에 대한 액세스 권한을 LLM에 제공합니다. RAG의 정보 검색 기능이 추가됨에 따라 LLM은 특정 사용 사례에 대해 더 정확하고 상황에 맞는 대답을 생성할 수 있습니다.
이 가이드에서는 AI Edge RAG SDK를 사용하여 LLM 추론 API를 사용하는 샘플 애플리케이션의 기본 구현을 안내합니다. 이 가이드는 RAG 파이프라인 구성에 중점을 둡니다. LLM 추론 API 사용에 관한 자세한 내용은 Android용 LLM 추론 가이드를 참고하세요.
GitHub에서 전체 샘플 애플리케이션을 확인할 수 있습니다.
GitHub
시작하려면 애플리케이션을 빌드하고 사용자 제공 데이터
(sample_context.txt)
를 읽고 텍스트 파일의 정보와 관련된 질문을 LLM에 합니다.
예시 애플리케이션 실행
이 가이드에서는 Android용 RAG를 사용하는 기본 텍스트 생성 앱의 예를 참고합니다. 샘플 앱을 자체 Android 앱의 시작점으로 사용하거나 기존 앱을 수정할 때 참고할 수 있습니다.
이 애플리케이션은 Pixel 8, Pixel 9, S23, S24와 같은 고급 기기에 최적화되어 있습니다. Android 기기를 워크스테이션에 연결하고 최신 버전의 Android 스튜디오가 있는지 확인합니다. 자세한 내용은 Android 설정 가이드를 참고하세요.
애플리케이션 코드 다운로드
다음 안내에서는 git 명령줄 도구를 사용하여 예시 코드의 로컬 사본을 만드는 방법을 보여줍니다.
다음 명령어를 사용하여 Git 저장소를 클론합니다.
git clone https://github.com/google-ai-edge/ai-edge-apis
예시 코드의 로컬 버전을 만든 후 프로젝트를 Android 스튜디오로 가져와 앱을 실행할 수 있습니다.
모델 다운로드
샘플 애플리케이션은 Gemma-3 1B를 사용하도록 구성되어 있습니다. Gemma-3 1B는 Gemini 모델을 만드는 데 사용되는 것과 동일한 연구와 기술로 빌드된 최첨단 경량 개방형 모델군인 Gemma의 일부입니다. 이 모델에는 10억 개의 매개변수와 개방형 가중치가 포함되어 있습니다.
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 임베더는 부동 소수점 모델과 양자화된 모델로 제공되며 시퀀스 길이가 다른 여러 버전이 있습니다. 자세한 내용은 Gecko 모델 카드를 참고하세요.
모델 사양은 모델 파일 이름에서 확인할 수 있습니다. 예를 들면 다음과 같습니다.
Gecko_256_f32.tflite: 최대 256개의 토큰 시퀀스를 지원하는 부동 소수점 모델입니다.Gecko_1024_quant.tflite: 최대 1,024개의 토큰 시퀀스를 지원하는 양자화된 모델입니다.
시퀀스 길이는 모델이 삽입할 수 있는 최대 청크 크기입니다. 예를 들어 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 임베더로 설정
Gemini 임베더 (GeminiEmbedder)는 Gemini Cloud API를 사용하여 임베딩을 만듭니다. 이렇게 하려면 Google Gemini API 설정 페이지에서 가져올 수 있는 Google Gemini API 키가 필요합니다.
Google AI Studio에서 Gemini API 키 가져오기
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 라이브러리를 사용합니다.
이 종속 항목을 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> 태그가 포함되어 있습니다. 그런 다음 각 청크의 임베딩이 생성됩니다. 프로덕션 애플리케이션에서 청크의 크기는 중요한 고려사항입니다. 청크가 너무 크면 벡터에 유용할 만큼 구체성이 충분하지 않고 너무 작으면 컨텍스트가 충분하지 않습니다.
샘플 애플리케이션은 memorizeChunks
function in
RagPipeline.kt를 통해 청킹을 처리합니다.
임베딩
애플리케이션은 텍스트 임베딩을 위한 두 가지 경로를 제공합니다.
- Gecko 임베더: Gecko 모델을 사용한 로컬 (기기 내) 텍스트 임베딩 추출입니다.
- Gemini 임베더: 생성형 언어 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 는 체인 인터페이스를 기반으로 합니다.
샘플 애플리케이션은 검색 및 추론 체인을 사용합니다. 다음 코드 스니펫은 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
}