Skip to content

response_match_score (ROUGE-1) is not effectively in Japanese (with manual tokenization) #4122

Closed

Description

@ftnext

Describe the bug
response_match_score uses rouge-score's English-oriented tokenizer.
Japanese text without whitespace is treated as a single token, so scores are incorrect.
Because we have no built-in Japanese tokenization, we had to manually pre-tokenize the Japanese input and pass it as space-separated text.
This is a workaround but there is a bug..

To Reproduce
Minimal example (using pre-tokenized Japanese as a workaround):

from google.adk.evaluation.final_response_match_v1 import _calculate_rouge_1_scores

candidate = "これ は テスト 候補 の 応答"
reference = "これ は テスト の 正解"
score = _calculate_rouge_1_scores(candidate, reference)
print(score)
Score(precision=0.0, recall=0.0, fmeasure=0.0)

Even in this case, the score depends on manual tokenization and does not reflect native Japanese text behavior.

Expected behavior
Japanese should be supported without requiring users to manually insert whitespace.
Ideally response_match_score should accept a tokenizer option or provide language-aware tokenization for ROUGE.

Score(precision=0.6666666666666666, recall=0.8, fmeasure=0.7272727272727272)

Desktop (please complete the following information):

  • OS: macOS
  • Python version(python -V): Python 3.13.8
  • ADK version(pip show google-adk): v1.22.0

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used(e.g. gemini-2.5-pro): N/A (offline metric)

Additional context

Activity

  1. added
    eval[Component] This issue is related to evaluation
    on Jan 12, 2026
  2. added theissue type on Jan 12, 2026
  3. added a commit that references this issue on Jan 13, 2026
    c00ef48
  4. maru0804 commented on Jan 13, 2026

    @maru0804
    Contributor

    I've submitted a PR (#4143) to fix this issue.

    The fix introduces a CJKTokenizer class that provides character-based tokenization for CJK languages. You can enable it by specifying RougeScoreCriterion(tokenizer='cjk') in your evaluation metric configuration.

    This allows ROUGE-1 scores to be calculated correctly for Chinese, Japanese, and Korean text.

  5. surajksharma07 commented on Jan 23, 2026

    @surajksharma07
    Collaborator

    @ftnext The ROUGE-1 scorer in final_response_match_v1.py:113 uses the default English tokenizer which splits on whitespace, causing Japanese text to be treated as a single token and returning 0.0 scores.

    PR #4143 addresses this by adding a CJK tokenizer option.

    Once merged, you can use RougeScoreCriterion(tokenizer='cjk') in your eval config for character-based tokenization.

    For now, you can apply the PR patch manually if this is blocking your work.

    Team is looking more into it.

    Thanks!

  6. added
    answered[Status] This issue has been answered by the maintainer
    on Jan 23, 2026
  7. surajksharma07 commented on Mar 26, 2026

    @surajksharma07
    Collaborator

    @ankursharmas Please have a look into it once.

  8. added
    needs review[Status] The PR/issue is awaiting review from the maintainer
    and removed
    answered[Status] This issue has been answered by the maintainer
    on Apr 16, 2026
  9. i-yliu commented on Jul 28, 2026

    @i-yliu
    Collaborator

    Hi @ftnext , thanks for raising the issue, we have merged PR #6292, it should resolve the issue with Japanese Characters in ROUGE-1

  10. ftnext commented on Jul 29, 2026

    @ftnext
    ContributorAuthor

    @i-yliu Thank you for working on this issue.

    I tested the implementation merged from #6292 against the original reproduction in this issue.
    Both the Japanese text without whitespace and the manually tokenized text produce the same character-level tokens and score:

    >>> from google.adk.evaluation.final_response_match_v1 import _calculate_rouge_1_scores
    >>> score = _calculate_rouge_1_scores("これ は テスト 候補 の 応答", "これ は テスト の 正解")
    >>> score
    Score(precision=0.6363636363636364, recall=0.7777777777777778, fmeasure=0.7000000000000001)
    
    >>> _calculate_rouge_1_scores("これはテスト候補の応答", "これはテストの正解")
    Score(precision=0.6363636363636364, recall=0.7777777777777778, fmeasure=0.7000000000000001)

    This confirms that #6292 fixes the problem where Japanese text always received a score of 0.0. Japanese text without whitespace can now be evaluated using character-level ROUGE-1.
    However, manually supplied word boundaries are not preserved. The whitespace-tokenized example from this issue is still split into individual characters instead of the supplied words. Therefore, it does not produce the expected word-level result:

    precision = 4 / 6 = 0.6666666666666666
    recall    = 4 / 5 = 0.8
    fmeasure  = 8 / 11 = 0.7272727272727272
    

    Also, there does not appear to be a public option for providing or selecting a tokenizer.

    Would it be possible to reopen this issue? I think #6292 resolves the “all Japanese scores are zero” problem, but it does not fully resolve the behavior reported here for manually pre-tokenized Japanese input.

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

Metadata

Metadata

Assignees

Labels

eval[Component] This issue is related to evaluationneeds review[Status] The PR/issue is awaiting review from the maintainer

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions