This page describes how to set up your Android project, configure the
genai-agent library, and create your first on-device agent.
Prerequisites
Before building agentic workflows with Gemini Nano, ensure your environment meets the following requirements:
- Android version: Android 14 (API level 34) or higher enrolled in the AICore Developer Preview program.
- Supported devices: For a list of supported devices and their Gemini Nano model versions, see Custom generation and agent device support.
- Minimum SDK:
minSdk 26or higher. - Kotlin: Kotlin 2.3 or higher.
Configure your project
Add the genai-agent dependency to your module's build.gradle.kts file:
dependencies {
// Gemini Nano agentic workflows
implementation("com.google.mlkit:genai-agent:1.0.0-alpha1")
// Optional: Only required when defining tools using Android AppFunctions
implementation("androidx.appfunctions:appfunctions:1.0.0-alpha13")
ksp("androidx.appfunctions:appfunctions-compiler:1.0.0-alpha13")
}
Build your first agent
An agent has two primary components:
- Agent definition: Instructions and guardrails configuring the agent's behavior.
- Agent runner: The execution engine that communicates with AICore and manages conversations.
1. Configure the agent and runner
The following code sample shows how to define your agent with system instructions and initialize the AgentRunner class:
import com.google.mlkit.genai.agent.Agent
import com.google.mlkit.genai.agent.AgentRunner
// 1. Build the agent configuration
val agent = Agent.builder()
.setName("Assistant")
.setInstructions("You are a helpful on-device assistant.")
.build()
// 2. Initialize the runner
val runner = AgentRunner(agent)
2. Run a conversation
Multi-turn conversations retain dialogue history across turns using an
AgentSession instance. Wrap your prompt text in a Content object and collect
the streamed response:
import android.util.Log
import androidx.lifecycle.lifecycleScope
import com.google.mlkit.genai.agent.textTokens
import com.google.mlkit.genai.prompt.Content
import kotlinx.coroutines.launch
// Create or retrieve a conversation session
val session = runner.getOrCreateSession("chat_session")
val prompt = Content.builder()
.text("Hello! Can you help me organize my day?")
.build()
// Collect streamed tokens in a coroutine
lifecycleScope.launch {
session.runAsync(prompt)
.textTokens()
.collect { token ->
Log.d("Agent", token)
}
}
For one-off queries where you don't need to retain conversation history, you
can call the runner.runSingleTurnAsync(prompt) method directly:
lifecycleScope.launch {
runner.runSingleTurnAsync(prompt)
.textTokens()
.collect { token ->
Log.d("Agent", token)
}
}
3. Clean up resources
The AgentRunner class implements the AutoCloseable interface. When your
ViewModel or Activity component is destroyed, close the runner to release
active sessions and cancel background coroutines:
runner.close()
Next steps
- Add capabilities with tools: Give your agent the ability to take actions or query app data using Android AppFunctions. See Define tools.
- Preserve sessions across rotation: Learn how to retain the
AgentSessioninstance inside aViewModelclass across configuration changes in Manage sessions and lifecycle. - Connect to Compose: Stream events and render interactive chat bubbles in Stream events and UI integration.