Skip to content

fix(evaluation): exclude thought parts from text extraction across criteria - #7117

Open
james-auror wants to merge 1 commit into
google:mainfrom
james-auror:fix-eval-thoughts
Open

james-auror wants to merge 1 commit into
google:mainfrom
james-auror:fix-eval-thoughts

Conversation

@james-auror

Copy link
Copy Markdown

Overview

Every text-extraction site in evaluation/ filtered parts with if part.text, which was equivalent to "visible model output" before thinking models became routine. It no longer is: parts marked thought=True are text parts, so agent reasoning leaks into ROUGE scoring, judge prompts, and hallucination grounding checks. In hallucinations_v1, each thought part became its own evaluation step, so an agent's private reasoning was checked for grounding against tool outputs as if it were a claim made to the user.

This generalizes the fix in #7091 (credit to @MrCapricornLiu for the diagnosis and regression-test approach) from final_response_match_v1 alone to every criterion that extracts text from Content.

Changes

  • Adds get_text_parts() alongside the existing get_text_from_content() in llm_as_judge_utils.py as the shared, thought-filtering source of truth for text extraction.
  • Routes every criterion through it:
    • final_response_match_v1, vertex_ai_eval_facade, and agent_evaluator each had a private copy of the same unfiltered extraction body — these now delegate to get_text_from_content().
    • hallucinations_v1 and rubric_based_multi_turn_trajectory_evaluator had inline extraction at five call sites — these now call get_text_parts() directly.
    • final_response_match_v2, rubric_based_final_response_quality_v1, rubric_based_tool_use_quality_v1, and rubric_based_evaluator already routed through the shared helper, so they're fixed by the helper change alone.
  • Adds a regression test per affected criterion asserting thought text is absent from the resulting score, prompt, or dialogue string.

🤖 Generated with Claude Code

…iteria

Every text-extraction site in evaluation/ filtered on `if part.text`, which
was equivalent to visible model output before thinking models became
routine. It no longer is: parts marked `thought=True` are text parts, so
agent reasoning leaked into scoring, judge prompts, and hallucination
grounding checks.

Adds get_text_parts() alongside the existing get_text_from_content() in
llm_as_judge_utils.py as the single source of truth, both now excluding
thought parts. Routes every criterion through it: three private copies of
the same unfiltered body (final_response_match_v1, vertex_ai_eval_facade,
agent_evaluator) now delegate to it, and five inline extraction sites
(hallucinations_v1, rubric_based_multi_turn_trajectory_evaluator) call the
new helper directly.

hallucinations_v1 was the worst affected: each thought part became its own
EvaluationStep, so an agent's private reasoning was checked for grounding
against tool outputs as if it were a claim made to the user.

Generalizes the fix from google#7091, which covered
final_response_match_v1 alone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@google-cla

google-cla Bot commented Sep 14, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@james-auror

Copy link
Copy Markdown
Author

I am working with our legal team to get the CLA signed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants