LedgeKitDocs
Evaluations
Developer documentation

Evaluate a dataset

Execute current application code against saved inputs and preserve report provenance.

This guide uses Apple Evaluations in an iOS/macOS 27 test target. LedgeKit loads inputs and reports results; your evaluation owns execution and scoring.

Construct native samples

Use the SummaryInput type from the dataset guide. Preserve each item's ID, original JSON, and source in its native sample:

import Evaluations
import Foundation
import LedgeKit
import LedgeKitTesting

@available(iOS 27.0, macOS 27.0, *)
struct SummarySample: SampleProtocol {
    let id: String
    let source: LedgeDatasetSource
    let savedInput: LedgeJSONValue
    let arguments: SummaryInput
    var input: String { id }
    var expected: String? { nil }

    init(_ item: LedgeDatasetInput<SummaryInput>) {
        id = item.id.uuidString.lowercased()
        source = item.source
        savedInput = item.input
        arguments = item.value
    }
}

The saved source describes where the input came from. A fresh model request made during evaluation has its own identity.

Define execution and scoring

The following evaluation calls the current summarize(_:client:) function from the Foundation Models guide. A nonempty-output metric is a minimal example; add quality checks appropriate to your application.

@available(iOS 27.0, macOS 27.0, *)
struct SummaryEvaluation: Evaluation {
    let samples: [SummarySample]
    let client: LedgeClient
    var dataset: ArrayLoader<SummarySample> { .init(samples: samples) }

    func subject(from sample: SummarySample) async throws -> ModelSubject<String> {
        let value = try await summarize(sample.arguments.text, client: client)
        return ModelSubject(value: value)
    }

    var evaluators: Evaluators {
        Evaluator<SummarySample> { _, subject in
            subject.value.isEmpty
                ? Metric("nonempty").failing()
                : Metric("nonempty").passing()
        }
    }

    func aggregateMetrics(using aggregator: inout MetricsAggregator) {
        aggregator.computeMean(of: Metric("nonempty"))
    }
}

This uses a string-valued native subject. If your evaluation uses a richer native model subject, retain its native capture when exporting; the uploader does not construct or replace it.

Run, save, and validate

let (dataset, inputs) = try await loadSummaryInputs(
    datasetID: datasetID, readKey: readKey
)
let evaluation = SummaryEvaluation(
    samples: inputs.map(SummarySample.init), client: client
)
let result = try await evaluation.run(info: dataset.evaluationInfo())
let reportURL = try result.saveJSON(
    to: reportDirectory, includeReportMetadata: true
)
let report = try LedgeEvaluationFile(data: Data(contentsOf: reportURL))
try dataset.validateResults(in: report)
try await reporter.submit(report)

client is your configured trace client, reporter is the evaluation reporter, and reportDirectory is a writable URL in your test environment.

evaluationInfo() records the full expected dataset membership before execution. validateResults(in:) requires every loaded item ID exactly once in the report. It does not score outputs or assert that native execution succeeded. Verify that result.errors.hasFailures is false and assert your quality metrics in the test as well.

Save the report before validation so incomplete results remain inspectable. A delivery retry should submit the saved file instead of calling run again.

Review the result

Open Evaluations in the write key's app and environment. Inspect sample responses and metrics, then use the recorded dataset/source information to follow the result back to its inputs where available.

On this page