| name | e2e-quality |
| description | Compare e2e captured translations against the baoyu-translate skill ground truth (tests/reference/article-zh-CN-<mode>/translation.md) for all three translation modes, computing both cheap metrics (character jaccard, Chinese 2-gram overlap, paragraph drift) and Claude judge scores across 5 dimensions (accuracy, terminology consistency, cultural annotation, fluency, faithfulness). Writes tests/e2e-out/<ts-sha>/quality.md. Use only after /e2e-diagnostician returns verdict=PASS — when the gate fails, this skill must not run. Triggers on /e2e-quality, "run quality", "compare translations", "judge e2e quality", or after a successful /e2e-diagnostician run. |
e2e-quality
Slice 7 of PRD #26 (Part A). 仅在 e2e-diagnostician verdict=PASS
后被调用 —— gate 失败时本 skill 不执行(由上游 orchestrator 把控)。
读三模式 captured.md vs tests/reference/article-zh-CN-<mode>/translation.md,
跑两类指标:
- cheap 指标:脚本可生成,不调 LLM —— 字符级 jaccard、中文 2-gram 重合度、
段落数偏差。给定量参考。
- judge 指标:Claude 在本 session 内以独立 vendor 身份(避免与翻译 model
自身认同)对 3 模式 × 2 输入(captured + reference)做 5 维评分 —— 准确性 /
术语一致 / 文化注释 / 通顺 / 忠实。给定性结论。
输出 tests/e2e-out/<ts-sha>/quality.md,供 e2e-reporter 汇总。
调用前提
tests/e2e-out/<ts-sha>/diagnosis.md 存在。
diagnosis.md 顶端 verdict: PASS 行被 grep 到。
- 三模式子目录下
captured.md / status.md / console.jsonl 存在
(与 e2e-diagnostician C0 共享前提;若此处发现缺失,说明 runner /
diagnostician 产物异常,应 STOP 并提示重跑,而非强行猜 reference)。
任一前提不满足 → 立即停止,不要试图补跑或自行生成产物。 报
"Quality precondition failed: ",由用户决定是否回退到
runner / diagnostician。
输入契约
tests/e2e-out/<ts-sha>/
├── article-zh-CN-quick/
│ └── captured.md # runner 写入的注入译文集合
├── article-zh-CN-normal/
│ └── captured.md
├── article-zh-CN-refined/
│ └── captured.md
├── diagnosis.md # verdict: PASS 行必须存在
└── (e2e-report.md? # 来自 runner 的占位,本 skill 不读)
tests/reference/article-zh-CN-<mode>/translation.md —— ground truth,
与 tests/reference/article.md (原文)配套。
段落计数方式
captured.md 在 paragraph_count: 行明确给出;translation.md 用
awk 'NF>0' <file> | wc -l 算非空行(忽略标题行 # article-zh-CN-...、
captured_at: 等元数据行)。与 e2e-diagnostician C4 计数方式一致
(避免两个 agent 报不同数)。
输出契约
tests/e2e-out/<ts-sha>/
├── diagnosis.md
├── quality.md # 本 skill 写
└── e2e-report.md # 由 e2e-reporter 写
quality.md 不覆盖诊断报告,只补翻译质量层评估;最终汇总留给
e2e-reporter。
Cheap 指标(脚本可生成)
每一模式各算 3 个数值,合入 quality.md 的表格。所有计算用 GNU coreutils
1. 字符级 Jaccard
captured 与 reference 的中文字符集合的交集 / 并集。过滤掉 ASCII
(数字、英文、标点)避免链接 / 路径污染:
import re
def zh_chars(text: str) -> set[str]:
return set(re.findall(r'[一-鿿]', text))
captured = zh_chars(open('captured.md').read())
reference = zh_chars(open('reference/translation.md').read())
jaccard = len(captured & reference) / len(captured | reference)
报告 0.0–1.0,保留 3 位小数。不设硬阈值 —— 翻译改写是 LLM 的本职,
字符完全相等反而意味着直译;e2e-reporter 据此定性。
2. 中文 2-gram 重合度
captured 与 reference 的中文 2-gram (连续 2 字) 集合的 Jaccard:
def zh_2grams(text: str) -> set[str]:
chars = re.findall(r'[一-鿿]', text)
return {''.join(pair) for pair in zip(chars, chars[1:])}
captured = zh_2grams(open('captured.md').read())
reference = zh_2grams(open('reference/translation.md').read())
overlap = len(captured & reference) / len(captured | reference)
报告 0.0–1.0,保留 3 位小数。比 1-gram 更能反映"用词风格是否对齐"。
3. 段落数偏差
captured_count = captured.md 头 paragraph_count: 行的整数;
reference_count = translation.md 非空行数;drift_pct = (captured / reference) × 100,保留 1 位小数。
drift_pct 应在 70–130%(与 e2e-diagnostician C4 阈值一致)。
注:cheap 指标在这里重复 C4 检出的偏差 —— 目的不同:
- C4 是 gate 判定(
e2e-diagnostician 用以决定 PASS/FAIL)。
- 这里把同一数值摆进质量报告,供
e2e-reporter 报告里"段落数 vs reference
接近度"一栏引用。
Judge 指标(Claude 5 维评分)
cheap 指标只能反映"表面相似"。翻译改写/术语选择/通顺度需要 LLM 判定。
PRD #26 §4.2 锁定:由 Claude 在本 session 内以独立 vendor 身份跑,5 维评分。
为什么是 Claude 而非翻译 model 自身
避免 self-affinity bias —— 让翻译 model 评自己的译文会系统性偏松。
ADR-0003 §4.2 明确:不新加 API key,直接用 Claude Code session 内的
推理能力(无需 fetch / 无需 token)。
评分维度
| 维度 | 含义 | 1 分代表 | 5 分代表 |
|---|
| 准确性 (accuracy) | 事实/数据/逻辑与原文是否一致 | 多处事实错 | 全部一致 |
| 术语一致 (terminology) | 关键术语全文是否统一翻译 | 同一术语多次翻法不一 | 全文统一,首现标注原文 |
| 文化注释 (cultural-notes) | 对中文读者陌生的概念是否加注 | 完全无注释 | 注释到位且简练 |
| 通顺 (fluency) | 是否像母语者写的中文 | 翻译腔重,逐句直译 | 自然流畅,无翻译腔 |
| 忠实 (faithfulness) | 是否贴近原文风格 / 修辞 / 语气 | 大幅改写脱离原文 | 保留原文幽默/自嘲/口语化 |
每维度 1–5 整数分。5 维总分 = 25 满分,每模式分别打。
执行范式
每次评分 = 1 个模式:把 captured.md 与 translation.md 一起作为输入,
judge 给 captured 打 5 维分(reference 作为对照基准,自身不独立打分)。
3 模式各打 1 次,共 3 次评分调用。每次评分 prompt 包含:
- 原文片段:
tests/reference/article.md 完整内容(可截取关键段)。
- 待评译文:
captured.md 或 translation.md 完整内容。
- 评分维度说明:上表 + 1/5 分锚点 + 0.5 步长(允许 4.5 这种)。
- 格式契约:返回 JSON
{"accuracy": 4.5, "terminology": 5, "culturalNotes": 4, "fluency": 5, "faithfulness": 4, "rationale": "..."}
便于解析。rationale 1-2 句点出关键观察。
Claude 作为 judge 的内部 prompt 模板见本文末尾 §Judge prompt template
(避免在 SKILL.md 内嵌过长 prompt)。
Judge 输入边界
- 不做端到端重译对照(那是评审,本 skill 是评分)。
- 不做长篇 critique(每维 1-2 句 rationale,详细诊断留给 e2e-diagnostician
的 finding 机制)。
- 不调翻译 model 自身作 judge(避免 self-affinity)。
quality.md shape
# e2e quality — <ts-sha>
generated_at: <ISO timestamp>
source_article: tests/reference/article.md
ground_truth_dir: tests/reference/article-zh-CN-{quick,normal,refined}
verdict: <PASS|REVIEW> # PASS = 3 模式总分均 >= 18/25;REVIEW = 至少 1 模式 < 18 或任一维度 <= 2
# 不阻断 e2e,只作 e2e-reporter 摘要
## Cheap metrics
| mode | jaccard (char) | 2-gram overlap | paragraph drift (captured / reference) |
|---------|----------------|----------------|----------------------------------------|
| quick | 0.342 | 0.187 | 75 / 75 (100.0%) |
| normal | 0.401 | 0.234 | 78 / 75 (104.0%) |
| refined | 0.456 | 0.298 | 84 / 84 (100.0%) |
## Judge scores (5-dim, 1-5 each, total / 25)
| mode | accuracy | terminology | cultural-notes | fluency | faithfulness | total |
|---------|----------|-------------|----------------|---------|--------------|-------|
| quick | 4.0 | 4.5 | 3.0 | 4.5 | 4.0 | 20.0 |
| normal | 4.5 | 5.0 | 4.0 | 4.5 | 4.5 | 22.5 |
| refined | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 | 25.0 |
## Per-mode rationale (摘录自 judge)
### quick
- accuracy 4.0: 数据点 "2,000 calories a day" 漏掉单位
- terminology 4.5: "Deliveroo" 首次出现加注"(英国外卖平台)",后续保持;但 "Ocado" 首次未加注
- cultural-notes 3.0: 多处英国本土品牌/概念未加注
- fluency 4.5: 整体自然,偶有长句可断
- faithfulness 4.0: "I didn't have any reason to ever leave the house" 略直译,口吻可更口语
### normal
...
### refined
...
## Recommendations (供 e2e-reporter 摘要用)
- quick 模式:术语注释覆盖度需改进(建议 EXTEND.md 加 audience=general 时
必加注释规则)
- normal 模式:整体可发布,小修即可
- refined 模式:对得上 baoyu-translate skill 标准译文质量
## Next step
调用 `/e2e-reporter` 汇总 `diagnosis.md` + `quality.md` → 最终 `e2e-report.md`。
verdict 行 REVIEW 表示"cheap 指标 + judge 评分至少 1 模式有显著不足
(总分 < 18 / 25 或任一维度 <= 2)",不阻断 e2e,只让 e2e-reporter 在
e2e-report.md 突出"质量待优化建议"。PASS 三模式均 ≥ 18 且无低分维度。
Judge prompt template
You are an independent translation quality judge. You are NOT the model that
produced the translation under review. Score on 5 dimensions, each 1-5
integer or half-integer (e.g. 3.5, 4.5), with a 1-2 sentence rationale per
dimension.
# Source article (English)
{article.md 完整内容}
# Reference translation (baoyu-translate skill output, ground truth)
{tests/reference/article-zh-CN-<mode>/translation.md 完整内容}
# Captured translation (e2e output under review)
{tests/e2e-out/<ts-sha>/article-zh-CN-<mode>/captured.md 完整内容}
# Scoring dimensions
- accuracy: 事实/数据/逻辑与原文是否一致 (1=多处错, 5=全部一致)
- terminology: 关键术语全文是否统一翻译 (1=多次翻法不一, 5=全文统一+首现标注)
- cultural-notes: 对中文读者陌生的概念是否加注 (1=完全无, 5=注释到位简练)
- fluency: 是否像母语者写的中文 (1=翻译腔重, 5=自然流畅)
- faithfulness: 是否贴近原文风格/修辞/语气 (1=大幅改写, 5=保留原文风格)
# Output format (strict)
Return ONLY a JSON object (no prose before/after):
{
"accuracy": <1-5>,
"terminology": <1-5>,
"culturalNotes": <1-5>,
"fluency": <1-5>,
"faithfulness": <1-5>,
"total": <sum>,
"rationale": "<1-2 句总评,关键观察>"
}
跨契约
ADR 契约(修改需同步):
[baoyu] 前缀虽不直接出现在本 skill 输入(消费的是 captured.md 而
非 console.jsonl),但间接:本 skill 假设 runner 已按 [baoyu] 过滤
console.jsonl,diagnostician 借此判定 console error。修改前缀需同步
ADR-0002 + runner + diagnostician + 本 skill 文档。
- Gate 行为由 ADR-0003 §Consequences 锁定:diagnostician FAIL → quality
不被调用。本 skill 自身不检 verdict(由上游 orchestrator 把控),但
在 SKILL.md 内显式写"调用前提"以便调用方有据可查。
代码库契约(复用既有实现,不重新声明):
- 三模式枚举
quick / normal / refined 复用 shared/types.ts::TranslationMode。
captured.md schema(段落数 / 元数据格式)由 e2e-runner/SKILL.md 锁
定;本 skill 读取端按该 schema 解析,字段缺失回退到 "Quality precondition
failed" STOP(不强行猜)。
translation.md 段落计数与 e2e-diagnostician C4 共享
awk 'NF>0' | wc -l 算法(避免两个 agent 报不同数)。
手工验证范式
TS_SHA="2026-06-02T10-30-00_abcdef1"
RUN="tests/e2e-out/${TS_SHA}"
cat > "$RUN/article-zh-CN-quick/captured.md" <<'EOF'
paragraph_count: 75
captured_at: 2026-06-02T10:30:42Z
<译文略,与 reference 字面 ~30% 重合>
EOF
不在本 skill 范围
- Gate 判定:由
e2e-diagnostician 负责;本 skill 不判 PASS/FAIL,
只在 quality.md 里给"质量层 verdict"(PASS / REVIEW,不阻断)。
- 最终 e2e-report.md:由
e2e-reporter 写,本 skill 不写。
- 重跑翻译:若 quality 不满意,需回
e2e-runner(改 prompt / provider /
模型)重出 captured,本 skill 只评不改。
- 阈值调优:cheap 指标判定"是否够对齐"留给
e2e-reporter 的人审;
judge verdict 阈值(总分 ≥ 18 / 25)按 issue #33 / 经验性,不在本 skill
锁死;若后续调优需开新 issue。
用法
触发本 skill 后:
- 确认 verdict=PASS:
grep '^verdict: PASS' "$RUN/diagnosis.md",失败
立即报"Diagnostician gate not PASS — quality not invoked"。
- 三模式 captured.md 存在 +
paragraph_count: 行可解析。
- 算 cheap 指标:Python 标准库脚本,1-2 秒出结果。
- 调 Claude judge:3 次评分调用(quick / normal / refined),每次按模板
prompt 给出 5 维评分 + rationale。
- 写
quality.md:表格 + rationale 摘录 + recommendations + verdict。
- 回报用户:"Quality done for
<ts-sha>. cheap 指标 + Claude 5 维评分见
quality.md。verdict=<PASS|REVIEW>。下一步:调 /e2e-reporter 汇总
diagnosis.md + quality.md → 最终 e2e-report.md。"
故障排查
| 现象 | 根因 | 修复 |
|---|
| "Diagnostician gate not PASS" | 上游没跑或跑挂 | 先跑 /e2e-diagnostician,verdict=PASS 后再调本 skill |
paragraph_count: 行解析失败 | runner 写盘格式变更 | 看 e2e-runner/SKILL.md 的 captured.md shape,改本 skill 解析端 |
| judge 返回 prose 而非 JSON | Claude 没遵守 format 约束 | 重新 prompt 加 Return ONLY a JSON object, no prose;若仍失败,记到 quality.md 的 judge_errors 段 |
| cheap 指标全 0 | captured.md 误读到 translation.md | 校对路径,本 skill 读 <ts-sha>/article-zh-CN-<mode>/captured.md 而非 reference |
| 1 模式 judge 总分 < 12 | 翻译严重偏离 | 不阻断,verdict: REVIEW + 在 recommendations 突出提示 |
参考
- PRD #26:父 PRD(Slice 7 / Part A:quality)。
- ADR-0002:日志 schema +
[baoyu] 前缀契约(本 skill 间接消费)。
- ADR-0003:e2e 流水线 + gate 行为 + 产物契约。
.claude/skills/e2e-runner/SKILL.md:captured.md schema 来源(Slice 5)。
.claude/skills/e2e-diagnostician/SKILL.md:C4 段落数 ±30% 阈值与本
skill paragraph drift 共享。
.claude/skills/e2e-reporter/SKILL.md:本 skill 的下游(汇总到
e2e-report.md)。
src/shared/types.ts::TranslationMode:三模式枚举。
tests/reference/article.md + tests/reference/article-zh-CN-<mode>/:
ground truth。