[NA] [SDK] fix: recover agentic LLM judge verdicts from prose-wrapped output#7402
Closed
alexkuzmik wants to merge 1 commit into
Closed
[NA] [SDK] fix: recover agentic LLM judge verdicts from prose-wrapped output#7402alexkuzmik wants to merge 1 commit into
alexkuzmik wants to merge 1 commit into
Conversation
… output The agentic LLM judge's final turn returns free-form content. OpenAI honors response_format strictly, but Anthropic (native and via LiteLLM) treats it as best-effort when tools are in the request: on a false verdict claude-haiku-4-5 narrates in prose and wraps the JSON in a ```json fence, sometimes preceded by a second JSON object (a quoted copy of the agent output). The parser's bare json.loads failed at char 0, so scoring_failed=True and temperature-0 retries reproduced the same prose — failing the agentic evaluation-metrics tests deterministically. - parsers.py: scan every embedded JSON object and return the first that validates against the schema, recovering a prose/fenced verdict and skipping the quoted agent-output block. Bare-JSON fast path unchanged. - agentic judge integration tests: run the Anthropic lanes against claude-sonnet-4-6 instead of claude-haiku-4-5; Sonnet follows the structured-output contract reliably. - add unit tests for prose+fence payloads and multi-object selection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
⏱️ pre-commit per-hook timing
⏭️ 36 skipped (no matching files changed)
|
alexkuzmik
marked this pull request as ready for review
July 8, 2026 14:08
Comment on lines
+36
to
+40
| index = 0 | ||
| while True: | ||
| start = content.find("{", index) | ||
| if start == -1: | ||
| return |
Contributor
There was a problem hiding this comment.
Duplicate JSON recovery logic
Lines 36-40 duplicate the brace-scanning JSONDecoder.raw_decode fallback already in sdks/python/src/opik/evaluation/metrics/llm_judges/parsing_helpers.py, so any tweak to prose/fenced-output recovery has to be made in two places — should we share that helper or move the loop into a common module?
Want Baz to fix this for you? Activate Fixer
alexkuzmik
marked this pull request as draft
July 8, 2026 14:53
Collaborator
Author
|
Superseded by #7405, which consolidates the Sonnet model switch (dropping the parser-leniency change per review) with the genai/adk matrix trim and removal of the broken genai rate-limit retry code. |
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.
Details
The agentic LLM judge's final turn returns free-form content. OpenAI honors
response_formatstrictly, but Anthropic (native and via LiteLLM) treats it as best-effort when tools are in the request — on a false verdictclaude-haiku-4-5narrates in prose and wraps the JSON in a```jsonfence, sometimes preceded by a second JSON object (a quoted copy of the agent output). The parser's barejson.loadsfailed at char 0, soscoring_failed=True, and temperature-0 retries reproduced the same prose — failing the agentic evaluation-metrics tests deterministically (test_false_assertion__fails[anthropic]and[litellm_anthropic]).parsers.py: scan every embedded JSON object and return the first that validates against the schema — recovers a prose/fenced verdict and skips the quoted agent-output block. The bare-JSON fast path (OpenAI / strict structured output) is unchanged.claude-sonnet-4-6instead ofclaude-haiku-4-5; Sonnet follows the structured-output contract reliably (the one-shot suite already used Sonnet).Change checklist
Issues
AI-WATERMARK
AI-WATERMARK: yes
Testing
Commands run from
sdks/python(project venv):python -m pytest tests/unit/evaluation/suite_evaluators/test_llm_judge_parsers.py→ 23 passed (20 existing + 3 new)python -m pytest tests/unit/evaluation/suite_evaluators/→ 213 passed, 2 skipped (no regressions)ruff check,ruff format --check, andmypyon the changed files → clean```jsonfence + a quoted agent-output object) throughResponseSchema.parse→ verdict recovered (scoring_failed=False,value=False).Not run locally: the two failing tests are library-integration tests that call real provider models (require
ANTHROPIC_API_KEY); they are validated by theevaluation_metrics_testsCI lane. Both fixes (tolerant parser + Sonnet) independently target that exact failure.Documentation
N/A — no user-facing or API changes.