feat(tools): TraceIndex — progressive trace disclosure for judge-based evaluators - #343
Open
pdebjyot wants to merge 4 commits into
Open
feat(tools): TraceIndex — progressive trace disclosure for judge-based evaluators#343pdebjyot wants to merge 4 commits into
pdebjyot wants to merge 4 commits into
Conversation
… agents
Large agent trajectories overflow a judge model's context window when inlined
into the evaluation prompt, forcing Experiment error-isolation to record the
case as score:0 / test_pass:False — a false failure for a correct agent.
TraceIndex builds an in-memory index over a Session and exposes:
- overview(): one compact line per span (index, type, tool, sizes, preview)
that always fits the judge context, substituted for the full trajectory.
- three discovery tools the judge calls on demand: list_spans / get_span /
search_spans (mirrors MLflow's ListSpans/GetSpan/SearchTraceRegex).
get_span pages oversized spans via max_read_chars + offset so no single tool
return can itself overflow the judge. Backend-agnostic: consumes any Session
produced by a provider/mapper.
… TraceIndex Covers overview() formatting, list_spans/get_span/search_spans behavior, offset paging on oversized spans, and end-to-end use through OutputEvaluator with tools=index.tools.
Compares OutputEvaluator judging grounded vs fabricated claims two ways — full trajectory inlined vs overview + discovery tools — asserting the index-equipped judge separates grounded from fabricated where inline overflows. Skips without live Bedrock credentials.
pdebjyot
requested a deployment
to
manual-approval
August 3, 2026 18:43 — with
GitHub Actions
Waiting
pdebjyot
requested a deployment
to
manual-approval
August 3, 2026 18:43 — with
GitHub Actions
Waiting
Member
|
/strands review |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(tools): TraceIndex — progressive trace disclosure for judge-based evaluators
Branch:
feat/trace-indexBuilds on: #324 (custom
tools=onOutputEvaluator/TrajectoryEvaluator)Addresses: #342
Problem
When the trajectory handed to a judge-based evaluator is larger than the judge
model's context window, the judge call raises
ContextWindowOverflowException.Experiment._run_evaluatorcatches it under error isolation and records the caseas
score: 0, test_pass: False— indistinguishable from a genuine qualityfailure. A correct agent response gets a false-negative failing score purely
because its trace was too big for the judge to read.
This isn't a theoretical edge. We observe it on real production agent traces,
where routine multi-step sessions serialize past a 200K-token judge window and
the largest run into the millions of tokens — so under a default Sonnet-class
judge, correct agents are being silently scored as failures today. The problem
is stack-agnostic: we reproduced identical overflow behavior across
strands-evals, DeepEval, and a Langfuse-style managed judge on a shared Bedrock
judge model (three distinct error signatures, same trace-size cliff).
The measured evidence below is from a synthetic, deterministic, offline
benchmark — no real data — so it's independently reproducible.
What this PR adds
TraceIndex— an in-memory index over aSessionthat lets a judge read a largetrace without inlining it. It is an established pattern: MLflow's
Agent-as-a-Judge trace scorers hand the judge
ListSpans/GetSpan/SearchTraceRegex, and Zhuge et al.'s Agent-as-a-Judge(arXiv:2410.10934) uses
retrieve/read/locatemodules to pull only the relevant segments.overview()— one compact line per span (index, type, tool name, sizes,preview). Always fits the judge context; substituted for the full trajectory.
list_spans/get_span/search_spans— discovery tools the judgecalls on demand (mirrors the MLflow triad).
get_spanpages oversized spansvia
max_read_chars(default 8000) +offset, so no single tool return canitself overflow the judge.
Sessiona provider/mapper produces.Two disclosure strategies compose from these pieces: index (substitute
overview()into the prompt — portable, works with any judge) and explore(index + discovery tools via #324's
tools=— Strands-native, best accuracy).Evidence
Cross-framework matrix (1344 cells). 200-trace labeled corpus × 3 frameworks
(strands-evals, DeepEval, Langfuse-style) × 4 metrics (groundedness, accuracy,
trajectory, tool_use) × inline/index/explore, all bound to one shared Bedrock
judge. Each metric scored as a binary classifier against planted ground truth
(overflow ⇒ wrong prediction):
all three frameworks.
indexandexplorehold accuracy on traces that fit and recover it ontraces that overflow (inline is unusable in the overflow bucket; index/explore
score correctly).
exploretools beat a bare index when the decisive fact isburied in a large tool result: on
wrong_tooltraces the deciding refundamount sits inside a large search result that
overview()elides, so the indexjudge false-fails groundedness (0.83);
get_span/search_spanslet the judgeretrieve it → groundedness 1.00.
still works.
Ground-truth A/B (grounded / fabricated claims, evidence buried mid-trace):
the index-equipped judge separates grounded from fabricated where the inline
judge overflows — captured as the integ test
test_judge_reliability_inline_vs_explore.Known limitation (called out honestly)
TrajectoryEvaluatorinlinesactual_trajectoryunconditionally(
case_prompt_template.py:51), so the trajectory metric still overflows on largetraces even with the index — the substitution only reaches evaluators that route
through the caller-controlled
actual_output(the output-family metrics, fixedtoday). Making the trajectory metric disclosure-aware needs a template change and
is proposed as a follow-up; this PR does not change that path.
Separately, this PR adds the capability but does not change
_run_evaluator's error handling — distinguishing harness overflow from aquality
score: 0is tracked in #342 as an independent change.Testing
oversized spans; cross-pattern; end-to-end through
OutputEvaluatorwithtools=index.tools) — all pass.ruff check/ruff formatclean.Checklist