← Tous les articles

Evaluations : XCTest pour la qualité des modèles (iOS 27)

Un test unitaire ordinaire affirme que add(2, 2) renvoie 4, et si ce n’est pas le cas, la compilation passe au rouge. Une fonctionnalité d’IA rompt ce contrat dès la première ligne, car la même invite peut produire une phrase différente à chaque exécution, et « différent » ne veut pas dire « faux ». Vous ne pouvez pas écrire #expect(summary == "the expected summary") face à un modèle, parce qu’il n’existe pas une seule chaîne attendue. Ce que vous pouvez mesurer, c’est si la sortie est suffisamment bonne, suffisamment souvent, au regard de critères que vous définissez. Le nouveau framework Evaluations d’Apple vous offre ce harnais de mesure, avec des API Swift typées qui s’exécutent au sein de votre flux de développement1. Il est inédit dans la version 27 et disponible sur toutes les plateformes Apple (iOS, iPadOS, macOS, visionOS et watchOS) : un outil de développement que vous lancez au moment des tests, généralement sur votre Mac, et non une fonctionnalité d’exécution que vous livrez à l’intérieur d’une application1.

La forme vous semblera familière si vous avez déjà écrit des tests. Vous définissez un jeu de données, générez les réponses du modèle, appliquez des métriques et agrégez les résultats, puis vous lisez quelle approche a le mieux performé et où certaines réponses individuelles ont échoué1. Le modèle mental, c’est XCTest pour la qualité des modèles : même boucle (préparer un cas, l’exécuter, affirmer quelque chose), assertion différente (une métrique notée plutôt qu’une égalité).

Dans la session 298, Apple formule le problème central ainsi : les fonctionnalités d’IA générative rompent un contrat fondamental pour le test logiciel, parce que la même entrée peut produire des sorties différentes, ce qui rend les tests unitaires insuffisants25.

Watch on Apple Developer ↗
Pourquoi une assertion d’égalité échoue face à une fonctionnalité d’IA : la même entrée peut produire des sorties différentes.

TL;DR / Points clés

  • Le framework Evaluations est inédit dans la version 27 sur toutes les plateformes Apple (iOS, iPadOS, macOS, visionOS, watchOS) ; il s’agit d’une couche d’outillage de développement destinée à mesurer les fonctionnalités dopées à l’intelligence, exécutée dans le cadre de votre flux de tests (généralement sur un Mac)1.
  • Evaluator est un évaluateur fondé sur une closure que vous écrivez en ligne ; le protocole Evaluation est le type que vous implémentez pour exécuter un système sous test face à un jeu de données et lui appliquer des évaluateurs23.
  • Metric transporte un résultat nommé via des méthodes de fabrique (passing, failing, scoring, ignore), et ScoreDimension nomme un axe noté pour un évaluateur de type modèle-juge45.
  • ModelSample est un échantillon d’évaluation à usage général ; SampleGenerator est un acteur qui génère des échantillons à partir d’un modèle de langage sous forme de flux asynchrone ; les résultats atterrissent dans un DataFrame doté de colonnes typées, dont une responseColumn678.
  • ToolCallEvaluator vérifie les appels d’outils agentiques face à une TrajectoryExpectation, ArgumentMatcher définissant la manière de valider chaque argument91011.
  • EvaluationTrait exécute une évaluation à l’intérieur d’un test et en enregistre le résultat sous forme de pièces jointes, ce qui constitue le pont vers une exécution Swift Testing12.

L’article parcourt la surface de l’API, explique pourquoi chaque pièce existe, et la relie au travail de tool-calling de Foundation Models qu’elle note. Là où je montre un appel dont Apple n’a pas publié la signature exacte, je le signale comme illustratif et vous invite à le confirmer dans la documentation.

Le modèle de l’évaluateur

La question centrale du framework est « à quel point cette sortie était-elle bonne », et il y répond avec un petit vocabulaire : un évaluateur décide, une métrique enregistre, une dimension de score note, et un résultat agrège.

Le protocole Evaluation est le type que vous implémentez pour définir une évaluation, laquelle exécute votre système sous test face à un jeu de données et lui applique des évaluateurs pour mesurer la performance3. La déclaration est minimale :

// 27.0 beta (all Apple platforms)
protocol Evaluation : Sendable

Le protocole est Sendable parce que l’évaluation est un travail concurrent : de nombreux échantillons, exécutés en parallèle, à la manière dont Swift Testing exécute les cas de test en parallèle par défaut13. Vous implémentez le protocole lorsque vous voulez une évaluation réutilisable et nommée. Quand vous voulez quelque chose de rapide, vous vous tournez plutôt vers Evaluator, qu’Apple décrit comme un évaluateur fondé sur une closure, à usage en ligne, sans définir de type personnalisé2 :

// 27.0 beta (all Apple platforms)
struct Evaluator<Input> where Input : SampleProtocol,
    Input.ExpectedValue : Decodable,
    Input.ExpectedValue : Encodable,
    Input.ExpectedValue : Sendable

La présentation d’Apple précise que la closure reçoit l’échantillon d’entrée et la réponse, avec accès à la fois à .value et à .transcript2. La .value est la sortie typée du modèle ; le .transcript est le journal de la façon dont il y est parvenu. Un évaluateur en ligne, c’est un bloc #expect d’une seule ligne pour la qualité d’un modèle : pas de sous-classe, seulement le jugement sous forme de closure. La forme d’appel suivante est illustrative ; confirmez l’initialiseur dans la documentation d’Apple :

import Evaluations

// Illustrative call shape — confirm against Apple's docs.
let nonEmpty = Evaluator<ModelSample<String>> { input, response in
    response.value.isEmpty ? .failing("empty output") : .passing()
}

Ce que renvoie la closure, c’est une Metric. Apple décrit Metric comme une métrique nommée qui transporte une valeur de résultat, et nomme explicitement les méthodes de fabrique : passing, failing, scoring et ignore renvoient chacune une nouvelle Metric dont le résultat est stocké à l’intérieur4 :

// 27.0 beta (all Apple platforms)
struct Metric

Les quatre fabriques correspondent aux types de jugement dont une fonctionnalité d’IA a besoin. Un résumeur inclut le fait requis ou ne l’inclut pas : il obtient donc passing ou failing. Une grille de notation du ton va de 1 à 5 : elle obtient scoring. Un échantillon que vous voulez écarter de l’agrégat (entrée malformée, fixture connue comme défectueuse) obtient ignore, ce qui conserve la ligne dans le jeu de données sans polluer les statistiques. L’éventail allant de passing au scoring noté est précisément ce que promet le framework : de simples vérifications réussite ou échec jusqu’à une notation détaillée avec des schémas de type modèle-juge1.

L’extrémité notée de cet éventail est là où ScoreDimension prend toute sa valeur. Apple la définit comme une dimension de notation nommée pour un évaluateur modèle-juge, où chaque dimension définit un nom (utilisé comme colonne du DataFrame), une description optionnelle et une définition de ce que signifie chaque score5 :

// 27.0 beta (all Apple platforms)
struct ScoreDimension

Une même sortie peut être bonne sur un axe et mauvaise sur un autre. Un courriel rédigé peut être factuellement correct et tonalement inadapté. ScoreDimension vous permet de noter ces axes séparément (exactitude, ton, concision), de sorte que l’agrégat vous indique quelle dimension a chuté, et pas seulement que la qualité globale a baissé. Le nom de la dimension devient une colonne, ce qui veut dire que les scores atterrissent dans un tableau structuré que vous pouvez trier et comparer, et non un mur de prose.

Ce tableau est un EvaluationResult. Apple le décrit comme les résultats de l’exécution d’une évaluation de modèle, une structure qui contient le résumé et les résultats détaillés d’une passe d’évaluation14 :

// 27.0 beta (all Apple platforms)
struct EvaluationResult

La forme à deux niveaux (résumé et détail) est ce qui rend les évals exploitables. Le résumé répond à « cette invite a-t-elle fait mieux que la précédente ». Le détail répond à « quels échantillons ont échoué », pour que vous puissiez ouvrir les pires lignes et lire ce que le modèle a produit1.

Échantillons et génération

Une évaluation a besoin de cas sur lesquels s’exécuter, et l’unité de cas du framework est l’échantillon. ModelSample est celui à usage général. Apple le décrit comme un échantillon d’évaluation de modèle de langage à usage général qui accepte des invites et des instructions sous forme de chaînes6 :

// 27.0 beta (all Apple platforms)
struct ModelSample<ExpectedValue> where ExpectedValue : Decodable,
    ExpectedValue : Encodable,
    ExpectedValue : Sendable

Le générique ExpectedValue est l’attente typée : une chaîne pour une tâche en texte libre, un type Codable structuré pour une tâche dont la réponse est connue. Les contraintes Codable et Sendable correspondent à l’Input.ExpectedValue d’Evaluator, parce que l’attente doit se sérialiser dans le tableau de résultats et franchir les frontières de concurrence lors d’une exécution parallèle. Pour les invites multimodales, Apple note que vous créez une conformité personnalisée ou utilisez un initialiseur avec une invite préconstruite6.

Écrire chaque échantillon à la main ne tient pas à l’échelle, et c’est pourquoi SampleGenerator existe : un acteur qui génère des échantillons d’évaluation à l’aide d’un modèle de langage7 :

// 27.0 beta (all Apple platforms)
actor SampleGenerator<SampleType> where SampleType : ModelSampleProtocol

C’est un actor parce qu’il possède un état de génération mutable (échantillons acceptés et rejetés) que l’itération asynchrone modifie, et l’isolation d’acteur est le garde-fou de Swift contre les courses aux données sur cet état. Le flux d’Apple : créer un générateur, configurer ses propriétés, puis l’appeler pour produire de nouveaux échantillons sous forme de flux asynchrone ; après l’itération, vous accédez à tous les échantillons générés, ou à ceux que le validateur a rejetés7. C’est sur le lot rejeté qu’il vaut la peine de s’arrêter. Un générateur qui écarterait silencieusement les mauvais échantillons masquerait son propre taux d’échec ; exposer les rejets vous permet d’auditer le jeu de données comme vous auditeriez des fixtures écrites à la main.

Une fois les échantillons exécutés, les réponses atterrissent dans un DataFrame doté de descripteurs de colonnes typés, de sorte que vous lisez le tableau sans recherches reposant sur des chaînes. Apple nomme la colonne de réponse exactement : responseColumn, un descripteur de colonne typé pour les réponses du modèle dans le DataFrame détaillé8 :

// 27.0 beta (all Apple platforms)
var responseColumn: ResultColumn<Self.Subject> { get }

Le générique ResultColumn<Value> est ce qui rend la colonne typée : un descripteur de colonne de DataFrame, paramétré par la valeur qu’elle contient15. Aux côtés de responseColumn, le framework expose une inputColumn pour les échantillons d’entrée et une expectedColumn pour les valeurs attendues, chacune étant un ResultColumn typé1617. Les colonnes typées relèvent du même instinct que la capture d’expression de Swift Testing : au lieu de tirer une valeur d’un sac non typé en espérant que le transtypage tienne, vous la lisez à travers un descripteur qui connaît son type. Lorsque vous alimentez les résultats dans MetricsAggregator pour la moyenne, la médiane et l’écart-type, les colonnes sont la manière dont vous adressez les données sans deviner les clés18.

Vérification des outils et des trajectoires

La fonctionnalité d’IA la plus difficile à tester est la fonctionnalité agentique, parce que la justesse n’est pas une chaîne, c’est une séquence d’actions. Lorsqu’une session Foundation Models appelle OCRTool, puis BarcodeReaderTool, puis votre propre recherche de catalogue, la question n’est pas « la phrase finale correspond-elle » mais « le modèle a-t-il emprunté le bon chemin »19. ToolCallEvaluator note ce chemin directement. Apple le décrit comme un évaluateur qui vérifie les appels d’outils agentiques face à une trajectoire attendue9 :

// 27.0 beta (all Apple platforms)
struct ToolCallEvaluator<Input> where Input : ModelSampleProtocol,
    Input.Expectation == TrajectoryExpectation

La clause where est la partie porteuse : l’attente de l’entrée doit être une TrajectoryExpectation. Apple décrit ce type comme le motif attendu d’appels d’outils pour une évaluation, spécifié selon trois axes10 :

// 27.0 beta (all Apple platforms)
struct TrajectoryExpectation

Apple indique que ToolCallEvaluator prend en charge les séquences ordonnées, les attentes non ordonnées, les vérifications d’outils interdits et les étapes groupées, et produit à la fois un résultat strict et un résultat partiel à partir d’une seule passe d’évaluation9. Chacun correspond à un échec réel d’agent. Les séquences ordonnées attrapent un modèle qui appelle les bons outils dans le mauvais ordre. Les attentes non ordonnées disent « ces appels doivent avoir lieu, l’ordre mis à part ». Les vérifications d’outils interdits attrapent un modèle qui se saisit d’un outil auquel il ne devrait jamais toucher (le cas de sûreté : un agent appelant un outil destructeur alors qu’il aurait dû rester en lecture seule). Les étapes groupées expriment « l’un quelconque parmi ceux-ci », pour les branches où plus d’un chemin est acceptable.

Le couple strict-et-partiel épouse la façon dont la qualité agentique se dégrade réellement. Une nouvelle invite fait rarement passer une fonctionnalité de parfaite à cassée ; elle la fait passer de « bonne trajectoire à chaque fois » à « bonne trajectoire la plupart du temps, avec un appel hors ordre ». Un résultat strict seul rapporte cela comme un échec uniforme et ne vous apprend rien sur la distance qui séparait le modèle du but. Le résultat partiel quantifie ces presque-réussites, qui sont le signal sur lequel vous réglez.

La justesse au niveau de chaque appel se situe un cran plus bas, dans les arguments. Un modèle peut appeler le bon outil avec les mauvaises valeurs, et ArgumentMatcher définit la manière de valider chaque argument. Apple le décrit comme les valeurs qui définissent comment valider l’argument d’un appel d’outil11 :

// 27.0 beta (all Apple platforms)
enum ArgumentMatcher

La présentation d’Apple énumère les règles de validation : exiger des valeurs exactes, vérifier la présence d’une clé, contrôler des plages, faire correspondre des motifs, ou recourir à un modèle de langage pour une correspondance sémantique11. Le cas de la correspondance sémantique est celui qu’une simple assertion d’égalité ne peut pas exprimer. Si un argument d’outil est une requête en texte libre, deux chaînes différentes peuvent être tout aussi correctes, et un == ordinaire ferait échouer un appel parfaitement bon. Déléguer cet argument à une correspondance de type modèle-juge, c’est la même échappatoire que celle qu’offre ScoreDimension au niveau de la sortie, appliquée au niveau de l’argument. L’orthographe des cas provient de l’énumération d’Apple ; ce qui suit est illustratif, alors confirmez dans la documentation :

import Evaluations

// Illustrative — confirm shapes against Apple's docs.
let expectation = TrajectoryExpectation(/* ordered / unordered / disallowed steps */)
let evaluator = ToolCallEvaluator<ModelSample<String>>(/* expectation */)

La boucle agentique évoquée ici est celle que l’article sur le tool-calling de Foundation Models décrit du côté exécution. Là-bas, GenerationOptions.ToolCallingMode régit l’agressivité avec laquelle le modèle embarqué se saisit des outils, et le framework peut basculer le mode après le premier appel pour borner l’activité d’outils d’une requête19. ToolCallEvaluator est le versant mesure de ce même comportement : vous fixez la posture d’appel à l’exécution, puis vous notez la trajectoire au moment des tests pour confirmer que la posture a produit le chemin que vous visiez. Le bouton d’exécution et l’évaluateur du moment des tests sont les deux extrémités d’une seule et même fonctionnalité.

Comment cela s’intègre à un flux de travail

Les évals ne sont pas un rituel à part que vous menez chaque trimestre. Elles ont leur place à côté de vos tests, dans la même boucle, exécutées sur le même Mac. Le pont du framework vers cette boucle, c’est EvaluationTrait. Apple le décrit comme un trait de test qui exécute une évaluation et en enregistre le résultat sous forme de pièces jointes12 :

// 27.0 beta (all Apple platforms)
struct EvaluationTrait

Le mot « trait » est délibéré. Tout le modèle de configuration de Swift Testing repose sur des traits appliqués aux déclarations @Test et @Suite : .enabled(if:), .disabled(_:), .tags(...), et les autres13. EvaluationTrait insère une évaluation dans ce vocabulaire, de sorte qu’une éval s’exécute comme s’exécute un test, sous la même invocation swift test, avec le même parallélisme. Enregistrer le résultat sous forme de pièces jointes réutilise le mécanisme que Swift Testing possède déjà pour les pièces jointes personnalisées, si bien que le résultat détaillé d’une éval voyage avec le rapport de test et les artefacts de CI que vous collectez13. Le framework expose aussi un EvaluationContext afin que le code à l’intérieur de la portée du test puisse lire le résultat une fois l’évaluation terminée20.

Ce trait répond à « où vivent les évals ». Elles vivent dans votre cible de test, à côté de vos tests unitaires, gardées par les mêmes traits. Une annotation .tags(.evals) n’exécute que les vérifications de qualité de modèle après un changement d’invite, comme .tags(.regression) cadre une exécution de régression13. Les tests rapides, de style unitaire, restent au vert à chaque édition ; les évals plus lentes, pilotées par le modèle, s’exécutent sur les invites et les définitions d’outils qui touchent au modèle.

La distinction éval-contre-test reflète la distinction exécution-contre-outillage de l’article sur le flux de travail agentique, qui trace la ligne entre le modèle embarqué que l’application livre et le modèle d’outillage que le développeur exécute pour écrire l’application21. Evaluations se situe du côté compilation de cette ligne : un outil de développement du cycle 27, exécuté pendant l’itération, qui mesure si la fonctionnalité d’exécution que vous livrez est suffisamment bonne1. Vous ne livrez pas le framework Evaluations aux utilisateurs, pas plus que vous ne livrez XCTest. Vous livrez la confiance qu’il produit.

Le framework reste également ouvert quant au modèle que vous notez. Apple note qu’il fonctionne avec n’importe quel modèle accessible à votre code, et le côté jeu de données est alimenté par un Loader, un protocole pour les types qui fournissent un jeu de données, avec des types concrets intégrés ou une conformité personnalisée pour vos propres sources122. Pour la notation de type modèle-juge, ModelJudgeEvaluator envoie la requête, la réponse et des données de référence optionnelles à un modèle juge qui renvoie des scores pour une ou plusieurs dimensions23, l’invite du juge étant configurable via ModelJudgePrompt, qui regroupe les instructions, la présentation de la réponse et l’injection des données de référence en une seule valeur composable24. Utilisez Claude via votre propre chemin de code pour le juge si c’est le modèle auquel votre pile fait déjà confiance ; le framework ne vous enferme pas dans un seul.

FAQ

Qu’est-ce que le framework Evaluations, et sur quelle plateforme s’exécute-t-il ?

Le framework Evaluations mesure la qualité des fonctionnalités dopées à l’intelligence de votre application à l’aide d’API Swift typées qui s’intègrent à votre flux de développement1. Il est inédit dans la version 27 sur iOS, iPadOS, macOS, visionOS et watchOS : un framework d’outillage de développement que vous exécutez au moment des tests (généralement sur un Mac), et non une fonctionnalité d’exécution livrée à l’intérieur d’une application1. Vous définissez des jeux de données, générez les réponses du modèle, appliquez des métriques et agrégez les résultats, puis vous lisez quelle approche a le mieux performé et où certaines réponses individuelles ont échoué1.

Pourquoi ne puis-je pas utiliser les assertions d’égalité de XCTest ou de Swift Testing pour des fonctionnalités d’IA ?

Une assertion d’égalité a besoin d’une seule valeur attendue, et un modèle non déterministe n’en a pas : la même invite peut produire une sortie valide différente à chaque exécution. Evaluations remplace l’égalité par un jugement noté. Une Metric enregistre un résultat passing, failing, scoring ou ignore, et une ScoreDimension note une sortie sur un axe nommé45. Vous exécutez toujours les évals à l’intérieur d’un test, via EvaluationTrait, de sorte qu’elles vivent dans la même cible et la même boucle swift test que vos autres tests12.

Comment le framework évalue-t-il le comportement de tool-calling agentique ?

Grâce à ToolCallEvaluator, qui vérifie les appels d’outils agentiques face à une trajectoire attendue9. Vous décrivez le chemin sous forme de TrajectoryExpectation selon trois axes ; l’évaluateur prend en charge les séquences ordonnées, les attentes non ordonnées, les vérifications d’outils interdits et les étapes groupées, en produisant des résultats stricts et partiels à partir d’une seule passe910. La validation argument par argument utilise ArgumentMatcher (valeurs exactes, présence de clé, plages, motifs, ou correspondance sémantique fondée sur un modèle)11.

Quelle est la différence entre un Evaluator et le protocole Evaluation ?

Evaluator est un évaluateur fondé sur une closure, à usage en ligne, sans définir de type personnalisé ; sa closure reçoit l’échantillon d’entrée et la réponse, avec accès à .value et à .transcript2. Le protocole Evaluation est le type que vous implémentez pour définir une évaluation réutilisable et nommée, qui exécute votre système sous test face à un jeu de données et lui applique des évaluateurs3. Tournez-vous vers Evaluator pour une vérification en ligne rapide, vers le protocole Evaluation pour une vérification structurée et reproductible.

Où vivent les échantillons générés et les résultats ?

SampleGenerator est un acteur qui produit des échantillons à partir d’un modèle de langage sous forme de flux asynchrone ; après l’itération, vous lisez les échantillons acceptés ou ceux que le validateur a rejetés7. Les résultats atterrissent dans un DataFrame doté de descripteurs ResultColumn typés : responseColumn, inputColumn et expectedColumn8161715. MetricsAggregator calcule la moyenne, la médiane et l’écart-type sur ces données18.

L’ensemble du cluster Apple Ecosystem : l’explication du framework Foundation Models ; la distinction entre le LLM d’exécution et le LLM d’outillage ; le contrôle du tool-calling dans iOS 27 que ce framework note ; et Swift Testing contre XCTest, dont le modèle de traits accueille EvaluationTrait. Le hub se trouve à la série Apple Ecosystem. Pour un contexte plus large d’iOS avec des agents d’IA, consultez le guide iOS Agent Development.



  1. Apple Developer, “Evaluations” framework overview. Available iOS 27.0, iPadOS 27.0, Mac Catalyst 27.0, macOS 27.0, visionOS 27.0, watchOS 27.0 (all beta). Abstracted as “measure the quality of your app’s intelligence-powered features.” Apple’s discussion states you define datasets, generate model responses, apply metrics, and aggregate results with type-safe Swift APIs that integrate into your development workflow; the framework evaluates features against metrics from simple pass or fail checks to detailed scoring with model-as-judge patterns, aggregates results into summaries that show which approach performs best and where individual responses fall short, and works with any model available to your code. (iOS 27.0+ beta, all Apple platforms) 

  2. Apple Developer, “Evaluator”. A structure (struct Evaluator<Input> with Input : SampleProtocol and Input.ExpectedValue conforming to Decodable, Encodable, Sendable) abstracted as a closure-based evaluator; Apple’s discussion states the closure receives the input sample and the response, providing access to .value and .transcript. (iOS 27.0+ beta, all Apple platforms) 

  3. Apple Developer, “Evaluation”. A protocol (protocol Evaluation : Sendable) abstracted as a type that defines an evaluation; Apple’s discussion states the evaluation runs your system under test against a dataset and applies evaluators to measure performance. (iOS 27.0+ beta, all Apple platforms) 

  4. Apple Developer, “Metric”. A structure (struct Metric) abstracted as a named metric that carries a result value; Apple’s discussion states the factory methods passing, failing, scoring, and ignore return a new Metric with the result stored inside. (iOS 27.0+ beta, all Apple platforms) 

  5. Apple Developer, “ScoreDimension”. A structure (struct ScoreDimension) abstracted as a named scoring dimension for a model judge evaluator; Apple’s discussion states each dimension defines a name (used as the DataFrame column), an optional description, and a definition of what each score means. (iOS 27.0+ beta, all Apple platforms) 

  6. Apple Developer, “ModelSample”. A structure (struct ModelSample<ExpectedValue> with ExpectedValue conforming to Decodable, Encodable, Sendable) abstracted as a general-purpose language model evaluation sample; Apple’s discussion states it accepts string-based prompts and instructions, and that multimodal prompts use a custom conformance or an initializer with a prebuilt prompt. (iOS 27.0+ beta, all Apple platforms) 

  7. Apple Developer, “SampleGenerator”. Declared actor SampleGenerator<SampleType> with SampleType : ModelSampleProtocol, abstracted as an actor that generates evaluation samples using a language model; Apple’s discussion states you create a generator, configure its properties, then call it to produce new samples as an async stream, after which you access all generated samples or any the validator rejected. (iOS 27.0+ beta, all Apple platforms) 

  8. Apple Developer, “responseColumn”. An instance property (var responseColumn: ResultColumn<Self.Subject> { get }) abstracted as a typed column descriptor for the model responses in the detailed DataFrame. (iOS 27.0+ beta, all Apple platforms) 

  9. Apple Developer, “ToolCallEvaluator”. A structure (struct ToolCallEvaluator<Input> with Input : ModelSampleProtocol and Input.Expectation == TrajectoryExpectation) abstracted as an evaluator that verifies agentic tool calls against an expected trajectory; Apple’s discussion states it produces both a strict and partial result from a single evaluation pass and supports ordered sequences, unordered expectations, disallowed tool checks, and group steps. (iOS 27.0+ beta, all Apple platforms) 

  10. Apple Developer, “TrajectoryExpectation”. A structure (struct TrajectoryExpectation) abstracted as the expected pattern of tool calls for an evaluation; Apple’s discussion states it specifies expected tool-calling behavior across three axes. (iOS 27.0+ beta, all Apple platforms) 

  11. Apple Developer, “ArgumentMatcher”. An enumeration (enum ArgumentMatcher) abstracted as the values that define how to validate a tool-call argument; Apple’s discussion states you can require exact values, verify key presence, check ranges, match patterns, or use a language model for semantic matching. (iOS 27.0+ beta, all Apple platforms) 

  12. Apple Developer, “EvaluationTrait”. A structure (struct EvaluationTrait) abstracted as a test trait that runs an evaluation and records the result as attachments. (iOS 27.0+ beta, all Apple platforms) 

  13. Author’s analysis in Swift Testing: The Framework Replacing XCTest, May 2, 2026, covering @Test, @Suite, #expect, #require, parallel-by-default execution, custom attachments, and the trait vocabulary (.enabled(if:), .disabled(_:), .serialized, .timeLimit(...), .tags(...), .bug(...)) that EvaluationTrait extends, with citations to Apple’s Swift Testing and Trait references. 

  14. Apple Developer, “EvaluationResult”. A structure (struct EvaluationResult) abstracted as the results of running a model evaluation; Apple’s discussion states it contains the summary and detailed results from an evaluation run. (iOS 27.0+ beta, all Apple platforms) 

  15. Apple Developer, “ResultColumn”. A structure (struct ResultColumn<Value>) abstracted as a typed descriptor for a column in an evaluation result DataFrame. (iOS 27.0+ beta, all Apple platforms) 

  16. Apple Developer, “inputColumn”. An instance property (var inputColumn: ResultColumn<Self.Sample> { get }) abstracted as a typed column descriptor for the input samples in the detailed DataFrame. (iOS 27.0+ beta, all Apple platforms) 

  17. Apple Developer, “expectedColumn”. An instance property (var expectedColumn: ResultColumn<Self.Sample.ExpectedValue> { get }) abstracted as a typed column descriptor for the expected values in the detailed DataFrame. (iOS 27.0+ beta, all Apple platforms) 

  18. Apple Developer, “MetricsAggregator”. A structure (struct MetricsAggregator) abstracted as a utility for computing aggregate statistics from evaluation metrics; Apple’s discussion states it calculates summary statistics like mean, median, and standard deviation, processing metric data from a DataFrame to produce aggregated results. (iOS 27.0+ beta, all Apple platforms) 

  19. Author’s analysis in Foundation Models in iOS 27: Tool-Calling Control, June 8, 2026, covering GenerationOptions.ToolCallingMode, the framework’s after-first-call mode shift, and the built-in Vision tools OCRTool and BarcodeReaderTool

  20. Apple Developer, “EvaluationContext”. A structure (struct EvaluationContext) abstracted as a context that provides the evaluation result within a test scope; Apple’s discussion states you access the result after the evaluation completes. (iOS 27.0+ beta, all Apple platforms) 

  21. Author’s analysis in Foundation Models Agentic Workflow: In-App vs Tooling LLM, May 1, 2026, on the runtime/tooling LLM distinction and the trust boundary between the shipped on-device model and the developer’s tooling model. 

  22. Apple Developer, “Loader”. A protocol (protocol Loader<Sample> : Sendable) abstracted as a protocol for types that supply a dataset for evaluation; Apple’s discussion states you use one of the built-in concrete types or implement the protocol directly for custom data sources. (iOS 27.0+ beta, all Apple platforms) 

  23. Apple Developer, “ModelJudgeEvaluator”. A structure (struct ModelJudgeEvaluator<Input> with Input : ModelSampleProtocol) abstracted as an evaluator that uses a language model as a judge to score responses; Apple’s discussion states it sends the query, response, and optional reference data to a judge model that returns scores for one or more dimensions. (iOS 27.0+ beta, all Apple platforms) 

  24. Apple Developer, “ModelJudgePrompt”. A structure (struct ModelJudgePrompt<Input> with Input : ModelSampleProtocol) abstracted as a configuration for how a model-as-judge evaluator constructs its prompt; Apple’s discussion states it bundles the instructions, response presentation, and reference-data injection into a single composable value. (iOS 27.0+ beta, all Apple platforms) 

  25. Apple, WWDC26 session 298, Meet the Evaluations framework. Apple states generative-AI features “break a contract that is fundamental to software testing” because “the same input can produce different outputs,” and concludes that “unit tests are insufficient.” 

Articles connexes

Les nouveautés de Swift (2026) : la mise à jour de la WWDC26

Swift 6.3 et 6.4 issus de la WWDC26 : disponibilité anyAppleOS, sélecteurs de module, accesseurs borrow/mutate, le proto…

19 min de lecture

Apple va ouvrir le code du framework Foundation Models

WWDC 2026 : le framework Foundation Models passe en open source cet été, de sorte que la même API Swift s'exécute côté s…

15 min de lecture

The Robots Are Taking Exams in My Search Console

First-party GSC data: 91% of 3.8M impressions fail a human-query filter. Exam questions, pasted errors, and agent sweeps…

10 min de lecture