Blog • AI / App Intents
Après iOS 27, comment le JSON d'une App Action circule-t-il vraiment ? De la phrase dite à l'appel d'API
Une demande Siri s'exécute parce qu'elle devient d'abord des paramètres d'App Intent, puis AppIntent décide dans perform() de rester sur l'appareil ou d'appeler votre API. Le système n'envoie pas la phrase brute à votre serveur.
Savoir si Siri est un agent est dans l'article précédent. Celui-ci suit une seule demande : comment une phrase choisit un Intent, comment les paramètres deviennent du JSON, et pourquoi l'API n'est appelée qu'après validation.
- Une phrase correspond à un App Shortcut. L'énoncé n'est pas exécuté comme du texte libre
- Trois sortes de paramètres : types intégrés, AppEnum fixé à la compilation, AppEntity à interroger
- Une entité ne donne qu'un id stable. La requête charge vos données avec cet id
- Vous gardez votre propre JSON de paramètres. Ce n'est pas le format réseau d'Apple
- Si resolved vaut false ou si le schéma échoue, n'appelez pas l'API. Rendez le dialogue à Siri
À retenir d'abord : La voix n'est pas le corps de requête. Les paramètres d'Intent remplis le sont. Ensuite : phrase, type de paramètre, id d'entité, votre JSON, puis l'API.
Cinq étapes d'une demande
L'entrée officielle est App Intents. Voir Démarrer avec App Intents. Siri, Raccourcis et un bouton dans l'app partagent un Intent. Ils diffèrent par qui remplit les paramètres.
- 1Faire correspondre la phrase
Vous enregistrez les phrases parlées sur
AppShortcutsProvider. Le système s'en sert pour choisir un Intent. Il ne donne pas la phrase brute à un modèle pour improviser. - 2Remplir les paramètres
Chaque
@Parameterde l'Intent dit au système quelle valeur il lui faut et si elle est obligatoire. S'il en manque une, il demande. Il ne devine pas pour envoyer. - 3Résoudre l'entité
Les données utilisateur passent par
EntityQueryselonid. Le paramètre contient l'entité, pas un paragraphe qui la décrit. - 4Exécuter
perform() est l'endroit où vous lisez des valeurs déjà résolues. Si l'appareil peut finir l'action, finissez-la là.
- 5Répondre à Siri
Renvoyez le résultat avec
IntentResultou un dialogue. Un échec a encore besoin d'une phrase audible. Ne le laissez pas seulement dans un journal serveur.
Trois sortes de paramètres
Les types sont dans Ajouter des paramètres à un app intent. Un mauvais type rend le JSON suivant instable.
| Type | Pour | Dans le JSON |
|---|---|---|
| Chaîne, nombre, date | Une saisie simple comme une quantité ou une note | La copier telle quelle dans parameters |
AppEnum | Un ensemble fixé à la compilation, par exemple retrait ou livraison | Stocker la valeur d'énumération. Ne pas utiliser le texte affiché comme clé |
AppEntity | Des données utilisateur qui changent, par exemple un produit | Ne stocker que l'id résolu |
Un ensemble fixe est un AppEnum. Une liste que la personne peut modifier est une AppEntity plus une requête. Si vous modelez une liste changeante en énumération, les phrases cessent de correspondre dès qu'une option expire.
Une entité ne garde que son id
Le système a besoin d'une entité qu'il peut afficher et interroger. Votre base reste la source des données. L'entité a au moins un id stable et un nom lisible.
{
"entity": "OrderItem",
"id": "sku_42",
"display": "Oat milk"
}
Implémentez entities(for identifiers:) et chargez l'objet par id. S'il manque, n'inventez pas un id pour continuer.
Le JSON de paramètres qui vous appartient
Le document ci-dessous est le contrat que vous enregistrez dans perform() avant de décider d'appeler l'API. Ce n'est pas le format de requête d'Apple, et le système ne lira pas le fichier pour vous.
{
"intent": "StartOrder",
"source": "siri",
"parameters": {
"item_id": "sku_42",
"quantity": 1
},
"resolved": true
}
intentutilise le nom du type d'Intent pour s'aligner sur l'action dans Raccourcis.item_idest l'id de l'entité, pas la phrase dite. La phrase peut changer. L'id ne devrait pas.- Si
resolvedvaut false, la résolution n'est pas finie ou la personne a annulé la question de suivi. N'appelez pas l'API. - Ne mettez pas la phrase brute, une trace de position ni un jeton dans ce JSON.
Quand appeler l'API
- 1Finir sur l'appareil
Une action qui ne change que l'état local se termine dans perform(). Elle n'a pas besoin du réseau.
- 2Valider d'abord
S'il vous faut un serveur, validez d'abord le JSON avec un schéma. Un item_id manquant ou une quantity inférieure à 1 s'arrête sur l'appareil.
- 3Puis aller sur le réseau
N'envoyez parameters à votre API qu'après validation et si resolved vaut true. Le serveur cherche son propre enregistrement par id. Il ne fait pas confiance au nom affiché.
- 4Dire l'échec clairement
Si l'API refuse ou expire, dites via le dialogue de l'Intent que ce n'est pas terminé. Ne laissez pas Siri annoncer un succès.
Comment une app tierce déclare l'Intent et renvoie un échec est l'article suivant. Celui-ci s'arrête au chemin des données.
Différence avec les articles plus anciens
| Siri est-il un agent ? | Cet article | |
|---|---|---|
| Question | Si le système planifie et appelle des outils tout seul | Quel JSON une demande traverse avant l'API |
| Ne pas chercher ici | Une autre annonce produit | Traiter la phrase brute comme un corps de requête à stocker |
Le récit produit du matériel et des fonctions système est dans pourquoi l'iPhone 18 est plus que du matériel. Ce texte ne découpe pas les champs de paramètres.
Vérifier ce JSON dans JSONNote
- 1Formater
Ouvrez l'enregistrement de paramètres dans Formater le JSON et vérifiez qu'il n'y a pas de virgule finale.
- 2Bloquer les champs manquants avec un schéma
Collez le schéma ci-dessous dans JSON Schema. Un intent ou un item_id manquant, ou une quantity qui n'est pas un entier positif, ne doit pas partir vers l'API.
- 3Puis vérifier un exemple
Collez un vrai exemple dans Valider le JSON. Regardez surtout si
item_idest une chaîne vide.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["intent", "source", "parameters", "resolved"],
"properties": {
"intent": { "type": "string", "minLength": 1 },
"source": { "enum": ["siri", "shortcut", "app"] },
"resolved": { "type": "boolean" },
"parameters": {
"type": "object",
"required": ["item_id", "quantity"],
"properties": {
"item_id": { "type": "string", "minLength": 1 },
"quantity": { "type": "integer", "minimum": 1 }
}
}
}
}
Questions fréquentes
Le système envoie-t-il toute la phrase à mon serveur ?
Pas sur ce chemin. Le serveur doit recevoir le JSON de paramètres que vous assemblez et validez dans perform(). La voix reste dans la reconnaissance sur l'appareil.
Pourquoi ne pas mettre le nom du produit dans les paramètres ?
Les noms changent et se répètent. Une AppEntity utilise un id stable, et la requête charge l'objet avec cet id. L'API ne doit accepter que l'id.
Si le schéma passe, puis-je appeler l'API ?
Regardez aussi resolved. Une forme valide avec une entité non résolue veut dire que la personne n'a pas encore choisi l'objet. Appeler l'API transforme une question de suivi en mauvaise commande.
Comment séparer le travail local d'un appel réseau ?
Ce qui ne change que des données locales se termine dans perform(). Ce qui a besoin de votre backend écrit le JSON, le valide, puis appelle. Les deux chemins renvoient le résultat via IntentResult.
Un raccourci dont on remplit les paramètres à la main suit-il le même chemin ?
Oui, c'est le même AppIntent. La différence est qui remplit les paramètres : Siri avec la phrase, Raccourcis avec la personne ou l'action précédente. Résolution d'entité, JSON et verrou d'API restent les mêmes.
Conclusion
Le chemin d'une demande : une phrase choisit l'Intent, les paramètres se remplissent par type, l'entité se réduit à un id, vous écrivez le JSON, l'API ne part qu'après validation, et un dialogue rend le résultat à Siri.
Conclusion directe : ne pas envoyer la phrase brute. Ne pas appeler l'API avant que l'id soit résolu. Dire l'échec à la personne au lieu de le laisser seulement dans un journal serveur.
Ensuite : verrouillez ce JSON de paramètres avec un schéma avant de le brancher dans perform().