Repository navigation
Fix the eval suite so it measures something, and add the missing runner - #13
Open
ericjohanson-langchain wants to merge 1 commit into
Open
ericjohanson-langchain wants to merge 1 commit into
ericjohanson-langchain wants to merge 1 commit into
Conversation
Two of the three evaluators were decoupled from agent behaviour, and nothing
caught it because no runner existed: the suite had never been executed. Fed a
simulated perfect agent whose outputs were byte-identical to ground truth,
severity_accuracy scored 0.000 across all 31 examples and tool_coverage scored
1.000. Fed a deliberately wrong agent, tool_coverage still scored 1.000.
severity_accuracy matched only bracketed markers like [CRITICAL]. The dataset
writes "CRITICAL: ...". Neither side extracted, so it returned 0 every time. It
now reads the typed overall_severity from a HealthReport when present and accepts
bracketed, colon-suffixed, and bare leading forms otherwise, which covers both the
bounded path and the orchestrator. Missing reference is now unscored rather than
scored zero, so a gap in the dataset stops looking like an agent failure.
tool_coverage read expected_trajectory from both sides, a key the dataset never
defines, so it short-circuited to 1.0 unconditionally. It now reads tools_called
from the run and expected_tools from the dataset.
response_quality could not execute at all. It built ChatOpenAI(gpt-4o-mini) while
langchain-openai was absent from requirements.txt and OPENAI_API_KEY was
configured nowhere, then annotated the result as a Pydantic model and subscripted
it as a dict. The judge is now Anthropic Haiku, which this repo already has a
credential for, so no second provider and no second key.
The output contract every evaluator depends on is now documented at the top of
evaluators.py, since reading the agent's output under the ground-truth field name
expected_response is what caused two of these defects.
Online evaluators were a separate problem. They ran as hand-copied reference-based
functions against production traces, which carry no ground-truth example, so they
compared "" against "" and recorded a constant 0 and a constant 1.0 on every live
run. Constant scores are worse than none because they look like data. Only
reference-free evaluators are uploaded now, and their source is read from
evaluators.py via inspect.getsource rather than maintained as a second copy.
Verified the generated source executes in an empty namespace with no repo imports,
which is what the sandbox gives it.
Two reference-free evaluators, both grounded in failures this agent actually
shipped. deferred_work catches a report that hands the question back to the
operator ("check pod CPU/memory metrics"), which is what the missing utilization
data produced for weeks. finding_specificity measures whether findings name a
concrete object, which also gates whether they can be fingerprinted at all.
Adds evals/run_eval.py with --dry-run and --limit. Its docstring records a real
limitation: the dataset describes fictional resources, so the agent's read tools
return not-found and response_quality measures diagnosis built on failed lookups.
Treat that metric as a floor until the tools are stubbed to return the scenario's
implied state.
25 tests on the evaluators themselves, including one asserting no reference-based
evaluator returns the same score for a good and a bad agent. That is the ten-line
check that would have caught all of this. 189 passing overall.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Two of the three evaluators were decoupled from agent behaviour. Nothing caught it because no runner existed — the suite had never been executed.
Fed a simulated perfect agent, outputs byte-identical to ground truth:
Fed a deliberately wrong agent,
tool_coveragestill returned1.000.What was broken
severity_accuracy[CRITICAL]; the dataset writesCRITICAL:. Neither side extracted, returned 0 every timetool_coverageexpected_trajectory, a key the dataset never defines. Short-circuited to 1.0 unconditionallyresponse_qualityChatOpenAI(gpt-4o-mini)withlangchain-openaiabsent from requirements andOPENAI_API_KEYconfigured nowhere; also annotated a Pydantic model then subscripted it as a dictseverity_accuracynow reads the typedoverall_severitywhen aHealthReportis present and accepts bracketed, colon-suffixed, and bare leading forms otherwise, covering both code paths. A missing reference is now unscored rather than zero, so a gap in the dataset stops looking like an agent failure. The judge moved to Anthropic Haiku — this repo already has that credential, so no second provider and no second key.The output contract is now documented at the top of
evaluators.py, since reading the agent output under the ground-truth field nameexpected_responseis exactly what caused two of these defects.Online evaluators were a separate problem
They ran as hand-copied reference-based functions against production traces, which carry no ground-truth example. So they compared
""against""and recorded a constantseverity_accuracy: 0andtool_coverage: 1.0on every live run. Reference-based metrics are structurally unable to work online.Now only reference-free evaluators upload, and their source comes from
evaluators.pyviainspect.getsourcerather than a second hand-maintained copy. Verified the generated source executes in an empty namespace with no repo imports, which is all the sandbox provides.Two reference-free evaluators, both grounded in failures this agent actually shipped:
deferred_work— catches a report handing the question back to the operator ("check pod CPU/memory metrics"), which is what the missing utilization data produced for weeksfinding_specificity— whether findings name a concrete object, which also gates whether they can be fingerprinted at allKnown limitation, recorded in the runner
The dataset describes fictional resources, so the agent read tools return not-found.
tool_coveragemeasures tool selection honestly;response_qualityis grading diagnosis built on failed lookups and will read lower than the agent deserves. Treat it as a floor until the tools are stubbed to return each scenario's implied state. That is the next obvious improvement to this dataset.Tests
25 on the evaluators themselves, including one asserting no reference-based evaluator returns the same score for a good and a bad agent. That ten-line check would have caught every defect above the day it was written. 189 passing overall.
Still blocked
run_eval.pyand the uploader both needLANGSMITH_API_KEY.LANGSMITH_RUNS_ENDPOINTScarries keys for trace export only; the dataset client does not consult it. Both scripts now fail with that explanation rather than a generic auth error.