Files
siemens_ragas/docs/superpowers/specs/2026-07-01-chinese-judge-prompt-design.md
T

9.9 KiB
Raw Blame History

中文评判 Prompt 适配设计(judge_language: zh

日期: 2026-07-01 状态: 已批准,待实现 范围: 让 RAGAS 的 LLM 评判 prompt 从默认英文切换为中文,提升对中文语料的判定一致性(架构设计 §10.5)。通过场景 YAML 字段 judge_language: zh 和 score API 可选字段 judge_language 控制,默认 en 保持完全向后兼容。


1. 背景与目标

架构设计 §10.5 明确要求:

语料为中文,评判模型选多语言能力充分者即可。RAGAS 评判 prompt 默认英文,对中文语料应启用其语言适配,将评判 prompt 切换为中文以提升判定一致性。

当前 rag_eval/metrics/factory.pywebapp/services/inline_scorer.py 构建的 RAGAS ragas.metrics.collections 指标全部使用默认英文 instruction + examples。本设计新增中文评判能力:

  • 场景 YAML 新增 judge_language: zh(默认 en)。
  • score 系列 API/api/score/api/score/async/api/score/session_async)新增可选 judge_language 字段。
  • 采用 RAGAS 原生 BasePrompt.adapt() + 提交到仓库的持久化缓存文件,生产运行完全确定、零额外延迟。

成功标准

  • judge_language: zh 时,6 个 LLM 评判指标使用中文 prompt;semantic_similarity(纯 embedding)不受影响。
  • 默认 en 时,所有既有场景与 API 行为逐字节不变。
  • 单变量对比可行:同一数据集分别以 en / zh 各评一次,比较指标均值与方差。

2. 需要本地化的指标与 prompt(已从 RAGAS 0.4.3 源码核实)

每个 LLM 评判指标把 prompt 存为实例属性,可在构建后覆盖:

指标 prompt 实例属性
faithfulness statement_generator_prompt, nli_statement_prompt
answer_relevancy prompt
context_recall prompt
context_precision prompt
noise_sensitivity statement_prompt, faithfulness_prompt
factual_correctness prompt, nli_prompt
semantic_similarity 无(纯 embedding,跳过)

权威映射(写入 judge_prompts.py):

METRIC_PROMPT_ATTRS = {
    "faithfulness": ("statement_generator_prompt", "nli_statement_prompt"),
    "answer_relevancy": ("prompt",),
    "context_recall": ("prompt",),
    "context_precision": ("prompt",),
    "noise_sensitivity": ("statement_prompt", "faithfulness_prompt"),
    "factual_correctness": ("prompt", "nli_prompt"),
}

ragas.prompt.metrics.base_prompt.BasePrompt 提供原生 async adapt(target_language, llm, adapt_instruction=False):翻译 examplesadapt_instruction=True 时同时翻译 instruction,返回新 prompt 实例,并设置 language 属性。


3. 架构与数据流

[一次性] scripts/build_judge_prompt_cache.py --language zh
    对每个指标的每个 prompt 调 adapt("chinese", llm, adapt_instruction=True)
    → 写出 configs/judge_prompts/zh/<metric>__<attr>.json(提交入库)

[运行时·YAML 场景路径]
    runner → factory.build_metric_pipeline(scenario)
        若 scenario.judge_language == "zh":
            localize_pipeline_prompts(registry, "zh")

[运行时·score API 路径]
    /api/score, /api/score/async, /api/score/session_async
        → inline_scorer.score(..., judge_language=...)
            → _build_metric_instances(...)
                若 language == "zh": localize_pipeline_prompts(registry, "zh")

两条路径共用同一个本地化器,保持 DRY。


4. 组件

4.1 一次性引导脚本 scripts/build_judge_prompt_cache.py

  • 参数:--language zh--judge-model <model>(默认取 settings)。
  • METRIC_PROMPT_ATTRS 每个 (metric, attr):取活体 prompt 实例,await prompt.adapt("chinese", llm, adapt_instruction=True),序列化为 JSON。
  • adapt() 失败重试若干次;仍失败则整体中止、不写半成品。
  • 产物提交入库,评审后即为生产资产。

4.2 缓存文件 configs/judge_prompts/zh/<metric>__<attr>.json

(metric, prompt_attr) 命名,1:1 对应覆盖目标,零碰撞(多个指标各自独立生成,即使 prompt 类同名也互不影响)。

{
  "metric": "faithfulness",
  "prompt_attr": "nli_statement_prompt",
  "language": "chinese",
  "ragas_version": "0.4.3",
  "source_hash": "<英文 instruction + 序列化 examples 的 sha256>",
  "instruction": "……中文 instruction……",
  "examples": [ { "input": { }, "output": { } } ]
}

4.3 运行时本地化器 rag_eval/metrics/judge_prompts.py

公开函数:localize_pipeline_prompts(registry: dict[str, Any], language: str) -> LocalizationReport

  • language == "en" 或空 → 直接返回,不做任何事。
  • 对 registry 中每个已知指标的每个 prompt 属性:
    1. 从缓存目录读取对应 JSON内存缓存已解析结果,按 language 键,首次读盘后复用,保证 /api/score 高频调用零额外磁盘 IO)。
    2. 活体 prompt 实例的 input_model / output_model 从 JSON 重建 examples,覆盖 prompt.instructionprompt.examplesprompt.language
  • 返回 LocalizationReport(已应用 / 跳过 / 告警计数),供日志与测试断言。

4.4 配置面

  • rag_eval/settings.py:新增 ragas_judge_languageenv RAGAS_JUDGE_LANGUAGE,默认 en)作为唯一全局默认。
  • rag_eval/shared/models.pyScenario@dataclass)新增 judge_language: str = "en",存放已解析的最终值。
  • YAML 场景路径的解析在配置加载器rag_eval/config)完成:judge_language = YAML 显式值 or settings.ragas_judge_language;同时在此处校验值域 {en, zh}(与既有 metrics 校验同层,dataclass 本身不做校验)。因此 Scenario.judge_language 对 factory 而言是权威值。
  • webapp/models.pyScoreRequest 新增 judge_language: str | None = NoneSessionScoreRequest 继承自动获得);score API 路径解析 request.judge_language or settings.ragas_judge_language
  • 统一优先级(两条路径一致):显式值(YAML 字段 / 请求字段)> settings.ragas_judge_language(默认 en)。

4.5 集成点改动

  • rag_eval/metrics/factory.pybuild_metric_pipeline() 构建 registry 后,若 scenario.judge_language == "zh",调 localize_pipeline_prompts(registry, "zh")
  • webapp/services/inline_scorer.pyscore()_build_metric_instances() 增加 judge_language 参数;构建指标后按需本地化。(judge_model, embedding_model) 缓存仅缓存 llm/embeddings,指标每次重建,故每次正确应用本地化,缓存键无需变动。
  • webapp/api/score.pywebapp/services/score_job_manager.pywebapp/services/session_score_manager.py:把 request.judge_language(回退到 settings 默认)透传给 inline_scorer.score()

5. 错误处理与漂移检测

  • 运行时缺文件 / JSON 损坏 / examples 按当前 schema 重建失败 → 记 WARNING,保留该 prompt 的英文默认,绝不中断评分(优雅降级)。
  • judge_language: zh 但缓存整体缺失 → 告警一次,按英文继续。
  • 漂移检测:加载时用当前英文源计算 source_hash 与缓存值比对:
    • 不一致但 schema 仍有效 → 应用中文 + 记 loud WARNING「缓存已过期,请重新运行 build_judge_prompt_cache.py」。
    • schema 已失效(重建抛错)→ 自动回退英文。
  • 引导脚本 adapt 失败 → 重试后中止,不写半成品。

6. 测试(确定性,Mock LLM,遵循 AGENTS.md

新增 tests/test_judge_prompt_localizer.py

  • fixture 缓存文件正确覆盖 metric.<attr>.instruction.examplesexamples 按活体 model 重建成功)。
  • 缺文件 → 保留英文默认、不抛异常。
  • source_hash 不匹配 → 记告警仍应用中文;schema 失效 → 回退英文。
  • language == "en" → registry 完全不变。
  • 内存缓存:同一 language 第二次调用不再读盘(用可计数的假 loader 或 monkeypatch 断言)。

扩展/新增:

  • Scenario schemajudge_language 解析、默认 en、非法值报错。
  • ScoreRequestjudge_language 可选、默认 None
  • 引导脚本:mock LLMadapt 返回预置中文)→ 断言写出预期 JSON 结构与字段。

可选人工验证(非 CI:固定小样本集分别以 en / zh 各评一次,比较均值/方差,并复核已知正确样本(如 “MAGNETOM Vida 设备总重 7370 kg”)。


7. 改动文件清单

新增

  • rag_eval/metrics/judge_prompts.py — 本地化器(加载/覆盖/hash/内存缓存)
  • scripts/build_judge_prompt_cache.py — 一次性引导脚本
  • configs/judge_prompts/zh/*.json — 提交入库的中文 prompt 缓存
  • tests/test_judge_prompt_localizer.py — 测试

修改

  • rag_eval/shared/models.pyScenario.judge_language 字段(存已解析值)
  • rag_eval/configYAML 加载器)— 解析 judge_language = 显式值 or settings 默认,并校验值域
  • rag_eval/settings.pyragas_judge_language 默认
  • rag_eval/metrics/factory.pybuild_metric_pipeline 接入本地化
  • webapp/models.pyScoreRequest.judge_language
  • webapp/services/inline_scorer.pyscore()/_build_metric_instances() +参数+本地化
  • webapp/api/score.pywebapp/services/score_job_manager.pywebapp/services/session_score_manager.py — 透传 judge_language
  • 示例场景 YAML(如 scenarios/siemens_build/*、一个 offline 示例)— 增加 judge_language: zh
  • README.md — 简述机制与「如何重新生成缓存」

8. 兼容性与影响

  • 三个 score 接口默认(不传 judge_language)行为逐字节不变,现有 Dify Tool 调用零影响。
  • YAML 场景默认 judge_language: en,既有 run 结果口径不变。
  • 仅当显式 zh 时切换中文 prompt;可随时通过重跑脚本刷新缓存。