Get started with agentic workflows

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:

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 AgentSession instance inside a ViewModel class across configuration changes in Manage sessions and lifecycle.
  • Connect to Compose: Stream events and render interactive chat bubbles in Stream events and UI integration.