reach.metrics¶
Compute standard evaluation, classification, routing, and multi-step trajectory metrics for skill selection probes.
Multi-Step Trajectory Routing¶
Modern agent runtimes execute multi-turn conversational trajectories where a task may require entering via one skill, performing a precursor handoff, and terminating at the target capability:
flowchart LR
Query["User Query"] --> E["Step 1: Entrypoint Skill<br/>(Entrypoint Accuracy)"]
E -->|Handoff| P["Step 2: Precursor Skill"]
P -->|Handoff| T["Step 3: Target Capability<br/>(Trajectory Reachability)"]
Trajectory Metrics¶
Reach evaluates multi-step trajectories against the ground-truth capability target \(T\):
| Metric | Symbol | Definition & Meaning |
|---|---|---|
| Entrypoint Accuracy | \(A_{\text{entry}}\) | Fraction of queries where the very first skill invoked matches the target skill \(T\) (\(\vec{s}_1 = T\)). Penalizes misrouted initial dispatch. |
| Trajectory Reachability | \(R_{\text{traj}}\) | Fraction of queries where the target skill \(T\) is reached anywhere in the trajectory (\(T \in \vec{s}\)). |
| Step Efficiency (MRR) | \(\text{MRR}\) | Reciprocal rank \(\frac{1}{\text{step}}\), measuring how directly and promptly the agent invoked the target skill. |
| Skill Selection F1 | \(F_1\) | Harmonic mean of precision (target reached / total unique skills invoked) and recall (target reached). |
| Skill Redundancy | \(\text{Redundancy}\) | Excess invocations beyond the target: \(\max(0, \text{len}(\vec{s}) - 1)\). Zero indicates optimal, direct execution. |
API Reference¶
Compute standard evaluation and routing metrics for skill selection probes.
ClassificationReport ¶
Bases: BaseModel
Hold aggregated classification and routing metrics for an evaluation run.
Source code in src/reach/metrics.py
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | |
abstention_interval
property
¶
abstention_interval: Interval | None
Calculate the Wilson confidence interval for overall abstention rate.
abstention_rate
property
¶
Calculate the overall abstention rate across scored probes.
entrypoint_accuracy
property
¶
Calculate entrypoint accuracy across scored probes.
entrypoint_interval
property
¶
entrypoint_interval: Interval | None
Calculate the Wilson confidence interval for entrypoint accuracy.
false_abstention_interval
property
¶
false_abstention_interval: Interval | None
Calculate the Wilson confidence interval for false abstention rate.
false_abstention_rate
property
¶
Calculate the false abstention rate over in-scope queries.
out_of_scope_detection
property
¶
Calculate the out-of-scope detection accuracy.
out_of_scope_interval
property
¶
out_of_scope_interval: Interval | None
Calculate the Wilson confidence interval for out-of-scope detection.
top1_interval
property
¶
top1_interval: Interval | None
Calculate the Wilson confidence interval for top-1 accuracy.
trajectory_interval
property
¶
trajectory_interval: Interval | None
Calculate the Wilson confidence interval for trajectory reachability.
trajectory_reachability
property
¶
Calculate trajectory reachability across scored probes.
top_attractors ¶
top_attractors(limit: int = 5) -> tuple[ClassMetrics, ...]
Return classes receiving the highest false-positive traffic.
Source code in src/reach/metrics.py
worst_recall ¶
worst_recall(limit: int = 5) -> tuple[ClassMetrics, ...]
Return classes with the lowest recall scores.
Source code in src/reach/metrics.py
ClassMetrics ¶
Bases: BaseModel
Report precision, recall, support, and F1 metrics for a single skill class.
Source code in src/reach/metrics.py
precision_interval
property
¶
precision_interval: Interval | None
Calculate the Wilson confidence interval for precision.
recall_interval
property
¶
recall_interval: Interval | None
Calculate the Wilson confidence interval for recall.
trajectory_recall
property
¶
Calculate trajectory recall (trajectory true positives / ground truth support).
DecompositionResult ¶
Bases: BaseModel
Represent decomposition of pass-rate drop between baseline and scaled catalogs.
Source code in src/reach/metrics.py
PrecursorEdge ¶
Bases: BaseModel
Represent an empirical directed transition between two skills in a trajectory.
Source code in src/reach/metrics.py
TrajectoryScore ¶
Bases: BaseModel
Evaluation outcomes for a single query across its invocation trajectory.
Source code in src/reach/metrics.py
classification_report ¶
classification_report(
results: Sequence[ProbeResult],
queries: Sequence[Query],
labels: Sequence[str] | None = None,
) -> ClassificationReport
Generate a comprehensive classification report across all probe results.
Source code in src/reach/metrics.py
classify_invocation_pattern ¶
classify_invocation_pattern(
query: Query, invoked_skills: Sequence[str]
) -> InvocationPattern
Classify trajectory invocation behavior relative to query ground truth.
Source code in src/reach/metrics.py
collisions ¶
collisions(
results: Sequence[ProbeResult], queries: Sequence[Query]
) -> Counter[tuple[str, str]]
Count misroutes between skill pairs.
Source code in src/reach/metrics.py
compute_f1 ¶
compute_precursor_graph ¶
compute_precursor_graph(
results: Sequence[ProbeResult],
queries: Sequence[Query],
skills: Sequence[Skill] = (),
min_observations: int = 1,
) -> tuple[PrecursorEdge, ...]
Compute empirical precursor transition matrix T_i,j from observed trajectories.
Source code in src/reach/metrics.py
confusion ¶
confusion(
results: Sequence[ProbeResult], queries: Sequence[Query]
) -> Counter[tuple[str, str | None]]
Count occurrences of expected-to-invoked skill selection pairs.
Source code in src/reach/metrics.py
consistency ¶
consistency(
results: Sequence[ProbeResult], queries: Sequence[Query]
) -> float
Calculate the fraction of queries with unanimous selection outcomes.
Source code in src/reach/metrics.py
consistency_counts ¶
consistency_counts(
results: Sequence[ProbeResult], queries: Sequence[Query]
) -> tuple[int, int]
Count unanimous and total observed queries across attempt replicates.
Source code in src/reach/metrics.py
decompose_pass_rate_drop ¶
decompose_pass_rate_drop(
baseline_results: Sequence[ProbeResult],
scaled_results: Sequence[ProbeResult],
queries: Sequence[Query] | None = None,
iterations: int = 2000,
seed: int = 42,
) -> DecompositionResult
Decompose overall pass-rate drop into context dilution versus skill shadowing components.
Source code in src/reach/metrics.py
labeled_pairs ¶
labeled_pairs(
results: Sequence[ProbeResult], queries: Sequence[Query]
) -> tuple[list[str], list[str]]
Extract aligned ground truth and predicted label sequences.
Source code in src/reach/metrics.py
score_trajectory ¶
score_trajectory(
query: Query, invoked_skills: Sequence[str]
) -> TrajectoryScore
Evaluate an observed skill trajectory against query target skill and acceptable skills.
Source code in src/reach/metrics.py
trajectory_scores ¶
trajectory_scores(
results: Sequence[ProbeResult], queries: Sequence[Query]
) -> dict[str, TrajectoryScore]
Return mapping of query_id to its aggregated TrajectoryScore across replicates.