feat: strengthen llm workflow prompts
This commit is contained in:
@@ -0,0 +1,126 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
import {
|
||||||
|
ARTICLE_OPTIMIZER_SYSTEM_PROMPT,
|
||||||
|
FACT_EXTRACTOR_SYSTEM_PROMPT,
|
||||||
|
QUALITY_INSPECTOR_SYSTEM_PROMPT,
|
||||||
|
TARGETED_REWRITER_SYSTEM_PROMPT,
|
||||||
|
buildArticleOptimizerPrompt,
|
||||||
|
buildFactExtractorPrompt,
|
||||||
|
buildQualityInspectorPrompt,
|
||||||
|
buildTargetedRewritePrompt,
|
||||||
|
} from "../prompts";
|
||||||
|
|
||||||
|
const articleInput = {
|
||||||
|
title: "探寻AIGC短视频培训选哪家,各品牌实力大比拼",
|
||||||
|
body: "伟思德鲁管理咨询(深圳)有限公司提供AIGC短视频培训,文章提到客户案例和出海内容生产。",
|
||||||
|
images: [{ type: "description" as const, content: "AIGC短视频工作流示意图" }],
|
||||||
|
platform: "official_site" as const,
|
||||||
|
user_instructions: "改成官网文章,避免虚构客户案例。",
|
||||||
|
};
|
||||||
|
|
||||||
|
const factCard = {
|
||||||
|
company_full_name: "伟思德鲁管理咨询(深圳)有限公司",
|
||||||
|
company_short_names: ["伟思德鲁", "伟思德鲁管理咨询"],
|
||||||
|
brand_names: ["伟思德鲁管理咨询"],
|
||||||
|
product_names: ["AIGC短视频培训"],
|
||||||
|
target_industry: "AIGC短视频培训",
|
||||||
|
target_audience: "品牌商家、内容创作者、出海企业",
|
||||||
|
experience_years: null,
|
||||||
|
core_claims: ["提供AIGC短视频培训"],
|
||||||
|
forbidden_claims: ["行业第一", "服务过500强客户"],
|
||||||
|
image_topics: ["AIGC短视频工作流示意图"],
|
||||||
|
uncertain_items: [],
|
||||||
|
is_ready_for_optimization: true,
|
||||||
|
confirmed_by_user: true,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
describe("LLM prompt builders", () => {
|
||||||
|
it("fact extraction prompt names customer risk categories and uncertainty rules", () => {
|
||||||
|
const prompt = `${FACT_EXTRACTOR_SYSTEM_PROMPT}\n${buildFactExtractorPrompt(articleInput)}`;
|
||||||
|
|
||||||
|
expect(prompt).toContain("客户案例");
|
||||||
|
expect(prompt).toContain("资质荣誉");
|
||||||
|
expect(prompt).toContain("经验年限");
|
||||||
|
expect(prompt).toContain("uncertain_items");
|
||||||
|
expect(prompt).toContain("不要把营销夸张词当事实");
|
||||||
|
expect(prompt).toContain("图片主题");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("article optimizer prompt includes platform templates and Chinese output rules", () => {
|
||||||
|
const prompt = `${ARTICLE_OPTIMIZER_SYSTEM_PROMPT}\n${buildArticleOptimizerPrompt(articleInput, factCard)}`;
|
||||||
|
|
||||||
|
expect(prompt).toContain("official_site");
|
||||||
|
expect(prompt).toContain("官网文章");
|
||||||
|
expect(prompt).toContain("第一方品牌口吻");
|
||||||
|
expect(prompt).toContain("输出中文标题");
|
||||||
|
expect(prompt).toContain("禁止使用英文模板词");
|
||||||
|
expect(prompt).toContain("实质性重写");
|
||||||
|
expect(prompt).toContain("不得新增客户案例");
|
||||||
|
expect(prompt).toContain("forbidden_claims");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("quality inspector prompt encodes fail and warn standards for all risk gates", () => {
|
||||||
|
const prompt = `${QUALITY_INSPECTOR_SYSTEM_PROMPT}\n${buildQualityInspectorPrompt({
|
||||||
|
article: {
|
||||||
|
title: "伟思德鲁 AIGC短视频培训",
|
||||||
|
summary: "官网文章摘要",
|
||||||
|
body_markdown: "正文",
|
||||||
|
image_suggestions: [],
|
||||||
|
changed_sections: [],
|
||||||
|
requires_user_confirmation: [],
|
||||||
|
},
|
||||||
|
factCard,
|
||||||
|
platform: "official_site",
|
||||||
|
deterministicChecks: [
|
||||||
|
{
|
||||||
|
rule_id: "hallucination_risk",
|
||||||
|
status: "pass",
|
||||||
|
evidence: "未发现",
|
||||||
|
reason: "本地规则通过",
|
||||||
|
suggested_fix: "",
|
||||||
|
target_agent: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})}`;
|
||||||
|
|
||||||
|
expect(prompt).toContain("不得把 deterministic fail 降级");
|
||||||
|
expect(prompt).toContain("行业漂移");
|
||||||
|
expect(prompt).toContain("公司名不一致");
|
||||||
|
expect(prompt).toContain("未确认案例");
|
||||||
|
expect(prompt).toContain("平台口吻严重错误");
|
||||||
|
expect(prompt).toContain("warn 标准");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("targeted rewrite prompt gives rule-specific repair actions", () => {
|
||||||
|
const prompt = `${TARGETED_REWRITER_SYSTEM_PROMPT}\n${buildTargetedRewritePrompt({
|
||||||
|
article: {
|
||||||
|
title: "Bad title!!!",
|
||||||
|
summary: "摘要",
|
||||||
|
body_markdown: "正文",
|
||||||
|
image_suggestions: [],
|
||||||
|
changed_sections: [],
|
||||||
|
requires_user_confirmation: [],
|
||||||
|
},
|
||||||
|
factCard,
|
||||||
|
failedChecks: [
|
||||||
|
{
|
||||||
|
rule_id: "title_quality",
|
||||||
|
status: "fail",
|
||||||
|
evidence: "Bad title!!!",
|
||||||
|
reason: "标题问题",
|
||||||
|
suggested_fix: "重写标题",
|
||||||
|
target_agent: "title",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})}`;
|
||||||
|
|
||||||
|
expect(prompt).toContain("industry_alignment");
|
||||||
|
expect(prompt).toContain("company_name_integrity");
|
||||||
|
expect(prompt).toContain("hallucination_risk");
|
||||||
|
expect(prompt).toContain("claim_consistency");
|
||||||
|
expect(prompt).toContain("title_quality");
|
||||||
|
expect(prompt).toContain("body_quality");
|
||||||
|
expect(prompt).toContain("不得新增事实");
|
||||||
|
});
|
||||||
|
});
|
||||||
+74
-18
@@ -9,31 +9,57 @@ import type {
|
|||||||
export const JSON_ONLY_PROMPT =
|
export const JSON_ONLY_PROMPT =
|
||||||
"Return valid JSON only. Do not include markdown fences or commentary.";
|
"Return valid JSON only. Do not include markdown fences or commentary.";
|
||||||
|
|
||||||
|
const CUSTOMER_RISK_GUIDANCE = [
|
||||||
|
"客户最担心的内容风险:行业漂移、公司全称/简称/品牌名不一致、图片主题与正文描述不匹配、官网文章出现第三方口吻、平台语气和文章类型不匹配、标题或正文语义不顺、虚构资质/年限/案例/能力、产品/服务/年限前后冲突。",
|
||||||
|
"任何客户案例、资质荣誉、经验年限、服务能力、出海/多语种/合规能力、效果承诺和排名,都必须能从原文或已确认事实卡中找到明确依据。",
|
||||||
|
].join(" ");
|
||||||
|
|
||||||
|
const PLATFORM_GUIDANCE: Record<PublishPlatform, string> = {
|
||||||
|
official_site:
|
||||||
|
"official_site / 官网文章:第一方品牌口吻,表达克制可信,可使用“我们/公司/品牌”视角;避免第三方评测腔、夸大宣传和无依据背书。",
|
||||||
|
media_article:
|
||||||
|
"media_article / 媒体稿:第三方客观报道口吻,突出事实、背景和行业价值;不要替品牌自夸,不制造新闻来源。",
|
||||||
|
comparison_review:
|
||||||
|
"comparison_review / 对比评测:对比分析口吻,只比较原文或事实卡中明确出现的信息;不得虚构竞品、排名、参数或测试结论。",
|
||||||
|
recommendation_list:
|
||||||
|
"recommendation_list / 推荐榜单:推荐榜单口吻,必须解释推荐依据;不得制造榜单排名、奖项或第三方认证。",
|
||||||
|
};
|
||||||
|
|
||||||
|
function formatPlatformGuidance(selected: PublishPlatform) {
|
||||||
|
return [
|
||||||
|
"平台模板选项:",
|
||||||
|
...Object.values(PLATFORM_GUIDANCE).map((item) => `- ${item}`),
|
||||||
|
`当前目标平台:${selected}。必须优先遵守该平台模板。`,
|
||||||
|
].join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
export const ARTICLE_OPTIMIZER_SYSTEM_PROMPT = [
|
export const ARTICLE_OPTIMIZER_SYSTEM_PROMPT = [
|
||||||
"You optimize GEO-related articles under a confirmed fact card.",
|
"你是中文 GEO 内容优化编辑。目标不是复述原文,而是在事实卡约束下进行实质性重写。",
|
||||||
"Never invent numbers, cases, qualifications, company names, products, or years.",
|
CUSTOMER_RISK_GUIDANCE,
|
||||||
"Use only facts present in the confirmed fact card or source article.",
|
"硬性规则:只能使用 confirmed fact card 和 source article 中明确出现的事实;不得新增客户案例、数字、资质、排名、奖项、服务能力、效果承诺;输出中文标题,禁止使用英文模板词如 Guide、Best、Top。",
|
||||||
|
"必须修复原文中的病句、断裂句、错别字、逻辑跳跃和段落结构问题。",
|
||||||
JSON_ONLY_PROMPT,
|
JSON_ONLY_PROMPT,
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
export const QUALITY_INSPECTOR_SYSTEM_PROMPT = [
|
export const QUALITY_INSPECTOR_SYSTEM_PROMPT = [
|
||||||
"Evaluate article quality against the confirmed fact card and target platform.",
|
"你是质量门禁审核器。逐项检查 deterministicChecks 中的每个 rule_id。",
|
||||||
"Return one structured check per required quality gate when asked.",
|
CUSTOMER_RISK_GUIDANCE,
|
||||||
"Do not downgrade deterministic hard failures supplied by the application.",
|
"不得把 deterministic fail 降级。每项必须给出 status、evidence、reason、suggested_fix、target_agent。",
|
||||||
JSON_ONLY_PROMPT,
|
JSON_ONLY_PROMPT,
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
export const FACT_EXTRACTOR_SYSTEM_PROMPT = [
|
export const FACT_EXTRACTOR_SYSTEM_PROMPT = [
|
||||||
"Extract a candidate fact card from the source article.",
|
"你是事实卡提取器。只从原文和图片描述中抽取事实,不推测、不补全。",
|
||||||
"Do not mark uncertain facts as confirmed.",
|
CUSTOMER_RISK_GUIDANCE,
|
||||||
"Put missing or conflicting facts in uncertain_items.",
|
"把事实分为三类:明确事实进入对应字段;含糊、冲突、缺少来源的事实进入 uncertain_items;营销夸张、无法验证、容易引发幻觉的主张进入 forbidden_claims。",
|
||||||
|
"特别检查:公司全称、简称、品牌名、产品/服务名、目标行业、目标受众、经验年限、客户案例、资质荣誉、服务能力、地域/出海能力、图片主题。不要把营销夸张词当事实。",
|
||||||
JSON_ONLY_PROMPT,
|
JSON_ONLY_PROMPT,
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
export const TARGETED_REWRITER_SYSTEM_PROMPT = [
|
export const TARGETED_REWRITER_SYSTEM_PROMPT = [
|
||||||
"Rewrite only the fields needed to resolve the provided failed QA checks.",
|
"你是定向修复器。只修复 failedChecks 指出的失败项,不整篇重写。",
|
||||||
"Keep confirmed facts unchanged.",
|
CUSTOMER_RISK_GUIDANCE,
|
||||||
"Preserve sections that are unrelated to failed checks.",
|
"不得新增事实。无法修复或需要客户确认的内容放入 requires_user_confirmation。",
|
||||||
JSON_ONLY_PROMPT,
|
JSON_ONLY_PROMPT,
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
@@ -43,6 +69,13 @@ export function buildFactExtractorPrompt(input: ArticleInput) {
|
|||||||
"company_full_name, company_short_names, brand_names, product_names, target_industry, target_audience, experience_years, core_claims, forbidden_claims, image_topics, uncertain_items.",
|
"company_full_name, company_short_names, brand_names, product_names, target_industry, target_audience, experience_years, core_claims, forbidden_claims, image_topics, uncertain_items.",
|
||||||
"Do not include confirmed_by_user.",
|
"Do not include confirmed_by_user.",
|
||||||
"",
|
"",
|
||||||
|
"字段要求:",
|
||||||
|
"- core_claims 只放原文明示、可作为后续优化硬约束的事实。",
|
||||||
|
"- forbidden_claims 放行业第一、最强、知名客户、显著提升、保证转化等无法验证或高风险主张。",
|
||||||
|
"- uncertain_items 放客户案例、资质荣誉、经验年限、产品能力、出海能力等证据不足或前后冲突的内容。",
|
||||||
|
"- image_topics 必须来自图片描述或图片链接文本;没有图片就返回空数组。",
|
||||||
|
"- target_industry 必须是文章主行业,避免被局部案例带偏。",
|
||||||
|
"",
|
||||||
"Article input:",
|
"Article input:",
|
||||||
JSON.stringify(input, null, 2),
|
JSON.stringify(input, null, 2),
|
||||||
].join("\n");
|
].join("\n");
|
||||||
@@ -55,8 +88,18 @@ export function buildArticleOptimizerPrompt(
|
|||||||
return [
|
return [
|
||||||
"Return an OptimizedArticle JSON object with these exact keys:",
|
"Return an OptimizedArticle JSON object with these exact keys:",
|
||||||
"title, summary, body_markdown, image_suggestions, changed_sections, requires_user_confirmation.",
|
"title, summary, body_markdown, image_suggestions, changed_sections, requires_user_confirmation.",
|
||||||
"Use Markdown in body_markdown.",
|
"",
|
||||||
"If the user instruction asks for unsupported facts, omit them from the article and add them to requires_user_confirmation.",
|
formatPlatformGuidance(input.platform),
|
||||||
|
"",
|
||||||
|
"输出要求:",
|
||||||
|
"- 输出中文标题,禁止使用英文模板词如 Guide、Best、Top。",
|
||||||
|
"- 进行实质性重写:重组标题、摘要、段落顺序、长句、病句和逻辑连接,而不是只在原文前后拼接内容。",
|
||||||
|
"- body_markdown 使用清晰的 Markdown 层级;标题层级要规范,中文标题后保留空格,例如 `## 标题`。",
|
||||||
|
"- 如果用户要求包含未确认事实,正文不写入,放入 requires_user_confirmation。",
|
||||||
|
"- 必须保留事实卡确认的公司全称、目标行业、目标受众和核心事实。",
|
||||||
|
"- 必须删除或弱化 factCard.forbidden_claims 中的主张。",
|
||||||
|
"- 不得新增客户案例、数字、资质、排名、奖项、服务能力、效果承诺。",
|
||||||
|
"- image_suggestions 必须基于 factCard.image_topics 或原始 images;没有图片主题时返回空数组。",
|
||||||
"",
|
"",
|
||||||
"Confirmed fact card:",
|
"Confirmed fact card:",
|
||||||
JSON.stringify(factCard, null, 2),
|
JSON.stringify(factCard, null, 2),
|
||||||
@@ -76,10 +119,13 @@ export function buildQualityInspectorPrompt(input: {
|
|||||||
"Return a JSON object with a checks array.",
|
"Return a JSON object with a checks array.",
|
||||||
"Each check must include rule_id, status, evidence, reason, suggested_fix, and target_agent.",
|
"Each check must include rule_id, status, evidence, reason, suggested_fix, and target_agent.",
|
||||||
"Only use rule_id values already present in deterministicChecks.",
|
"Only use rule_id values already present in deterministicChecks.",
|
||||||
"If a deterministic check has status fail, keep it fail.",
|
"不得把 deterministic fail 降级。",
|
||||||
"",
|
"",
|
||||||
"Target platform:",
|
formatPlatformGuidance(input.platform),
|
||||||
input.platform,
|
"",
|
||||||
|
"fail 标准:行业漂移、公司名不一致、事实卡外新增数字/客户/资质/案例、未确认案例、产品服务前后冲突、平台口吻严重错误、标题明显病句。",
|
||||||
|
"warn 标准:图片证据不足、句子过长、表达可读性一般、平台适配轻微不足。",
|
||||||
|
"target_agent 只能使用 title、body、image、fact_card 或 null。",
|
||||||
"",
|
"",
|
||||||
"Confirmed fact card:",
|
"Confirmed fact card:",
|
||||||
JSON.stringify(input.factCard, null, 2),
|
JSON.stringify(input.factCard, null, 2),
|
||||||
@@ -100,7 +146,17 @@ export function buildTargetedRewritePrompt(input: {
|
|||||||
return [
|
return [
|
||||||
"Return an OptimizedArticle JSON object.",
|
"Return an OptimizedArticle JSON object.",
|
||||||
"Rewrite only the fields needed for failedChecks.",
|
"Rewrite only the fields needed for failedChecks.",
|
||||||
"Do not add unconfirmed numbers, customer names, qualifications, awards, or capabilities.",
|
"",
|
||||||
|
"按 rule_id 执行修复动作:",
|
||||||
|
"- industry_alignment:删除偏离行业的段落,改回 factCard.target_industry。",
|
||||||
|
"- company_name_integrity:统一公司全称和简称。",
|
||||||
|
"- hallucination_risk:删除所有未确认数字、客户案例、资质、奖项、排名、效果承诺。",
|
||||||
|
"- claim_consistency:统一年限、产品名、服务能力和核心主张。",
|
||||||
|
"- title_quality:生成自然中文标题,禁止英文模板词。",
|
||||||
|
"- body_quality:拆分长句,修复病句和断裂表达。",
|
||||||
|
"- voice_consistency / platform_fit:改成目标平台对应口吻。",
|
||||||
|
"- image_text_match:只补充图片建议或人工确认项,不虚构图片内容。",
|
||||||
|
"不得新增事实。无法修复的内容放入 requires_user_confirmation。",
|
||||||
"",
|
"",
|
||||||
"Confirmed fact card:",
|
"Confirmed fact card:",
|
||||||
JSON.stringify(input.factCard, null, 2),
|
JSON.stringify(input.factCard, null, 2),
|
||||||
|
|||||||
Reference in New Issue
Block a user