
-
Voici le framework Foundation Models
Découvrez comment exploiter le grand modèle de langage contenu dans l'appareil qui sous-tend Apple Intelligence ! Cette vue d'ensemble couvre tout, de la génération guidée pour générer des structures de données Swift et du streaming pour des expériences réactives, aux appels d'outils pour l'intégration des sources de données et aux séances pour la gestion du contexte. Cette séance n'a pas de prérequis.
Chapitres
- 0:00 - Introduction
- 2:05 - Le modèle
- 5:20 - Génération guidée
- 7:45 - Streaming instantané
- 11:28 - Appel d’outils
- 16:11 - Séance avec état
- 21:02 - Expérience de développement
Ressources
Vidéos connexes
WWDC25
- Code-along : Intégrez l’IA contenue sur l’appareil à votre app à l’aide du framework de Foundation Models
- Découvrir les frameworks d’apprentissage automatique et d’IA sur les plates-formes Apple
- Explorez la conception rapide et la sécurité pour les modèles de fondation sur l’appareil
- Présentation approfondie du framework de Foundation Models
-
Rechercher dans cette vidéo…
Bonjour, je m’appelle Erik. Et moi Yifei. Aujourd’hui, nous avons le privilège de vous présenter le nouveau framework de Foundation Models ! Le framework de Foundation Models vous permet d’accéder sur votre appareil au grand modèle de langage qui alimente Apple Intelligence, grâce à une API Swift puissante. Il est disponible sur macOS, iOS, iPadOS et visionOS ! Vous pouvez l’utiliser pour améliorer des fonctionnalités de vos apps, comme la fourniture de suggestions de recherche personnalisées. Vous pouvez créer de toutes nouvelles fonctionnalités, comme un itinéraire dans une app de voyage, tout cela sur l’appareil. Vous pouvez l’utiliser pour créer des dialogues instantanés pour les personnages d’un jeu.
Il est optimisé pour générer du contenu, synthétiser du texte, analyser les entrées utilisateur et bien plus encore. Tout cela s’exécute sur l’appareil, de sorte que toutes les données entrantes et sortantes du modèle restent confidentielles. Il peut donc fonctionner hors ligne ! Et comme il est intégré au système d’exploitation, la taille de votre app n’augmente pas. Pour vous aider à tirer le meilleur parti du framework de Foundation Models, nous avons préparé une série de vidéos. Dans cette première vidéo, nous vous fournirons une vue d’ensemble de l’intégralité du framework. Nous commencerons par les détails du modèle. Nous présenterons ensuite la génération guidée, qui permet d’obtenir une sortie structurée dans Swift, ainsi que les API de streaming haute performance qui transforment la latence en une expérience satisfaisante. Nous parlerons de l’appel d’outils, grâce auquel le modèle exécute de manière autonome le code que vous définissez dans votre app. Nous expliquerons comment nous prenons en charge les sessions multi-tours avec état et comment nous intégrons de manière transparente le framework dans l’écosystème Apple Developer. Bien sûr, la partie la plus importante du framework est le modèle qui l’alimente. Et pour commencer à utiliser ce modèle, la meilleure méthode est de se lancer dans Xcode. Le test d’un large éventail d’invites pour trouver la plus efficace constitue une étape importante du processus de création à l’aide de grands modèles de langage. À cet égard, la nouvelle fonctionnalité Playgrounds de Xcode est ce qu’il y a de mieux. Avec seulement quelques lignes de code, vous pouvez immédiatement solliciter le modèle sur l’appareil. Je lui demande de générer un billet pour un voyage au Japon, et la sortie du modèle s’affichera dans le canevas à droite. Je veux vérifier si cette invite fonctionne aussi bien pour d’autres destinations. Dans un #Playground, vous pouvez accéder aux types définis dans votre app. Je crée une boucle for sur les points de repère présents dans la mienne. Xcode va me montrer la réponse du modèle pour tous les points de repère.
Le modèle sur l’appareil est un grand modèle de langage comportant 3 milliards de paramètres, chacun quantifié à 2 bits. Il dépasse de plusieurs ordres de grandeur tous les autres modèles faisant partie du système d’exploitation.
Il est important de garder à l’esprit que le modèle sur l’appareil reste dimensionné pour ce dernier. Il est optimisé pour des cas d’utilisation tels que la synthèse, l’extraction, la classification etc. Il n’est pas conçu pour des raisonnements avancés, des tâches pour lesquelles on pourra utiliser des LLM dimensionnés pour des serveurs.
Les modèles pour appareils nécessitent de décomposer les tâches en éléments plus petits. En travaillant avec le modèle, vous développerez une connaissance intuitive de ses forces et faiblesses.
Pour certains cas d’utilisation courants, tels que le balisage de contenu, nous fournissons des adaptateurs spécialisés qui optimisent les capacités du modèle dans des domaines précis.
Nous continuerons à améliorer nos modèles au fil du temps. Plus loin dans cette vidéo, nous vous expliquerons comment nous faire part de vos retours sur l’utilisation de nos modèles, ce qui nous aidera à les adapter à vos besoins.
Après nous être intéressés au modèle, la première étape de notre voyage sera la génération guidée. La génération guidée est ce qui permet de créer des fonctionnalités comme celles que vous venez de voir. C’est le cœur battant du framework de Foundation Models. Examinons un problème courant et voyons comment la génération guidée le résout. Par défaut, les modèles de langage produisent en sortie un langage naturel non structuré. Il est facile à lire pour les humains, mais difficile à transférer sur les vues de votre app.
Une solution consiste à demander au modèle de produire quelque chose de facile à analyser, comme des objets JSON ou CSV.
Cela peut vite s’apparenter au jeu du chat et de la souris. Vous devez ajouter des instructions de plus en plus précises sur quoi faire ou ne pas faire... Sans trop de succès... Et vous finissez par écrire des hacks pour extraire et corriger le contenu. Ce n’est pas fiable. En effet, le modèle est probabiliste. Il y a donc un risque non nul d’erreurs structurelles. La génération guidée offre une solution fondamentale à ce problème.
Lorsque vous importez Foundation Models, vous avez accès à deux nouvelles macros, @Generable et @Guide. Generable vous permet de décrire un type dont vous souhaitez que le modèle génère une instance. Guide vous permet de fournir des descriptions en langage naturel de propriétés et de contrôler par programmation les valeurs qui peuvent être générées pour ces propriétés.
Une fois un type Generable défini, vous pouvez faire en sorte que le modèle réponde aux invites en générant une instance de ce type. C’est très efficace. Comme vous le voyez, notre invite n’a plus besoin de spécifier le format de sortie. Le framework s’en charge pour vous.
Le plus important bien sûr, c’est que nous obtenons maintenant un objet Swift riche et facile à transférer sur une vue attrayante.
Les types Generable peuvent être élaborés à l’aide de primitives, comme Strings, Integers, Doubles, Floats, et Decimals, Booleans. Il est également possible de générer des tableaux, et de composer des types Generable. Generable prend même en charge les types récursifs, qui offrent des applications performantes dans des domaines tels que les interfaces utilisateur génératives. La chose la plus importante à comprendre concernant la génération guidée est qu’elle garantit l’exactitude structurelle grâce à une technique appelée le décodage contraint. Lorsque vous utilisez la génération guidée, vos invites peuvent être axées sur le comportement souhaité plutôt que sur le format. La génération guidée tend à améliorer la précision du modèle. Elle nous permet aussi d’effectuer des optimisations qui accélèrent l’inférence. Tout cela est possible par l’intégration coordonnée des systèmes d’exploitation et des outils de développement Apple, ainsi que par l’entraînement de nos modèles de base. Il y a beaucoup à dire sur la génération guidée, notamment sur la façon de créer des schémas dynamiques lors de l’exécution. Pour en savoir plus, consultez notre vidéo d’approfondissement. Nous avons vu comment le puissant système de types de Swift augmente les invites en langage naturel afin de garantir une sortie structurée fiable. Notre prochain sujet est le streaming, et il s’appuie sur la macro @Generable que vous connaissez déjà. Si vous avez déjà travaillé avec de grands modèles de langage, vous savez qu’ils génèrent du texte sous forme de courts groupes de caractères appelés jetons. Lors de l’envoi d’une sortie en streaming, les jetons sont fournis dans ce que l’on appelle un delta, mais le framework de Foundation Models offre une approche différente.
Au fur et à mesure de la production des deltas, c’est généralement le développeur qui est responsable de leur accumulation. Il ajoute chaque delta au fur et à mesure. Et la réponse augmente au fil du temps. Les choses se compliquent lorsque le résultat est structuré. Si vous voulez afficher la chaîne de salutation après chaque delta, vous devez l’analyser à partir de l’accumulation, et ce n’est pas simple, surtout pour les structures compliquées. Le streaming basé sur des deltas n’est pas la bonne option pour des sorties structurées. Les sorties structurées sont au cœur même du framework de Foundation Models. C’est pourquoi nous avons développé une approche différente. Au lieu de deltas bruts, nous diffusons des instantanés.
À mesure que le modèle produit des deltas, le framework les transforme en instantanés. Les instantanés représentent des réponses partiellement générées. Leurs propriétés sont toutes facultatives. Ils se remplissent à mesure que le modèle produit une plus grande partie de la réponse. Les instantanés offrent un moyen pratique de diffuser des sorties structurées en streaming.
Vous connaissez déjà la macro @Generable. Il s’avère qu’elle sert également à définir les types partiellement générés. Si vous développez la macro, vous découvrirez qu’elle produit un type nommé « PartiallyGenerated ». Il s’agit en fait d’un miroir de la structure extérieure, sauf que chaque propriété est facultative.
Le type partiellement généré entre en jeu quand vous appelez la méthode « streamResponse » lors de votre session.
La réponse en streaming renvoie une séquence asynchrone. Et les éléments de cette séquence sont des instances d’un type partiellement généré. Chaque élément de la séquence contiendra un instantané mis à jour.
Ces instantanés fonctionnent parfaitement avec les frameworks déclaratifs comme SwiftUI. Vous devez tout d’abord créer un état contenant un type partiellement généré. Il vous suffit ensuite d’itérer sur un streaming de réponses, de sauvegarder ses éléments et de regarder votre UI prendre vie.
Examinons quelques bonnes pratiques en matière de streaming.
Soyez créatif avec les animations et les transitions SwiftUI pour masquer la latence. Vous pouvez transformer un moment d’attente en un moment de plaisir. Ensuite, réfléchissez bien à l’identité de vue dans SwiftUI, en particulier lors de la génération de tableaux. Gardez à l’esprit que les propriétés sont générées dans l’ordre de leur déclaration dans votre structure Swift. C’est un point important, tant pour les animations que pour la qualité de la sortie du modèle. Par exemple, vous pouvez constater que le modèle produit de meilleures synthèses lorsqu’elles constituent la dernière propriété de la structure.
Pour en savoir plus, n’oubliez pas de regarder notre vidéo sur l’intégration des Foundation Models dans votre app. C’est ainsi que se termine le streaming avec les Foundation Models. Yifei va tout vous dire sur l’appel d’outils ! Merci Erik ! L’appel d’outils est une de nos fonctionnalités essentielles. Il permet au modèle d’exécuter le code que vous définissez dans votre app. L’appel d’outils est important pour tirer le meilleur parti de notre modèle, car il lui confère de nombreuses capacités supplémentaires. Il permet au modèle de savoir si une tâche nécessite des informations ou des actions supplémentaires, et de décider de manière autonome de l’outil à utiliser et du moment opportun, lorsque la programmation se prête difficilement à une prise de décision. Les infos que vous fournissez au modèle peuvent être des données publiques ou personnelles, des événements récents. Dans notre app de voyage, l’appel d’outils fournit des informations sur divers lieux à partir de MapKit. Cela permet au modèle de citer des sources de vérité, lesquelles pourront supprimer les hallucinations et vérifier les sorties du modèle. Enfin, il permet au modèle de prendre des mesures, que ce soit dans votre app, le système ou le monde réel. L’intégration de diverses sources d’informations est une stratégie gagnante pour créer des expériences attrayantes. Maintenant que vous connaissez l’utilité de l’appel d’outils, voyons son fonctionnement. Sur la gauche, nous avons une transcription qui enregistre tout ce qui s’est passé jusqu’à présent. Si vous avez fourni des outils à la session, celle-ci les présentera au modèle accompagnés des instructions. Vient ensuite l’invite, où nous indiquons au modèle la destination à visiter. Si le modèle estime que l’appel d’un outil peut améliorer la réponse, il déclenchera un ou plusieurs appels d’outils. Ici, le modèle produit deux appels d’outils, interroger les restaurants et les hôtels. À ce stade, le framework de Foundation Models appelle automatiquement le code que vous avez écrit pour ces outils. Le framework insère ensuite automatiquement les sorties des outils dans la transcription. Pour terminer, le modèle intègre ces sorties, ainsi que tout le reste, dans la transcription pour fournir la réponse finale.
Maintenant que nous avons une connaissance précise de l’appel d’outils, définissons ce qu’est un outil.
Nous définissons ici un outil météo simple, conforme au protocole relatif aux outils. L’outil météo s’est en quelque sorte imposé comme le « hello world » de l’appel d’outils, et c’est un excellent point de départ.
Le protocole vous demande de spécifier le nom et une description en langage naturel de l’outil.
Le framework les fournira automatiquement au modèle pour l’aider à comprendre quand appeler votre outil.
Lorsque le modèle appelle votre outil, il exécute la méthode d’appel définie par vos soins.
L’argument de la méthode d’appel peut être n’importe quel type Generable.
Vos arguments doivent être générables, car l’appel d’outils s’appuie sur la génération guidée pour garantir le fait que le modèle ne produira jamais de noms d’outils ou d’arguments non valides. Après avoir défini votre type d’arguments, vous pouvez écrire ce que vous voulez dans le corps de votre méthode. Nous utilisons ici CoreLocation et WeatherKit pour trouver la température d’une ville donnée. La sortie est représentée à l’aide du type ToolOutput, qui peut être créé à partir de GeneratedContent pour représenter des données structurées. Ou à partir d’une chaîne de caractères si la sortie de votre outil est en langage naturel. Maintenant que nous avons défini un outil, nous devons nous assurer que le modèle y a accès. Pour ce faire, passez votre outil dans l’initialiseur de votre session. Les outils doivent être connectés à l’initialisation de la session et seront accessibles au modèle pendant toute la durée de la session.
Après avoir créé une session avec des outils, il ne vous reste qu’à inviter le modèle comme à votre habitude. Les appels d’outils se dérouleront de manière autonome, et le modèle intégrera les résultats obtenus dans sa réponse finale. Les exemples montrent comment définir des outils sécurisés lors de la compilation, ce qui convient à la grande majorité des cas d’utilisation. Mais les outils sont aussi dynamiques ! Vous pouvez définir les arguments et les comportements d’un outil lors de l’exécution, en utilisant des schémas de génération dynamiques. Si ce sujet vous intéresse, n’hésitez pas à regarder notre vidéo d’approfondissement. Voilà pour l’appel d’outils. Nous avons appris comment mettre en œuvre des outils pour étendre les capacités du modèle. Parlons maintenant des sessions avec état. Vous avez déjà vu le mot session apparaître à plusieurs reprises dans cette vidéo. Le framework de Foundation Models s’articule autour de la notion de session avec état. Par défaut, lorsque vous créez une session, vous sollicitez le modèle à usage général de l’appareil. Vous pouvez lui fournir des instructions personnalisées. Les instructions sont pour vous l’occasion d’expliquer au modèle son rôle et de fournir des conseils sur la façon dont il doit répondre. Vous pouvez spécifier des éléments tels que le style et la verbosité. Sachez que des instructions personnalisées sont facultatives et qu’en leur absence, des instructions par défaut raisonnables seront utilisées.
Si vous choisissez de fournir des instructions personnalisées, il est important de comprendre la différence entre les instructions et les invites. Les instructions doivent provenir de vous, le développeur, tandis que les invites peuvent provenir de l’utilisateur. Le modèle est entraîné à obéir à des instructions plutôt qu’à des invites. Cela protège contre les attaques par injection d’invites, mais sans garantie. En règle générale, les instructions sont surtout statiques et il est préférable de ne pas interpoler des données utilisateur non fiables dans les instructions. Il s’agit donc d’une introduction sur la meilleure façon de formuler vos instructions et vos invites. Pour découvrir plus de bonnes pratiques, regardez notre vidéo sur la conception et la sécurité des invites. Maintenant que vous avez initialisé une session, parlons des interactions multi-tours ! Lors de l’utilisation des méthodes respond ou streamResponse dont nous avons parlé précédemment, chaque interaction avec le modèle est conservée sous forme de contexte dans une transcription, de sorte que le modèle pourra se référer à des interactions multi-tours antérieures et les comprendre au cours d’une même session. Ici, le modèle est capable de comprendre le message « fais-en un autre » lorsque nous faisons référence à l’écriture d’un haïku.
La propriété « transcript » sur l’objet de session vous permettra d’inspecter les interactions précédentes ou de dessiner des vues d’UI pour les représenter.
Il y a une chose importante à savoir. Pendant que le modèle produit une sortie, sa propriété « isResponding » devient « true ». Vous devrez peut-être surveiller cette propriété et veiller à ne pas soumettre d’autres invites tant que le modèle n’aura pas fini de répondre. Au-delà du modèle par défaut, nous proposons également des cas d’utilisation spécialisés intégrés, soutenus par des adaptateurs. Si vous trouvez un cas d’utilisation intégré qui correspond à vos besoins, vous pouvez le transmettre à l’initialiseur de SystemLanguageModel. Pour savoir quels sont les cas d’utilisation intégrés disponibles et comment les utiliser, consultez notre documentation sur le site des développeurs. Un adaptateur spécialisé dont je souhaite parler plus en détail est l’adaptateur de balisage de contenu. Il offre des supports de premier ordre pour la génération de balises, l’extraction d’entités et la détection de rubriques. L’adaptateur est entraîné à produire des balises de rubrique et conçu pour s’intégrer dès le départ à la génération guidée. Vous pouvez donc définir une structure avec notre macro Generable, et transmettre les données de l’utilisateur pour en extraire des rubriques.
Mais ce n’est pas tout ! En lui fournissant des instructions et un type de sortie Generable personnalisés, vous pouvez l’utiliser pour détecter des actions et des émotions. Avant de créer une session, vérifiez la disponibilité du modèle, car il ne peut s’exécuter que sur les appareils compatibles avec Apple Intelligence dans les zones géographiques prises en charge. Pour vérifier si le modèle est disponible, vous pouvez accéder à la propriété Availability sur SystemLanguageModel.
Cette propriété fait partie d’une énumération à deux options, à savoir disponible ou indisponible. En cas d’indisponibilité, vous recevez un motif pour ajuster votre interface utilisateur en conséquence.
Pour finir, vous pouvez rencontrer des erreurs lorsque vous appelez le modèle. Il peut s’agir d’une violation de la barrière de sécurité, une langue non prise en charge ou un dépassement de la fenêtre de contexte. Pour offrir la meilleure expérience, vous devez les gérer de manière appropriée. La vidéo d’approfondissement vous informera davantage. C’est tout pour les sessions multi-tours avec état ! Nous avons appris à créer une session et à l’utiliser, ainsi qu’à comprendre comment un modèle garde une trace de votre contexte. Maintenant, parlons des outils et de l’expérience des développeurs. Vous pouvez accéder à n’importe quel fichier Swift de votre projet et utiliser la nouvelle macro playground pour lancer le modèle.
Les playgrounds sont efficaces, car ils vous permettent d’effectuer des itérations rapides avec vos invites, sans avoir à concevoir et exécuter de nouveau votre app. Dans un playground, votre code peut accéder à tous les types de votre projet, par exemple, les types Generable qui alimentent déjà votre UI.
Ensuite, nous savons que pour créer des expériences applicatives alimentées par de grands modèles de langage, il est important de comprendre la latence interne au système, car les grands modèles de langage s’exécutent plus lentement que les modèles ML traditionnels. Comprendre la latence peut vous aider à ajuster la verbosité de vos invites ou à déterminer quand faire appel à des API utiles comme le préchauffage.
Et notre nouveau modèle de profilage d’app Instruments est conçu pour cela. Vous pouvez établir le profil de latence d’une demande de modèle, observer les zones d’amélioration et quantifier les améliorations.
Vous pouvez soumettre des commentaires qui peuvent nous aider à améliorer nos modèles et nos API.
Nous vous encourageons à envoyer vos avis par le biais de l’Assistant d’évaluation. Nous fournissons même une structure de données encodable pour les commentaires que vous pouvez joindre sous forme de fichier.
Enfin, si vous êtes un adepte de l’apprentissage automatique, avec des cas d’utilisation hautement spécialisés et un ensemble de données personnalisé, vous pouvez former des adaptateurs personnalisés à l’aide de notre kit de formation pour adaptateurs. Gardez à l’esprit que cela suppose des responsabilités importantes, car vous devrez les réentraîner à mesure qu’Apple perfectionne le modèle. Pour en savoir plus, consultez le site web des développeurs. Maintenant que vous connaissez plusieurs des fonctionnalités intéressantes du nouveau framework de Foundation Models, nous avons hâte de découvrir toutes vos créations incroyables ! Pour en savoir plus sur l’intégration de l’IA générative dans votre app, sur le fonctionnement interne des technologies telles que la génération guidée et sur la façon de créer les meilleures invites, nous vous proposons toute une série de vidéos et d’articles passionnants. Merci beaucoup pour votre présence aujourd’hui ! Bonne génération !
-
-
2:28 - Playground - Trip to Japan
import FoundationModels import Playgrounds #Playground { let session = LanguageModelSession() let response = try await session.respond(to: "What's a good name for a trip to Japan? Respond only with a title") }
-
2:43 - Playground - Loop over landmarks
import FoundationModels import Playgrounds #Playground { let session = LanguageModelSession() for landmark in ModelData.shared.landmarks { let response = try await session.respond(to: "What's a good name for a trip to \(landmark.name)? Respond only with a title") } }
-
5:32 - Creating a Generable struct
// Creating a Generable struct @Generable struct SearchSuggestions { @Guide(description: "A list of suggested search terms", .count(4)) var searchTerms: [String] }
-
5:51 - Responding with a Generable type
// Responding with a Generable type let prompt = """ Generate a list of suggested search terms for an app about visiting famous landmarks. """ let response = try await session.respond( to: prompt, generating: SearchSuggestions.self ) print(response.content)
-
6:18 - Composing Generable types
// Composing Generable types @Generable struct Itinerary { var destination: String var days: Int var budget: Float var rating: Double var requiresVisa: Bool var activities: [String] var emergencyContact: Person var relatedItineraries: [Itinerary] }
-
9:20 - PartiallyGenerated types
// PartiallyGenerated types @Generable struct Itinerary { var name: String var days: [Day] }
-
9:40 - Streaming partial generations
// Streaming partial generations let stream = session.streamResponse( to: "Craft a 3-day itinerary to Mt. Fuji.", generating: Itinerary.self ) for try await partial in stream { print(partial) }
-
10:05 - Streaming itinerary view
struct ItineraryView: View { let session: LanguageModelSession let dayCount: Int let landmarkName: String @State private var itinerary: Itinerary.PartiallyGenerated? var body: some View { //... Button("Start") { Task { do { let prompt = """ Generate a \(dayCount) itinerary \ to \(landmarkName). """ let stream = session.streamResponse( to: prompt, generating: Itinerary.self ) for try await partial in stream { self.itinerary = partial } } catch { print(error) } } } } }
-
11:00 - Property order matters
@Generable struct Itinerary { @Guide(description: "Plans for each day") var days: [DayPlan] @Guide(description: "A brief summary of plans") var summary: String }
-
13:42 - Defining a tool
// Defining a tool import WeatherKit import CoreLocation import FoundationModels struct GetWeatherTool: Tool { let name = "getWeather" let description = "Retrieve the latest weather information for a city" @Generable struct Arguments { @Guide(description: "The city to fetch the weather for") var city: String } func call(arguments: Arguments) async throws -> ToolOutput { let places = try await CLGeocoder().geocodeAddressString(arguments.city) let weather = try await WeatherService.shared.weather(for: places.first!.location!) let temperature = weather.currentWeather.temperature.value let content = GeneratedContent(properties: ["temperature": temperature]) let output = ToolOutput(content) // Or if your tool’s output is natural language: // let output = ToolOutput("\(arguments.city)'s temperature is \(temperature) degrees.") return output } }
-
15:03 - Attaching tools to a session
// Attaching tools to a session let session = LanguageModelSession( tools: [GetWeatherTool()], instructions: "Help the user with weather forecasts." ) let response = try await session.respond( to: "What is the temperature in Cupertino?" ) print(response.content) // It’s 71˚F in Cupertino!
-
16:30 - Supplying custom instructions
// Supplying custom instructions let session = LanguageModelSession( instructions: """ You are a helpful assistant who always \ responds in rhyme. """ )
-
17:46 - Multi-turn interactions
// Multi-turn interactions let session = LanguageModelSession() let firstHaiku = try await session.respond(to: "Write a haiku about fishing") print(firstHaiku.content) // Silent waters gleam, // Casting lines in morning mist— // Hope in every cast. let secondHaiku = try await session.respond(to: "Do another one about golf") print(secondHaiku.content) // Silent morning dew, // Caddies guide with gentle words— // Paths of patience tread. print(session.transcript) // (Prompt) Write a haiku about fishing // (Response) Silent waters gleam... // (Prompt) Do another one about golf // (Response) Silent morning dew...
-
18:22 - Gate on isResponding
import SwiftUI import FoundationModels struct HaikuView: View { @State private var session = LanguageModelSession() @State private var haiku: String? var body: some View { if let haiku { Text(haiku) } Button("Go!") { Task { haiku = try await session.respond( to: "Write a haiku about something you haven't yet" ).content } } // Gate on `isResponding` .disabled(session.isResponding) } }
-
18:39 - Using a built-in use case
// Using a built-in use case let session = LanguageModelSession( model: SystemLanguageModel(useCase: .contentTagging) )
-
19:19 - Content tagging use case - 1
// Content tagging use case @Generable struct Result { let topics: [String] } let session = LanguageModelSession(model: SystemLanguageModel(useCase: .contentTagging)) let response = try await session.respond(to: ..., generating: Result.self)
-
19:35 - Content tagging use case - 2
// Content tagging use case @Generable struct Top3ActionEmotionResult { @Guide(.maximumCount(3)) let actions: [String] @Guide(.maximumCount(3)) let emotions: [String] } let session = LanguageModelSession( model: SystemLanguageModel(useCase: .contentTagging), instructions: "Tag the 3 most important actions and emotions in the given input text." ) let response = try await session.respond(to: ..., generating: Top3ActionEmotionResult.self)
-
19:56 - Availability checking
// Availability checking struct AvailabilityExample: View { private let model = SystemLanguageModel.default var body: some View { switch model.availability { case .available: Text("Model is available").foregroundStyle(.green) case .unavailable(let reason): Text("Model is unavailable").foregroundStyle(.red) Text("Reason: \(reason)") } } }
-
22:13 - Encodable feedback attachment data structure
let feedback = LanguageModelFeedbackAttachment( input: [ // ... ], output: [ // ... ], sentiment: .negative, issues: [ LanguageModelFeedbackAttachment.Issue( category: .incorrect, explanation: "..." ) ], desiredOutputExamples: [ [ // ... ] ] ) let data = try JSONEncoder().encode(feedback)
-
-
- 0:00 - Introduction
Le framework de Foundation Models vous donne accès à un grand modèle de langage local sur macOS, iOS, iPadOS et visionOS. Il permet de créer des fonctionnalités personnalisées, comme des suggestions de recherche, des itinéraires ou des dialogues au sein du jeu, tout en préservant la confidentialité, les données restant sur l’appareil et étant traitées hors ligne. Le framework est optimisé pour la génération de contenu, le résumé de texte et l’analyse des saisies utilisateur. Pour accompagner les développeurs, Apple a préparé une série de vidéos couvrant une présentation du framework, la génération guidée, les API de streaming, l’appel d’outils, la gestion multi-turn et l’intégration fluide dans l’écosystème des développeurs Apple.
- 2:05 - Le modèle
La nouvelle fonctionnalité Playgrounds de Xcode est idéale pour expérimenter les requêtes envoyées au grand modèle de langage local. En quelques lignes de code, vous pouvez tester des prompts et voir les réponses du modèle en temps réel. Le modèle local, avec ses 3 milliards de paramètres, est optimisé pour le résumé, l’extraction et la classification, mais pas pour la connaissance générale ni le raisonnement avancé. Décomposez les tâches en petits morceaux pour maximiser son efficacité. La génération guidée, composant central du framework FoundationModels, facilite l’intégration des résultats du modèle dans les apps. Elle permet de créer des fonctionnalités plus fiables grâce à une approche structurée, dépassant les limites des formats comme JSON ou CSV générés par le modèle.
- 5:20 - Génération guidée
Avec l’importation de FoundationModels, deux nouvelles macros, @Generable et @Guide sont introduites. @Generable permet de décrire des types pour des instances générées par le modèle, pouvant être construites à partir de types primitifs, tableaux, ou types composés et récursifs. @Guide fournit des descriptions en langage naturel des propriétés et contrôle les valeurs générées, garantissant la validité structurelle via un décodage contraint. Cette approche de génération guidée simplifie les prompts, améliore la précision du modèle et accélère l’inférence. Elle vous permet de recevoir directement des objets Swift riches depuis le modèle, facilement exploitables dans des vues, sans avoir à spécifier le format de sortie dans le prompt.
- 7:45 - Streaming instantané
Le framework FoundationModels diffère du streaming delta traditionnel basé sur les jetons pour les grands modèles de langage. Il diffuse plutôt des instantanés (des réponses partiellement générées avec des propriétés optionnelles) plus robustes et pratiques pour gérer des sorties structurées. Cette approche exploite la macro @Generable, qui produit un type PartiallyGenerated reflétant la structure extérieure avec des propriétés facultatives. La méthode streamResponse renvoie une séquence asynchrone de ces types partiellement générés, permettant une intégration fluide avec des frameworks déclaratifs comme SwiftUI. Utilisez les animations et les transitions SwiftUI pour améliorer l’expérience utilisateur lors du streaming. Gérer l’identité des vues et l’ordre des propriétés est crucial pour un résultat optimal.
- 11:28 - Appel d’outils
L’appel d’outils permet à un modèle d’IA d’exécuter du code personnalisé dans une app, augmentant ses capacités. Cette fonctionnalité permet au modèle de décider seul quand utiliser des outils externes pour récupérer des infos ou effectuer des actions, comme rechercher des restaurants, des hôtels ou la météo, selon le contexte de la demande. Le modèle peut s’intégrer à diverses sources fiables, comme MapKit, pour fournir des infos précises et à jour. Ce processus implique que le modèle génère des appels d’outils, automatiquement exécutés par le framework FoundationModels, dont les résultats sont ensuite intégrés à la transcription de la conversation pour que le modèle puisse les utiliser dans sa réponse finale.
- 16:11 - Séance avec état
Le framework de Foundation Models permet des sessions avec état avec un modèle généraliste local. Vous pouvez donner des instructions personnalisées pour guider le style et la concision des réponses, mais cela reste facultatif. Vous définissez vos instructions, distinctes des prompts utilisateur, et le modèle est entraîné à privilégier les instructions pour renforcer la sécurité. Pendant une session, le modèle garde le contexte des échanges, ce qui lui permet de comprendre et de faire référence aux messages précédents. La propriété transcript peut être utilisée pour inspecter ces interactions. Le framework inclut des cas d’usage spécialisés, comme l’adaptateur de balisage, qui gère la création de tags, l’extraction d’entités et la détection de sujets. Personnalisez ces adaptateurs selon vos besoins. Avant de créer une session, vérifiez que le modèle est disponible sur un appareil Apple Intelligence dans une zone géographique prise en charge. Une bonne gestion des erreurs est essentielle pour gérer les violations de sécurité, les langues non prises en charge et les dépassements de contexte.
- 21:02 - Expérience de développement
L’outil Playgrounds permet d’itérer rapidement les prompts des grands modèles de langage dans tous types de projets d’app. Le nouveau modèle de profilage d’Instruments optimise la latence en repérant les points à améliorer dans les requêtes au modèle et la longueur des prompts. Nous vous encourageons à envoyer vos commentaires via l’Assistant d’évaluation.