feat: localize quality report
This commit is contained in:
@@ -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: {
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user