Documentation
¶
Overview ¶
Package eval defines a subject-agnostic quality-evaluation kernel. Evaluator is generic over the subject, Metric carries structured identity and measurement semantics, and Report independently represents an optional verdict, normalized quality score, raw numeric measurement, feedback, and child reports. SuiteEvaluator preserves heterogeneous results while CompositeEvaluator explicitly aggregates comparable scored verdicts. Dataset owns case identity, Experiment executes it with bounded concurrency, and ExperimentReport.Compare reports exact aggregate deltas without inventing statistical claims. ProjectionEvaluator adapts aggregate subjects to narrow evaluator inputs.
Domain vocabularies live outside the kernel: judge supplies generic model-backed evaluation, text owns generated-text metrics, ranking owns provider-neutral ranking metrics, and trajectory owns deterministic Agent execution evaluation. New domains implement Evaluator directly and do not depend on another domain's vocabulary.
Index ¶
- Constants
- Variables
- type Case
- type CaseID
- type CaseResult
- type Comparison
- type Component
- type CompositeConfig
- type CompositeEvaluator
- type Dataset
- type Direction
- type Distribution
- type DistributionDelta
- type ErrorPolicy
- type Evaluator
- type EvaluatorFunc
- type Experiment
- type ExperimentConfig
- type ExperimentReport
- type ExperimentSummary
- type Metric
- func (m Metric) Clone() Metric
- func (m Metric) Direction() Direction
- func (m Metric) MarshalJSON() ([]byte, error)
- func (m Metric) Name() MetricName
- func (m Metric) Namespace() string
- func (m Metric) Parameters() metadata.Map
- func (m Metric) String() string
- func (m Metric) Unit() string
- func (m *Metric) UnmarshalJSON(data []byte) error
- func (m Metric) Validate() error
- type MetricComparison
- type MetricConfig
- type MetricName
- type MetricSummary
- type PassPolicy
- type Projection
- type ProjectionEvaluator
- type Report
- type Score
- type SuiteConfig
- type SuiteEvaluator
- type Verdict
Examples ¶
Constants ¶
const DefaultMaxConcurrency = 4
const MaxReportDepth = 64
MaxReportDepth bounds recursive detail trees at every public trust boundary.
Variables ¶
var ( ErrInvalidEvaluatorConfig = errors.New("eval: evaluator configuration is invalid") ErrInvalidMetric = errors.New("eval: invalid metric") ErrInvalidScore = errors.New("eval: invalid score") ErrInvalidReport = errors.New("eval: invalid report") ErrInvalidCase = errors.New("eval: invalid case") ErrInvalidDataset = errors.New("eval: invalid dataset") ErrInvalidExperiment = errors.New("eval: invalid experiment") ErrInvalidComparison = errors.New("eval: invalid comparison") ErrCaseNotEvaluated = errors.New("eval: case was not evaluated") )
Functions ¶
This section is empty.
Types ¶
type CaseResult ¶
type Comparison ¶
type Comparison struct {
Baseline ExperimentSummary
Candidate ExperimentSummary
EvaluatedDelta int
PassedDelta int
FailedDelta int
UnjudgedDelta int
ErrorDelta int
Metrics []MetricComparison
}
type Component ¶
Component assigns score weight and pass criticality to one evaluator. A zero Weight selects 1. Required components must pass independently of the aggregate pass policy.
type CompositeConfig ¶
type CompositeConfig[T any] struct { Components []Component[T] PassPolicy PassPolicy MinimumPassed int MaxConcurrency int }
CompositeConfig defines score aggregation, pass semantics, and bounded concurrency. A zero MaxConcurrency selects DefaultMaxConcurrency.
type CompositeEvaluator ¶
type CompositeEvaluator[T any] struct { // contains filtered or unexported fields }
func NewCompositeEvaluator ¶
func NewCompositeEvaluator[T any](config CompositeConfig[T]) (*CompositeEvaluator[T], error)
type Dataset ¶
type Dataset[T any] struct { // contains filtered or unexported fields }
Dataset is an immutable ordered set of uniquely identified cases. Evaluators must not mutate subjects; metadata is owned and cloned by the Dataset.
type Direction ¶
type Direction string
Direction describes how a raw measurement relates to quality. It is kept separate from Score, whose direction is always higher-is-better.
type Distribution ¶
type Distribution struct {
Count int
Mean float64
Minimum float64
P10 float64
P50 float64
P90 float64
Maximum float64
}
Distribution summarizes one homogeneous numeric signal. Count distinguishes an absent distribution from a real distribution whose values are all zero.
type DistributionDelta ¶
DistributionDelta is candidate mean minus baseline mean. Present is false when either side has no values, so absence cannot be mistaken for zero.
type ErrorPolicy ¶
type ErrorPolicy string
const ( ErrorCollect ErrorPolicy = "collect" ErrorFailFast ErrorPolicy = "fail_fast" )
type Evaluator ¶
type Evaluator[T any] interface { // Evaluate inspects one subject without mutating it and returns a valid, // owned report for the evaluator's metric. Implementations must honor ctx; // a non-nil error means the report must not be consumed. Evaluate(ctx context.Context, subject T) (Report, error) }
Evaluator evaluates one subject and returns a valid report.
type EvaluatorFunc ¶
type Experiment ¶
type Experiment[T any] struct { // contains filtered or unexported fields }
Experiment is an immutable plan for evaluating one Dataset. It owns bounded scheduling and error semantics, but no persistence, artifacts, or product identity.
func NewExperiment ¶
func NewExperiment[T any](config ExperimentConfig[T]) (Experiment[T], error)
func (Experiment[T]) Run ¶
func (e Experiment[T]) Run(ctx context.Context) (ExperimentReport, error)
Example ¶
package main
import (
"context"
"fmt"
"github.com/Tangerg/scope/eval"
)
func main() {
metric, err := eval.NewMetric(eval.MetricConfig{
Namespace: "example",
Name: "non_empty",
})
if err != nil {
panic(err)
}
evaluator := eval.EvaluatorFunc[string](func(_ context.Context, subject string) (eval.Report, error) {
return eval.Report{Metric: metric, Verdict: eval.VerdictPass}, nil
})
dataset, err := eval.NewDataset(
eval.Case[string]{ID: "first", Subject: "answer"},
)
if err != nil {
panic(err)
}
experiment, err := eval.NewExperiment(eval.ExperimentConfig[string]{
Dataset: dataset, Evaluator: evaluator,
})
if err != nil {
panic(err)
}
report, err := experiment.Run(context.Background())
if err != nil {
panic(err)
}
summary := report.Summary()
fmt.Println(summary.Total, summary.Passed)
}
Output: 1 1
type ExperimentConfig ¶
type ExperimentConfig[T any] struct { Dataset Dataset[T] Evaluator Evaluator[T] MaxConcurrency int ErrorPolicy ErrorPolicy }
type ExperimentReport ¶
type ExperimentReport struct {
// contains filtered or unexported fields
}
func (ExperimentReport) Cases ¶
func (e ExperimentReport) Cases() []CaseResult
Cases returns owned results in Dataset order.
func (ExperimentReport) Compare ¶
func (e ExperimentReport) Compare(candidate ExperimentReport) (Comparison, error)
Compare keeps the baseline authoritative: only reports over the same ordered Dataset and Metric identities are comparable. Exact deltas avoid inventing statistical significance or a synthetic score across unlike units.
func (ExperimentReport) Summary ¶
func (e ExperimentReport) Summary() ExperimentSummary
Summary returns the owned aggregate calculated from Cases.
type ExperimentSummary ¶
type Metric ¶
type Metric struct {
// contains filtered or unexported fields
}
Metric identifies an evaluation without encoding configuration into a string. Parameters holds owned, structured identity for calculation and decision rules. Unit and Direction describe optional raw measurements; normalized scores are always unitless and higher-is-better.
func NewMetric ¶
func NewMetric(config MetricConfig) (Metric, error)
func (Metric) MarshalJSON ¶ added in v0.13.0
func (Metric) Name ¶
func (m Metric) Name() MetricName
func (Metric) Parameters ¶
func (*Metric) UnmarshalJSON ¶ added in v0.13.0
type MetricComparison ¶
type MetricComparison struct {
Metric Metric
Baseline MetricSummary
Candidate MetricSummary
EvaluatedDelta int
PassedDelta int
FailedDelta int
UnjudgedDelta int
ScoreDelta DistributionDelta
MeasurementDelta DistributionDelta
}
type MetricConfig ¶
type MetricName ¶
type MetricName string
MetricName identifies one quality calculation within a namespace.
const MetricNameComposite MetricName = "composite"
const MetricNameSuite MetricName = "suite"
type MetricSummary ¶
type MetricSummary struct {
Metric Metric
Evaluated int
Passed int
Failed int
Unjudged int
Scores Distribution
Measurements Distribution
}
MetricSummary keeps score and measurement distributions attached to their full Metric identity so unrelated units, directions, and configurations are never aggregated together. Experiment summarizes both top-level reports and their Details.
type PassPolicy ¶
type PassPolicy string
const ( PassAll PassPolicy = "all" PassAny PassPolicy = "any" PassAtLeast PassPolicy = "at_least" )
type Projection ¶
type ProjectionEvaluator ¶
type ProjectionEvaluator[T, Subject any] struct { // contains filtered or unexported fields }
ProjectionEvaluator adapts one aggregate case to the narrower subject a domain evaluator consumes.
func NewProjectionEvaluator ¶
func NewProjectionEvaluator[T, Subject any]( evaluator Evaluator[Subject], projection Projection[T, Subject], ) (*ProjectionEvaluator[T, Subject], error)
type Report ¶
type Report struct {
Metric Metric `json:"metric"`
Verdict Verdict `json:"verdict,omitzero"`
Score *Score `json:"score,omitzero"`
Measurement *float64 `json:"measurement,omitzero"`
Feedback string `json:"feedback,omitzero"`
Metadata metadata.Map `json:"metadata,omitzero"`
Details []Report `json:"details,omitzero"`
}
Report is one evaluation result. Verdict, normalized Score, and raw Measurement are independent and optional so measurement-only and qualitative evaluations do not need to invent a pass threshold or quality score. Details contains owned child reports instead of convention-based metadata keys.
func (Report) MarshalJSON ¶
func (*Report) UnmarshalJSON ¶
type Score ¶
type Score float64
Score is a normalized quality score in the closed interval [0, 1], where a higher value is always better.
type SuiteConfig ¶
SuiteConfig groups heterogeneous evaluators without collapsing their results into one score. A zero MaxConcurrency selects DefaultMaxConcurrency.
type SuiteEvaluator ¶
type SuiteEvaluator[T any] struct { // contains filtered or unexported fields }
SuiteEvaluator preserves every child report and records the ordered child metrics in its own identity. Its verdict fails when any decided child fails, passes when at least one child passes and none fail, and remains unspecified when every child is measurement-only or qualitative.
func NewSuiteEvaluator ¶
func NewSuiteEvaluator[T any](config SuiteConfig[T]) (*SuiteEvaluator[T], error)
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package judge evaluates arbitrary subjects with a structured-output chat model.
|
Package judge evaluates arbitrary subjects with a structured-output chat model. |
|
Package ranking evaluates ranked outputs against graded relevance judgments.
|
Package ranking evaluates ranked outputs against graded relevance judgments. |
|
Package text evaluates generated text without imposing one shared sample on metrics with different semantic inputs.
|
Package text evaluates generated text without imposing one shared sample on metrics with different semantic inputs. |