← 모든 글

Evaluations: 모델 품질을 위한 XCTest (iOS 27)

일반적인 단위 테스트는 add(2, 2)4를 반환하는지 단언하고, 그렇지 않으면 빌드가 빨갛게 됩니다. 그런데 AI 기능은 첫 줄에서부터 그 계약을 깨뜨립니다. 같은 프롬프트라도 실행할 때마다 다른 문장을 만들어낼 수 있고, “다르다”는 것이 “틀렸다”는 뜻은 아니기 때문입니다. 모델을 상대로 #expect(summary == "the expected summary")라고 쓸 수는 없습니다. 기대되는 문자열이 하나로 정해져 있지 않으니까요. 측정할 수 있는 것은, 직접 정의한 기준에 비추어 출력이 충분히 좋은지, 그리고 그 일이 충분히 자주 일어나는지입니다. Apple의 새로운 Evaluations 프레임워크는 개발 워크플로의 일부로 실행되는 타입 안전한 Swift API를 갖춘 그 측정 하니스를 제공합니다1. 27 릴리스에서 새로 등장했으며 Apple의 모든 플랫폼(iOS, iPadOS, macOS, visionOS, watchOS)에서 사용할 수 있습니다. 앱 안에 담아 출시하는 런타임 기능이 아니라, 테스트 시점에 보통 Mac에서 실행하는 개발자 도구입니다1.

테스트를 작성해 본 적이 있다면 그 모양이 익숙하게 느껴질 것입니다. 데이터셋을 정의하고, 모델 응답을 생성하고, 메트릭을 적용하고, 결과를 집계합니다. 그런 다음 어떤 접근이 가장 좋은 성적을 냈는지, 개별 응답이 어디에서 기준에 못 미쳤는지를 읽어냅니다1. 멘탈 모델은 모델 품질을 위한 XCTest입니다. 루프는 동일하지만(케이스를 준비하고, 실행하고, 무언가를 단언함) 단언이 다릅니다(동등성이 아니라 채점된 메트릭).

세션 298에서 Apple은 이 핵심 문제를 이렇게 설명합니다. 생성형 AI 기능은 소프트웨어 테스트에 근본적인 계약을 깨뜨리는데, 같은 입력이 다른 출력을 만들어낼 수 있어 단위 테스트로는 충분하지 않다는 것입니다25.

Watch on Apple Developer ↗
동등성 단언이 AI 기능에서 실패하는 이유: 같은 입력이 다른 출력을 만들어낼 수 있다.

TL;DR / 핵심 요약

  • Evaluations 프레임워크는 27 릴리스에서 모든 Apple 플랫폼(iOS, iPadOS, macOS, visionOS, watchOS)에 새로 등장한, 인텔리전스 기반 기능을 측정하기 위한 개발자 도구 계층이며, 테스트 워크플로의 일부로(보통 Mac에서) 실행합니다1.
  • Evaluator는 인라인으로 작성하는 클로저 기반 평가기입니다. Evaluation 프로토콜은 테스트 대상 시스템을 데이터셋에 대해 실행하고 평가기를 적용하기 위해 구현하는 타입입니다23.
  • Metric은 이름이 붙은 결과를 팩토리 메서드(passing, failing, scoring, ignore)를 통해 전달하고, ScoreDimension은 모델을 심판으로 삼는 평가기를 위해 채점 축에 이름을 붙입니다45.
  • ModelSample은 범용 평가 샘플입니다. SampleGenerator는 언어 모델로부터 비동기 스트림으로 샘플을 생성하는 액터이며, 결과는 responseColumn을 포함한 타입이 지정된 열을 갖춘 DataFrame에 담깁니다678.
  • ToolCallEvaluator는 에이전트형 도구 호출을 TrajectoryExpectation에 비추어 검증하고, ArgumentMatcher가 각 인자를 어떻게 검증할지 정의합니다91011.
  • EvaluationTrait는 테스트 안에서 평가를 실행하고 그 결과를 첨부 파일로 기록합니다. 이것이 Swift Testing 실행으로 이어지는 다리입니다12.

이 글은 API 표면을 따라가며 각 요소가 왜 존재하는지 설명하고, 그것이 채점 대상으로 삼는 Foundation Models 도구 호출 작업으로 연결합니다. Apple이 정확한 시그니처를 공개하지 않은 호출을 보여주는 부분에서는 예시임을 표시하고 문서에서 확인하도록 안내합니다.

평가기 모델

이 프레임워크의 핵심 질문은 “이 출력이 얼마나 좋았는가”이며, 작은 어휘로 답합니다. 평가기가 판단하고, 메트릭이 기록하고, 스코어 디멘션이 채점하고, 결과가 집계합니다.

Evaluation 프로토콜은 평가를 정의하기 위해 구현하는 타입으로, 테스트 대상 시스템을 데이터셋에 대해 실행하고 평가기를 적용해 성능을 측정합니다3. 선언은 최소한입니다.

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

이 프로토콜이 Sendable인 이유는 평가가 동시성 작업이기 때문입니다. 많은 샘플을 병렬로 실행합니다. Swift Testing이 기본적으로 테스트 케이스를 병렬로 실행하는 것과 같은 방식입니다13. 재사용 가능하고 이름이 붙은 평가가 필요하면 이 프로토콜을 구현합니다. 빠르게 처리하고 싶을 때는 대신 Evaluator를 사용합니다. Apple은 이것을 사용자 정의 타입을 정의하지 않고 인라인으로 사용하는 클로저 기반 평가기로 설명합니다2.

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

Apple의 설명에 따르면 클로저는 입력 샘플과 응답을 받으며 .value.transcript 양쪽에 접근할 수 있습니다2. .value는 모델의 타입이 지정된 출력이고, .transcript는 거기에 이르기까지의 기록입니다. 인라인 평가기는 모델 품질을 위한 한 줄짜리 #expect 블록과 같습니다. 서브클래스가 필요 없고, 판단 자체를 클로저로 작성하면 됩니다. 다음 호출 모양은 예시입니다. 이니셜라이저는 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()
}

클로저가 반환하는 것은 Metric입니다. Apple은 Metric을 결과값을 전달하는 이름이 붙은 메트릭으로 설명하며, 팩토리 메서드를 명시적으로 거론합니다. passing, failing, scoring, ignore는 각각 결과를 내부에 저장한 새로운 Metric을 반환합니다4.

// 27.0 beta (all Apple platforms)
struct Metric

네 가지 팩토리는 AI 기능이 필요로 하는 판단의 종류에 대응합니다. 요약기는 필수 사실을 포함하거나 포함하지 않거나 둘 중 하나이므로 passing 또는 failing을 얻습니다. 톤을 채점하는 루브릭은 1부터 5까지 펼쳐지므로 scoring을 얻습니다. 집계에서 빼고 싶은 샘플(잘못된 입력, 알려진 불량 픽스처)에는 ignore를 줍니다. 이것은 행을 데이터셋에 남겨두면서 통계를 오염시키지 않게 해줍니다. passing부터 채점되는 scoring까지의 범위가 바로 이 프레임워크가 약속하는 것입니다. 즉 단순한 합격·불합격 검사부터 모델을 심판으로 삼는 패턴을 통한 상세한 채점까지입니다1.

그 범위의 채점 쪽에서 ScoreDimension이 제 역할을 합니다. Apple은 이것을 모델 심판 평가기를 위한 이름이 붙은 채점 디멘션으로 정의하며, 각 디멘션은 이름(DataFrame 열로 사용됨), 선택적 설명, 그리고 각 점수가 무엇을 의미하는지에 대한 정의를 가집니다5.

// 27.0 beta (all Apple platforms)
struct ScoreDimension

하나의 출력이 어떤 축에서는 좋고 다른 축에서는 나쁠 수 있습니다. 초안으로 작성한 이메일이 사실적으로는 옳지만 톤은 틀릴 수 있습니다. ScoreDimension은 그러한 축(정확성, 톤, 간결성)을 따로 채점하게 해주므로, 집계는 전체 품질이 떨어졌다는 것만이 아니라 어떤 디멘션이 떨어졌는지를 알려줍니다. 디멘션 이름은 열이 됩니다. 즉 점수는 끝없이 이어지는 산문의 벽이 아니라, 정렬하고 비교할 수 있는 구조화된 표에 담깁니다.

그 표가 EvaluationResult입니다. Apple은 이것을 모델 평가를 실행한 결과로 설명하며, 평가 실행의 요약과 상세 결과를 담는 구조체입니다14.

// 27.0 beta (all Apple platforms)
struct EvaluationResult

요약과 상세라는 두 단계 구조가 바로 평가를 실행 가능한 것으로 만듭니다. 요약은 “이 프롬프트가 이전 것보다 나았는가”에 답합니다. 상세는 “어떤 샘플이 기준에 못 미쳤는가”에 답하므로, 가장 나쁜 행을 열어 모델이 무엇을 만들어냈는지 읽어볼 수 있습니다1.

샘플과 생성

평가에는 실행할 대상이 되는 케이스가 필요하며, 프레임워크에서 케이스의 단위가 샘플입니다. ModelSample은 그 범용판입니다. Apple은 이것을 문자열 기반 프롬프트와 지침을 받아들이는 범용 언어 모델 평가 샘플로 설명합니다6.

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

제네릭 ExpectedValue는 타입이 지정된 기댓값입니다. 자유 텍스트 작업이면 문자열, 정해진 답이 있는 작업이면 구조화된 Codable 타입이 됩니다. CodableSendable 제약은 EvaluatorInput.ExpectedValue와 일치합니다. 기댓값이 결과 표로 직렬화되어야 하고, 병렬 실행 중에 동시성 경계를 넘어야 하기 때문입니다. 멀티모달 프롬프트에 대해서는 사용자 정의 준수를 만들거나 미리 만들어진 프롬프트를 쓰는 이니셜라이저를 사용한다고 Apple은 언급합니다6.

모든 샘플을 손으로 작성하는 것은 확장되지 않습니다. 그래서 SampleGenerator가 존재합니다. 언어 모델을 사용해 평가 샘플을 생성하는 액터입니다7.

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

이것이 actor인 이유는 변경 가능한 생성 상태(수락된 샘플과 거부된 샘플)를 소유하고, 비동기 반복이 그 상태를 변경하기 때문입니다. 액터 격리는 그 상태에 대한 데이터 경쟁을 막는 Swift의 안전장치입니다. Apple의 워크플로는 이렇습니다. 생성기를 만들고, 그 속성을 구성한 뒤, 그것을 호출해 새 샘플을 비동기 스트림으로 만들어냅니다. 반복이 끝나면 생성된 모든 샘플, 또는 검증기가 거부한 샘플에 접근합니다7. 잠시 멈춰 살펴볼 가치가 있는 것은 거부된 쪽입니다. 불량 샘플을 조용히 버리는 생성기는 자신의 실패율을 숨겨버릴 것입니다. 거부된 것을 드러내면 손으로 작성한 픽스처를 감사하듯 데이터셋을 감사할 수 있습니다.

샘플이 실행되면 응답은 타입이 지정된 열 디스크립터를 갖춘 DataFrame에 담기므로, 문자열에 의존하는 조회 없이 표를 읽을 수 있습니다. Apple은 응답 열의 이름을 정확히 이렇게 붙였습니다. responseColumn, 상세 DataFrame에서 모델 응답을 위한 타입이 지정된 열 디스크립터입니다8.

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

열을 타입이 지정되게 만드는 것은 ResultColumn<Value> 제네릭입니다. 이것은 DataFrame 열의 디스크립터로, 보유하는 값에 따라 매개변수화됩니다15. responseColumn과 더불어 프레임워크는 입력 샘플을 위한 inputColumn과 기댓값을 위한 expectedColumn을 노출하며, 각각 타입이 지정된 ResultColumn입니다1617. 타입이 지정된 열은 Swift Testing의 식 캡처와 같은 본능입니다. 타입이 없는 자루에서 값을 꺼내 캐스트가 통하기를 바라는 대신, 자신의 타입을 아는 디스크립터를 통해 읽습니다. 평균, 중앙값, 표준편차를 구하기 위해 결과를 MetricsAggregator에 넘길 때, 이 열이 바로 키를 추측하지 않고 데이터를 지목하는 방법입니다18.

도구와 궤적 검사

테스트하기 가장 어려운 AI 기능은 에이전트형 기능입니다. 정확성이 문자열이 아니라 일련의 동작이기 때문입니다. Foundation Models 세션이 OCRTool, 다음으로 BarcodeReaderTool, 그리고 자체 카탈로그 조회를 호출할 때, 질문은 “최종 문장이 일치했는가”가 아니라 “모델이 올바른 경로를 밟았는가”입니다19. ToolCallEvaluator는 그 경로를 직접 채점합니다. Apple은 이것을 에이전트형 도구 호출을 기대 궤적에 비추어 검증하는 평가기로 설명합니다9.

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

where 절이 핵심 부분입니다. 입력의 기댓값은 반드시 TrajectoryExpectation이어야 합니다. Apple은 이 타입을 평가를 위한 기대되는 도구 호출 패턴으로 설명하며, 세 가지 축에 걸쳐 지정됩니다10.

// 27.0 beta (all Apple platforms)
struct TrajectoryExpectation

Apple에 따르면 ToolCallEvaluator는 순서가 있는 시퀀스, 순서를 따지지 않는 기대, 금지된 도구 검사, 그리고 그룹 단계를 지원하며, 단일 평가 패스에서 엄격한 결과와 부분적인 결과 양쪽을 만들어냅니다9. 각각은 실제 에이전트 실패에 대응합니다. 순서가 있는 시퀀스는 올바른 도구를 잘못된 순서로 호출하는 모델을 잡아냅니다. 순서를 따지지 않는 기대는 “이 호출들은 순서와 무관하게 반드시 일어나야 한다”고 말합니다. 금지된 도구 검사는 결코 건드려서는 안 될 도구에 손을 뻗는 모델을 잡아냅니다(안전 사례로, 읽기 전용에 머물러야 할 에이전트가 파괴적인 도구를 호출하는 경우입니다). 그룹 단계는 “이들 중 어느 하나”를 표현하며, 둘 이상의 경로가 허용되는 분기에 대응합니다.

엄격함과 부분이라는 쌍은 에이전트형 품질이 실제로 저하되는 방식과 들어맞습니다. 새 프롬프트가 기능을 완벽에서 완전한 고장으로 단번에 바꾸는 일은 드뭅니다. 오히려 “매번 올바른 궤적”에서 “대부분 올바른 궤적이지만 한 호출이 순서에서 벗어남”으로 바꿉니다. 엄격한 결과만 내놓으면 그것을 일률적인 실패로 보고하고 모델이 얼마나 아슬아슬했는지에 대해서는 아무것도 알려주지 않습니다. 부분적인 결과는 그 아슬아슬한 실패를 정량화합니다. 이것이 바로 튜닝의 근거가 되는 신호입니다.

호출별 정확성은 한 단계 아래, 인자에 깃들어 있습니다. 모델은 올바른 도구를 잘못된 값으로 호출할 수 있고, ArgumentMatcher가 각 인자를 어떻게 검증할지 정의합니다. Apple은 이것을 도구 호출 인자를 어떻게 검증할지 정의하는 값으로 설명합니다11.

// 27.0 beta (all Apple platforms)
enum ArgumentMatcher

Apple의 설명은 검증 규칙을 열거합니다. 정확한 값을 요구하기, 키의 존재를 검증하기, 범위를 검사하기, 패턴을 매칭하기, 또는 의미적 매칭을 위해 언어 모델을 사용하기입니다11. 의미적 매칭 사례는 단순한 동등성 단언으로는 표현할 수 없는 것입니다. 도구 인자가 자유 텍스트 쿼리라면 서로 다른 두 문자열이 똑같이 옳을 수 있고, 일반적인 ==는 더할 나위 없이 좋은 호출을 불합격시킬 것입니다. 그 인자를 모델 심판 매칭에 위임하는 것은 ScoreDimension이 출력 수준에서 제공하는 것과 같은 탈출구를 인자 수준에 적용한 것입니다. 케이스 철자는 Apple의 열거에서 가져온 것입니다. 다음은 예시이니 문서에서 확인하세요.

import Evaluations

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

여기서의 에이전트형 루프는 Foundation Models 도구 호출 글이 런타임 쪽에서 설명하는 것과 동일합니다. 그곳에서는 GenerationOptions.ToolCallingMode가 온디바이스 모델이 얼마나 적극적으로 도구에 손을 뻗는지를 좌우하고, 프레임워크는 첫 호출 이후에 모드를 전환해 요청의 도구 활동을 제한할 수 있습니다19. ToolCallEvaluator는 바로 그 동작의 측정 쪽입니다. 런타임에서 호출 태세를 설정한 다음, 테스트 시점에 궤적을 채점해 그 태세가 의도한 경로를 만들어냈는지 확인합니다. 런타임 노브와 테스트 시점 평가기는 하나의 기능의 양 끝입니다.

워크플로에 맞춰 넣는 법

평가는 분기마다 한 번씩 실행하는 별개의 의식이 아닙니다. 테스트 곁에, 같은 루프 안에, 같은 Mac에서 자리합니다. 프레임워크가 그 루프로 이어주는 다리가 EvaluationTrait입니다. Apple은 이것을 평가를 실행하고 그 결과를 첨부 파일로 기록하는 테스트 트레이트로 설명합니다12.

// 27.0 beta (all Apple platforms)
struct EvaluationTrait

“트레이트”라는 단어는 의도된 것입니다. Swift Testing의 구성 모델 전체가 @Test@Suite 선언에 적용되는 트레이트입니다. .enabled(if:), .disabled(_:), .tags(...) 등입니다13. EvaluationTrait는 평가를 그 어휘에 끼워 넣으므로, 평가는 테스트가 실행되는 것과 같은 방식으로 같은 swift test 호출 아래, 같은 병렬성으로 실행됩니다. 결과를 첨부 파일로 기록하는 것은 Swift Testing이 이미 갖춘 사용자 정의 첨부 메커니즘을 재사용하므로, 평가의 상세 결과가 수집하는 테스트 리포트와 CI 아티팩트에 함께 실려 갑니다13. 프레임워크는 또한 EvaluationContext를 노출하여, 테스트 범위 안의 코드가 평가 완료 후 결과를 읽을 수 있게 합니다20.

그 트레이트가 “평가는 어디에 사는가”에 답합니다. 평가는 테스트 타겟 안, 단위 테스트 곁에 살며, 같은 트레이트로 게이트됩니다. .tags(.evals) 주석은 .tags(.regression)이 회귀 실행의 범위를 한정하는 것과 같은 방식으로, 프롬프트 변경 이후에 모델 품질 검사만 실행합니다13. 빠른 단위 스타일 테스트는 편집할 때마다 초록을 유지하고, 더 느린 모델 구동 평가는 모델에 닿는 프롬프트와 도구 정의에 대해 실행됩니다.

평가 대 테스트의 구분은 에이전트형 워크플로 글이 그리는 런타임 대 도구의 구분을 그대로 비춥니다. 그 글은 앱이 출시하는 온디바이스 모델과, 개발자가 앱을 작성하기 위해 실행하는 도구 모델 사이에 선을 긋습니다21. Evaluations는 그 선의 빌드 쪽에 자리합니다. 반복 작업 중에 실행하는 27 사이클의 개발자 도구이며, 출시하는 런타임 기능이 충분히 좋은지를 측정합니다1. XCTest를 출시하지 않듯이 Evaluations 프레임워크를 사용자에게 출시하는 일은 없습니다. 출시하는 것은 그것이 만들어내는 확신입니다.

프레임워크는 또한 어떤 모델을 채점할지에 대해 열려 있습니다. Apple은 코드에서 사용할 수 있는 어떤 모델과도 작동한다고 언급하며, 데이터셋 쪽은 Loader를 통해 공급됩니다. 이것은 데이터셋을 공급하는 타입을 위한 프로토콜로, 내장된 구체 타입을 쓰거나 자체 소스를 위해 사용자 정의 준수를 구현합니다122. 모델 심판 채점에서는 ModelJudgeEvaluator가 쿼리, 응답, 그리고 선택적 참조 데이터를 심판 모델에 보내면, 심판 모델이 하나 이상의 디멘션에 대한 점수를 반환합니다23. 심판 프롬프트는 ModelJudgePrompt를 통해 구성할 수 있으며, 이것은 지침, 응답 제시 방식, 참조 데이터 주입을 하나의 합성 가능한 값으로 묶습니다24. 스택이 이미 신뢰하는 모델이 그것이라면, 자체 코드 경로를 통해 Claude를 심판으로 사용하세요. 프레임워크는 하나의 모델에 묶어두지 않습니다.

FAQ

Evaluations 프레임워크란 무엇이며, 어떤 플랫폼에서 실행되나요?

Evaluations 프레임워크는 개발 워크플로에 통합되는 타입 안전한 Swift API를 사용해 앱의 인텔리전스 기반 기능의 품질을 측정합니다1. 27 릴리스에서 iOS, iPadOS, macOS, visionOS, watchOS에 걸쳐 새로 등장한, 테스트 시점에(보통 Mac에서) 실행하는 개발자 도구 프레임워크이며, 앱 안에 담아 출시하는 런타임 기능이 아닙니다1. 데이터셋을 정의하고, 모델 응답을 생성하고, 메트릭을 적용하고, 결과를 집계합니다. 그런 다음 어떤 접근이 가장 좋은 성적을 냈는지, 개별 응답이 어디에서 기준에 못 미쳤는지를 읽어냅니다1.

왜 AI 기능에 XCTest나 Swift Testing의 동등성 단언을 쓸 수 없나요?

동등성 단언에는 기대되는 값 하나가 필요한데, 비결정적인 모델에는 그것이 없습니다. 같은 프롬프트가 실행할 때마다 다른 유효한 출력을 만들어낼 수 있기 때문입니다. Evaluations는 동등성을 채점된 판단으로 대체합니다. Metricpassing, failing, scoring, ignore 결과를 기록하고, ScoreDimension은 이름이 붙은 축에서 출력을 채점합니다45. 평가는 여전히 테스트 안에서 EvaluationTrait를 통해 실행되므로, 다른 테스트와 같은 타겟, 같은 swift test 루프 안에 삽니다12.

프레임워크는 에이전트형 도구 호출 동작을 어떻게 평가하나요?

ToolCallEvaluator를 통해서입니다. 이것은 에이전트형 도구 호출을 기대 궤적에 비추어 검증합니다9. 경로를 세 가지 축에 걸친 TrajectoryExpectation으로 기술합니다. 평가기는 순서가 있는 시퀀스, 순서를 따지지 않는 기대, 금지된 도구 검사, 그룹 단계를 지원하며, 하나의 패스에서 엄격한 결과와 부분적인 결과 양쪽을 만들어냅니다910. 인자별 검증에는 ArgumentMatcher를 사용합니다(정확한 값, 키 존재, 범위, 패턴, 또는 모델 기반 의미적 매칭)11.

Evaluator와 Evaluation 프로토콜의 차이는 무엇인가요?

Evaluator는 사용자 정의 타입을 정의하지 않고 인라인으로 사용하는 클로저 기반 평가기입니다. 그 클로저는 입력 샘플과 응답을 받으며 .value.transcript에 접근합니다2. Evaluation 프로토콜은 테스트 대상 시스템을 데이터셋에 대해 실행하고 평가기를 적용하는, 재사용 가능하고 이름이 붙은 평가를 정의하기 위해 구현하는 타입입니다3. 빠른 인라인 검사에는 Evaluator를, 구조화되고 반복 가능한 검사에는 Evaluation 프로토콜을 사용하세요.

생성된 샘플과 결과는 어디에 사나요?

SampleGenerator는 언어 모델로부터 비동기 스트림으로 샘플을 생성하는 액터입니다. 반복이 끝나면 수락된 샘플, 또는 검증기가 거부한 샘플을 읽을 수 있습니다7. 결과는 타입이 지정된 ResultColumn 디스크립터를 갖춘 DataFrame에 담깁니다. responseColumn, inputColumn, expectedColumn입니다8161715. MetricsAggregator가 그 데이터에 대해 평균, 중앙값, 표준편차를 계산합니다18.

Apple Ecosystem 클러스터 전체는 다음과 같습니다. Foundation Models 프레임워크 해설, 런타임 대 도구 LLM 구분, 이 프레임워크가 채점하는 iOS 27 도구 호출 제어, 그리고 EvaluationTrait가 끼워 넣어지는 트레이트 모델을 가진 Swift Testing 대 XCTest. 허브는 Apple Ecosystem 시리즈에 있습니다. AI 에이전트를 곁들인 iOS에 대한 더 넓은 맥락은 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.” 

관련 게시물

Swift의 새로운 기능 (2026): WWDC26 업데이트

WWDC26에서 발표된 Swift 6.3과 6.4: anyAppleOS 가용성, 모듈 선택자, borrow/mutate 접근자, Iterable 프로토콜, Swift Testing 상호 운용, 그리고 MLX.

13 분 소요

Apple이 Foundation Models 프레임워크를 오픈소스로 공개합니다

WWDC 2026: Foundation Models 프레임워크가 올여름 오픈소스가 되어 동일한 Swift API가 서버 측에서도 실행되며, 새로운 Skills 패키지가 GitHub에 공개되었습니다.

10 분 소요

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 분 소요