关于博客

我的博客 AI 摘要是怎么工作的:main、deploy 与 Cloudflare Workers AI

2026-07-26 #记录
早风依旧
正在加载歌曲信息……
私有音源
0:00 0:00

这篇文章专门记录博客里的 AI 摘要系统。

它和 QQ 群通知是两套独立工作流:

  • AI 摘要负责生成文章摘要、更新 deploy、触发 Cloudflare 部署
  • QQ 群通知负责在新文章真正上线后发送群消息

这篇只记录 AI 摘要部分,方便以后回顾架构、排查问题,或者继续修改生成逻辑。


目前的分支结构

博客现在使用两个 Git 分支:

1
2
3
4
5
6
7
8
9
10
11
12
13
main
├─ 我手动维护
├─ 保存 Markdown 文章
├─ 保存 Hexo 配置
├─ 保存主题、CSS 和 JavaScript
├─ 保存 GitHub Actions 工作流
└─ 不保存 AI 摘要缓存

deploy
├─ GitHub Actions 自动维护
├─ 内容以最新 main 为基础
├─ 额外保存 AI 摘要缓存
└─ 由 Cloudflare 实际构建并部署

日常开发只操作:

1
main

不要手动修改:

1
deploy

一句话概括:

1
我维护 main,机器人维护 deploy,Cloudflare 只部署 deploy。

为什么不用 main 直接保存摘要

最初的方案是让 GitHub Actions 把摘要缓存提交回 main:

1
source/_data/ai-summaries.json

这样虽然能工作,但机器人每生成一次摘要,远程 main 就会多出一个提交。

本地继续推送时可能出现:

1
! [rejected] main -> main (fetch first)

然后需要额外执行:

1
git pull --rebase origin main

如果本地还有未提交内容,还可能需要:

1
2
3
git stash
git pull --rebase origin main
git stash pop

为了避免机器人不断修改我日常使用的 main,后来把自动生成内容全部放到了独立的 deploy 分支。

现在:

1
2
3
4
5
main
只保存我手动维护的源码

deploy
保存最新源码和自动生成的摘要

这样本地发布文章时,不会再因为摘要机器人提交而产生同步冲突。


AI 摘要工作流的文件位置

GitHub Actions 工作流:

1
.github/workflows/generate-ai-summaries.yml

摘要生成脚本:

1
.github/scripts/generate-ai-summaries.mjs

Hexo 摘要渲染脚本:

1
scripts/ai-summary-render.js

摘要样式:

1
source/css/ai-summary.css

摘要缓存:

1
source/_data/ai-summaries.json

其中,摘要缓存只由 deploy 分支保存。

main 中通过 .gitignore 忽略:

1
source/_data/ai-summaries.json

完整自动流程

当我把内容推送到 main 后,AI 摘要工作流自动启动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
本地修改文章或博客源码
↓
提交并推送 main
↓
GitHub Actions 检出最新 main
↓
从 deploy 恢复已有 ai-summaries.json
↓
检查本次有哪些文章发生变化
↓
调用 Cloudflare Workers AI
↓
生成或更新摘要缓存
↓
把最新 main 和摘要缓存一起推送到 deploy
↓
Cloudflare 检测到 deploy 更新
↓
执行 Hexo 构建
↓
部署博客

Cloudflare 不再直接部署 main。

只有 deploy 更新时,才会触发正式网站构建。


当前使用的 AI 模型

当前模型:

1
@cf/zai-org/glm-4.7-flash

通过 Cloudflare Workers AI REST API 调用。

GitHub 仓库中需要配置两个 Secrets:

1
2
CLOUDFLARE_ACCOUNT_ID
CLOUDFLARE_AI_TOKEN

Token 不能写入代码、文章或普通仓库文件中。


摘要什么时候会重新生成

脚本会根据文章内容生成一个哈希:

1
sourceHash

它用于判断文章是否发生变化。

规则如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
新文章
→ 生成摘要

文章正文改变
→ 重新生成摘要

文章标题或参与哈希的内容改变
→ 重新生成摘要

文章没有变化
→ 使用 deploy 中已有的缓存

只修改主题、CSS、JavaScript 或配置
→ 不调用模型,只把最新 main 同步到 deploy

因此不会每次部署都重复调用模型。


摘要缓存保存了什么

ai-summaries.json 中每篇文章大致包含:

1
2
3
4
5
6
7
8
{
"title": "文章标题",
"slug": "文章文件名或 slug",
"summary": "模型生成的摘要",
"sourceHash": "内容哈希",
"model": "@cf/zai-org/glm-4.7-flash",
"generatedAt": "生成时间"
}

其中:

  • title:文章标题
  • slug:用于匹配文章
  • summary:最终显示的摘要
  • sourceHash:判断缓存是否仍然有效
  • model:摘要来源
  • generatedAt:生成时间

摘要如何显示到文章里

Hexo 构建时,scripts/ai-summary-render.js 会读取:

1
source/_data/ai-summaries.json

然后根据以下信息匹配文章:

1
2
3
文章源文件路径
slug
标题

匹配成功后,把 AI 摘要卡片插入正文最前面:

1
2
3
4
5
文章标题与元信息
↓
AI 摘要卡片
↓
文章正文

摘要是构建时静态写入 HTML 的,不是访客打开页面后再请求 AI。

这样做的好处:

  • AI Token 不会暴露给浏览器
  • 访客打开文章时不需要等待模型
  • 已生成摘要不会受 AI 服务临时故障影响
  • 搜索引擎能直接读取静态 HTML
  • 不会增加每次访问文章的 AI 调用成本

私密文章的处理

脚本默认不会把私密文章发送给 AI。

满足以下任意条件时,会跳过:

1
permalink: /private/...

或者:

1
private: true

或者:

1
2
tags:
- 私密文章

或者:

1
2
categories:
- 私人记录

日志会显示:

1
私密文章默认不发送给 AI

允许某篇私密文章调用 AI

1
ai_summary_private: true

只有确认文章内容可以发送给模型时才使用。

关闭某篇文章的 AI 摘要

1
ai_summary: false

自己填写摘要,不调用模型

1
2
ai_summary_text: >
这里填写手动摘要。

手动摘要仍会显示在文章中,但不会消耗 Workers AI 调用。


手动运行摘要工作流

进入:

1
2
3
4
5
GitHub
→ zqf-blog
→ Actions
→ 生成文章 AI 摘要并同步 deploy
→ Run workflow

Use workflow from 始终选择:

1
main

不要选择 deploy。

missing 模式

1
2
3
生成范围:missing
文章路径:留空
最多生成:按需要填写

作用:

1
2
3
为缺少摘要的文章生成摘要
重新处理正文已经变化的文章
跳过仍然有效的缓存

这是最常用的模式。

single 模式

1
2
3
生成范围:single
文章路径:source/_posts/文章文件名.md
最多生成:1

适合只测试一篇文章。

all 模式

1
生成范围:all

它会强制重新生成候选文章。

通常只有在以下情况使用:

  • 修改了摘要提示词
  • 更换了模型
  • 想把所有旧摘要重写一遍

平时不需要选择 all。


Cloudflare 的相关设置

Cloudflare 连接的仓库:

1
zqf1314/zqf-blog

生产分支:

1
deploy

非生产分支构建:

1
关闭

所以:

1
2
3
4
5
main 更新
→ 不直接部署

deploy 更新
→ 执行正式构建

当前构建命令:

1
pnpm run build

对应执行:

1
hexo generate

当前部署命令:

1
pnpm exec wrangler deploy

最终部署的是:

1
public/

修改不同内容时会发生什么

新增文章

1
2
3
4
推送 main
→ 生成新摘要
→ 更新 deploy
→ Cloudflare 部署

修改旧文章正文

1
2
3
4
5
推送 main
→ 文章哈希变化
→ 重新生成摘要
→ 更新 deploy
→ Cloudflare 部署

修改主题、CSS 或 JavaScript

1
2
3
4
5
推送 main
→ 候选文章可能为 0
→ 模型调用为 0
→ 仍然同步 deploy
→ Cloudflare 部署

日志出现下面内容是正常的:

1
2
3
本次候选文章:0
模型调用:0
失败:0

这表示本次没有文章需要调用 AI,不代表部署失败。

删除文章

1
2
3
4
推送 main
→ deploy 同步删除文章
→ 清理失效摘要缓存
→ Cloudflare 部署

总结

当前 AI 摘要系统可以概括为:

1
2
3
4
main 保存人工维护的源码
deploy 保存可部署源码和 AI 摘要
GitHub Actions 负责连接二者
Cloudflare 只部署 deploy

以后只需要维护 main。

deploy、AI 摘要缓存和 Cloudflare 部署全部由自动化流程处理。

评论
分享

评论