AppFunctions kalite yönergeleri

AppFunctions, Android'deki MCP sunucularının pratik karşılığıdır. Bu sayede, uygulamanızın mantığının bir kısmını yapay zeka ajanları ve asistanlarıyla paylaşabilirsiniz.

Temsilciler, bir isteği yerine getiren AppFunction'ı seçmek için açıklamaları kullanır. Bu seçim süreci, geleneksel MCP aracı keşfi gibi çalışır. Yapay zeka uygulamaları, seçimlerini yönlendirmek için MCP sunucusunu ve araç açıklamalarını kullanır. Uygulamanız, Android MCP sunucusu olarak çalışır ve her AppFunction, bu sunucunun araçlarından biri olarak işlev görür. Aşağıdaki açıklamaları ekleyin:

  • Uygulama açıklaması (Android MCP sunucusu). Uygulama açıklamanız, temsilcilerin uygulamanızın neler yapabileceğini anlaması için ilk giriş noktasıdır. Temsilcilerin uygulamanızı keşfetmesine yardımcı olmak için uygulamanızın birincil alan adıyla başlayın ve AppFunctions'ın gerçekleştirmesine izin verdiği görevleri kısaca listeleyin.
    • Uygulama açıklamasını, uygulama meta veri XML dosyanızda kendiniz yazın.
    • Uygulama açıklamasını, işlevlerin çağrılma sırası gibi tek tek işlev açıklamalarının açıklayamayacağı şeyleri açıklamak için kullanın.
  • AppFunction açıklamaları (araçlar). Her işlev açıklaması, bir AppFunction'ın davranışını açıklar. İşlev açıklamaları genellikle güncelle, oluştur veya rezervasyon yap gibi bir fiil ve ayarlar, kanal veya oda gibi bir kaynak etrafında yapılandırılır.

İşlev açıklaması yönergeleri

Temsilciler, bir isteğe hangi işlevin uygun olduğuna ve bu işlevin nasıl çağrılacağına karar vermek için işlev açıklamalarını kullanır.

Kısa ve net AppFunction açıklamaları yazma

Açıklama ne kadar net olursa temsilci, istek için doğru işlevi o kadar güvenilir bir şekilde seçebilir. Aşağıdaki tabloda, işlev açıklamalarında yapılması ve kaçınılması gerekenler listelenmiştir:

Yapılması gerekenler Yapılmaması gerekenler
İşlevin amacını ve çalıştırılmasının sonucunu net ve tarafsız bir dille açıklayın. Açıklamaları istem olarak kullanmayın. "Şunu söylemelisiniz" ve "Kullanıcıdan şunu istemelisiniz" gibi komutlar, işlevi açıklamak yerine temsilciye nasıl davranması gerektiğini söyler.
Açıklamaların başına önemli bilgileri ekleyin ve açıklamaları kısa tutun. Açıklamaları "Bu işlev şu amaçla kullanılır:" gibi dolgu ifadelerle doldurmayın. Gereksiz kelimeler, açıklamayı daha net hale getirmeden uzatır.
Parametreleri ve çıkışı da dahil olmak üzere kodun ne yaptığını doğru bir şekilde yansıtmalıdır. Örneğin, salt okunur olarak tanımlanan bir işlev, veri yazmamalı veya silmemelidir. Kullanıcı verilerini silen bir işleve fetchData adını vermek gibi yanıltıcı adlar kullanmayın.
Parametreler ve dönüş türü dahil olmak üzere işlev açıklamalarını KDoc biçiminde yazın. Adlandırma için Kotlin stil kılavuzunu takip edin ve açıklamaları, uygulama hakkında bilgi sahibi olmadan anlaşılabilir hale getirin. Açıklamanın belirli bölümlerine dikkat çekmek için aşırı büyük harf veya özel karakter (ör. **CRITICAL** ya da VERY IMPORTANT) kullanmayın.
AppFunctions için kullanıcılar tarafından okunabilen adlar kullanın.
Her AppFunction'ın ne yaptığını açık ve net bir şekilde belirtin. "Önce kişiyi arayın" gibi diğer işlevleri içeren prosedür talimatları vermeyin. Temsilciler, işlevler arasında çağrı planlamak için uygulama açıklamanızı kullanır. Bu nedenle, bu sırayı orada açıklayın.
Temsilcinin işlevden ne bekleyebileceğini "X varsa Y" gibi bir dille açıklayın.
Temsilcilerin genel olarak AppFunctions'ı kullanmak için kendi talimatları olduğunu varsayın. İşlev açıklamanız, işlevin ne yaptığını belirtir ve temsilcinin talimatları, işlevin nasıl kullanılacağını kapsar. Temsilci düzeyindeki talimatları geçersiz kılmaya veya işlev açıklamalarına yerleştirmeye çalışmayın.

Kapsüllemeyi göz önünde bulundurarak yazma

Her işlev açıklamasını bağımsız tutun. Böylece temsilci, başka bir işlevi değil, yalnızca o işlevi kullanma konusunda yönlendirilir. Aşağıdaki tabloda kapsülleme kuralları listelenmiştir:

Yapılması gerekenler Yapılmaması gerekenler
İşlev açıklamalarını, tek ve iyi tanımlanmış bir amaca yönelik, spesifik ve odaklanmış şekilde yazın. Örneğin, "kişisel görevler oluşturma, bulma ve silme". Açıklamanın çok geniş kapsamlı olmamasına dikkat edin. Aksi takdirde temsilci, işlevinizi uygunsuz zamanlarda veya yanlış nedenlerle çağırabilir.
Çok amaçlı AppFunction'lar oluşturmayın veya aynı kullanım alanı için birden fazla AppFunction göstermeyin. Birden fazla işlevin benzer amaçları olduğunda temsilcilerin yanlış işlevi seçme olasılığı daha yüksektir.
Uygulamanızdaki veya diğer uygulamalardaki diğer AppFunctions'a atıfta bulunmayın ya da bunların davranışını etkilemeye çalışmayın. Bu durum, istenmeyen bağımlılıklara ve yan etkilere neden olabilir.

İzin verilen işlemler ve veri paylaşımı

Temsilciler uygulamanızın işlevlerini kullanırken kullanıcı gizliliğini ve güvenliğini korumak için aşağıdaki yönergeleri uygulayın:

Yapılması gerekenler Yapılmaması gerekenler
Yalnızca kullanıcının normalde uygulamanızda yapacağı güvenli ve zararsız görevleri gerçekleştirin. Temsilci, kullanıcının isteğinden net parametreler sağlayabilir (ör. başlık içeren bir görev oluşturma veya not arama).
Yalnızca çok kişisel veya gizli olmayan bilgileri ya da kullanıcının işlem için paylaşılmasına açıkça izin verdiği verileri paylaşın. Temsilciye kullanıcı verilerine veya sistem kaynaklarına geniş kapsamlı erişim izni vermeyin.
Şifre, finansal bilgiler, özel anahtarlar veya diğer son derece hassas kişisel bilgileri gerektiren ya da döndüren AppFunctions tasarlamayın.
Kullanıcının istediği işlemleri, daha sonra veya arka planda çalıştırılsa bile gerçekleştirme (ör. kullanıcının seçtiği bir zamanda mesaj gönderme) Kullanıcının istemediği işlemleri (ör. kendi kendine başlayan veya isteğin kapsamını aşan görevler) gerçekleştirmeyin.
Doğal dilden yararlanan işlevlere odaklanın. Örneğin, kullanıcı arayüzünde gezinmek yerine sohbet yoluyla ifade edilmesi daha kolay olan görevler: "[Yapay zeka aracısı], lütfen önümüzdeki hafta takvimimde uygun zamanları bulmama yardımcı olur musun? Ardından, bu günlerden biri için Chicago'ya uçuş önerir misin?"
Telefon dışındaki form faktörlerinde, TV'ler, Android Auto ve Android Automotive OS gibi paylaşılan cihazlarda kullanıcının gizliliğine saygı gösterin. Uygulamanızın kullanıcı arayüzünün söz konusu form faktöründe desteklemediği bilgileri açıklamayın veya işlemleri gerçekleştirmeyin.
İşlevinizin amacını net ve benzersiz bir şekilde tanımlayın. Başka bir araç veya hizmetmiş gibi davranmayın. İşlevinizin adı ve açıklaması, temsilcinin işlevinizi yanlışlıkla seçmesine neden olabilecek şekilde diğer araçlara kafa karıştırıcı bir şekilde benzememelidir.

Parametre ve dönüş değeri tasarımı

Parametre ve dönüş değeri tasarımının dikkatli yapılması, belirsizliği önler ve geçersiz çağrı olasılığını azaltır. Aşağıdaki kurallara uyun:

Yapılması gerekenler Yapılmaması gerekenler
Yalnızca işlevinizin ihtiyaç duyduğu veriler için parametreler tanımlayın. İşlevin kullanmadığı bilgileri istemeyin. Bu sayede, verilerin açığa çıkma riski en aza indirilir ve işlevin kullanımı basitleştirilir.
Beklenen girişi yansıtan parametre adları kullanın (ör. taskId, searchQuery veya recipientEmail). full_context veya conversation_history gibi adlar kullanmayın. Temsilciler bu terimleri kendi bağlamları ve görüşme geçmişleri için kullandığından bu tür adlar belirsizdir. Temsilci, bu talimatları yanlış yorumlayabilir ve işlevinize büyük miktarda gereksiz veri aktararak veri sızıntısına neden olabilir.
Kendi türlerinizi tanımlamak yerine AppFunctions'ın desteklediği türleri kullanın. Örneğin, tarih ve saatler için LocalDate, LocalTime, LocalDateTime veya Instant, bağlantılar için Uri kullanın. Kitaplık, bu türleri her uygulamada aynı şekilde temsil eder. Böylece temsilciler tutarlı bir biçim elde eder. Desteklenen türlerin tam listesi için AppFunctionSerializable sayfasına bakın.
Bir parametre, işlevin amacı için gerekli değilse isteğe bağlı yapın. Bu sayede temsilci, kullanıcıdan yalnızca kısmi bilgi aldığında esneklik kazanır. Daha fazla bilgi için İsteğe bağlı parametreler bölümüne bakın.
AppFunction'ınız mevcut kaynakları güncelliyorsa her parametrenin"null olarak ayarla " ile "değiştirme" arasında ayrım yapabildiğinden emin olun. Örnek için Mevcut kaynaklarda yapılan güncellemeler bölümüne bakın.
Temsilcinin uygulamanızda belirli bir ekranı açmasına izin vermek için o ekranla ilgili bir PendingIntent döndürün. Temsilci, uygulamanız için bir intent oluşturmadan PendingIntent öğesini olduğu gibi başlatabilir. Temsilcinin yönlendirdiği yeri değiştirememesi için bunu açık bir intent ve FLAG_IMMUTABLE ile oluşturun.

İsteğe bağlı parametreler

Yalnızca null değer alabilen, temel, liste ve dizi türleri isteğe bağlı olabilir. Temsilci isteğe bağlı bir parametreyi atladığında kitaplık, sizin bildirdiğiniz varsayılan değer yerine türün varsayılan değerini (null, sıfır, false veya boş) iletir. Aşağıdaki örnekte olduğu gibi, işlev gövdesinde anlamlı varsayılan değerleri çözün:

/**
 * Creates a note.
 *
 * @param title The title of the note.
 * @param content The body text of the note.
 * @param attachments The files to attach to the note.
 * @param owner The ID of the user who owns the note.
 * @return The created note.
 */
@AppFunctionDeclaration(isDescribedByKDoc = true)
suspend fun createNote(
    title: String, // Required
    content: String? = null, // Optional
    attachments: List<Attachment> = emptyList(), // Optional
    owner: String? = null, // Optional
): Note = withContext(Dispatchers.IO) {
    noteRepository.createNote(
        title = title,
        // The library ignores declared default values and passes null for
        // omitted nullable parameters, so resolve meaningful defaults here.
        content = content ?: "",
        attachments = attachments,
        owner = owner ?: currentUserId(),
    )
}

Mevcut kaynaklarda yapılan güncellemeler

Aşağıdaki örnekte, temsilcinin güncelleyebileceği her alan için null değer alabilen bir SetField sarmalayıcı kullanılmaktadır. Boş bir SetField "değiştirme" anlamına gelir ve SetField(null) "boş olarak ayarla" anlamına gelir:

/** A new value for a field of an existing item. */
@AppFunctionSerializable(isDescribedByKDoc = true)
data class SetField<T>(
    /** The new value of the field. */
    val value: T,
)

/**
 * Updates an existing note. Omitted fields keep their values.
 *
 * @param noteId The ID of the note to update.
 * @param title The new title of the note.
 * @param content The new body text of the note.
 * @return The updated note.
 */
@AppFunctionDeclaration(isDescribedByKDoc = true)
suspend fun updateNote(
    noteId: String,
    title: SetField<String>? = null,
    content: SetField<String?>? = null,
): Note = withContext(Dispatchers.IO) {
    val note = noteRepository.getNote(noteId)
        ?: throw AppFunctionElementNotFoundException(
            "No note found with ID $noteId"
        )
    noteRepository.updateNote(
        noteId = noteId,
        // A null SetField means "don't change", and SetField(null) means
        // "set to null", so don't use ?: for nullable fields.
        title = title?.value ?: note.title,
        content = if (content != null) content.value else note.content,
    )
}

Hata işleme

Bir çağrı başarısız olduğunda temsilci, işlevinizin oluşturduğu istisnayı (türü ve mesajı dahil) alır. Temsilcinin hatayı düzeltebilmesi veya kullanıcıya bildirebilmesi için aşağıdaki kurallara uyun:

Yapılması gerekenler Yapılmaması gerekenler
Nedene uyan AppFunctionException alt sınıfını, sorunu basit bir dille açıklayan bir mesajla birlikte gönderin. Örneğin, bir bağımsız değişken geçerli olmadığında AppFunctionInvalidArgumentException veya istenen bir öğe mevcut olmadığında AppFunctionElementNotFoundException. Tür, temsilciye ne tür bir hatanın meydana geldiğini bildirir ve mesaj, temsilciye kurtarma için gereken ayrıntıları (ör. bir bağımsız değişkeni düzeltme veya kullanıcıya bildirme) sağlar. Mevcut kaynaklarda yapılan güncellemeler bölümündeki updateNote örneği bu kalıbı gösterir. Diğer istisnaların işlevinizden kaçmasına izin vermeyin. Temsilci, bunları AppFunctionAppUnknownException olarak alır. Bu, hata türünü tanımlamaz.