Foundation Models dans iOS 27 : le contrôle de l'appel d'outils
iOS 26 a doté une application d’un grand modèle de langage sur l’appareil, d’un moyen d’obtenir une sortie au typage sûr grâce à @Generable et d’un protocole Tool qui laissait le modèle appeler votre code en pleine génération1. C’est le modèle qui décidait quand recourir à un outil, et c’est vous qui écriviez l’outil. La seule chose que vous ne pouviez pas faire, c’était orienter le comportement d’appel lui-même ; et la seule chose que vous deviez toujours faire, c’était écrire chaque outil à la main, y compris ceux dont toute application a besoin. iOS 27 comble ces deux lacunes. GenerationOptions.ToolCallingMode vous permet de contrôler la façon dont le modèle interagit avec les outils, requête par requête2, et le framework Vision livre désormais deux outils prêts à l’emploi, OCRTool et BarcodeReaderTool, que vous rattachez à une session sans écrire vous-même le code de reconnaissance34. Ensemble, ils achèvent la boucle agentique amorcée par le framework : le modèle décide quoi faire, vous décidez avec quelle vigueur il est autorisé à le faire, et Apple fournit les outils de perception qui lisent le monde physique.
Ce qui suit constitue la couche iOS 27 posée sur la référence du framework. Si vous n’avez pas encore rencontré LanguageModelSession, le protocole Tool ou la génération guidée, commencez par l’explication du framework Foundation Models, puis revenez.
En bref
GenerationOptions.ToolCallingModeest une nouvelle structure d’iOS 27 qui décrit le comportement du modèle autour de l’usage des outils, définie requête par requête viaGenerationOptions2. Apple documente trois modes.- Le framework peut changer de mode après le premier appel d’outil, de sorte que le modèle cesse d’appeler des outils et produit une réponse finale, ce qui borne l’activité d’outils d’une même requête2.
OCRToolreconnaît le texte d’une image et renvoie une chaîne contenant tout ce qu’il a lu. Vous l’activez en configurant votreLanguageModelSessionavec une instance d’OCRTool3.BarcodeReaderToollit les codes lisibles par machine et renvoie un tableau de résultatsBarcode, chacun portant le contenu décodé et le type de symbologie. Vous l’activez de la même manière, en configurant la session avec une instance4.- Les deux outils Vision vous laissent remplacer le nom et la description par défaut, de sorte que vous maîtrisez la façon dont le modèle identifie chacun et décide de l’utiliser34.
- Tout ce qui figure ici relève de la bêta iOS 27 (et des bêtas correspondantes iPadOS, macOS, visionOS et, pour deux des trois symboles, watchOS)234.
Ce qui a changé entre iOS 26 et iOS 27
Le framework d’iOS 26 traitait l’appel d’outils de façon binaire à la surface de l’API. Vous remettiez à une session un ensemble d’outils, et dès lors le modèle seul décidait s’il fallait les appeler et à quelle fréquence. Cela convient pour une consultation isolée. Cela devient malaisé dès l’instant où vous voulez un comportement différent d’une requête à l’autre au sein d’une même session : une invite où le modèle doit consulter un outil, une autre où vous préféreriez qu’il réponde à partir du contexte et fasse l’économie de l’aller-retour.
iOS 27 fait passer cette décision entre vos mains. ToolCallingMode est une valeur que vous transmettez via GenerationOptions, le même objet d’options qui pilote déjà le décodage25, et le mode est une propriété de la requête, non de la session. Les outils Vision intégrés changent l’autre versant de l’équation : au lieu d’écrire un pipeline d’OCR ou un lecteur de codes-barres puis de l’envelopper dans votre propre conformité Tool, vous rattachez l’implémentation d’Apple et consacrez votre énergie à l’invite.
GenerationOptions.ToolCallingMode : orienter les appels
ToolCallingMode est une structure rattachée à GenerationOptions, disponible dans les bêtas iOS 27, iPadOS 27, Mac Catalyst 27, macOS 27, visionOS 27 et watchOS 272. Le résumé d’Apple tient en une phrase : une valeur que vous employez pour décrire le comportement du modèle en matière d’usage des outils2. La déclaration est on ne peut plus dépouillée :
// iOS 27 beta
struct ToolCallingMode
La documentation d’Apple indique que le mode d’appel d’outils prend en charge trois modes2. Le texte de discussion qui en nommerait chacun est en partie élidé dans la référence au moment où ces lignes sont écrites ; aussi, plutôt que de deviner les identifiants, je décris ce que le framework documente du comportement, car c’est cette partie qui guide réellement votre conception.
Le comportement qu’Apple explicite, le voici : le framework peut changer de mode après le premier appel d’outil, ce qui permet au modèle de produire une réponse finale2. Cette seule phrase est la pièce porteuse. Elle signifie qu’une requête peut débuter dans une posture où le modèle est libre d’appeler un outil (ou tenu de le faire), et qu’une fois ce premier appel revenu, le framework bascule le mode pour que le modèle cesse de recourir aux outils et s’engage sur une réponse. L’effet concret est de borner l’activité d’outils d’une même requête : vous n’êtes pas à la merci d’un modèle qui appellerait des outils en boucle jusqu’à épuiser la fenêtre de contexte.
Vous définissez le mode via l’objet d’options que vous transmettez déjà à respond(to:) :
import FoundationModels
let session = LanguageModelSession(tools: [FindContacts()])
// A request where you want to govern tool-calling behavior explicitly.
var options = GenerationOptions()
options.toolCallingMode = .someMode // one of the three documented modes
let response = try await session.respond(
to: "Draft a dinner invite to three of my contacts.",
options: options
)
L’orthographe exacte de .someMode provient des trois cas documentés ; ce qui compte, c’est le mécanisme, et le mécanisme tient à ceci : le comportement vaut requête par requête et il est porté par GenerationOptions. Cet objet est la même structure d’iOS 26 qui régit la stratégie de décodage, la manière dont le modèle choisit ses jetons de sortie, et le plafond facultatif de jetons de réponse auquel vous ne recourez que pour vous prémunir d’une verbosité galopante5. Le mode d’appel d’outils est une dimension nouvelle sur une surface de contrôle que vous utilisez déjà, et non un nouvel objet à faire transiter dans votre code.
Le contrôle se situe au niveau de la requête plutôt que de la session parce que le besoin d’outil est une propriété de la question, non de la conversation. Une session de discussion peut traiter un tour qui requiert véritablement une consultation des contacts, et un tour suivant qui n’est qu’une reformulation que le modèle peut produire à partir de ce qu’il détient déjà. Forcer un appel d’outil au second tour gaspille un aller-retour et brûle des jetons que la fenêtre de contexte partagée ne peut se permettre5. Le mode par requête laisse chaque tour déclarer sa propre posture.
Outils Vision intégrés : OCRTool et BarcodeReaderTool
La seconde moitié de l’histoire iOS 27 vient du framework Vision, exposé sous forme d’outils Foundation Models. Apple livre désormais deux outils que vous rattachez à une LanguageModelSession exactement comme l’un des vôtres, à ceci près que vous n’écrivez aucun code de reconnaissance.
LanguageModelSession sans écrire le code de reconnaissance.
Dans la session 241, Apple présente BarcodeReaderTool et OCRTool comme des outils système intégrés qui renforcent la capacité du modèle à raisonner sur l’information visuelle d’une manière qu’il ne saurait atteindre nativement.7
OCRTool
OCRTool reconnaît le texte d’une image. Le résumé d’Apple est exactement cela, et la discussion est précise sur le contrat : l’outil renvoie une chaîne contenant tout le texte reconnu dans l’image3. Pour l’activer, vous configurez votre LanguageModelSession avec une instance d’OCRTool3. La déclaration :
// iOS 27 beta, Vision framework
struct OCRTool
Le rattacher suit la même forme que n’importe quel outil, car pour la session ce n’est qu’un Tool de plus :
import FoundationModels
import Vision
// Configure the session with an OCRTool instance to enable it.
let session = LanguageModelSession(tools: [OCRTool()])
let response = try await session.respond(
to: "Pull the total and the date off this receipt image and summarize them."
)
Le modèle décide à quel moment l’invite réclame du texte tiré d’une image, appelle OCRTool, récupère une chaîne de tout ce que l’outil a lu, et intègre cette chaîne à sa réponse exactement comme il intégrerait le résultat d’un outil que vous auriez écrit3. Vous n’avez écrit aucune requête Vision ni aucun code de traitement. Vous avez rattaché un outil et décrit la tâche.
Apple vous laisse remplacer le nom et la description par défaut afin de personnaliser la manière dont le modèle identifie et utilise l’outil3. Ce point d’ancrage est le seul levier dont vous disposez sur le moment où le modèle recourt à l’OCR. Si votre application lit des reçus, rédiger la description de l’outil en termes de reçus oriente le modèle vers l’appel sur les invites en forme de reçu et l’en écarte pour les invites où l’image n’est que décorative. La description est une doc de fonction que le modèle lit : rédigez-la comme telle.
BarcodeReaderTool
BarcodeReaderTool lit les codes lisibles par machine présents dans une image4. Là où OCRTool renvoie une chaîne plate, l’outil de codes-barres renvoie de la structure : quand le modèle rencontre une image contenant des codes lisibles par machine, il peut appeler cet outil pour les décoder, et l’outil renvoie un tableau de résultats Barcode, chacun contenant le contenu décodé et le type de symbologie4. La déclaration et le rattachement reflètent OCRTool :
// iOS 27 beta, Vision framework
struct BarcodeReaderTool
// Configure the session with a BarcodeReaderTool instance to enable it.
let session = LanguageModelSession(tools: [BarcodeReaderTool()])
let response = try await session.respond(
to: "Scan this label and tell me what product it is and which standard the code uses."
)
Le type de symbologie présent dans chaque résultat Barcode est le détail qui justifie le retour structuré4. Un QR code, un code-barres EAN-13 d’épicerie et un PDF417 sur un permis de conduire sont tous des codes lisibles par machine, mais ils ne veulent pas dire la même chose pour votre application. Comme l’outil restitue la symbologie aux côtés de la charge utile décodée, le modèle (et votre code en aval) peut se brancher sur le genre de code, et pas seulement sur les octets qu’il renferme. Comme pour OCRTool, vous pouvez remplacer le nom et la description par défaut afin d’orienter la manière dont le modèle identifie et utilise l’outil4.
Les deux outils partagent la même disponibilité en bêta : iOS 27, iPadOS 27, Mac Catalyst 27, macOS 27 et visionOS 27 pour l’un comme pour l’autre, BarcodeReaderTool étant en outre listé pour watchOS 2734.
Composer la boucle : perception et appels maîtrisés
Les deux fonctionnalités sont intéressantes chacune de leur côté et meilleures réunies, car elles occupent les deux extrémités d’une même requête agentique. Les outils Vision sont la perception, les yeux du modèle sur une image. ToolCallingMode est la gouvernance, votre main sur la pression que le modèle exerce sur ces yeux.
Imaginez une fonctionnalité de réapprovisionnement de garde-manger. L’utilisateur photographie une étagère. La session a les deux outils Vision rattachés, plus un outil à vous, un LookUpProduct qui interroge le catalogue de l’application. Une seule requête demande au modèle d’identifier les articles et de bâtir une liste de réassort. Le modèle appelle BarcodeReaderTool pour décoder les étiquettes qu’il voit, lit avec OCRTool tout texte imprimé pour les articles dépourvus d’un code net, et appelle votre LookUpProduct pour résoudre chaque charge utile décodée en une entrée du catalogue. Trois outils, une invite, une réponse cohérente.
import FoundationModels
import Vision
let session = LanguageModelSession(tools: [
OCRTool(),
BarcodeReaderTool(),
LookUpProduct(), // your own Tool conformance over the app catalog
])
var options = GenerationOptions()
options.toolCallingMode = .someMode // govern how the model sequences the calls
let response = try await session.respond(
to: "Identify everything on this shelf and build a reorder list.",
options: options
)
Voilà la boucle vers laquelle le framework tend depuis le début. iOS 26 a fourni le modèle d’exécution, la génération guidée et le protocole Tool qui laisse le modèle sur l’appareil invoquer votre code sans que vous ayez à analyser du texte libre1. L’article d’architecture de ce groupe traçait la ligne entre ce modèle d’exécution et le LLM d’outillage qu’un développeur fait tourner dans Claude Code pour écrire l’application, et plaidait pour une unique fonction de domaine Swift soutenant un Tool Foundation Models, un App Intent et un outil MCP à travers trois adaptateurs minces6. iOS 27 s’insère du côté exécution de ce tableau : les outils Vision intégrés sont des fonctions de domaine qu’Apple a écrites et que vous montez, LookUpProduct est la fonction de domaine que vous avez écrite, le modèle orchestre l’ensemble, et ToolCallingMode est l’accélérateur de l’orchestration.
La frontière de confiance ne bouge pas. OCRTool et BarcodeReaderTool s’exécutent dans le processus de l’application, sur l’appareil, sur l’image de l’utilisateur, sous le même bac à sable et la même posture de confidentialité qu’un outil que vous auriez écrit. Qu’Apple fournisse l’implémentation change qui maintient le code de reconnaissance, non qui répond de la fonctionnalité. Vous restez maître de l’invite, de la session, de la vérification de disponibilité et de la décision de placer une caméra devant l’utilisateur.
Quand recourir à chaque mode et à chaque outil
Quelques règles qui découlent des contrats ci-dessus.
Recourez à ToolCallingMode quand le besoin d’outil varie d’une requête à l’autre. Si chaque tour d’une session réclame le même comportement d’outil, la valeur par défaut suffit et le mode n’est que du bruit. Le mode gagne sa place lorsqu’une requête doit consulter un outil tandis qu’une autre devrait répondre à partir du contexte, ou lorsque vous voulez que la bascule du framework après le premier appel borne une requête qui, autrement, pourrait boucler2. Définissez-le sur la requête, et non une fois pour la session, car c’est là que réside le contrôle2.
Recourez à OCRTool quand la réponse est du texte prisonnier d’une image. Reçus, panneaux, notes manuscrites, captures d’écran de texte. L’outil renvoie une seule chaîne de tout ce qu’il a lu3 ; il convient donc aux invites où vous voulez que le modèle raisonne sur les mots, non sur la mise en page. S’il vous faut des cadres englobants ou un indice de confiance ligne par ligne, c’est une requête Vision de plus bas niveau, pas cet outil.
Recourez à BarcodeReaderTool quand l’image porte des codes lisibles par machine et que le genre de code importe. Étiquettes de produits, billets, pièces d’identité, étiquettes d’inventaire. Le retour structuré, contenu décodé et symbologie4, est la raison de le préférer au traitement d’un code-barres comme du texte ordinaire. Branchez-vous sur la symbologie dans votre propre outil ou dans votre post-traitement.
Remplacez le nom et la description chaque fois que votre application confie une tâche précise à un outil générique. Les deux outils Vision ont par défaut une identité générique, et le modèle choisit en partie les outils d’après leurs descriptions34. Une application qui ne lit jamais que des reçus devrait le dire dans la description de l’outil d’OCR, afin que le modèle ne l’appelle pas sur chaque photo où figure par hasard un mot.
FAQ
Qu’est-ce que GenerationOptions.ToolCallingMode dans iOS 27 ?
C’est une structure, nouvelle dans la bêta iOS 27, qui décrit le comportement du modèle autour de l’usage des outils pour une requête donnée. Vous la définissez via le GenerationOptions que vous transmettez à respond(to:), de sorte que le comportement d’appel d’outils est une propriété de chaque requête plutôt que de la session entière. Apple documente trois modes2.
Combien de modes d’appel d’outils Apple documente-t-elle, et comment sont-ils nommés ?
La documentation d’Apple indique que le mode d’appel d’outils prend en charge trois modes2. Le texte de la référence qui nommerait chaque mode est en partie élidé au moment où ces lignes sont écrites ; je décris donc le comportement documenté plutôt que de deviner les identifiants. Le comportement qu’Apple énonce explicitement : le framework peut changer de mode après le premier appel d’outil afin que le modèle produise une réponse finale, ce qui borne l’activité d’outils d’une même requête2.
Comment activer l’outil d’OCR intégré d’Apple ?
Configurez votre LanguageModelSession avec une instance d’OCRTool, de la même manière que vous rattachez n’importe quel outil3. Le modèle l’appelle alors lorsqu’une invite réclame du texte tiré d’une image, et l’outil renvoie une chaîne contenant tout le texte reconnu. OCRTool se trouve dans le framework Vision et est disponible dans la bêta iOS 273.
Que renvoie BarcodeReaderTool ?
Il renvoie un tableau de résultats Barcode, chacun contenant le contenu décodé et le type de symbologie4. La symbologie vous permet de distinguer un QR code d’un EAN-13 ou d’un PDF417 et de vous brancher sur le genre de code, et pas seulement sur sa charge utile. Vous l’activez en configurant une LanguageModelSession avec une instance de BarcodeReaderTool4.
Puis-je modifier la façon dont le modèle décide d’employer les outils Vision intégrés ?
Oui. OCRTool comme BarcodeReaderTool vous laissent remplacer le nom et la description par défaut afin de personnaliser la manière dont le modèle identifie et utilise l’outil34. La description est le levier sur le moment où le modèle recourt à l’outil : la rédiger dans les termes propres à votre application oriente le modèle vers les bons appels.
Les outils Vision intégrés envoient-ils les images hors de l’appareil ?
Non. OCRTool et BarcodeReaderTool sont des outils Foundation Models qui s’exécutent dans le processus de l’application, sur l’appareil, sous le même bac à sable et la même posture de confidentialité qu’un outil que vous écririez vous-même134. Qu’Apple fournisse le code de reconnaissance change qui le maintient, non l’endroit où il s’exécute ni qui répond de la fonctionnalité.
L’intégralité du groupe Apple Ecosystem : l’explication du framework Foundation Models ; le LLM sur l’appareil ; la distinction entre LLM d’exécution et LLM d’outillage ; les adaptateurs personnalisés ; les App Intents typés ; la nouvelle exécution en arrière-plan et la synchronisation des App Intents dans iOS 27 ; la question du routage face aux outils MCP ; le framework Vision ; l’inférence Core ML ; les trois surfaces. Le carrefour est la série Apple Ecosystem. Pour un contexte plus large d’iOS avec des agents d’IA, consultez le guide de développement d’agents iOS.
-
Apple Developer, “Foundation Models” framework overview and “Tool” protocol. The iOS 26 framework introduced the on-device model,
LanguageModelSession, guided generation via@Generable, and theToolprotocol that lets the model invoke app code mid-generation. ↩↩↩ -
Apple Developer, “GenerationOptions.ToolCallingMode”. A structure (
struct ToolCallingMode) available in the iOS 27.0, iPadOS 27.0, Mac Catalyst 27.0, macOS 27.0, visionOS 27.0, and watchOS 27.0 betas, abstracted as a value that describes model behavior around tool usage. Apple’s discussion states tool calling mode supports three modes and that the framework can change the mode after the first tool call, which lets the model produce a final response. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple Developer, “OCRTool”. A Vision-framework structure (
struct OCRTool) available in the iOS 27.0, iPadOS 27.0, Mac Catalyst 27.0, macOS 27.0, and visionOS 27.0 betas, abstracted as a tool that recognizes text in an image. Apple’s discussion states the tool returns a string containing all recognized text, that you enable it by configuring yourLanguageModelSessionwith an instance ofOCRTool, and that you can override the default name and description. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple Developer, “BarcodeReaderTool”. A Vision-framework structure (
struct BarcodeReaderTool) available in the iOS 27.0, iPadOS 27.0, Mac Catalyst 27.0, macOS 27.0, visionOS 27.0, and watchOS 27.0 betas, abstracted as a tool that scans machine-readable codes in an image. Apple’s discussion states the tool returns an array ofBarcoderesults, each containing the decoded content and the symbology type, that you enable it by configuring yourLanguageModelSessionwith an instance ofBarcodeReaderTool, and that you can override the default name and description. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple Developer, “GenerationOptions”. The iOS 26 structure (
struct GenerationOptions) whose options determine the decoding strategy the framework uses to adjust how the model chooses output tokens; Apple notes a strict response-token limit should be used only to guard against unexpectedly verbose responses, and that all input contributes to the shared context window. ↩↩↩ -
Author’s analysis in Foundation Models Agentic Workflow: In-App vs Tooling LLM, May 1, 2026, on the runtime/tooling LLM distinction, the on-device
Toolprotocol’s trust boundary, and the single-domain-function, multiple-adapter pattern across Foundation Models tools, App Intents, and MCP. The routing question between those surfaces is developed in App Intents vs MCP: The Routing Question. ↩ -
Apple, WWDC26 session 241, “What’s new in the Foundation Models framework.” developer.apple.com/videos/play/wwdc2026/241. Apple introduces
BarcodeReaderToolandOCRToolas native system tools backed by the Vision framework, alongside a Spotlight-powered search tool for on-device RAG, describing them as enhancing the model’s ability to reason about visual information in ways it cannot do natively. ↩