יצירת סוכני ADK ל-Android

הספרייה Agent Development Kit ‏ (ADK) ל-Android מאפשרת לכם ליצור סוכני AI מתוחכמים ולשלב אותם ישירות באפליקציות ל-Android. ‫ADK היא מסגרת פיתוח בקוד פתוח ליצירת סוכנים מבוססי-AI שפועלים באופן מקומי, בשירותים מתארחים ובמכשירי Android. המסגרת תומכת בשפות התכנות Kotlin ו-Java, ומאפשרת לכם להתחיל במהירות לבנות סוכנים ולהרחיב לאפליקציות מורכבות עם כמה סוכנים.

ספריית ADK ל-Android מספקת תלויות מיוחדות ותמיכה בזמן ריצה שמותאמות לסביבות ניידות. אתם יכולים ליצור סוכנים שמריצים מודלים של AI במכשיר באמצעות Gemini Nano וממשקי ה-API של ML Kit GenAI, וכך ליצור חוויות AI שמתמקדות בפרטיות ועם זמן אחזור נמוך, שיכולות לפעול ללא גישה לרשת.

שימוש ב-ADK Kotlin בפרויקטים של Android

אתם יכולים להשתמש ב-ADK Kotlin agent API כדי ליצור סוכני AI שפועלים בתוך אפליקציות Android. קוד הסוכן שאתם כותבים זהה למדריך תחילת העבודה עם ADK Kotlin. ההבדלים הם בתלות ב-Gradle, בהגדרת הפרויקט ובאופן ההפעלה של הסוכן בזמן הריצה.

דרישות מוקדמות

ספריית ה-ADK ל-Android כוללת את דרישות הפיתוח הבאות:

  • ‫Android Studio
  • ‫Android SDK (‏compileSdk 34 ואילך, minSdk 24 ואילך)

הגדרת הפרויקט ל-Android

בקובץ build.gradle.kts של פרויקט Android, מוסיפים את התלות ב-ADK Android ואת מעבד האנוטציות (Annotation processor) של KSP:

plugins {
    id("com.android.application")
    kotlin("android")
    id("com.google.devtools.ksp") version "2.1.20-2.0.1"
}

android {
    namespace = "com.example.agent"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.agent"
        minSdk = 24
        targetSdk = 34
    }
}

dependencies {
    implementation("com.google.adk:google-adk-kotlin-core-android:0.1.0")
    ksp("com.google.adk:google-adk-kotlin-processor:0.1.0")
}

kotlin {
    jvmToolchain(17)
}

הגדרת הסוכן

קוד הסוכן זהה למדריך למתחילים ב-Kotlin של ADK. דוגמת הקוד HelloTimeAgent עם התחביר @Tool, @Param ו-.generatedTools() פועלת ללא שינוי ב-Android:

package com.example.agent
import com.google.adk.kt.agents.Instruction
import com.google.adk.kt.agents.LlmAgent
import com.google.adk.kt.annotations.Param
import com.google.adk.kt.annotations.Tool
import com.google.adk.kt.models.Gemini
class TimeService {
    /** Mock tool implementation */
    @Tool
    fun getCurrentTime(
        @Param("Name of the city to get the time for") city: String
    ): Map<String, String> {
        return mapOf("city" to city, "time" to "The time is 10:30am.")
    }
}
object HelloTimeAgent {
    @JvmField
    val rootAgent = LlmAgent(
        name = "hello_time_agent",
        description = "Tells the current time in a specified city.",
        model = Gemini(
            name = "gemini-flash-latest",
            apiKey = System.getenv("GOOGLE_API_KEY")
                ?: error("GOOGLE_API_KEY environment variable not set."),
        ),
        instruction = Instruction(
            "You are a helpful assistant that tells the current time in a city. "
                + "Use the 'getCurrentTime' tool for this purpose."
        ),
        tools = TimeService().generatedTools(),
    )
}

הפעלת הסוכן מאפליקציית Android

במכשירים עם Android, משתמשים ב-InMemoryRunner כדי להפעיל את הסוכן ולאסוף תשובות משגרת המשך (coroutine), כמו בדוגמת הקוד הבאה:

import com.google.adk.kt.runners.InMemoryRunner
import com.google.adk.kt.sessions.InMemorySessionService
import com.google.adk.kt.types.Content
import com.google.adk.kt.types.Part
import com.google.adk.kt.types.Role
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
// Create a runner and session service
val sessionService = InMemorySessionService()
val runner = InMemoryRunner(
    agent = HelloTimeAgent.rootAgent,
    sessionService = sessionService,
)
// Call the agent from a coroutine (e.g. in a ViewModel or Activity)
scope.launch {
    runner.runAsync(
        userId = "user-123",
        sessionId = "session-123",
        newMessage = Content(
            role = Role.USER,
            parts = listOf(Part(text = "What time is it in New York?")),
        ),
    ).collect { event ->
        val text = event.content?.parts?.firstOrNull()?.text
        if (!text.isNullOrBlank()) {
            // Update your UI with the agent's response
        }
    }
}

שימוש בסוכנים ליצירת ממשק משתמש

אם הסוכן צריך להחזיר ממשקי משתמש אינטראקטיביים ומובנים, כמו כרטיסים, טפסים או רשימות, במקום טקסט פשוט, צריך להשתמש בפרוטוקול agent-to-UI (A2UI).

אתם יכולים להשתמש ב-Jetpack Compose A2UI Renderer כדי להציג באופן אוטומטי תגובות של A2UI כרכיבים מקוריים של Jetpack Compose ו-Material 3 בהיררכיית ממשק המשתמש של האפליקציה. כדי להתחיל, אפשר לעיין במדריך בנושא Jetpack Compose A2UI.

מודלים במכשיר עם Gemini Nano

הארטיפקט של ADK ל-Android כולל תמיכה בהסקת מסקנות במכשיר באמצעות Gemini Nano דרך ML Kit GenAI API. הגישה הזו מאפשרת לסוכנים לפעול ללא גישה לרשת, ולשמור את הנתונים במכשיר.

כדי להשתמש במודל במכשיר, יוצרים מודל GenaiPrompt במקום Gemini, כמו בדוגמת הקוד הבאה:

import com.google.adk.kt.models.mlkit.GenaiPrompt
import com.google.mlkit.genai.prompt.GenerativeModel
// Create an ML Kit GenerativeModel for on-device inference
val generativeModel: GenerativeModel = // ... initialize using ML Kit
val onDeviceModel = GenaiPrompt.create(
    generativeModel = generativeModel,
    name = "gemini-nano",
)
val agent = LlmAgent(
    name = "on_device_agent",
    model = onDeviceModel,
    instruction = Instruction("You are a helpful assistant."),
)

אפשר גם לשלב מודלים בענן ובמכשיר במערכת מרובת סוכנים: להשתמש ב- מבוסס-ענן Gemini בתור המארגן הראשי ובמודלים GenaiPrompt במכשיר בתור סוכני משנה שמטפלים במשימות שקשורות לפרטיות. מידע נוסף על הדפוס הזה מופיע בפוסט בבלוג בנושא ADK ל-Kotlin ול-Android.

כדי לראות פעילות מלאה לדוגמה ועוד דוגמאות, אפשר לעיין בדוגמאות ל-ADK Kotlin ב-GitHub.