feat: localize quality report

This commit is contained in:
Codex
2026-06-21 23:43:02 +08:00
parent a457a4acf3
commit 936084465d
3 changed files with 78 additions and 35 deletions
+24 -2
View File
@@ -12,6 +12,24 @@ const statusLabels = {
fail: "失败",
} as const;
const ruleLabels: Record<string, string> = {
industry_alignment: "行业一致性",
image_text_match: "图文匹配",
voice_consistency: "表达视角一致性",
platform_fit: "平台适配",
company_name_integrity: "公司名称完整性",
title_quality: "标题质量",
body_quality: "正文质量",
hallucination_risk: "事实幻觉风险",
claim_consistency: "主张一致性",
context_sensitive_terms: "语境敏感词",
};
const targetAgentLabels: Record<string, string> = {
title: "标题改写",
body: "正文改写",
};
export function QaReportPanel({ report }: QaReportPanelProps) {
if (!report) {
return (
@@ -33,7 +51,7 @@ export function QaReportPanel({ report }: QaReportPanelProps) {
{report.checks.map((check) => (
<div className="qa-item" key={check.rule_id}>
<div className="qa-title-row">
<strong>{check.rule_id.replace(/_/g, " ")}</strong>
<strong>{ruleLabels[check.rule_id] ?? check.rule_id}</strong>
<span className={`status-pill ${check.status}`}>
{statusLabels[check.status]}
</span>
@@ -41,7 +59,11 @@ export function QaReportPanel({ report }: QaReportPanelProps) {
<p>{check.reason}</p>
<small>{check.evidence}</small>
{check.suggested_fix && <em>{check.suggested_fix}</em>}
{check.target_agent && <code>{check.target_agent}</code>}
{check.target_agent && (
<code>
{targetAgentLabels[check.target_agent] ?? check.target_agent}
</code>
)}
</div>
))}
</div>
@@ -133,6 +133,27 @@ describe("workflow nodes", () => {
]);
});
it("returns quality report details in Chinese", () => {
const report = inspectQuality({
article: {
title: "Example GEO Optimization Guide",
summary: "A factual guide for marketing teams.",
body_markdown:
"Example Technology Co., Ltd. has eight years of GEO optimization experience.",
image_suggestions: [],
changed_sections: [],
requires_user_confirmation: [],
},
factCard: confirmedFactCard,
platform: "official_site",
sourceImages: [],
});
expect(report.checks[0]?.reason).toContain("行业");
expect(report.checks[0]?.suggested_fix).toContain("行业");
expect(report.checks[0]?.evidence).not.toContain("Article");
});
it("hard-fails incomplete company names, hallucinated numbers, industry drift, and conflicting years", () => {
const report = inspectQuality({
article: {
+33 -33
View File
@@ -55,9 +55,9 @@ function inspectRule(
aligned ? "pass" : "fail",
aligned ? factCard.target_industry : article.summary,
aligned
? "Article stays aligned with the confirmed industry."
: "Article drifts from the confirmed industry.",
"Rewrite affected paragraphs around the confirmed industry.",
? "文章内容与事实卡确认的目标行业一致。"
: "文章内容偏离事实卡确认的目标行业。",
"围绕事实卡确认的目标行业重写相关段落。",
aligned ? null : "body",
);
}
@@ -67,11 +67,11 @@ function inspectRule(
return check(
ruleId,
hasImages ? "pass" : "warn",
hasImages ? "Image topics are available." : "No image descriptions supplied.",
hasImages ? "已有可用于比对的图片主题。" : "未提供图片描述。",
hasImages
? "Image guidance can be compared with article sections."
: "Image-text confidence is low without image descriptions.",
"Add image descriptions or review image placement manually.",
? "图片建议可以和文章内容进行比对。"
: "缺少图片描述时,图文匹配置信度较低。",
"补充图片描述,或人工检查图片与正文的对应关系。",
null,
);
}
@@ -81,11 +81,11 @@ function inspectRule(
return check(
ruleId,
thirdPartyOfficial ? "warn" : "pass",
thirdPartyOfficial ? "Third-party pronouns found." : "Voice matches platform.",
thirdPartyOfficial ? "发现第三方代词。" : "表达视角符合平台要求。",
thirdPartyOfficial
? "Official-site content should avoid detached third-party voice."
: "No obvious voice mismatch detected.",
"Rewrite in official brand voice.",
? "官网文章应避免疏离的第三方叙述口吻。"
: "未发现明显的平台口吻不一致问题。",
"改写为更适合官网的品牌表达。",
thirdPartyOfficial ? "body" : null,
);
}
@@ -97,8 +97,8 @@ function inspectRule(
? "pass"
: "warn",
article.summary,
"Platform fit is based on the generated summary and structure.",
"Review platform-specific framing.",
"平台适配基于生成摘要与文章结构判断。",
"复核文章是否符合目标平台的表达方式和结构。",
null,
);
}
@@ -110,9 +110,9 @@ function inspectRule(
hasFullName ? "pass" : "fail",
hasFullName ? factCard.company_full_name : article.body_markdown,
hasFullName
? "Confirmed company full name is present."
: "The confirmed company full name is missing or shortened.",
"Use the confirmed company full name at first mention.",
? "文章中包含事实卡确认的公司全称。"
: "文章缺少事实卡确认的公司全称,或使用了不完整简称。",
"首次出现公司时使用事实卡确认的公司全称。",
hasFullName ? null : "body",
);
}
@@ -123,8 +123,8 @@ function inspectRule(
ruleId,
badTitle ? "fail" : "pass",
article.title,
badTitle ? "Title appears awkward or over-punctuated." : "Title reads naturally.",
"Rewrite title for clarity and grammar.",
badTitle ? "标题存在语义不顺或标点堆砌问题。" : "标题表达自然清晰。",
"重写标题,提升语义清晰度和语法质量。",
badTitle ? "title" : null,
);
}
@@ -134,11 +134,11 @@ function inspectRule(
return check(
ruleId,
longSentence ? "warn" : "pass",
longSentence ? "Long sentence detected." : "Body structure is readable.",
longSentence ? "发现过长句子。" : "正文结构可读。",
longSentence
? "Some sentences are too long for comfortable reading."
: "No severe body grammar issue detected.",
"Split long sentences and clarify references.",
? "部分句子过长,影响阅读和理解。"
: "未发现严重正文语法问题。",
"拆分长句,并明确指代关系。",
longSentence ? "body" : null,
);
}
@@ -150,11 +150,11 @@ function inspectRule(
unsupportedNumber || article.requires_user_confirmation.length > 0 ? "fail" : "pass",
unsupportedNumber
? findUnsupportedNumbers(combined, factCard).join(", ")
: "No unsupported numeric claims found.",
: "未发现未确认的数字类事实主张。",
unsupportedNumber
? "Numeric claims are not traceable to the confirmed fact card."
: "Factual claims are traceable to the confirmed fact card.",
"Remove or confirm unsupported claims.",
? "数字类主张无法追溯到已确认事实卡。"
: "事实主张可以追溯到已确认事实卡。",
"删除未确认主张,或先补充到事实卡并确认。",
unsupportedNumber ? "body" : null,
);
}
@@ -167,11 +167,11 @@ function inspectRule(
return check(
ruleId,
conflicts.length > 0 ? "fail" : "pass",
conflicts.length > 0 ? conflicts.join(", ") : "No conflicting claims found.",
conflicts.length > 0 ? conflicts.join(", ") : "未发现冲突事实。",
conflicts.length > 0
? "Experience years conflict with the confirmed fact card."
: "Repeated claims are consistent.",
"Normalize years, products, and service claims to confirmed facts.",
? "经验年限与事实卡确认内容冲突。"
: "重复出现的事实主张保持一致。",
"将年限、产品和服务表述统一为事实卡确认内容。",
conflicts.length > 0 ? "body" : null,
);
}
@@ -179,9 +179,9 @@ function inspectRule(
return check(
ruleId,
/\b(?:sensitive|forbidden)\b/i.test(combined) ? "warn" : "pass",
"Context-sensitive wording scan complete.",
"Sensitive terms need context-aware review when present.",
"Review wording manually instead of deleting terms mechanically.",
"已完成语境敏感词检查。",
"涉及敏感或禁用表达时,需要结合上下文判断。",
"人工复核相关表述,避免机械删除导致语义错误。",
null,
);
}