Evaluations: XCTest für Modellqualität (iOS 27)
Ein gewöhnlicher Unit-Test stellt sicher, dass add(2, 2) den Wert 4 zurückgibt, und schlägt der Build fehl, wird er rot. Eine KI-Funktion bricht diesen Vertrag schon in der ersten Zeile, denn derselbe Prompt kann bei jedem Durchlauf einen anderen Satz erzeugen, und „anders” ist nicht „falsch”. Sie können kein #expect(summary == "die erwartete Zusammenfassung") gegen ein Modell schreiben, weil es keine einzelne erwartete Zeichenkette gibt. Messen lässt sich hingegen, ob die Ausgabe gut genug ist, und zwar oft genug, gemessen an Kriterien, die Sie selbst festlegen. Apples neues Evaluations-Framework liefert Ihnen genau diese Mess-Infrastruktur, mit typsicheren Swift-APIs, die als Teil Ihres Entwicklungs-Workflows laufen1. Es ist neu im 27er-Release und auf allen Apple-Plattformen verfügbar (iOS, iPadOS, macOS, visionOS und watchOS): ein Entwicklerwerkzeug, das Sie zur Testzeit ausführen, typischerweise auf Ihrem Mac, keine Laufzeitfunktion, die Sie in einer App ausliefern1.
Die Struktur wird Ihnen vertraut vorkommen, wenn Sie schon einmal Tests geschrieben haben. Sie definieren einen Datensatz, erzeugen Modellantworten, wenden Metriken an und aggregieren Ergebnisse; danach lesen Sie ab, welcher Ansatz am besten abgeschnitten hat und wo einzelne Antworten zurückblieben1. Das mentale Modell ist XCTest für Modellqualität: dieselbe Schleife (einen Fall vorbereiten, ausführen, etwas zusichern), nur mit einer anderen Zusicherung (eine bewertete Metrik statt Gleichheit).
In Session 298 formuliert Apple das Kernproblem so: Generative-KI-Funktionen brechen einen für das Softwaretesten grundlegenden Vertrag, weil dieselbe Eingabe unterschiedliche Ausgaben erzeugen kann, was Unit-Tests unzureichend macht25.
TL;DR / Die wichtigsten Erkenntnisse
- Das
Evaluations-Framework ist neu im 27er-Release auf allen Apple-Plattformen (iOS, iPadOS, macOS, visionOS, watchOS), eine Entwicklerwerkzeug-Schicht zum Messen intelligenzgestützter Funktionen, ausgeführt als Teil Ihres Test-Workflows (typischerweise auf einem Mac)1. Evaluatorist ein closure-basierter Evaluator, den Sie inline schreiben; dasEvaluation-Protokoll ist der Typ, den Sie implementieren, um ein zu testendes System gegen einen Datensatz laufen zu lassen und Evaluatoren anzuwenden23.Metricträgt ein benanntes Ergebnis über Factory-Methoden (passing,failing,scoring,ignore), undScoreDimensionbenennt eine bewertete Achse für einen Model-as-Judge-Evaluator45.ModelSampleist ein universell einsetzbares Evaluations-Sample;SampleGeneratorist ein Actor, der Samples aus einem Sprachmodell als asynchronen Stream erzeugt; die Ergebnisse landen in einem DataFrame mit typisierten Spalten, darunter eineresponseColumn678.ToolCallEvaluatorüberprüft agentische Tool-Aufrufe gegen eineTrajectoryExpectation, wobei derArgumentMatcherfestlegt, wie jedes Argument validiert wird91011.EvaluationTraitführt eine Evaluation innerhalb eines Tests aus und protokolliert das Ergebnis als Attachments, was die Brücke in einen Swift-Testing-Lauf darstellt12.
Der Beitrag arbeitet die API-Oberfläche durch, erklärt, warum es jeden Baustein gibt, und bindet alles an die Foundation-Models-Tool-Aufrufe zurück, die das Framework bewertet. Wo ich einen Aufruf zeige, dessen exakte Signatur Apple noch nicht veröffentlicht hat, kennzeichne ich ihn als illustrativ und weise Sie an, ihn gegen die Dokumentation zu prüfen.
Das Evaluator-Modell
Die Kernfrage des Frameworks lautet „wie gut war diese Ausgabe”, und es beantwortet sie mit einem kleinen Vokabular: ein Evaluator entscheidet, eine Metrik protokolliert, eine Score-Dimension bewertet, und ein Ergebnis aggregiert.
Das Evaluation-Protokoll ist der Typ, den Sie implementieren, um eine Evaluation zu definieren, die Ihr zu testendes System gegen einen Datensatz laufen lässt und Evaluatoren anwendet, um die Leistung zu messen3. Die Deklaration ist minimal:
// 27.0 beta (all Apple platforms)
protocol Evaluation : Sendable
Das Protokoll ist Sendable, weil Evaluation nebenläufige Arbeit ist: viele Samples, parallel ausgeführt, genauso wie Swift Testing Testfälle standardmäßig parallel ausführt13. Sie implementieren das Protokoll, wenn Sie eine wiederverwendbare, benannte Evaluation möchten. Wenn es schnell gehen soll, greifen Sie stattdessen zu Evaluator, den Apple als closure-basierten Evaluator für den Inline-Einsatz ohne Definition eines eigenen Typs beschreibt2:
// 27.0 beta (all Apple platforms)
struct Evaluator<Input> where Input : SampleProtocol,
Input.ExpectedValue : Decodable,
Input.ExpectedValue : Encodable,
Input.ExpectedValue : Sendable
Apples Erläuterung besagt, dass die Closure das Eingabe-Sample und die Antwort erhält, mit Zugriff sowohl auf .value als auch auf .transcript2. Der .value ist die typisierte Ausgabe des Modells; das .transcript ist die Aufzeichnung, wie es dorthin gelangt ist. Ein Inline-Evaluator ist ein einzeiliger #expect-Block für Modellqualität: keine Unterklasse, nur das Urteil als Closure. Die folgende Aufrufform ist illustrativ; prüfen Sie den Initializer gegen Apples Dokumentation:
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()
}
Was die Closure zurückgibt, ist eine Metric. Apple beschreibt Metric als benannte Metrik, die einen Ergebniswert trägt, und benennt die Factory-Methoden ausdrücklich: passing, failing, scoring und ignore geben jeweils eine neue Metric zurück, in der das Ergebnis gespeichert ist4:
// 27.0 beta (all Apple platforms)
struct Metric
Die vier Factories bilden die Arten von Urteilen ab, die eine KI-Funktion braucht. Eine Zusammenfassung enthält die geforderte Tatsache entweder oder nicht, also bekommt sie passing oder failing. Eine Tonalitätsbewertung reicht von 1 bis 5, also bekommt sie scoring. Ein Sample, das Sie aus der Aggregation heraushalten möchten (fehlerhafte Eingabe, ein bekanntermaßen schlechtes Fixture), bekommt ignore, was die Zeile im Datensatz belässt, ohne die Statistik zu verfälschen. Genau die Spanne von passing bis zum bewerteten scoring ist es, was das Framework verspricht: von einfachen Bestanden-oder-Durchgefallen-Prüfungen bis hin zu detaillierter Bewertung mit Model-as-Judge-Mustern1.
Am bewerteten Ende dieser Spanne verdient sich ScoreDimension seinen Platz. Apple definiert es als benannte Bewertungsdimension für einen Model-Judge-Evaluator, wobei jede Dimension einen Namen (der als DataFrame-Spalte dient), eine optionale Beschreibung und eine Definition dessen festlegt, was jeder Score bedeutet5:
// 27.0 beta (all Apple platforms)
struct ScoreDimension
Eine einzelne Ausgabe kann auf der einen Achse gut und auf einer anderen schlecht sein. Eine entworfene E-Mail kann sachlich korrekt und tonal verfehlt sein. ScoreDimension lässt Sie diese Achsen getrennt bewerten (Korrektheit, Tonalität, Prägnanz), sodass die Aggregation Ihnen verrät, welche Dimension eingebrochen ist, und nicht nur, dass die Gesamtqualität gesunken ist. Der Dimensionsname wird zur Spalte, was bedeutet, dass die Scores in einer strukturierten Tabelle landen, die Sie sortieren und vergleichen können, statt einer Wand aus Prosa.
Diese Tabelle ist ein EvaluationResult. Apple beschreibt es als das Ergebnis einer durchgeführten Modell-Evaluation, eine Struktur, die die Zusammenfassung und die detaillierten Ergebnisse eines Evaluationslaufs enthält14:
// 27.0 beta (all Apple platforms)
struct EvaluationResult
Die zweistufige Form (Zusammenfassung plus Detail) ist es, was Evals umsetzbar macht. Die Zusammenfassung beantwortet „hat dieser Prompt besser abgeschnitten als der vorherige”. Das Detail beantwortet „welche Samples blieben zurück”, sodass Sie die schlechtesten Zeilen öffnen und lesen können, was das Modell produziert hat1.
Samples und Generierung
Eine Evaluation braucht Fälle, gegen die sie läuft, und die Einheit eines Falls ist im Framework ein Sample. ModelSample ist das universell einsetzbare. Apple beschreibt es als universell einsetzbares Sprachmodell-Evaluations-Sample, das zeichenkettenbasierte Prompts und Anweisungen entgegennimmt6:
// 27.0 beta (all Apple platforms)
struct ModelSample<ExpectedValue> where ExpectedValue : Decodable,
ExpectedValue : Encodable,
ExpectedValue : Sendable
Der generische ExpectedValue ist die typisierte Erwartung: eine Zeichenkette für eine Freitext-Aufgabe, ein strukturierter Codable-Typ für eine mit bekannter Antwort. Die Constraints Codable plus Sendable decken sich mit Evaluators Input.ExpectedValue, denn die Erwartung muss in die Ergebnistabelle serialisiert werden und während eines parallelen Laufs Nebenläufigkeitsgrenzen überschreiten. Für multimodale Prompts merkt Apple an, dass Sie eine eigene Konformität erstellen oder einen Initializer mit einem vorgefertigten Prompt verwenden6.
Jedes Sample von Hand zu schreiben skaliert nicht, weshalb es SampleGenerator gibt, einen Actor, der Evaluations-Samples mithilfe eines Sprachmodells erzeugt7:
// 27.0 beta (all Apple platforms)
actor SampleGenerator<SampleType> where SampleType : ModelSampleProtocol
Es ist ein actor, weil er veränderlichen Generierungszustand besitzt (akzeptierte und abgelehnte Samples), den die asynchrone Iteration verändert, und die Actor-Isolation ist Swifts Schutzmechanismus gegen Data Races auf diesem Zustand. Apples Workflow: Sie erstellen einen Generator, konfigurieren seine Eigenschaften und rufen ihn dann auf, um neue Samples als asynchronen Stream zu erzeugen; nach der Iteration greifen Sie auf alle generierten Samples zu oder auf jene, die der Validator abgelehnt hat7. Der Ablehnungs-Topf ist das Detail, bei dem es sich zu verweilen lohnt. Ein Generator, der schlechte Samples stillschweigend verwirft, würde seine eigene Fehlerquote verbergen; das Offenlegen der Ablehnungen erlaubt Ihnen, den Datensatz so zu prüfen, wie Sie handgeschriebene Fixtures prüfen würden.
Sobald die Samples gelaufen sind, landen die Antworten in einem DataFrame mit typisierten Spaltenbeschreibungen, sodass Sie die Tabelle ohne stringbasierte Lookups lesen. Apple benennt die Antwortspalte exakt: responseColumn, ein typisierter Spaltenbeschreiber für die Modellantworten im detaillierten DataFrame8:
// 27.0 beta (all Apple platforms)
var responseColumn: ResultColumn<Self.Subject> { get }
Der generische ResultColumn<Value> ist es, was die Spalte typisiert macht: ein Beschreiber für eine DataFrame-Spalte, parametrisiert über den Wert, den sie enthält15. Neben responseColumn stellt das Framework eine inputColumn für die Eingabe-Samples und eine expectedColumn für die erwarteten Werte bereit, jeweils eine typisierte ResultColumn1617. Typisierte Spalten folgen demselben Instinkt wie Swift Testings Ausdrucks-Erfassung: Statt einen Wert aus einem untypisierten Beutel zu ziehen und zu hoffen, dass der Cast hält, lesen Sie ihn über einen Beschreiber, der seinen Typ kennt. Wenn Sie die Ergebnisse für Mittelwert, Median und Standardabweichung in den MetricsAggregator einspeisen, sind die Spalten der Weg, über den Sie die Daten adressieren, ohne bei den Schlüsseln zu raten18.
Tool- und Trajektorienprüfung
Die KI-Funktion, die am schwersten zu testen ist, ist die agentische, denn Korrektheit ist keine Zeichenkette, sondern eine Folge von Aktionen. Wenn eine Foundation-Models-Session OCRTool aufruft, dann BarcodeReaderTool, dann Ihren eigenen Katalog-Lookup, lautet die Frage nicht „stimmte der finale Satz überein”, sondern „ist das Modell den richtigen Weg gegangen”19. ToolCallEvaluator bewertet diesen Weg direkt. Apple beschreibt es als Evaluator, der agentische Tool-Aufrufe gegen eine erwartete Trajektorie überprüft9:
// 27.0 beta (all Apple platforms)
struct ToolCallEvaluator<Input> where Input : ModelSampleProtocol,
Input.Expectation == TrajectoryExpectation
Die where-Klausel ist der tragende Teil: Die Erwartung der Eingabe muss eine TrajectoryExpectation sein. Apple beschreibt diesen Typ als das erwartete Muster von Tool-Aufrufen für eine Evaluation, festgelegt über drei Achsen10:
// 27.0 beta (all Apple platforms)
struct TrajectoryExpectation
Apple gibt an, dass ToolCallEvaluator geordnete Sequenzen, ungeordnete Erwartungen, Prüfungen auf unzulässige Tools und Gruppenschritte unterstützt und aus einem einzigen Evaluationsdurchlauf sowohl ein striktes als auch ein partielles Ergebnis erzeugt9. Jedes davon entspricht einem realen Agenten-Fehler. Geordnete Sequenzen ertappen ein Modell, das die richtigen Tools in der falschen Reihenfolge aufruft. Ungeordnete Erwartungen sagen „diese Aufrufe müssen stattfinden, Reihenfolge egal”. Prüfungen auf unzulässige Tools ertappen ein Modell, das nach einem Tool greift, das es nie anrühren sollte (der Sicherheitsfall: ein Agent, der ein destruktives Tool aufruft, obwohl er nur lesend hätte bleiben sollen). Gruppenschritte drücken „eines von diesen” aus, für Verzweigungen, bei denen mehr als ein Weg akzeptabel ist.
Das Paar aus strikt und partiell passt dazu, wie agentische Qualität tatsächlich nachlässt. Ein neuer Prompt bringt eine Funktion selten von perfekt zu kaputt; er bringt sie von „jedes Mal die richtige Trajektorie” zu „meistens die richtige Trajektorie, mit einem Aufruf in falscher Reihenfolge”. Ein nur striktes Ergebnis meldet das als glatten Fehlschlag und sagt Ihnen nichts darüber, wie nah das Modell gekommen ist. Das partielle Ergebnis quantifiziert die Beinahe-Treffer, und genau das ist das Signal, gegen das Sie justieren.
Die Korrektheit pro Aufruf liegt eine Ebene tiefer, in den Argumenten. Ein Modell kann das richtige Tool mit den falschen Werten aufrufen, und der ArgumentMatcher legt fest, wie jedes Argument validiert wird. Apple beschreibt es als die Werte, die festlegen, wie ein Tool-Aufruf-Argument zu validieren ist11:
// 27.0 beta (all Apple platforms)
enum ArgumentMatcher
Apples Erläuterung listet die Validierungsregeln auf: exakte Werte verlangen, das Vorhandensein eines Schlüssels prüfen, Bereiche kontrollieren, Muster abgleichen oder ein Sprachmodell für semantisches Matching verwenden11. Der Fall des semantischen Matchings ist derjenige, den eine schlichte Gleichheitszusicherung nicht ausdrücken kann. Ist ein Tool-Argument eine Freitext-Abfrage, können zwei verschiedene Zeichenketten gleichermaßen korrekt sein, und ein gewöhnliches == würde einen völlig guten Aufruf durchfallen lassen. Dieses Argument einem Model-as-Judge-Abgleich zu überlassen, ist dieselbe Notluke, die ScoreDimension auf Ausgabeebene bietet, nur auf Argumentebene angewandt. Die Schreibweisen der Fälle stammen aus Apples Enumeration; das Folgende ist illustrativ, prüfen Sie es also gegen die Dokumentation:
import Evaluations
// Illustrative — confirm shapes against Apple's docs.
let expectation = TrajectoryExpectation(/* ordered / unordered / disallowed steps */)
let evaluator = ToolCallEvaluator<ModelSample<String>>(/* expectation */)
Die agentische Schleife hier ist dieselbe, die der Beitrag zum Foundation-Models-Tool-Aufruf von der Laufzeitseite beschreibt. Dort steuert GenerationOptions.ToolCallingMode, wie aggressiv das On-Device-Modell nach Tools greift, und das Framework kann den Modus nach dem ersten Aufruf umstellen, um die Tool-Aktivität einer Anfrage zu begrenzen19. ToolCallEvaluator ist die Messseite genau dieses Verhaltens: Sie legen die Aufruf-Haltung zur Laufzeit fest und bewerten dann die Trajektorie zur Testzeit, um zu bestätigen, dass die Haltung den beabsichtigten Weg hervorgebracht hat. Der Laufzeit-Regler und der Test-Evaluator sind zwei Enden ein und derselben Funktion.
Wie sich das in einen Workflow einfügt
Evals sind kein gesondertes Ritual, das Sie vierteljährlich durchführen. Sie gehören neben Ihre Tests, in dieselbe Schleife, ausgeführt auf demselben Mac. Die Brücke des Frameworks in diese Schleife ist EvaluationTrait. Apple beschreibt es als Test-Trait, der eine Evaluation ausführt und das Ergebnis als Attachments protokolliert12:
// 27.0 beta (all Apple platforms)
struct EvaluationTrait
Das Wort „Trait” ist bewusst gewählt. Swift Testings gesamtes Konfigurationsmodell besteht aus Traits, die auf @Test- und @Suite-Deklarationen angewendet werden: .enabled(if:), .disabled(_:), .tags(...) und der Rest13. EvaluationTrait fügt eine Evaluation in dieses Vokabular ein, sodass ein Eval so läuft, wie ein Test läuft, unter demselben swift test-Aufruf, mit derselben Parallelität. Das Protokollieren des Ergebnisses als Attachments verwendet denselben Mechanismus, den Swift Testing bereits für eigene Attachments besitzt, sodass das detaillierte Ergebnis eines Evals im Testbericht und in den CI-Artefakten mitreist, die Sie einsammeln13. Das Framework stellt außerdem einen EvaluationContext bereit, damit Code innerhalb des Test-Scopes das Ergebnis lesen kann, nachdem die Evaluation abgeschlossen ist20.
Dieser Trait beantwortet „wo leben Evals”. Sie leben in Ihrem Test-Target, neben Ihren Unit-Tests, gesteuert von denselben Traits. Eine .tags(.evals)-Annotation führt nach einer Prompt-Änderung nur die Modellqualitätsprüfungen aus, so wie .tags(.regression) einen Regressionslauf eingrenzt13. Schnelle, unit-artige Tests bleiben bei jeder Bearbeitung grün; die langsameren, modellgetriebenen Evals laufen auf den Prompts und Tool-Definitionen, die das Modell berühren.
Die Trennung von Eval und Test spiegelt die Trennung von Laufzeit und Werkzeug aus dem Beitrag zum agentischen Workflow wider, der die Grenze zwischen dem On-Device-Modell, das die App ausliefert, und dem Werkzeug-Modell, das der Entwickler zum Schreiben der App betreibt, zieht21. Evaluations steht auf der Build-Seite dieser Grenze: ein Entwicklerwerkzeug des 27er-Zyklus, ausgeführt während der Iteration, das misst, ob die Laufzeitfunktion, die Sie ausliefern, gut genug ist1. Sie liefern das Evaluations-Framework ebenso wenig an Nutzer aus wie XCTest. Sie liefern das Vertrauen aus, das es erzeugt.
Das Framework bleibt zudem offen dafür, welches Modell Sie bewerten. Apple merkt an, dass es mit jedem Modell funktioniert, das Ihrem Code zur Verfügung steht, und die Datensatzseite wird über einen Loader gespeist, ein Protokoll für Typen, die einen Datensatz liefern, mit eingebauten konkreten Typen oder einer eigenen Konformität für Ihre eigenen Quellen122. Für die Model-as-Judge-Bewertung sendet ModelJudgeEvaluator die Abfrage, die Antwort und optionale Referenzdaten an ein Judge-Modell, das Scores für eine oder mehrere Dimensionen zurückgibt23, wobei der Judge-Prompt über ModelJudgePrompt konfigurierbar ist, der Anweisungen, Antwortdarstellung und Referenzdaten-Einspeisung zu einem komponierbaren Wert bündelt24. Verwenden Sie Claude über Ihren eigenen Code-Pfad als Judge, wenn das das Modell ist, dem Ihr Stack ohnehin vertraut; das Framework bindet Sie nicht an ein einziges.
FAQ
Was ist das Evaluations-Framework, und auf welcher Plattform läuft es?
Das Evaluations-Framework misst die Qualität der intelligenzgestützten Funktionen Ihrer App mithilfe typsicherer Swift-APIs, die sich in Ihren Entwicklungs-Workflow integrieren1. Es ist neu im 27er-Release auf iOS, iPadOS, macOS, visionOS und watchOS: ein Entwicklerwerkzeug-Framework, das Sie zur Testzeit ausführen (typischerweise auf einem Mac), keine Laufzeitfunktion, die in einer App ausgeliefert wird1. Sie definieren Datensätze, erzeugen Modellantworten, wenden Metriken an und aggregieren Ergebnisse; danach lesen Sie ab, welcher Ansatz am besten abgeschnitten hat und wo einzelne Antworten zurückblieben1.
Warum kann ich für KI-Funktionen keine Gleichheitszusicherungen von XCTest oder Swift Testing verwenden?
Eine Gleichheitszusicherung braucht einen einzelnen erwarteten Wert, und ein nichtdeterministisches Modell hat keinen: derselbe Prompt kann bei jedem Durchlauf eine andere gültige Ausgabe erzeugen. Evaluations ersetzt Gleichheit durch bewertetes Urteil. Eine Metric protokolliert ein Ergebnis als passing, failing, scoring oder ignore, und eine ScoreDimension bewertet eine Ausgabe auf einer benannten Achse45. Sie führen die Evals weiterhin innerhalb eines Tests aus, über EvaluationTrait, sodass sie im selben Target und in derselben swift test-Schleife leben wie Ihre übrigen Tests12.
Wie bewertet das Framework agentisches Tool-Aufruf-Verhalten?
Über ToolCallEvaluator, der agentische Tool-Aufrufe gegen eine erwartete Trajektorie überprüft9. Sie beschreiben den Weg als TrajectoryExpectation über drei Achsen; der Evaluator unterstützt geordnete Sequenzen, ungeordnete Erwartungen, Prüfungen auf unzulässige Tools und Gruppenschritte und erzeugt aus einem Durchlauf sowohl strikte als auch partielle Ergebnisse910. Die Validierung pro Argument verwendet ArgumentMatcher (exakte Werte, Vorhandensein eines Schlüssels, Bereiche, Muster oder modellbasiertes semantisches Matching)11.
Was ist der Unterschied zwischen einem Evaluator und dem Evaluation-Protokoll?
Evaluator ist ein closure-basierter Evaluator für den Inline-Einsatz ohne Definition eines eigenen Typs; seine Closure erhält das Eingabe-Sample und die Antwort, mit Zugriff auf .value und .transcript2. Das Evaluation-Protokoll ist der Typ, den Sie implementieren, um eine wiederverwendbare, benannte Evaluation zu definieren, die Ihr zu testendes System gegen einen Datensatz laufen lässt und Evaluatoren anwendet3. Greifen Sie zu Evaluator für eine schnelle Inline-Prüfung und zum Evaluation-Protokoll für eine strukturierte, wiederholbare.
Wo leben generierte Samples und Ergebnisse?
SampleGenerator ist ein Actor, der Samples aus einem Sprachmodell als asynchronen Stream erzeugt; nach der Iteration lesen Sie die akzeptierten Samples oder jene, die der Validator abgelehnt hat7. Die Ergebnisse landen in einem DataFrame mit typisierten ResultColumn-Beschreibern: responseColumn, inputColumn und expectedColumn8161715. MetricsAggregator berechnet Mittelwert, Median und Standardabweichung über diese Daten18.
Das vollständige Apple-Ecosystem-Cluster: die Erklärung zum Foundation-Models-Framework; die Unterscheidung zwischen Laufzeit- und Werkzeug-LLM; die iOS-27-Tool-Aufruf-Steuerung, die dieses Framework bewertet; und Swift Testing vs. XCTest, in dessen Trait-Modell sich EvaluationTrait einklinkt. Der Hub befindet sich bei der Apple-Ecosystem-Serie. Für einen breiteren Kontext zu iOS mit KI-Agenten siehe den Leitfaden zur iOS-Agentenentwicklung.
-
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) ↩↩↩↩↩↩↩↩↩↩↩
-
Apple Developer, “Evaluator”. A structure (
struct Evaluator<Input>withInput : SampleProtocolandInput.ExpectedValueconforming toDecodable,Encodable,Sendable) abstracted as a closure-based evaluator; Apple’s discussion states the closure receives the input sample and the response, providing access to.valueand.transcript. (iOS 27.0+ beta, all Apple platforms) ↩↩↩↩ -
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) ↩↩↩ -
Apple Developer, “Metric”. A structure (
struct Metric) abstracted as a named metric that carries a result value; Apple’s discussion states the factory methodspassing,failing,scoring, andignorereturn a newMetricwith the result stored inside. (iOS 27.0+ beta, all Apple platforms) ↩↩↩ -
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) ↩↩↩ -
Apple Developer, “ModelSample”. A structure (
struct ModelSample<ExpectedValue>withExpectedValueconforming toDecodable,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) ↩↩↩ -
Apple Developer, “SampleGenerator”. Declared
actor SampleGenerator<SampleType>withSampleType : 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) ↩↩↩↩ -
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) ↩↩↩ -
Apple Developer, “ToolCallEvaluator”. A structure (
struct ToolCallEvaluator<Input>withInput : ModelSampleProtocolandInput.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) ↩↩↩↩↩ -
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) ↩↩↩ -
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) ↩↩↩↩ -
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) ↩↩↩ -
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(...)) thatEvaluationTraitextends, with citations to Apple’s Swift Testing and Trait references. ↩↩↩↩ -
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) ↩ -
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) ↩↩ -
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) ↩↩ -
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) ↩↩ -
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) ↩↩ -
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 toolsOCRToolandBarcodeReaderTool. ↩↩ -
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) ↩ -
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. ↩
-
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) ↩ -
Apple Developer, “ModelJudgeEvaluator”. A structure (
struct ModelJudgeEvaluator<Input>withInput : 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) ↩ -
Apple Developer, “ModelJudgePrompt”. A structure (
struct ModelJudgePrompt<Input>withInput : 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) ↩ -
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.” ↩