Bu kılavuzda, AppFunctions API'yi Android uygulamanıza nasıl entegre edeceğiniz, bir işlevin mantığını nasıl uygulayacağınız ve entegrasyonun doğru şekilde çalıştığını nasıl doğrulayacağınız açıklanmaktadır.
Sürüm uyumluluğu
Bu uygulama, projenizin compileSdk API düzeyi 36 veya sonraki sürümlere ayarlanmasını gerektirir.
Uygulamanızın, AppFunctions'ın desteklenip desteklenmediğini doğrulaması gerekmez. Bu işlem, AppFunctions Jetpack kitaplığı içinde otomatik olarak gerçekleştirilir.
AppFunctionManager, özellik destekleniyorsa bir örnek, desteklenmiyorsa null döndürür.
Bağımlılıklar
Gerekli kitaplık bağımlılıklarını modülünüzün build.gradle.kts (veya build.gradle) dosyasına ekleyin ve KSP eklentisini üst düzey uygulama modülünüzde gösterildiği gibi yapılandırın:
# Add this to your app module at the top level. For multi module applications,
# you only need to specify this once.
ksp {
arg("appfunctions:aggregateAppFunctions", "true")
}
dependencies {
implementation("androidx.appfunctions:appfunctions:1.0.0-alpha09")
implementation("androidx.appfunctions:appfunctions-service:1.0.0-alpha09")
// If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
// See Add the KSP plugin to your project
ksp("androidx.appfunctions:appfunctions-compiler:1.0.0-alpha09")
}
AppFunctions mantığını uygulama
Android uygulamanız için bir AppFunction uygulamak üzere belirli AppFunctions mantığını uygulayan bir sınıf oluşturun. Bu işlem, parametreler ve yanıtlar için serileştirilebilir veri sınıfları oluşturmayı, ardından işlev yönteminde temel mantığı sağlamayı içerir.
Aşağıdaki kodda, özel parametrelerin ve yanıt türlerinin tanımlanması ile bir depo kullanılarak ana işlev mantığının oluşturulması da dahil olmak üzere TODO uygulamasında görev oluşturmaya yönelik örnek bir uygulama gösterilmektedir.
package com.example.android.appfunctions
import androidx.appfunctions.AppFunctionSerializable
import androidx.appfunctions.AppFunctionContext
import androidx.appfunctions.AppFunctionElementNotFoundException
import androidx.appfunctions.AppFunctionInvalidArgumentException
import androidx.appfunctions.service.AppFunction
import javax.inject.Inject
...
// Developers can provide additional parameters in the constructor if needed.
// This requires a custom factory setup in the next step.
class TaskFunctions @Inject constructor(
private val taskRepository: TaskRepository
) {
/** The parameter to create the task. */
@AppFunctionSerializable(isDescribedByKDoc = true)
data class CreateTaskParams(
/** The title of the task. */
val title: String,
/** The content of the task. */
val content: String
)
/** The user-created task. */
@AppFunctionSerializable(isDescribedByKDoc = true)
data class Task(
/** The ID of the task. */
val id: String,
/** The title of the task. */
val title: String,
/** The content of the task. */
val content: String
)
/**
* Creates a task based on [createTaskParams].
*
* @param createTaskParams The parameter to describe how to create the task.
*/
@AppFunction(isDescribedByKDoc = true)
suspend fun createTask(
appFunctionContext: AppFunctionContext,
createTaskParams: CreateTaskParams,
): Task = withContext(Dispatchers.IO) {
// Developers can use predefined exceptions to let the agent know
// why it failed.
if (createTaskParams.title == null && createTaskParams.content == null) {
throw AppFunctionInvalidArgumentException("Title or content should be non-null")
}
val id = taskRepository.createTask(
createTaskParams.title,
createTaskParams.content)
return taskRepository
.getTask(id)
?.toTask()
?: throw AppFunctionElementNotFoundException("Task not found for ID = $id")
}
// Maps internal TaskEntity
private fun TaskEntity.toTask() = Task(id = id, title = title, content = description)
}
Kodla ilgili önemli noktalar
- Varsayılan olarak, AppFunction uygulaması Android kullanıcı arayüzü iş parçacığında çalışır.
Bu nedenle, uzun süreli bir işlem aşağıdakileri yapmalıdır:
- AppFunction'ı askıya alma işlevi olarak bildirin.
- İşlem, iş parçacığını engelleyebileceğinde uygun bir eş yordam dağıtıcısına geçin.
isDescribedByKDoc,trueolarak ayarlandığında işlev açıklaması veya serileştirilebilir açıklama,AppFunctionMetadata'ın bir parçası olarak kodlanır. Bu sayede, ajanın uygulamanın AppFunction'ını nasıl kullanacağını anlamasına yardımcı olunur.
İsteğe bağlı: Özel bir AppFunction fabrikası sağlamak için Hilt'i kullanma
AppFunction uygulama sınıfınızın oluşturucusunda bağımlılıklar gerekiyorsa (ör. önceki örnekteki TaskRepository gibi) sistemin nasıl örnek oluşturacağını bilmesi için özel bir fabrika sağlamanız gerekir. Bu adım isteğe bağlıdır ve yalnızca işlev sınıfınızın oluşturucu parametreleri varsa gereklidir. Bu örnekte, bağımlılık yerleştirme için Hilt'i kullanarak özel bir AppFunctionFactory oluşturma ve bunu Application sınıfınızda yapılandırma işlemi gösterilmektedir.
import android.app.Application
import androidx.appfunctions.service.AppFunctionConfiguration
import com.example.android.appfunctions.TaskFunctions
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject
@HiltAndroidApp
class TodoApplication : Application(), AppFunctionConfiguration.Provider {
@Inject lateinit var taskFunctions: TaskFunctions
override fun onCreate() {
super.onCreate()
}
// This shows how AppFunctions works with Hilt.
override val appFunctionConfiguration: AppFunctionConfiguration
get() =
AppFunctionConfiguration.Builder()
.addEnclosingClassFactory(TaskFunctions::class.java) { taskFunctions }
.build()
}
İsteğe bağlı: Çalışma zamanında AppFunction kullanılabilirliğini değiştirme
AppFunction'larınızı sınırlarken işlevleri açıkça etkinleştirmek veya devre dışı bırakmak için AppFunctionManager API'sini kullanın. Uygulamanızın belirli özellikleri tüm kullanıcılara sunulmadığında sınırlama kullanışlı olabilir. AppFunction'ları dinamik olarak etkinleştirip devre dışı bırakarak, yapay zeka sistemi kullanıcınızın herhangi bir zamanda hangi özelliklere erişebileceğini tam olarak bilir.
Belirli bir hesap durumu gerektiren AppFunction'ları güvenli bir şekilde sınırlamak için iki adımlı bir süreç izleyin:
1. adım. İşlevi varsayılan olarak devre dışı bırakma
İşlevin, özellik bayrağınız doğrulanmadan önce erişilebilir olmasını önlemek için @AppFunction ek açıklamanızın isEnabled parametresini false olarak ayarlayın.
@AppFunction(isEnabled = false, isDescribedByKDoc = true)
suspend fun createTask(...) { ... }
2. Adım Çalışma zamanında işlevi dinamik olarak etkinleştirme
Derleyici, her AppFunction sınıfı için işlev kimliği sabitlerini içeren (Ids sonekini kullanarak) karşılık gelen bir sınıf oluşturur. Bir işlevin etkinleştirilmiş durumunu çalışma zamanında değiştirmek için bu oluşturulan kimlik sabitlerini AppFunctionManagerCompat içindeki setAppFunctionEnabled yöntemiyle birlikte kullanabilirsiniz.
import androidx.appfunctions.AppFunctionManager
// Assuming there is a hook API to observe user state or feature flags
suspend fun onFeatureEnabled() {
try {
AppFunctionManager.getInstance(context)
.setAppFunctionEnabled(
// Function ID is generated for developer to get
TaskFunctionsIds.CREATE_TASK_ID,
AppFunctionManagerCompat.APP_FUNCTION_STATE_ENABLED,
)
} catch (e: Exception) {
// Handle exception: AppFunctions indexation may not be fully completed
// upon initial app startup.
}
}
suspend fun onFeatureDisabled() {
AppFunctionManagerCompat.getInstance(context)
.setAppFunctionEnabled(
TaskFunctionsIds.CREATE_TASK_ID,
AppFunctionManagerCompat.APP_FUNCTION_STATE_DISABLED,
)
}
Kullanıma sunulacak işlev türleriyle ilgili dikkat edilmesi gerekenler
Güvenlik her zaman önceliğimizdir. Uygulamanızın hangi özelliklerini AppFunction olarak kullanıma sunacağınızı seçerken sistem aracıların, gelişmiş LLM özelliklerinden yararlanmak için kullanıcı sorgularını sunucuda işleyebileceğini unutmayın.
Hassas bilgilerin açığa çıkmasını önlerken aynı zamanda mükemmel bir kullanıcı deneyimi sunmak için aşağıdaki yönergeleri uygulamanızı öneririz:
- Doğal dilden yararlanan işlevler: Kullanıcının manuel kullanıcı arayüzü gezinme yerine sohbet yoluyla ifade etmesinin daha kolay olduğu görevleri kullanılabilir hale getirin.
- Sınırlı erişim: Yalnızca kullanıcının belirli isteğini karşılamak için gereken verilere ve işlemlere erişim izni veren AppFunction'lar oluşturun.
- Hassas olmayan bilgiler: Yalnızca çok kişisel veya gizli olmayan ya da kullanıcının işlem bağlamında paylaşmayı açıkça kabul ettiği verileri paylaşın.
- Herhangi bir yıkıcı işlem için net onay: Yıkıcı işlemler (ör. veri silme) gerçekleştiren işlevlere karşı son derece dikkatli olun. Aracı bunları çağırabilir ancak uygulamanız kendi onay adımını içermeli ve amaçlarla ilgili net, anlaşılır bir dil kullanmalıdır. Kullanıcının ne yapması gerektiğinin farkında olduğundan emin olmak için birden fazla onay adımı eklemek de faydalı olur.
AppFunction entegrasyonunu doğrulama
AppFunctions'ı doğru şekilde entegre edip etmediğinizi doğrulamak için adb
shell cmd app_function kullanabilirsiniz.
Uygulamanızın sağladığı AppFunctions'ın ayrıntılarını görmek için adb shell cmd app_function list-app-functions | grep --after-context 10
$myPackageName simgesini kullanın.
Android Studio'da Gemini'da veya seçtiğiniz diğer aracılarda aşağıdaki gibi bir istem girin.
Execute `adb shell cmd app_function` to learn how the tool works, then act as a
chat agent aiming to invoke AppFunctions to fulfil user prompts for this app.
Rely on the AppFunction description as instructions.