Skip to content

feat(scorers): align remote delegated scorer signatures with native comparators - #590

Open
saurabh-net wants to merge 10 commits into
mainfrom
feat/delegated-scoring-context
Open

feat(scorers): align remote delegated scorer signatures with native comparators#590
saurabh-net wants to merge 10 commits into
mainfrom
feat/delegated-scoring-context

Conversation

@saurabh-net

@saurabh-net saurabh-net commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Context & Problem

This PR refactors delegated remote scoring proxying to ensure strict protocol parity with EvalBench's native Comparator.compare(...) signature:

  1. Protocol Symmetry with Comparator.compare() return type:
    Native comparators return either a single score tuple (score, logs) or a list of sub-metric tuples [(metric_name, score, logs), ...]. We represent this in Protobuf using a clean oneof result:

    message SingleScore {
      float score = 1;
      string comparison_logs = 2;
    }
    
    message MetricScore {
      string metric_name = 1;
      float score = 2;
      string comparison_logs = 3;
    }
    
    message MultiScore {
      repeated MetricScore scores = 1;
    }
    
    message ScoringResponse {
      oneof result {
        SingleScore single_score = 1;
        MultiScore multi_score = 2;
      }
    }
  2. Direct Parameter Passing in ScoringContext:
    Parameters are mapped directly to ScoringContext fields (nl_prompt, golden_query, query_type, golden_result, golden_eval_results, golden_error, generated_query, generated_result, eval_results, generated_error, database). Parameter names in RemoteScorerProxy.compare are aligned with the Comparator base class (golden_query, generated_query), with backward-compatible keyword fallbacks for golden_sql / generated_sql, golden_execution_result / generated_execution_result, and golden_eval_result / generated_eval_result.

  3. Important Note on Runtime Types in EvalBench Runners:
    While Comparator.compare hints string types, EvalBench runners do not strictly enforce strings at runtime across all evaluation modes.
    Specifically, in agent evaluations (evalbench/work/agentscorework.py and trajectorymatcher.py):

    • generated_result is passed as a raw Python list (accumulated tool call records: ['tool_a', ...]).
    • eval_results is passed as a raw Python dict (self.eval_output).
    • generated_error is passed as None.

    Because Google Protobuf string fields require str or bytes and raise a TypeError if passed a list, dict, or None, RemoteScorerProxy defensively converts non-string inputs using a dedicated module-level _to_str helper (JSON-serializing lists and dicts, and mapping None to "") before packing them into ScoringContext. Remote scorers can parse these fields back with json.loads() when evaluating structured tool trajectories or turn outputs.

Changes

  • evalbench/evalproto/eval_agent.proto: Added SingleScore, MetricScore, MultiScore, and oneof result inside ScoringResponse. Updated ScoringContext with direct parameter fields.
  • evalbench/scorers/remote_scorer.py: Aligned parameter names with Comparator base class, added keyword aliases, unpacked SingleScore and MultiScore, and extracted defensive string coercion into a module-level _to_str helper.
  • evalbench/test/agent_grpc_proxy_test.py: Added tests for SingleScore, MultiScore, timeout, direct _to_str helper unit tests, and end-to-end verification of non-string runtime type coercion (test_remote_scorer_runtime_type_coercion).
  • evalbench/test/agent_grpc_proxy_integration_test.py: Verified multi-turn and concurrent sessions with delegated scoring.

Verification

  • pytest evalbench/test/agent_grpc_proxy_test.py evalbench/test/agent_grpc_proxy_integration_test.py (10 passed in 9.2s).
  • pycodestyle clean (0 errors).
  • Zero generated files tracked in diff.

Comment thread evalbench/scorers/remote_scorer.py Fixed
…omparators

Align the remote delegated scorer wire protocol and Python proxy with EvalBench's native in-process Comparator signature:
- Input parity: Pass full evaluation context (prompt, golden/generated outputs, eval results, database, scenario ID) via ScoringContext on ScoringRequest.
- Output parity: Return a flat repeated MetricScore list on ScoringResponse, allowing remote scorers to return either a single metric (score, logs) or multiple metrics [(metric_name, score, logs), ...].
- Add comprehensive unit tests for single-score, multi-score, and timeout handling.
@saurabh-net
saurabh-net force-pushed the feat/delegated-scoring-context branch from 541090e to 675963d Compare September 4, 2026 11:27
@prernakakkar-google

Copy link
Copy Markdown
Collaborator

/gcbrun

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