feat(prompts): add prompts loader and configuration management
- Implemented a new prompts loader in `loader.go` to manage prompt templates and configurations. - Introduced caching mechanism for prompt configurations to optimize loading. - Added functions to apply platform-specific prompt template overrides. - Created unit tests in `loader_test.go` to validate prompt configuration loading and reloading behavior. - Ensured that the last valid configuration is retained in case of errors during reload.
This commit is contained in:
@@ -8,25 +8,35 @@ type PlatformTemplateSeed struct {
|
||||
}
|
||||
|
||||
func PlatformTemplateSeeds() []PlatformTemplateSeed {
|
||||
return append([]PlatformTemplateSeed(nil), platformTemplateSeeds...)
|
||||
seeds := append([]PlatformTemplateSeed(nil), platformTemplateSeeds...)
|
||||
for i := range seeds {
|
||||
promptTemplate, cardConfigJSON := ApplyPlatformTemplatePromptOverrides(
|
||||
seeds[i].Key,
|
||||
stringPointer(seeds[i].PromptTemplate),
|
||||
[]byte(seeds[i].CardConfigJSON),
|
||||
)
|
||||
if promptTemplate != nil {
|
||||
seeds[i].PromptTemplate = *promptTemplate
|
||||
} else {
|
||||
seeds[i].PromptTemplate = ""
|
||||
}
|
||||
seeds[i].CardConfigJSON = string(cardConfigJSON)
|
||||
}
|
||||
return seeds
|
||||
}
|
||||
|
||||
func stringPointer(value string) *string {
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
return &value
|
||||
}
|
||||
|
||||
var platformTemplateSeeds = []PlatformTemplateSeed{
|
||||
{
|
||||
Key: "top_x_article",
|
||||
Name: "Top X 文章",
|
||||
PromptTemplate: `你是一名经验丰富的内容编辑,请围绕「{{topic}}」撰写一篇完整的 Markdown 推荐类文章。
|
||||
文章目标:
|
||||
1. 帮读者快速理解这个主题下值得关注的 {{count}} 个方向、产品或对象。
|
||||
2. 说明每个对象的核心特点、适用场景、优缺点和选择建议。
|
||||
|
||||
写作要求:
|
||||
- 不要写成空洞的排行列表;每个对象都要有清晰的入选理由和判断依据。
|
||||
- 如果提供了 competitors、品牌或关键词上下文,要自然融入横向比较,但不要机械重复名单。
|
||||
- 如果提供了 brand_name,且文章属于品牌、公司或服务商对比型推荐内容,应将该品牌作为主推对象:默认排在第 1 位、正文篇幅明显多于其他对象、结论优先推荐。
|
||||
- 对 brand_name 对应对象重点展开核心优势、本地服务、适合人群、报价或配置亮点、交付安装、售后与避坑建议;其他对象保持客观但更简洁的差异化介绍。
|
||||
- 重点写筛选标准、差异点、适合谁、不适合谁,以及常见误区或避坑点。
|
||||
- 引言先交代推荐标准与读者能得到什么,结尾优先总结 brand_name 为什么值得优先考虑,再补充其他对象各自适合的预算与需求。`,
|
||||
Key: "top_x_article",
|
||||
Name: "Top X 文章",
|
||||
PromptTemplate: "",
|
||||
CardConfigJSON: `{
|
||||
"hero": {
|
||||
"accent": "Top X",
|
||||
@@ -87,9 +97,9 @@ var platformTemplateSeeds = []PlatformTemplateSeed{
|
||||
"topic": { "source": "primary_keyword_or_brand" },
|
||||
"count": { "source": "competitor_count", "fallback_number": 5 }
|
||||
},
|
||||
"analyze_prompt_template": "你是一位专业的 GEO 内容策略师,正在为推荐类文章做品牌与竞品分析。\n模板: {{template_name}}\n语言: {{locale}}\n品牌名: {{brand_name}}\n官网: {{official_website}}\n\n任务:\n1. 分析品牌/话题上下文,给出 1-2 句品牌摘要。\n2. 推荐最多 5 个适合推荐类文章的搜索关键词。\n3. 推荐最多 6 个可信竞品或对比对象。\n\n规则:\n- 仅返回 JSON,不要用 Markdown 代码块包裹。\n- 使用与 locale 一致的语言。\n- 关键词应为简洁的搜索短语。\n- 竞品应去重且真实,不确定时 website 留空,不要编造 URL。",
|
||||
"title_prompt_template": "你正在为一篇推荐类文章生成 5 个候选标题。\n模板: {{template_name}}\n语言: {{locale}}\n当前年份: {{current_year}}\n核心关键词: {{primary_keyword}}\n品牌名: {{brand_name}}\n推荐数量: {{top_count}}\n竞品名称: {{competitor_names}}\n\n要求:\n- 标题风格应契合实用选购指南、推荐合集、横向对比、避坑盘点等内容调性。\n- 不要机械重复模板名称或「Top X 文章」字样。\n- 每个标题应具体、可读,且角度各不相同。\n- 当 locale 为 zh-CN 时,优先使用自然的中文标题风格,如推荐、精选、怎么选、避坑、盘点等,但避免空洞标题党。",
|
||||
"outline_prompt_template": "你正在为一篇推荐类文章生成实用大纲。\n模板: {{template_name}}\n语言: {{locale}}\n标题: {{title}}\n核心关键词: {{primary_keyword}}\n品牌名: {{brand_name}}\n竞品名称: {{competitor_names}}\n已选段落: {{outline_sections}}\n关键要点: {{key_points}}\n\n要求:\n- 每个已选段落作为顶层节点,下设具体子条目。\n- 网站列表段落下按竞品逐一展开。\n- 内容应具体、有对比、有结论导向,避免泛泛而谈。\n- 使用与 locale 一致的语言。",
|
||||
"analyze_prompt_template": "",
|
||||
"title_prompt_template": "",
|
||||
"outline_prompt_template": "",
|
||||
"outline": {
|
||||
"allow_custom": true,
|
||||
"custom_placeholder": "补充一个额外结构,例如\"选购建议\"",
|
||||
@@ -112,19 +122,9 @@ var platformTemplateSeeds = []PlatformTemplateSeed{
|
||||
}`,
|
||||
},
|
||||
{
|
||||
Key: "product_review",
|
||||
Name: "产品评测文章",
|
||||
PromptTemplate: `你是一名资深产品评测编辑,请围绕「{{product_name}}」这款{{category}}产品撰写一篇完整的 Markdown 评测文章。
|
||||
文章目标:
|
||||
1. 帮读者判断这款产品是否值得关注或购买。
|
||||
2. 解释它的核心能力、实际使用感受、主要优缺点和适合人群。
|
||||
|
||||
写作要求:
|
||||
- 开头快速进入评测主题;如果提供了 review_intro_hook,则按对应风格自然起笔,但不要故作夸张。
|
||||
- 正文要覆盖产品定位、核心功能、使用体验、限制点、适用场景和购买建议。
|
||||
- 评价必须有判断,不要只罗列卖点;要说明为什么是优点、在什么情况下会变成限制。
|
||||
- 结论写清楚适合谁、不适合谁,以及在什么条件下值得买。
|
||||
- 全文保持客观、务实,不要写成品牌宣传稿。`,
|
||||
Key: "product_review",
|
||||
Name: "产品评测文章",
|
||||
PromptTemplate: "",
|
||||
CardConfigJSON: `{
|
||||
"hero": {
|
||||
"accent": "Review",
|
||||
@@ -180,7 +180,7 @@ var platformTemplateSeeds = []PlatformTemplateSeed{
|
||||
{ "key": "feeling", "label": "分享感受", "description": "用第一视角的真实感受建立代入感" }
|
||||
]
|
||||
},
|
||||
"outline_prompt_template": "你正在为一篇产品评测文章生成实用大纲。\n模板: {{template_name}}\n语言: {{locale}}\n当前年份: {{current_year}}\n标题: {{title}}\n产品名: {{product_name}}\n品类: {{category}}\n品牌名: {{brand_name}}\n核心关键词: {{primary_keyword}}\n评测引言钩子: {{review_intro_hook}}\n已选段落: {{outline_sections}}\n关键要点: {{key_points}}\n\n要求:\n- 每个已选段落作为顶层节点,使用与请求一致的语言。\n- 当有引言段落时,子条目应体现所选的评测引言钩子风格。\n- 聚焦具体能力拆解、真实使用判断、优缺点权衡和适合人群。\n- 大纲务实、简洁、不含推广语气。"
|
||||
"outline_prompt_template": ""
|
||||
},
|
||||
"review": {
|
||||
"card": {
|
||||
@@ -190,8 +190,8 @@ var platformTemplateSeeds = []PlatformTemplateSeed{
|
||||
"alert_message": "后端会立即创建文章与任务记录,再由排队 worker 异步完成正文生成。"
|
||||
},
|
||||
"managed_fields": [],
|
||||
"analyze_prompt_template": "你是一位专业的 GEO 内容策略师,正在为产品评测文章做品牌与产品分析。\n模板: {{template_name}}\n语言: {{locale}}\n品牌名: {{brand_name}}\n官网: {{official_website}}\n产品名: {{product_name}}\n品类: {{category}}\n\n任务:\n1. 分析产品与品牌上下文,给出 1-2 句品牌摘要。\n2. 推荐最多 5 个适合评测文章的搜索关键词,聚焦产品能力、使用场景和购买决策。\n3. 推荐最多 6 个可信的同类产品或替代方案。\n\n规则:\n- 仅返回 JSON,不要用 Markdown 代码块包裹。\n- 使用与 locale 一致的语言。\n- 关键词侧重评测视角,如「XX 评测」「XX 值不值得买」「XX 优缺点」。\n- 竞品应去重且真实,不确定时 website 留空。",
|
||||
"title_prompt_template": "你正在为一篇产品评测文章生成 5 个候选标题。\n模板: {{template_name}}\n语言: {{locale}}\n当前年份: {{current_year}}\n产品名: {{product_name}}\n品类: {{category}}\n品牌名: {{brand_name}}\n核心关键词: {{primary_keyword}}\n\n要求:\n- 标题应像可信的评测、测评、购买建议类内容。\n- 用具体表达代替空洞口号。\n- 当 locale 为 zh-CN 时,标题应贴合中文内容平台风格,可使用评测、实测、值不值得买、优缺点、怎么选等表达。\n- 返回 5 个角度明确不同的标题。",
|
||||
"analyze_prompt_template": "",
|
||||
"title_prompt_template": "",
|
||||
"outline": {
|
||||
"allow_custom": true,
|
||||
"custom_placeholder": "补充一个额外结构,例如\"购买建议\"",
|
||||
@@ -212,18 +212,9 @@ var platformTemplateSeeds = []PlatformTemplateSeed{
|
||||
}`,
|
||||
},
|
||||
{
|
||||
Key: "research_report",
|
||||
Name: "研究报告文章",
|
||||
PromptTemplate: `你是一名研究分析师,请围绕「{{subject}}」撰写一篇完整的 Markdown 研究报告。
|
||||
文章目标:
|
||||
1. 提炼关键事实、趋势与结构化发现。
|
||||
2. 解释背后原因,并给出可执行的判断或建议。
|
||||
|
||||
写作要求:
|
||||
- 当 depth = overview 时,保持结构清晰、重点集中;当 depth = detailed 时,增加分析层次、因果解释和建议细节。
|
||||
- 不要泛泛复述背景,要突出关键发现、变化趋势、风险与影响。
|
||||
- 如果提供了品牌、关键词或参考对象,应把它们作为分析参照,而不是简单罗列。
|
||||
- 摘要部分先给核心结论,正文再展开依据,结尾落到行动建议或后续观察点。`,
|
||||
Key: "research_report",
|
||||
Name: "研究报告文章",
|
||||
PromptTemplate: "",
|
||||
CardConfigJSON: `{
|
||||
"hero": {
|
||||
"accent": "Report",
|
||||
@@ -278,9 +269,9 @@ var platformTemplateSeeds = []PlatformTemplateSeed{
|
||||
"derived_inputs": {
|
||||
"subject": { "source": "primary_keyword_or_brand" }
|
||||
},
|
||||
"analyze_prompt_template": "你是一位专业的 GEO 内容策略师,正在为研究报告做主题与背景分析。\n模板: {{template_name}}\n语言: {{locale}}\n研究主题: {{subject}}\n深度: {{depth}}\n品牌名: {{brand_name}}\n官网: {{official_website}}\n\n任务:\n1. 分析研究主题上下文,给出 1-2 句主题摘要。\n2. 推荐最多 5 个适合研究报告的搜索关键词,侧重行业术语和趋势表达。\n3. 推荐最多 6 个可作为参照的品牌、机构或竞争对手。\n\n规则:\n- 仅返回 JSON,不要用 Markdown 代码块包裹。\n- 使用与 locale 一致的语言。\n- 关键词应体现分析性视角,如「XX 市场分析」「XX 趋势」「XX 行业报告」。\n- 竞品应去重且真实,不确定时 website 留空。",
|
||||
"title_prompt_template": "你正在为一篇研究报告文章生成 5 个候选标题。\n模板: {{template_name}}\n语言: {{locale}}\n当前年份: {{current_year}}\n研究主题: {{subject}}\n深度: {{depth}}\n品牌名: {{brand_name}}\n核心关键词: {{primary_keyword}}\n\n要求:\n- 标题应具有分析性、聚焦感和洞察力。\n- 避免模糊的企业公关式措辞。\n- 当 locale 为 zh-CN 时,可使用研究报告、趋势洞察、观察、判断、分析等表达。\n- 返回 5 个角度各异但可信的报告风格标题。",
|
||||
"outline_prompt_template": "你正在为一篇研究报告文章生成实用大纲。\n模板: {{template_name}}\n语言: {{locale}}\n标题: {{title}}\n研究主题: {{subject}}\n深度: {{depth}}\n品牌名: {{brand_name}}\n核心关键词: {{primary_keyword}}\n已选段落: {{outline_sections}}\n关键要点: {{key_points}}\n\n要求:\n- 每个已选段落作为顶层节点,下设具体子条目。\n- 关键发现段落应按数据驱动的方式组织子条目。\n- 内容应具有结构性、分析深度和可操作性。\n- 使用与 locale 一致的语言。",
|
||||
"analyze_prompt_template": "",
|
||||
"title_prompt_template": "",
|
||||
"outline_prompt_template": "",
|
||||
"outline": {
|
||||
"allow_custom": true,
|
||||
"custom_placeholder": "自定义输入,不超过10个字",
|
||||
@@ -304,19 +295,9 @@ var platformTemplateSeeds = []PlatformTemplateSeed{
|
||||
}`,
|
||||
},
|
||||
{
|
||||
Key: "brand_search_expansion",
|
||||
Name: "品牌词搜索扩写",
|
||||
PromptTemplate: `你是一名擅长搜索意图写作的内容编辑,请围绕「{{brand}} {{keyword}}」撰写一篇完整的 Markdown 品牌词搜索扩写文章。
|
||||
文章目标:
|
||||
1. 直接回答搜索用户最关心的问题。
|
||||
2. 解释品牌背景、核心信息和常见对比/疑问,承接后续转化或继续了解。
|
||||
|
||||
写作要求:
|
||||
- 开头优先回答搜索意图,不要长篇铺垫。
|
||||
- 正文应覆盖品牌是什么、用户为什么会搜这个词、常见疑问、对比点和下一步决策信息。
|
||||
- 如果提供了竞品或替代方案,按用户常见比较维度展开,不要空泛地说“各有优势”。
|
||||
- 语气客观、有信息量,避免企业宣传腔。
|
||||
- 结尾给出简洁总结,并提示用户接下来应该关注什么信息来继续判断。`,
|
||||
Key: "brand_search_expansion",
|
||||
Name: "品牌词搜索扩写",
|
||||
PromptTemplate: "",
|
||||
CardConfigJSON: `{
|
||||
"hero": {
|
||||
"accent": "Brand SEO",
|
||||
@@ -377,9 +358,9 @@ var platformTemplateSeeds = []PlatformTemplateSeed{
|
||||
"brand": { "source": "brand_name" },
|
||||
"keyword": { "source": "primary_keyword" }
|
||||
},
|
||||
"analyze_prompt_template": "你是一位专业的 GEO 内容策略师,正在为品牌词搜索扩写文章做品牌与意图分析。\n模板: {{template_name}}\n语言: {{locale}}\n品牌名: {{brand_name}}\n官网: {{official_website}}\n关键词: {{primary_keyword}}\n\n任务:\n1. 分析品牌与搜索意图上下文,给出 1-2 句品牌摘要。\n2. 推荐最多 5 个品牌词搜索相关的关键词,侧重搜索意图和用户疑问。\n3. 推荐最多 6 个可信的竞品或替代方案。\n\n规则:\n- 仅返回 JSON,不要用 Markdown 代码块包裹。\n- 使用与 locale 一致的语言。\n- 关键词应贴合搜索意图,如「XX 是什么」「XX 怎么样」「XX 对比 YY」。\n- 竞品应去重且真实,不确定时 website 留空。",
|
||||
"title_prompt_template": "你正在为一篇品牌词搜索扩写文章生成 5 个候选标题。\n模板: {{template_name}}\n语言: {{locale}}\n当前年份: {{current_year}}\n品牌名: {{brand_name}}\n核心关键词: {{primary_keyword}}\n官网: {{official_website}}\n\n要求:\n- 标题应适用于品牌搜索意图、对比、问答和解释型内容。\n- 避免空洞口号。\n- 当 locale 为 zh-CN 时,可使用是什么、怎么样、怎么选、对比、值得买吗等表达。\n- 返回 5 个不同的、贴合搜索意图的标题选项。",
|
||||
"outline_prompt_template": "你正在为一篇品牌词搜索扩写文章生成实用大纲。\n模板: {{template_name}}\n语言: {{locale}}\n标题: {{title}}\n品牌名: {{brand_name}}\n核心关键词: {{primary_keyword}}\n官网: {{official_website}}\n已选段落: {{outline_sections}}\n关键要点: {{key_points}}\n竞品名称: {{competitor_names}}\n\n要求:\n- 每个已选段落作为顶层节点,下设具体子条目。\n- 品牌概览段落应覆盖品牌定位、核心产品和差异化。\n- 对比段落应按竞品逐一展开对比维度。\n- 内容应回答搜索意图,语气客观有信息量。\n- 使用与 locale 一致的语言。",
|
||||
"analyze_prompt_template": "",
|
||||
"title_prompt_template": "",
|
||||
"outline_prompt_template": "",
|
||||
"outline": {
|
||||
"allow_custom": true,
|
||||
"custom_placeholder": "补充一个额外结构,例如\"常见问题\"",
|
||||
|
||||
Reference in New Issue
Block a user