120 lines
4.5 KiB
Python
120 lines
4.5 KiB
Python
"""Tests that the factory and inline scorer invoke the localizer per language."""
|
|||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
from unittest.mock import MagicMock, patch
|
||
|
|
|
||
|
|
import rag_eval.metrics.factory as factory_mod
|
||
|
|
import webapp.services.inline_scorer as inline_mod
|
||
|
|
|
||
|
|
|
||
|
|
def test_build_pipeline_localizes_when_zh(monkeypatch):
|
||
|
|
"""build_metric_pipeline calls localize_pipeline_prompts with 'zh'."""
|
||
|
|
calls = []
|
||
|
|
monkeypatch.setattr(factory_mod, "localize_pipeline_prompts",
|
||
|
|
lambda registry, language: calls.append(language))
|
||
|
|
|
||
|
|
from rag_eval.shared.models import DatasetConfig, Scenario
|
||
|
|
from rag_eval.settings import EvaluationSettings
|
||
|
|
from ragas.llms.base import InstructorBaseRagasLLM
|
||
|
|
from ragas.embeddings.base import BaseRagasEmbedding
|
||
|
|
|
||
|
|
scenario = Scenario(
|
||
|
|
scenario_name="t", mode="offline",
|
||
|
|
dataset=DatasetConfig(path=Path("x.csv")),
|
||
|
|
judge_model="gpt-5", embedding_model="text-embedding-3-small",
|
||
|
|
metrics=["faithfulness"], output_dir=Path("out"),
|
||
|
|
judge_language="zh",
|
||
|
|
)
|
||
|
|
factory_mod.build_metric_pipeline(
|
||
|
|
scenario, EvaluationSettings(_env_file=None),
|
||
|
|
llm=MagicMock(spec=InstructorBaseRagasLLM),
|
||
|
|
embeddings=MagicMock(spec=BaseRagasEmbedding),
|
||
|
|
)
|
||
|
|
assert calls == ["zh"]
|
||
|
|
|
||
|
|
|
||
|
|
def test_build_pipeline_falls_back_to_settings_default(monkeypatch):
|
||
|
|
"""When scenario.judge_language is None, settings.ragas_judge_language is used."""
|
||
|
|
calls = []
|
||
|
|
monkeypatch.setattr(factory_mod, "localize_pipeline_prompts",
|
||
|
|
lambda registry, language: calls.append(language))
|
||
|
|
|
||
|
|
from rag_eval.shared.models import DatasetConfig, Scenario
|
||
|
|
from rag_eval.settings import EvaluationSettings
|
||
|
|
from ragas.llms.base import InstructorBaseRagasLLM
|
||
|
|
from ragas.embeddings.base import BaseRagasEmbedding
|
||
|
|
|
||
|
|
scenario = Scenario(
|
||
|
|
scenario_name="t", mode="offline",
|
||
|
|
dataset=DatasetConfig(path=Path("x.csv")),
|
||
|
|
judge_model="gpt-5", embedding_model="text-embedding-3-small",
|
||
|
|
metrics=["faithfulness"], output_dir=Path("out"),
|
||
|
|
judge_language=None,
|
||
|
|
)
|
||
|
|
settings = EvaluationSettings(_env_file=None)
|
||
|
|
settings.ragas_judge_language = "zh"
|
||
|
|
factory_mod.build_metric_pipeline(
|
||
|
|
scenario, settings,
|
||
|
|
llm=MagicMock(spec=InstructorBaseRagasLLM),
|
||
|
|
embeddings=MagicMock(spec=BaseRagasEmbedding),
|
||
|
|
)
|
||
|
|
assert calls == ["zh"]
|
||
|
|
|
||
|
|
|
||
|
|
def test_build_pipeline_en_is_noop(monkeypatch):
|
||
|
|
"""Default language 'en' still calls localize (which is a no-op inside)."""
|
||
|
|
calls = []
|
||
|
|
monkeypatch.setattr(factory_mod, "localize_pipeline_prompts",
|
||
|
|
lambda registry, language: calls.append(language))
|
||
|
|
|
||
|
|
from rag_eval.shared.models import DatasetConfig, Scenario
|
||
|
|
from rag_eval.settings import EvaluationSettings
|
||
|
|
from ragas.llms.base import InstructorBaseRagasLLM
|
||
|
|
from ragas.embeddings.base import BaseRagasEmbedding
|
||
|
|
|
||
|
|
scenario = Scenario(
|
||
|
|
scenario_name="t", mode="offline",
|
||
|
|
dataset=DatasetConfig(path=Path("x.csv")),
|
||
|
|
judge_model="gpt-5", embedding_model="text-embedding-3-small",
|
||
|
|
metrics=["faithfulness"], output_dir=Path("out"),
|
||
|
|
)
|
||
|
|
factory_mod.build_metric_pipeline(
|
||
|
|
scenario, EvaluationSettings(_env_file=None),
|
||
|
|
llm=MagicMock(spec=InstructorBaseRagasLLM),
|
||
|
|
embeddings=MagicMock(spec=BaseRagasEmbedding),
|
||
|
|
)
|
||
|
|
assert calls == ["en"]
|
||
|
|
|
||
|
|
|
||
|
|
def test_inline_score_threads_judge_language(monkeypatch):
|
||
|
|
"""InlineScorer.score forwards judge_language to _build_metric_instances."""
|
||
|
|
seen: dict = {}
|
||
|
|
|
||
|
|
def fake_build_instances(metrics, llm, embeddings, judge_language="en"):
|
||
|
|
seen["lang"] = judge_language
|
||
|
|
return {}
|
||
|
|
|
||
|
|
monkeypatch.setattr(inline_mod, "_build_metric_instances", fake_build_instances)
|
||
|
|
monkeypatch.setattr(inline_mod.InlineScorer, "_get_models",
|
||
|
|
lambda self, j, e, s: (object(), object()))
|
||
|
|
|
||
|
|
class _FakePipeline:
|
||
|
|
def __init__(self, *a, **k):
|
||
|
|
pass
|
||
|
|
|
||
|
|
async def score_sample(self, sample):
|
||
|
|
return _FakeResult()
|
||
|
|
|
||
|
|
class _FakeResult:
|
||
|
|
metrics: dict = {}
|
||
|
|
|
||
|
|
import asyncio
|
||
|
|
monkeypatch.setattr(inline_mod, "MetricPipeline", _FakePipeline)
|
||
|
|
monkeypatch.setattr(asyncio, "run", lambda coro: _FakeResult())
|
||
|
|
|
||
|
|
scorer = inline_mod.InlineScorer()
|
||
|
|
scorer.score(question="q", answer="a", contexts=[], ground_truth=None,
|
||
|
|
metrics=["faithfulness"], judge_model="gpt-5",
|
||
|
|
embedding_model="e", settings=MagicMock(), judge_language="zh")
|
||
|
|
assert seen.get("lang") == "zh"
|