ML Kit GenAI Prompt API — On-Device Prompting for Android with Gemini Nano

Google's Android skill covers on-device prompting through ML Kit: API 26, Gemini Nano availability, structured output with @Generable, prefix caching, system instructions, lifecycle, and device constraints.

October 22, 2026
skillsandroidml-kitgemini-nanoon-device-aistructured-output
ML Kit GenAI Prompt API — On-Device Prompting for Android with Gemini Nano

ML Kit GenAI Prompt API

ML Kit GenAI Prompt API is Google's Android skill for sending natural-language requests to Gemini Nano on a device. It covers prompt design, structured output, prefix caching, system instructions, model availability, and lifecycle cleanup.

The install is small, but the runtime requirements are not. This is on-device AI with a device-gated model, a beta SDK, and APIs that are still changing. The skill is most useful when you treat it as a checklist for those constraints, not as a guarantee that a prompt will run on every Android phone.

Source and revision

FieldValue
MaintainerGoogle LLC (android/skills)
Canonical sourcedevice-ai/ml-kit-genai-prompt-api/SKILL.md at ac42384
Revision inspectedac4238481a4837fd6c8387f32116706293ee81a7, updated 2026-09-07
Access date2026-10-23
LicenseApache-2.0 (LICENSE.txt); the skill frontmatter says "Complete terms in LICENSE.txt"
Install unitdevice-ai/ml-kit-genai-prompt-api/, including six local reference files

What the skill actually does

The core file gives a short implementation path:

  1. Prompt optimization. Use concise prompts, examples for in-context learning, XML/HTML delimiters for dynamic input, output constraints, and the Structured Output API when the response must be parsed.
  2. Prefix caching. If the prompt is more than 200 words, separate a static prefix from the dynamic suffix and use the prefix caching API.
  3. Lifecycle. Check FeatureStatus before the first inference. Download the model if it is DOWNLOADABLE. Call close() on the GenerativeModel when the activity, fragment, or view model is destroyed.
  4. Structured output. Verify isStructuredOutputFeatureAvailable() before use, return a @Generable typed object instead of a string, and handle parse errors.

The six local references expand on prompt optimization, prompt design, prefix caching, getting started, structured output, and system instructions. The skill routes to them rather than duplicating everything.

Runtime constraints you must plan for

ConstraintDetail
Android API level26 or higher (minSdk 26)
Prompt API dependencycom.google.mlkit:genai-prompt, at least 1.0.0-beta4 according to SKILL.md
Structured outputKotlin only; KSP plugin 2.3.6 or higher; genai-schema-compiler
ModelGemini Nano must be AVAILABLE on the device
DownloadIf DOWNLOADABLE, the app must download it before inference
System instructionsRequire Gemini Nano V3 or higher
Prefix cachingExperimental; only a subset of Prompt API devices; text-only input
Device supportChanges over time; check the current Prompt API device-support list

The version detail is a real drift signal: the SKILL.md says 1.0.0-beta4, while the get-started reference at the same commit shows 1.0.0-beta2. Treat the skill's prerequisite as the newer requirement and verify the current release in the Android documentation before pinning a version.

Illustrative implementation

This is a constructed example based on the skill's documented API, not a compiled or run app.

Task: parse a customer email into sender, title, and a short summary.

Before: the function returns a String, and the caller parses JSON by hand.

After:

@Generable
data class ParsedEmail(
    @Guide(description = "Sender of the email")
    var sender: String = "",

    @Guide(description = "Title of the email")
    var title: String = "",

    @Guide(description = "Summary of the email in 10 words or fewer")
    var summary: String = ""
)

suspend fun parseEmail(email: String): ParsedEmail? {
    val prompt = "Parse this email: $email"
    val baseRequest = GenerateContentRequest.Builder(TextPart(prompt)).build()
    val typedRequest = generateTypedContentRequest(baseRequest, ParsedEmail::class)
    val response = generativeModel.generateContent(typedRequest)
    return response.candidates.firstOrNull()?.response
}

The surrounding code still needs:

  • A checkStatus() branch that handles UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, and AVAILABLE.
  • A fallback UI when the model is unavailable or the download fails.
  • isStructuredOutputFeatureAvailable() before the typed request.
  • ProGuard keep rules for the annotated class in release builds.
  • close() in the owner's onDestroy or onCleared.

The skill's prompt-optimization reference also recommends delimiters such as <email>[content]</email> so the model can distinguish instructions from user data. That is a prompt-injection mitigation, not a guarantee.

When to use it

  • You are adding on-device summarization, classification, entity extraction, or rewriting to an Android app.
  • You need structured output instead of parsing free-form JSON.
  • You have a long, repeated prompt prefix and want to test prefix caching.
  • You need to check Gemini Nano availability and handle model download.
  • You are reviewing an Android codebase that already uses ML Kit GenAI.

When not to use it

  • You need a model that runs on every Android device. Gemini Nano availability is device-gated.
  • You need a cloud model with larger context or stronger reasoning. This is on-device and constrained.
  • You are building for iOS, web, or desktop.
  • You need a stable, long-term API. The SDK and several features are beta or experimental.
  • You need to process images with prefix caching. Prefix caching is text-only.
  • You need a server-side key or a hosted endpoint. There is no API key in this workflow; the model is on the device.

Install

android skills add ml-kit-genai-prompt-api --project=.

The Android CLI installs the skill into the current project for detected agents. Use --agent to target a specific host and --all only if you want the whole Android collection.

Prerequisites and footprint

ItemDetail
BuildAndroid project with minSdk 26 or higher
Dependencycom.google.mlkit:genai-prompt (beta)
ToolingKSP 2.3.6+ for structured output; ProGuard keep rules
DeviceGemini Nano available, or downloadable and permitted by the user
NetworkModel download and any app content the prompt includes
StorageModel download plus prefix-cache files in app-private storage
CredentialsNone; this is on-device inference
WritesApp code and Gradle files you approve

Prefix caching stores encrypted cache files and metadata, including the original prefix text, in the app's private storage. The reference says the cache count is managed by LRU and can be cleared with clearImplicitCaches().

Limitations

  • Device availability is the hard gate. A device that does not support Gemini Nano cannot run the feature, regardless of minSdk.
  • Beta and experimental APIs. Prefix caching is experimental, clearImplicitCaches() is experimental, and the Prompt API dependency is beta.
  • Structured output is Kotlin-only. Java projects cannot use the typed output path described here.
  • Version drift. The core file and the get-started reference disagree on the dependency version. Verify the current release.
  • No credential story, but a download story. The absence of API keys does not mean zero network or storage cost.
  • Prompt injection still applies. On-device content can contain instructions. Delimiters help; they are not a security boundary.
  • No runtime test by us. We did not build the app or run it on a device.

Verify it yourself

  1. Read the skill and all six references. Confirm the API level, dependency version, KSP version, and model requirements for your target devices.
  2. Check the current Prompt API device-support list. Do not assume a flagship device from last year is supported.
  3. Write a small screen that calls checkStatus() and renders every state, including UNAVAILABLE and DOWNLOADABLE. Test it on a device that lacks the model.
  4. Test structured output with a deliberately invalid value to see how finishReason and GenAiException surface.
  5. Add the ProGuard keep rule and test a release build, not only debug.
  6. Verify close() is called and that a second screen does not reuse a closed model.

Review transparency

FieldValue
Last reviewed2026-10-23
What was inspectedFull SKILL.md, references/get-started.md, prompt-optimization.md, prefix-caching.md, structured-output.md, system-instructions.md, repository README, license, pinned commit metadata
What was not doneNo install, no Android build, no device run, no model download, no structured-output test
ReviewersEditorial source inspection only. Not a two-model security review.
Re-vet triggerAny change to the dependency version, device-support list, or beta status; more than 30 days

This is an original guide with short attributed code examples. It does not reproduce the full skill or its reference files.