借助 Cloudflare Workers 实现一个静态博客可用的 AI 摘要

24 年 11 月 16 日 星期六
1541 字
8 分钟

AI 摘要

奋力赶来...

使用 Astro-Gyoza 搭建博客后一直想加上 AI 摘要功能,看了下 TianliGPT 这样的解决方案,对于我这种没什么流量的小站,使用商业化方案并没有什么太大的意义,于是就有了自己实现一个的想法。

方案设计思路

在实现 AI 摘要功能时,静态博客通常有两种技术路线:构建时生成和访问时生成。考虑到 AI 接口调用的稳定性和成本因素,本方案选择了访问时生成的策略,并通过 Cloudflare 的 Workers、D1 和 KV 构建了一套完整的缓存机制。这种架构不仅能够保证服务的稳定性,还能显著降低运营成本。

功能逻辑与系统架构

页面被访问时将页面的 url 发送到 Worker,Worker 再根据 D1 中是否有缓存摘要、是否过期的判断再进行调用 AI 进行摘要的生成与更新。

Workers 中根据 Accept-Language 或者指定的参数生成对应语言的摘要,摘要更新借助 KV 实现一个锁机制减少 AI 调用(虽然小流量完全用不到)。为了除了网页内容,引入了 https://r.jina.ai 实现 HTML =>> Markdown 的转换(后续也有其他逻辑处理 HTML,但目前还没用到)。

Accept-Language 作为 Prompt 时会出现摘要语言不稳定的情况(可能是不同模型能力问题),所以引入 Cloudflare AI 的小模型以及一张基础数据表构成语言转换功能,实现 zh-CN =>> Chinese (Simplified, China) 的转换。

AI摘要逻辑

总体来说响应速度是最优先考虑的因素,总结核心流程就是五个步骤:

  1. 接收页面访问请求及 URL
  2. 检查 D1 数据库中的 AI 摘要缓存状态,返回缓存中的摘要内容
  3. 根据缓存状态决定是否调用 AI 生成摘要(首次生成或更新缓存)
  4. 通过 KV 锁机制控制 AI 调用并发
  5. 摘要缓存入库,首次摘要生成的页面此时返回结果

Cloudflare Summary Worker 部署简述

  1. GitHub 中 Fork cf-worker-summary 到自己账号下,并在 Settings - Secrets and variables - Action 中添加必要的变量,D1、KV、Cloudflre Token 需要先创建完成获取相应的参数,更详细说明可以阅读仓库的 ReadMe 以及 deploy.yml
secret
  • AI_PROVIDER:要使用的 AI 服务提供商(openai、anthropic 或 cloudflare)
  • AI_MODEL:要使用的特定 AI 模型(例如,OpenAI 的 gpt-3.5-turbo)
  • AI_API_KEY:您选择的 AI 提供商的 API 密钥
  • AI_ENDPOINT:(可选)AI API 的自定义端点 URL
  • ALLOWED_DOMAINS:允许的文章 URL 域名列表,用逗号分隔
  • CACHE_TTL:缓存生存时间(以秒为单位,例如 604800 表示 7 天)
  • MAX_CONTENT_LENGTH:允许处理的文章内容的最大长度
  • SUMMARY_MIN_LENGTH:生成摘要的最小长度
  • KV_NAMESPACE_ID: 用于绑定 Worker KV
  • D1_DATABASE_NAME: 创建的 D1 数据库名称
  • D1_DATABASE_ID: D1 数据库的 ID,创建后可复制
  • CLOUDFLARE_API_TOKEN: 用于发布 Worker 的 Cloudflare Token
  • SUMMARY_API: 用于调用的 API 地址,例如:api.example.com
  • CLOUDFLARE_ZONE_ID: 可在 Cloudflare 域名页面中中找到
  1. 在 Cloudflare D1 中执行以下 SQL 完成库表创建以及基础数据的初始化。(此步骤非必需但建议)
sql
CREATE TABLE summaries (
     article_url TEXT NOT NULL,
     summary TEXT NOT NULL,
     model TEXT NOT NULL,
     language TEXT NOT NULL,
     created_at INTEGER NOT NULL,
     PRIMARY KEY (article_url, language)
   );

   CREATE TABLE languages (
     language_code TEXT PRIMARY KEY,
     language_name TEXT NOT NULL,
     created_at DATETIME DEFAULT CURRENT_TIMESTAMP
   );

   INSERT INTO languages (language_code, language_name) VALUES
  ('en', 'English'),
  ('en-US', 'English (United States)'),
  ('en-GB', 'English (United Kingdom)'),
  ('en-CA', 'English (Canada)'),
  ('en-AU', 'English (Australia)'),
  ('en-NZ', 'English (New Zealand)'),
  ('en-IE', 'English (Ireland)'),
  ('en-SG', 'English (Singapore)'),
  ('zh', 'Chinese'),
  ('zh-CN', 'Chinese (Simplified, China)'),
  ('zh-TW', 'Chinese (Traditional, Taiwan)'),
  ('zh-HK', 'Chinese (Traditional, Hong Kong)'),
  ('zh-MO', 'Chinese (Traditional, Macau)'),
  ('zh-SG', 'Chinese (Simplified, Singapore)'),
  ('vi', 'Vietnamese'),
  ('vi-VN', 'Vietnamese (Vietnam)'),
  ('ta', 'Tamil'),
  ('ta-IN', 'Tamil (India)'),
  ('ta-SG', 'Tamil (Singapore)');
  1. 在 Action 中运行 workflow 即可等待完成 Cloudflare Worker 的部署。
deploy

API 接口说明

基础调用

  1. 使用 accept-language 确定摘要语言的摘要生成服务,其中 url 参数指定为需要总结的页面
http
GET https://your-worker-url.workers.dev/summary?url=https://example.com/article
  1. 指定特定语言摘要的接口,需要通过 lang 参数指定语言,比如:zh、en、en-US
http
GET https://your-worker-url.workers.dev/summary?url=https://example.com/article&lang=zh

响应格式

API 将返回一个 JSON 响应

json
{
  "summary": "生成的文章摘要",
  "model": "用于摘要的 AI 模型"
}

关于模型的选择

虽然默认只做了 OpenAI、Claude、Claudflare AI 的接口适配,但是多数 AI 厂商都选择兼容 OpenAI,无形中增加了可选模型的范围,所以整个体验也就测试了不少厂商的模型。

模型厂商感受
deepseek-chat深度求索1. 中文摘要很出彩,相同的 Prompt,要强于千问1.5
2. 价格应该是最低的,在访问量相近、缓存策略相同的情况下,费用远低于月之暗面
moonshot-v1-8k月之暗面1. 中文摘要依然很强,需要调教一下 Prompt
2. 费用应该是高于 deepseek,但是最终摘要质量相差不大
llama-3.2-90b-text-previewMeta1. 中文摘要质量不算差,只是偶尔会有中英混合的情况以及乱翻译的情况(Cloudflare 变成 云flare)
2. 使用的免费服务,价格消耗不太确定
qwen1.5-14b-chat-awq阿里使用的 Cloudflare AI 中的模型,完全可以胜任中文摘要使用
gpt-4o-minOpenAI多语言支持很好,在产出非中文摘要时,有些带有中文文化色彩的名词会保留(比如:过年)

选用的模型单纯在摘要产出这样的简单应用层面,都能够达到很好的效果,只是在 prompt 方面可能需要一些不同的调整和优化(先天不足,后天可补)。更大的模型确实表现的效果会更好一些,但结合实际的应用场景,响应速度、价格才是更应关注的层面,这也是在实现这套摘要逻辑时引入了缓存以及锁机制的原因。

未来规划(非计划):一点想法

AI 接口考虑整体使用独立 Cloudflare Workers 部署,外部应用可以使用统一的接口调用,扩展 AI 支持上会更方便,同时不影响下游应用。接口上按照默认 AI 调用队列、指定特定 AI 模型、指定特定 AI 调用队列三种方式应该足够满足使用场景。

文章标题:借助 Cloudflare Workers 实现一个静态博客可用的 AI 摘要

文章作者:Cedar

文章链接:https://some.fylsen.com/posts/building-ai-summary-service-with-cloudflare-workers  [复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。