AppFunctions sind das praktische Äquivalent zu MCP-Servern auf Android-Geräten. Damit können Sie Teile der Logik Ihrer Anwendung mit KI-Agenten und ‑Assistenten teilen.
KI-Agenten verwenden Beschreibungen, um die AppFunction auszuwählen, die eine Anfrage erfüllt. Dieser Auswahlprozess funktioniert wie die herkömmliche MCP-Toolerkennung, bei der KI-Anwendungen MCP-Server- und Toolbeschreibungen verwenden, um ihre Auswahl zu treffen. Ihre App fungiert als Android-MCP-Server und jede AppFunction als eines ihrer Tools. Geben Sie die folgenden Beschreibungen an:
- App-Beschreibung (Android-MCP-Server). Die App-Beschreibung ist der erste Einstiegspunkt für KI-Agenten, um zu verstehen, was Ihre App kann. Damit KI-Agenten Ihre App finden, sollten Sie die primäre Domain angeben und die Aufgaben, die mit Ihren AppFunctions erledigt werden können, kurz auflisten.
- Sie können die App-Beschreibung selbst in der XML-Datei mit den App-Metadaten verfassen.
- Verwenden Sie die Anwendungsbeschreibung, um zu beschreiben, was in den einzelnen Funktionsbeschreibungen nicht möglich ist, z. B. die Reihenfolge, in der Funktionen aufgerufen werden sollen.
- AppFunction-Beschreibungen (die Tools). In jeder Funktionsbeschreibung wird das Verhalten einer AppFunction erläutert. Funktionsbeschreibungen sind im Allgemeinen um ein Verb wie aktualisieren, erstellen oder buchen und eine Ressource wie Einstellungen, Kanal oder Raum strukturiert.
Richtlinien für Funktionsbeschreibungen
KI-Agenten entscheiden anhand von Funktionsbeschreibungen, welche Funktion zu einer Anfrage passt und wie sie aufgerufen werden soll.
Prägnante, eindeutige AppFunction-Beschreibungen schreiben
Je eindeutiger eine Beschreibung ist, desto zuverlässiger kann ein Agent die richtige Funktion für eine Anfrage auswählen. In der folgenden Tabelle ist aufgeführt, was Sie in Funktionsbeschreibungen tun und was Sie vermeiden sollten:
| Das sollten Sie tun | Das sollten Sie nicht tun |
|---|---|
| Beschreiben Sie den Zweck der Funktion und das Ergebnis ihrer Ausführung in klarer und neutraler Sprache. | Verwenden Sie keine Beschreibungen als Prompts. Befehle wie „Du MUSST sagen“ und „Du musst den Nutzer nach … fragen“ weisen den KI-Agenten an, wie er sich verhalten soll, anstatt die Funktion zu beschreiben. |
| Stelle die wichtigsten Informationen an den Anfang der Beschreibungen und halte sie kurz. | Verwenden Sie keine Füllwörter wie „Diese Funktion wird verwendet, um“. Füllwörter machen eine Beschreibung länger, ohne sie klarer zu machen. |
| Geben Sie genau an, was der Code tut, einschließlich seiner Parameter und der Ausgabe. Eine Funktion, die als Lesezugriff beschrieben wird, sollte beispielsweise keine Daten schreiben oder löschen. | Verwenden Sie keine irreführenden Namen, z. B. eine Funktion namens fetchData, die Nutzerdaten löscht. |
| Schreiben Sie Funktionsbeschreibungen im KDoc-Format, einschließlich Parametern und Rückgabetyp. Folgen Sie dem Kotlin-Styleguide für die Benennung und formulieren Sie Beschreibungen so, dass sie auch ohne Kenntnis der Implementierung verständlich sind. | Verwenden Sie keine übermäßige Großschreibung oder Sonderzeichen, um die Aufmerksamkeit auf Teile der Beschreibung zu lenken, z. B. **CRITICAL** oder VERY IMPORTANT. |
| Verwenden Sie menschenlesbare Namen für AppFunctions. | |
| Beschreiben Sie klar und direkt, was die einzelnen AppFunctions tun. | Geben Sie keine Verfahrensanweisungen, die andere Funktionen betreffen, z. B. „Suchen Sie zuerst nach dem Kontakt“. KI-Agenten verwenden Ihre App-Beschreibung, um Aufrufe über Funktionen hinweg zu planen. Beschreiben Sie diese Reihenfolge daher stattdessen dort. |
| Beschreiben Sie, was der KI-Agent von der Funktion erwarten kann, z. B. „Wenn X, dann Y“. | |
| Gehen Sie davon aus, dass Agenten ihre eigenen Anweisungen für die allgemeine Verwendung von AppFunctions haben. In der Funktionsbeschreibung wird angegeben, was die Funktion tut, und in den Anweisungen des KI-Agenten wird beschrieben, wie sie verwendet wird. | Versuchen Sie nicht, Anweisungen auf Agentenebene in Funktionsbeschreibungen zu überschreiben oder einzubetten. |
Beim Schreiben an die Kapselung denken
Halten Sie jede Funktionsbeschreibung eigenständig, damit der Agent nur diese Funktion und keine andere verwendet. In der folgenden Tabelle sind die Richtlinien für die Kapselung aufgeführt:
| Das sollten Sie tun | Das sollten Sie nicht tun |
|---|---|
| Schreiben Sie Funktionsbeschreibungen, die spezifisch und fokussiert sind und einen einzigen, klar definierten Zweck haben. Beispiel: „persönliche Aufgaben erstellen, finden und löschen“. | Schreiben Sie keine zu allgemeine Beschreibung, da der KI-Agent Ihre Funktion sonst zu unpassenden Zeiten oder aus den falschen Gründen aufrufen könnte. |
| Erstelle keine AppFunctions für mehrere Zwecke und stelle nicht viele AppFunctions für denselben Anwendungsfall bereit. Die Wahrscheinlichkeit, dass Agenten die falsche Funktion auswählen, ist höher, wenn mehrere Funktionen ähnliche Intents haben. | |
| Verweisen Sie nicht auf andere AppFunctions in Ihrer App oder in anderen Apps und versuchen Sie nicht, deren Verhalten zu beeinflussen. Dies kann zu unbeabsichtigten Abhängigkeiten und Nebenwirkungen führen. |
Zulässige Aktionen und Datenweitergabe
Beachten Sie die folgenden Richtlinien, um den Datenschutz für Nutzer und die Sicherheit zu schützen, wenn KI-Agenten die Funktionen Ihrer App verwenden:
| Das sollten Sie tun | Das sollten Sie nicht tun |
|---|---|
| Führen Sie nur sichere, nicht destruktive Aufgaben aus, die der Nutzer normalerweise in Ihrer App ausführen würde und bei denen der Agent klare Parameter aus der Anfrage des Nutzers bereitstellen kann, z. B. das Erstellen einer Aufgabe mit einem Titel oder das Suchen nach Notizen. | |
| Teilen Sie nur Informationen, die nicht hochgradig personenbezogen oder vertraulich sind, oder Daten, für die der Nutzer ausdrücklich seine Einwilligung zur Weitergabe für die Aktion gegeben hat. | Gewähren Sie dem Agenten keinen umfassenden Zugriff auf Nutzerdaten oder Systemressourcen. |
| Entwickeln Sie keine AppFunctions, die Passwörter, Finanzdaten, private Schlüssel oder andere hochsensible personenbezogene Daten erfordern oder zurückgeben. | |
| Aktionen ausführen, die ein Nutzer angefordert hat, auch wenn sie später oder im Hintergrund ausgeführt werden, z. B. eine Nachricht zu einem vom Nutzer ausgewählten Zeitpunkt senden. | Führe keine Aktionen aus, die der Nutzer nicht angefordert hat, z. B. Aufgaben, die von selbst starten oder über die Anfrage hinausgehen. |
| Konzentrieren Sie sich auf Funktionen, die von natürlicher Sprache profitieren, z. B. Aufgaben, die sich im Gespräch leichter ausdrücken lassen als über die Navigation in der Benutzeroberfläche, z. B.: „[KI-Agent], kannst du mir bitte helfen, freie Zeiten in meinem Kalender für nächste Woche zu finden, und mir dann einen Flug nach Chicago an einem dieser Tage vorschlagen?“ | |
| Achte bei anderen Formfaktoren als Smartphones auf die Privatsphäre der Nutzer auf gemeinsam genutzten Geräten wie Fernsehern, Android Auto und Android Automotive OS. | Lege keine Informationen offen und führe keine Aktionen aus, die von der Benutzeroberfläche deiner App auf diesem Formfaktor nicht unterstützt werden. |
| Geben Sie den Zweck Ihrer Funktion klar und eindeutig an. | Geben Sie sich nicht als ein anderes Tool oder ein anderer Dienst aus. Der Name und die Beschreibung Ihrer Funktion dürfen nicht so ähnlich wie die anderer Tools sein, dass der Agent Ihre Funktion versehentlich auswählt. |
Parameter- und Rückgabewertdesign
Eine sorgfältige Gestaltung von Parametern und Rückgabewerten verhindert Mehrdeutigkeiten und verringert die Wahrscheinlichkeit ungültiger Aufrufe. Folgen Sie diesen Konventionen:
| Das sollten Sie tun | Das sollten Sie nicht tun |
|---|---|
| Definieren Sie Parameter nur für Daten, die Ihre Funktion benötigt. | Fordern Sie keine Informationen an, die die Funktion nicht verwendet. Dadurch wird die Offenlegung von Daten minimiert und die Verwendung der Funktion vereinfacht. |
Verwenden Sie Parameternamen, die die erwartete Eingabe widerspiegeln, z. B. taskId, searchQuery oder recipientEmail. |
Verwenden Sie keine Namen wie full_context oder conversation_history. Solche Namen sind mehrdeutig, da Agenten diese Begriffe für ihren eigenen Kontext und Unterhaltungsverlauf verwenden. Ein Agent könnte sie falsch interpretieren und eine große Menge unnötiger Daten an Ihre Funktion übergeben, was zu einer Daten-Exfiltration führen kann. |
Verwenden Sie die von AppFunctions unterstützten Typen, anstatt eigene zu definieren, z. B. LocalDate, LocalTime, LocalDateTime oder Instant für Datums- und Uhrzeitangaben und Uri für Links. Die Bibliothek stellt diese Typen in jeder App auf dieselbe Weise dar, sodass KI-Agenten ein einheitliches Format erhalten. Eine vollständige Liste der unterstützten Typen finden Sie unter AppFunctionSerializable. |
|
| Wenn ein Parameter für den Zweck der Funktion nicht unbedingt erforderlich ist, machen Sie ihn optional. So ist der Agent flexibel, wenn er nur unvollständige Informationen vom Nutzer hat. Weitere Informationen finden Sie unter Optionale Parameter. | |
| Wenn Ihre AppFunction vorhandene Ressourcen aktualisiert, achten Sie darauf, dass jeder Parameter zwischen „auf null setzen“ und „nicht ändern“ unterscheiden kann. Ein Beispiel finden Sie unter Aktualisierungen vorhandener Ressourcen. | |
Wenn der KI-Agent einen bestimmten Bildschirm in Ihrer App öffnen soll, geben Sie einen PendingIntent für diesen Bildschirm zurück. Der Agent kann den PendingIntent unverändert starten, ohne einen Intent für Ihre App zu erstellen. Erstellen Sie ihn mit einem expliziten Intent und FLAG_IMMUTABLE, damit der Agent das Ziel nicht ändern kann. |
Optionale Parameter
Nur Nullable-, primitive, Listen- und Array-Typen können optional sein. Wenn der Agent einen optionalen Parameter weglässt, übergibt die Bibliothek den Standardwert des Typs (null, null, false oder leer) anstelle des von Ihnen deklarierten Standardwerts.
Lösen Sie sinnvolle Standardwerte im Funktionsrumpf auf, wie im folgenden Beispiel:
/**
* 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(),
)
}
Aktualisierungen vorhandener Ressourcen
Im folgenden Beispiel wird ein Nullable-SetField-Wrapper für jedes Feld verwendet, das der Agent aktualisieren kann. Ein Nullwert für SetField bedeutet „nicht ändern“ und SetField(null) bedeutet „auf Null setzen“:
/** 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,
)
}
Fehlerbehandlung
Wenn ein Aufruf fehlschlägt, erhält der Agent die Ausnahme, die von Ihrer Funktion ausgelöst wird, einschließlich Typ und Nachricht. Beachten Sie die folgenden Konventionen, damit der Agent den Fehler beheben oder dem Nutzer melden kann:
| Das sollten Sie tun | Das sollten Sie nicht tun |
|---|---|
Lösen Sie die Unterklasse AppFunctionException aus, die der Ursache entspricht, und geben Sie eine Nachricht an, die das Problem in einfacher Sprache beschreibt, z. B. AppFunctionInvalidArgumentException, wenn ein Argument ungültig ist, oder AppFunctionElementNotFoundException, wenn ein angefordertes Element nicht vorhanden ist. Der Typ gibt dem KI-Agenten Aufschluss darüber, welche Art von Fehler aufgetreten ist, und die Nachricht enthält die Details, die er zur Behebung benötigt, z. B. die Korrektur eines Arguments oder die Benachrichtigung des Nutzers. Das Beispiel updateNote in Aktualisierungen vorhandener Ressourcen zeigt dieses Muster. |
Lassen Sie keine anderen Ausnahmen aus Ihrer Funktion entweichen. Der Agent empfängt sie als AppFunctionAppUnknownException, wodurch die Art des Fehlers nicht identifiziert wird. |