ThresholdCalibrator

class ThresholdCalibrator(embedder: Embedder, guards: List<MatchGuard> = MatchGuards.standard())

Finds the similarity threshold that fits your embedding model, by measuring instead of guessing.

A threshold copied from a blog post is a threshold tuned to somebody else's model. The same pair of prompts might score 0.86 with one embedding model and 0.94 with another, so a value that is safely tight for one is dangerously loose for the next — and the failure is silent, because a false hit looks exactly like a fast response.

Give the calibrator prompt pairs you have labelled and it sweeps the threshold range, reporting how many correct hits and how many wrong answers each setting produces on your own model, with your own guards in the loop:

val report = ThresholdCalibrator(myEmbedder).calibrate(myLabelledPairs)
println(report.summary())
val cache = SemanticCache(myEmbedder, threshold = report.recommended.threshold)

A hundred pairs drawn from your own traffic is plenty, and half of them should be near-misses: prompts that look alike but need different answers. Pairs that are obviously unrelated teach the calibrator nothing, because no threshold ever confuses them.

Parameters

embedder

the model you intend to cache with — results do not transfer between models.

guards

the guards you intend to run. Pass MatchGuards.none to measure the similarity-only baseline and see what the guards are buying you.

Constructors

Link copied to clipboard
constructor(embedder: Embedder, guards: List<MatchGuard> = MatchGuards.standard())

Types

Link copied to clipboard
object Companion

Functions

Link copied to clipboard
suspend fun calibrate(pairs: List<PromptPair>, range: ClosedFloatingPointRange<Double> = DEFAULT_RANGE, step: Double = DEFAULT_STEP, maxFalseHitRate: Double = 0.0): CalibrationReport

Embeds every pair once, then evaluates every threshold in range.