Skip to content

[azure-ai-evaluation] DocumentRetrievalEvaluator fidelity sorts labels as strings; BLEU/GLEU/METEOR tokenize response and ground truth differently #49830

Closed as not planned

Description

  • Package: azure-ai-evaluation 1.18.10 (code unchanged on main at 8371069)
  • Python: 3.9, Linux

Two metric-correctness bugs in built-in evaluators. Both give wrong scores silently, without errors or warnings.

1. DocumentRetrievalEvaluator: Fidelity is wrong when ground_truth_label_max >= 10

_document_retrieval.py, _compute_fidelity → calculate_weighted_sum_by_rating:

label_counts = {str(i): 0 for i in range(s, self.ground_truth_label_max + 1)}
...
sorted_label_counts = [x[1] for x in sorted(label_counts.items(), key=lambda x: x[0])]
weights = [(math.pow(2, i + 1) - 1) for i in range(s, self.ground_truth_label_max + 1)]

The counts are keyed by str(label) and sorted as strings ("1", "10", "2", …), but the weights are in numeric order. When the scale goes up to 10 or more, counts are multiplied by the wrong weights. The default 0–4 scale is not affected.

Repro:

from azure.ai.evaluation import DocumentRetrievalEvaluator

e = DocumentRetrievalEvaluator(ground_truth_label_min=0, ground_truth_label_max=10)
gt = [{"document_id": "a", "query_relevance_label": 10},
      {"document_id": "b", "query_relevance_label": 2}]
ret = [{"document_id": "b", "relevance_score": 1.0}]
print(e(retrieval_ground_truth=gt, retrieved_documents=ret)["document_retrieval_properties"]["fidelity"])
# 0.6818..., and fidelity_result is "pass"

Only the low-relevance document was retrieved, so the expected Fidelity is (2³−1) / ((2¹¹−1) + (2³−1)) ≈ 0.0034. The evaluator reports 0.68 and marks it as passing the 0.5 threshold.

Fix: key the counts by int (or index a list by label - s) so counts and weights stay in the same order.

2. BLEU / GLEU / METEOR: the tokenizer is chosen separately for the response and the ground truth

_common/utils.py, nltk_tokenize:

if not text.isascii():
    tokens = NISTTokenizer().international_tokenize(text)
else:
    tokens = nltk.word_tokenize(text)

_bleu.py, _gleu.py and _meteor.py call this once for the ground truth and once for the response. If only one side contains a single non-ASCII character (a curly quote, an em dash, "café"), the two sides are tokenized differently, and ordinary words stop matching:

from azure.ai.evaluation import BleuScoreEvaluator
from azure.ai.evaluation._common.utils import nltk_tokenize

ref = "The U.S. economy didn't grow; prices rose 5.00 percent in March."
b = BleuScoreEvaluator()
b(response=ref, ground_truth=ref)["bleu_score"]          # 1.0
b(response=ref + " —", ground_truth=ref)["bleu_score"]   # 0.446
b(response=ref + " -", ground_truth=ref)["bleu_score"]   # 0.925 (ASCII hyphen, for comparison)

nltk_tokenize(ref)         # ['The', 'U.S.', 'economy', 'did', "n't", ...]
nltk_tokenize(ref + " —")  # ['The', 'U', '.', 'S', '.', 'economy', 'didn', "'", 't', ...]

LLM responses often contain typographic quotes and dashes while references are plain ASCII, so this can move scores a lot on real data.

Fix: pick one tokenizer per (response, ground truth) pair, for example the international tokenizer if either text is non-ASCII, and use it for both sides. Add a unit test where only one side has a non-ASCII character.

I'm happy to send a PR with fixes and tests for both if that's welcome.

Activity

  1. github-actions commented on Nov 4, 2026

    @github-actions
    Contributor

    Thank you for your feedback. Tagging and routing to the team member(s) best able to assist.

    //cc: Hanchi Wang (@luigiw) Neehar Duvvuri (@needuv) Ankit Singhal (@singankit)

  2. added
    questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that
    Service AttentionWorkflow: This issue is responsible by Azure service team.
    ClientThis issue points to a problem in the data-plane of the library.
    customer-reportedIssues that are reported by GitHub users external to the Azure organization.
    needs-team-attentionWorkflow: This issue needs attention from Azure service team or SDK team
    EvaluationIssues related to the client library for Azure AI Evaluation
    on Nov 4, 2026
  3. github-actions commented on Nov 4, 2026

    @github-actions
    Contributor

    🎯 Agentic Issue Triage

    Summary: Two silent metric-correctness bugs in azure-ai-evaluation built-in evaluators: DocumentRetrievalEvaluator fidelity miscomputes when ground_truth_label_max >= 10 due to lexicographic (string) sorting of integer label keys, and the BLEU/GLEU/METEOR tokenizer in _common/utils.py can pick different tokenization strategies for the response vs. ground truth when only one side contains a non-ASCII character.

    📋 Issue Details

    Package: azure-ai-evaluation 1.18.10 (confirmed unchanged on main at commit 8371069)
    Affected API: DocumentRetrievalEvaluator._compute_fidelity / calculate_weighted_sum_by_rating (_document_retrieval.py); nltk_tokenize (_common/utils.py) used by BleuScoreEvaluator, GleuScoreEvaluator, MeteorScoreEvaluator
    Scenarios:

    • Fidelity scoring with a ground_truth_label_max >= 10 scale produces a wrong weighted sum because label counts are keyed by str(label) and sorted as strings ("1", "10", "2", ...) while weights are generated in numeric order, misaligning counts to weights.
    • BLEU/GLEU/METEOR scores diverge unexpectedly when response and ground truth differ only by presence of a single non-ASCII character (e.g., a typographic dash or curly quote), because nltk_tokenize chooses the NIST international tokenizer vs. nltk.word_tokenize independently per string, producing incompatible token boundaries for otherwise-identical ASCII text.

    Root ask: Fix both correctness bugs (keying counts by int/index instead of string-sorted keys; selecting a single shared tokenizer per response/ground-truth pair based on whether either side is non-ASCII) and add regression tests. Author has offered to submit a PR.

    🔎 Debugging / Reproduction Notes

    Both repros in the issue are self-contained and appear logically sound based on reading the referenced source snippets (not independently executed in this triage pass):

    • Fidelity repro shows 0.68 reported vs. an expected ≈0.0034, with fidelity_result incorrectly marked "pass" against the 0.5 threshold — a false negative on a real quality signal.
    • Tokenizer repro shows bleu_score dropping from 1.0 to 0.446 when an em dash is appended to only one side, versus 0.925 for an ASCII hyphen, demonstrating the asymmetry is specific to the non-ASCII branch selection.

    No related open issues were found for either specific bug via search.

    Suggested investigation steps:

    1. Reproduce both snippets against current main to confirm the described behavior before merging a fix.
    2. For the fidelity bug, verify the fix (indexing by label - s or using int keys) against scales both below and at/above 10 to avoid regressing the default 0–4 scale.
    3. For the tokenizer bug, add a unit test with asymmetric non-ASCII content (one side only) across BLEU, GLEU, and METEOR evaluators to confirm consistent tokenizer selection for both sides.
    🏷️ Label Confidence
    • Category: Client — azure-ai-evaluation is a data-plane client package (not azure-mgmt-*).
    • Service: Evaluation — issue explicitly references the azure-ai-evaluation package and files under /sdk/evaluation/.
    • Confidence: High — the issue unambiguously names the package, file paths, and class/function names involved, with no overlap with other services.
    👥 Owner Routing
    • Matched CODEOWNERS entry: # ServiceLabel: %Evaluation (line 257) — exact match scanning bottom-to-top for the predicted service label "Evaluation".
    • AzureSdkOwners: none listed
    • ServiceOwners: @luigiw, @needuv, @singankit
    • Routing action: Added "Service Attention" and "needs-team-attention" labels; left unassigned; pinged ServiceOwners via routing comment.
    • Scan notes: No other # ServiceLabel: entries for "Evaluation" were encountered; this was the first and only match found scanning upward from the end of CODEOWNERS.

    Generated by Agentic Triage for #49830 · copilot · sonnet50 · 37.6 AIC · ⌖ 0.651 AIC · ⊞ 5K · ◷

  4. 14H034160212 commented on Nov 6, 2026

    @14H034160212
    Author

    Duplicate of #49829 (opened twice by mistake).

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    ClientThis issue points to a problem in the data-plane of the library.EvaluationIssues related to the client library for Azure AI EvaluationService AttentionWorkflow: This issue is responsible by Azure service team.customer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-team-attentionWorkflow: This issue needs attention from Azure service team or SDK teamquestionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions