本文首发地址 https://h89.cn/archives/643.html

写博客这几年,一直有个头疼的问题:标签。

刚开博客那会儿,每篇文章都认真打标签,写描述。时间一长就懈怠了——发布按钮一点,标题扔上去就完事,哪还记得补 description 和标签。日积月累,文章几百篇,标签没几个,搜索结果页的描述也常年空缺。

试过手动整理,坚持了两天就放弃了。几百篇文章,一篇篇翻、写标签、写描述,这活不是人干的。

所以有了这个插件。当前版本支持:面板按文章质量、有无标签、有无Meta筛选文章,自动同步文章状态、批量TAG/Meta增强 SEO/GEO。

市面上 Typecho 的 SEO 插件不少,但基本只做静态优化——改改 title、加加 keywords、生成个 sitemap。没有用 LLM 做内容理解的。而标签和描述恰恰是最需要语义理解的事:读懂文章才能写出好描述,理解内容才能推荐准标签。这事 LLM 最擅长,所以把两件事合并到一个插件里。

它能干什么

自动生成 SEO 描述。 每发布一篇文章,插件自动调 LLM 生成一段 SEO 描述(下限 100 字,引导 100-180 字),直接写进文章的自定义字段。前台自动输出到 <meta name="description">,搜索结果展示的时候就有内容了。也支持手动触发——编辑页有个「AI 生成描述」按钮,点一下就行。

标签补充 + 质量评估。 插件扫描你所有已发布的文章,对每篇读标题和正文,看你现有的标签库,推荐 4-7 个标签(优先复用已有标签,必要时创建新标签),给当前标签质量打分:high / medium / low,顺手把关系写进 typecho_relationships。后台有个批量面板,进度条、实时日志、暂停继续、失败重试都有。几百篇文章跑一轮也就几分钟。

怎么用

安装。 把仓库放到 Typecho 插件目录:

cd data/usr/plugins/
git clone https://gitee.com/chenjim/LLM-SEO-Tag-Meta LLMSEOTagMeta

然后进 Typecho 后台 → 插件 → 启用,配置 API Key 即可。

配置。 打开设置页面,配好 LLM API(默认指向 DeepSeek,兼容任意 OpenAI 接口):

  • API Endpoint — 你用的模型服务地址
  • API Key — 从服务商获取的密钥
  • Model — 模型名

建议用 deepseek-v4-flash 或同类快速模型,单次生成耗时基本在 1-3 秒内。默认发布时自动生成描述+异步子进程模式,不阻塞发布流程。想改成手动也行,在设置里选一下。

批量处理。 后台菜单「LLM SEO Tag Meta」进面板,统一文章列表页面:

  1. 筛选 + 批量操作 — 按标签/Meta/质量 筛选文章,勾选后批量生成标签或描述
  2. 单篇操作 — 每行有生成标签和 Meta 的独立按钮,质量 badge 直接显示在标题旁
  3. 自动同步 + 配置校验 — 进入面板自动同步文章状态,顶部 info bar 一键校验 API 配置

截图。

后台面板

后台面板:文章列表、筛选、批量操作

设置页

设置页:API 配置与 Meta/标签参数

测试。

docker compose exec -T typecho php /app/usr/plugins/LLMSEOTagMeta/test_plugin.php

45 个集成测试用例覆盖语法、表单、清洗、JSON 解析、parseFlatTags、BLOCKLIST、数据库操作、插件激活。

设计与实现

目录结构。

LLMSEOTagMeta/
├── Plugin.php              # 插件入口:激活、配置、Hook 注册、Action 注册
├── Action.php              # Action 路由:统一处理 ?do=xxx 请求(10 个端点)
├── panel.php               # 后台单页面板:info bar + 统计 + 筛选 + 文章列表 + 批量操作 + 分页
├── worker.php              # 异步子进程入口(CLI,可选)
├── lib/
│   ├── LLMClient.php       # OpenAI 兼容 Chat API 封装(cURL + 重试)
│   ├── ContentCleaner.php  # HTML/Markdown 清洗 + 多字节截断
│   ├── MetaDescService.php # Meta 描述生成、字段读写、前台输出
│   ├── TagService.php      # 标签推荐、标签创建、关系写入、质量评估
│   ├── TaskService.php     # 批量任务状态、统计、断点续跑
│   └── JsonHelper.php      # LLM JSON 解析辅助
└── assets/
    ├── admin.js            # 后台 AJAX、分页、批量队列、质量 badge
    └── admin.css           # 单页布局样式

Plugin.php 只做注册和分发,不承载复杂业务。MetaDescService 和 TagService 分别处理两个业务域,LLMClient/ContentCleaner 被两者共享。

数据库。 Meta 描述存储在 typecho_fields,字段名 seo_description_llm;标签使用 Typecho 原生 typecho_metas + typecho_relationships;任务状态存在自定义表 typecho_seo_tag_meta_status,tag_status 和 meta_status 两列分别跟踪,枚举值 pending/processing/done/skipped/failed。所有 SQL 兼容 SQLite / MySQL。

Hook 与 Action。

Hook 触发 用途
finishPublish 文章发布 自动生成 Meta 描述(auto 模式)
write-post.php:bottom 编辑页 注入"AI 生成描述"按钮
admin/header.php (filter) 后台所有页 注入 CSS/JS
headerOptions (filter) 前台页面 输出 <meta name="description">
getDefaultFieldItems (filter) 编辑页 注入 seo_description_llm 字段

发布时自动生成条件:旧状态非 publish、新状态为 publish、meta_mode=auto、字段不存在、正文非空、API 配置有效。不阻塞发布流程。

Action 统一端点 /action/llm-seo-tag-meta:

do 说明 权限
generate_meta 单篇生成 Meta 描述 editor+
generate_tags 单篇生成标签 administrator
batch_generate_meta 批量生成 Meta administrator
enhance_tags 批量增强标签 administrator
stats 获取统计 administrator
sync_posts 同步文章到状态表 administrator
reset_tag_status 重置标签状态 administrator
reset_meta_status 重置 Meta 状态 administrator
validate_config 校验 API 配置 administrator
get_meta_posts 文章列表分页查询(支持 tag/meta/quality 筛选) administrator

核心模块。

LLMClient 是统一的 OpenAI 兼容 Chat API 封装,核心方法 chat(array $messages, array $options): array。响应兼容 choices[0].message.content、choices[0].text、data.content,并将 reasoning_content 作为 content 为空的回退。连接超时默认 5 秒,请求总超时默认 120 秒;HTTP 429 / 500 / 502 / 503 / 504 可重试,400 / 401 / 403 不重试,重试间隔 1 秒。应用层重试由各 Service 控制。

MetaDescService 生成流程:校验 → 清洗正文 → 截取 → 渲染 Prompt → 调 LLM → 后处理(去前缀、去 reasoning 前缀)。meta_retry_count + 1 次尝试,LLM 返回为空、后处理为空或字数低于 meta_min_chars(默认 100 字)时自动重试。下限 100 字硬校验+重试,上限由 Prompt 软引导(100-180 字),不硬截断。

TagService 增强流程:校验 → 清洗 → 截取 → 加载现有标签库 → 渲染 Prompt → 调 LLM → JSON 解析 → BLOCKLIST 过滤 → 创建/复用标签 → 清空旧关系 → 写入新关系 → 更新标签计数 → 更新状态表。tag_range 控制标签数量(默认 4-7),代码层按上限硬截断。slug 生成:去空格 → 转小写 → 非字母数字中文替换为 - → 合并连续 -。常量 BLOCKLIST_TAGS 剔除描述性泛词,中文如教程/指南/经验等,英文如 tutorial/guide/api/data 等。parseFlatTags 兜底:LLM 返回逗号/换行分隔的文本列表时自动解析为标签数组,不报错。

版本兼容。 支持 Typecho 1.2+。本插件使用 namespace 风格钩子注册 \Typecho\Plugin::factory('Widget\\Contents\\Post\\Edit');Typecho 1.3 无 leftJoin(),改用 join() + Db::LEFT_JOIN;PluginInterface 接口名在 1.3 为 \Typecho\Plugin\PluginInterface;admin/header 钩子在 1.3 变为 filter 类型;addPanel() 索引推荐用 1(控制台下)。

安全。 所有 POST 请求校验 Typecho CSRF token,缺失或无效返回 403;editor 可单篇生成 Meta,administrator 可批量/配置/标签操作;administrator 可操作全部文章,editor 仅限自己的文章;日志不记录 API Key、完整正文、完整 Prompt;不依赖 Referer 或 X-Requested-With 替代 token;停用插件不会删除状态表、自定义字段、标签关系,回滚后数据可直接复用。

Prompt 模板。 Prompt 内嵌在 Plugin.php::defaultMetaPrompt() 和 defaultTagPrompt() 中,不暴露给用户编辑。Meta 描述 Prompt 使用 {title}、{content}、{tags} 变量;标签增强使用 {title}、{content}、{existing_tags}、{tag_range}。两者均发送 system message:直接输出 JSON/文字,不做任何推理分析。

技术栈

  • Typecho 1.2+ / PHP 8.2+
  • SQLite(兼容 MySQL)
  • cURL 直调 OpenAI 兼容 API,无多余依赖
  • 异步子进程可选,exec() 启动独立 PHP 进程,不阻塞 Web 请求

本文链接:LLM SEO Tag Meta — 用 AI 给你的 Typecho 博客做 SEO - https://h89.cn/archives/643.html

版权声明:原创文章 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文链接和本声明。

标签: AI, Typecho, deepseek, openai, Prompt, Token, LLM, SEO

欸谨特公众号
微信扫码关注:欸谨特
Agent · 效率工具 · 实战笔记

添加新评论