对齐 Zibll 的 AI 生成 SEO 流程:统一 WP AI Client/主题 Provider 双后端、文章/分类 SEO 框与生成回填、投稿摘要/标签建议,并收敛扩展页为连接配置。
159 lines
5.3 KiB
PHP
159 lines
5.3 KiB
PHP
<?php
|
||
/**
|
||
* AKSRT AI Prompt — AI Prompt 模板管理
|
||
*
|
||
* @package AKSRT
|
||
*/
|
||
|
||
defined('ABSPATH') || exit;
|
||
|
||
class AKSRT_AI_Prompt {
|
||
|
||
private static $instance = null;
|
||
|
||
public static function get_instance(): self {
|
||
if (null === self::$instance) {
|
||
self::$instance = new self();
|
||
}
|
||
return self::$instance;
|
||
}
|
||
|
||
/**
|
||
* SEO 标题 system instruction(Zibll 默认长提示词)。
|
||
*/
|
||
public function get_seo_title_system_instruction(): string {
|
||
$custom = $this->read_custom_prompt('ai_seo_title_prompt');
|
||
if ($custom !== '') {
|
||
return $custom;
|
||
}
|
||
|
||
return '你是一名资深的网站 SEO 编辑,擅长撰写既符合搜索习惯又具备点击力的文章标题。
|
||
请严格遵循以下规则:
|
||
1. 输出 1 条最佳标题,作为该文章的 <title>。
|
||
2. 字数控制在 20 至 40 个汉字之间,避免过短或过长。
|
||
3. 必须包含文章的主关键词,且把最重要的关键词放在标题前部。
|
||
4. 不要堆砌关键词、不要重复同义词、不要使用煽动性或夸张词汇。
|
||
5. 不要包含网站名称、品牌后缀,我们会自动追加站点名。
|
||
6. 直接输出标题文本本身,不要任何前缀、引号、Markdown、序号或解释。
|
||
7. 不要输出"标题:"、"答:"、"以下是" 等任何前导词。';
|
||
}
|
||
|
||
/**
|
||
* SEO 关键词 system instruction。
|
||
*/
|
||
public function get_seo_keywords_system_instruction(): string {
|
||
$custom = $this->read_custom_prompt('ai_seo_keywords_prompt');
|
||
if ($custom !== '') {
|
||
return $custom;
|
||
}
|
||
|
||
return '你是一名资深 SEO 编辑,负责为网站生成文章 meta keywords。
|
||
请严格遵循以下规则:
|
||
1. 输出 4 到 8 个最具搜索价值的关键词。
|
||
2. 全部使用中文(专有英文词可保留原文,例如 WordPress、AI、SEO)。
|
||
3. 使用英文逗号"," 分隔,不要使用顿号、句号、换行或编号。
|
||
4. 第一个关键词必须是文章的主关键词,紧扣标题与正文核心主题。
|
||
5. 不要堆砌、不要重复同义词、不要出现"等"、"以及"等填充语。
|
||
6. 直接输出关键词列表,不要任何前缀、解释、Markdown、引号或括号。
|
||
7. 关键词总长度建议控制在 50 个汉字以内。';
|
||
}
|
||
|
||
/**
|
||
* SEO 描述 system instruction。
|
||
*/
|
||
public function get_seo_description_system_instruction(): string {
|
||
$custom = $this->read_custom_prompt('ai_seo_description_prompt');
|
||
if ($custom !== '') {
|
||
return $custom;
|
||
}
|
||
|
||
return '你是一名资深的中文 SEO 编辑,擅长撰写吸引点击的搜索结果摘要(meta description)。
|
||
请严格遵循以下规则:
|
||
1. 输出 1 段描述,作为该文章的 meta description。
|
||
2. 字数控制在 80 至 150 个汉字之间,写成1至4句通顺的中文。
|
||
3. 必须自然融入文章的主关键词,但不要堆砌。
|
||
4. 体现文章的核心价值、目标读者或可获得的收益,要有吸引力但不夸张。
|
||
5. 不要分行、不要使用项目符号、不要使用 Markdown,不要包含品牌后缀或网址。
|
||
6. 直接输出描述文本本身,不要任何前缀、引号或解释。';
|
||
}
|
||
|
||
/**
|
||
* 兼容旧单 prompt 构建(草稿/无 ID 场景)。
|
||
*/
|
||
public function build_seo_prompt(string $title, string $content): string {
|
||
$title_instruction = $this->get_seo_title_system_instruction();
|
||
$kw_instruction = $this->get_seo_keywords_system_instruction();
|
||
$desc_instruction = $this->get_seo_description_system_instruction();
|
||
|
||
return <<<PROMPT
|
||
请根据以下文章内容,生成 SEO 优化建议。
|
||
|
||
文章标题:{$title}
|
||
|
||
文章内容:
|
||
{$content}
|
||
|
||
请以 JSON 格式返回,包含以下字段:
|
||
- suggested_title: {$title_instruction}
|
||
- suggested_description: {$desc_instruction}
|
||
- suggested_keywords: {$kw_instruction}(以 JSON 数组形式返回)
|
||
|
||
只返回 JSON,不要其他内容。
|
||
PROMPT;
|
||
}
|
||
|
||
public function build_summary_prompt(string $content, int $max_length = 200): string {
|
||
$content = mb_substr($content, 0, 3000);
|
||
return <<<PROMPT
|
||
请为以下内容生成一段简洁的摘要,不超过 {$max_length} 个字。
|
||
|
||
内容:
|
||
{$content}
|
||
|
||
只返回摘要文本,不要其他内容。
|
||
PROMPT;
|
||
}
|
||
|
||
public function build_tags_prompt(string $title, string $content): string {
|
||
$content = mb_substr($content, 0, 2000);
|
||
return <<<PROMPT
|
||
请根据以下文章内容,建议合适的标签。
|
||
|
||
文章标题:{$title}
|
||
|
||
文章内容:
|
||
{$content}
|
||
|
||
请以 JSON 数组格式返回标签列表(5-10个),例如:["标签1", "标签2"]
|
||
只返回 JSON 数组,不要其他内容。
|
||
PROMPT;
|
||
}
|
||
|
||
public function build_excerpt_prompt(string $title, string $content): string {
|
||
$content = mb_substr($content, 0, 2000);
|
||
return <<<PROMPT
|
||
请为以下文章生成一段吸引人的摘要(excerpt),用于列表页展示。
|
||
|
||
文章标题:{$title}
|
||
|
||
文章内容:
|
||
{$content}
|
||
|
||
要求:
|
||
- 50-100字
|
||
- 突出文章核心价值
|
||
- 吸引读者点击
|
||
|
||
只返回摘要文本,不要其他内容。
|
||
PROMPT;
|
||
}
|
||
|
||
private function read_custom_prompt(string $key): string {
|
||
if (!class_exists('AKSRT_Settings')) {
|
||
return '';
|
||
}
|
||
$s = AKSRT_Settings::get_all();
|
||
return trim((string) ($s[$key] ?? ''));
|
||
}
|
||
}
|