实战:基于 Cloudflare Vectorize 与 Gemini 构建全自动 AI 语义搜索
在 2026 年,给个人博客加上 AI 搜索已经不是什么新鲜事。但如何零成本、全自动且高性能地实现这一功能,依然是一个值得探讨的技术话题。
本文将详细拆解本站 AI Search 功能背后的技术架构,展示如何组合 Cloudflare Workers、Vectorize、D1 以及 Google Gemini,构建一套闭环的 RAG(检索增强生成)系统。
1. 核心架构设计
我们的目标是实现一个“全自动”的流程:写作即部署。作者只需 Push Markdown 文章,剩下的向量生成、索引更新、前端部署全部自动化完成。
graph TD
subgraph "Control Plane (GitHub Actions)"
Push[Git Push Markdown] --> Action[Sync Workflow]
Action -->|Extract Text| Script[Python Script]
Script -->|Embed| Gemini[Gemini API]
Script -->|Upsert Vectors| Vectorize[Cloudflare Vectorize]
end
subgraph "Data Plane (Cloudflare)"
User[User Query] -->|Request| Worker[Cloudflare Worker]
Worker -->|Embed Query| Gemini
Worker -->|Search| Vectorize
Worker -->|Log & Stats| D1[D1 SQL Database]
Worker -->|Return Matches| User
end
graph TD
subgraph "Control Plane (GitHub Actions)"
Push[Git Push Markdown] --> Action[Sync Workflow]
Action -->|Extract Text| Script[Python Script]
Script -->|Embed| Gemini[Gemini API]
Script -->|Upsert Vectors| Vectorize[Cloudflare Vectorize]
end
subgraph "Data Plane (Cloudflare)"
User[User Query] -->|Request| Worker[Cloudflare Worker]
Worker -->|Embed Query| Gemini
Worker -->|Search| Vectorize
Worker -->|Log & Stats| D1[D1 SQL Database]
Worker -->|Return Matches| User
end
graph TD
subgraph "Control Plane (GitHub Actions)"
Push[Git Push Markdown] --> Action[Sync Workflow]
Action -->|Extract Text| Script[Python Script]
Script -->|Embed| Gemini[Gemini API]
Script -->|Upsert Vectors| Vectorize[Cloudflare Vectorize]
end
subgraph "Data Plane (Cloudflare)"
User[User Query] -->|Request| Worker[Cloudflare Worker]
Worker -->|Embed Query| Gemini
Worker -->|Search| Vectorize
Worker -->|Log & Stats| D1[D1 SQL Database]
Worker -->|Return Matches| User
end
graph TD
subgraph "Control Plane (GitHub Actions)"
Push[Git Push Markdown] --> Action[Sync Workflow]
Action -->|Extract Text| Script[Python Script]
Script -->|Embed| Gemini[Gemini API]
Script -->|Upsert Vectors| Vectorize[Cloudflare Vectorize]
end
subgraph "Data Plane (Cloudflare)"
User[User Query] -->|Request| Worker[Cloudflare Worker]
Worker -->|Embed Query| Gemini
Worker -->|Search| Vectorize
Worker -->|Log & Stats| D1[D1 SQL Database]
Worker -->|Return Matches| User
end
关键组件选型:
- Embedding 模型:
text-embedding-004(Google Gemini),维度 768,免费且效果优秀。 - 向量数据库:Cloudflare Vectorize,边缘原生,查询延迟极低。
- 持久化存储:Cloudflare D1 (SQLite),用于存储搜索日志和统计数据。
- 计算运行时:Cloudflare Workers,处理业务逻辑。
2. 自动化向量同步(Control Plane)
为了避免“发了文章还要手动跑脚本”的繁琐,我们利用 GitHub Actions 构建了自动同步管道。
递归文件扫描与向量化
传统的同步脚本往往只扫描根目录,但 Hugo 博客通常采用 Page Bundle 结构(content/posts/xxx/index.md)。我们需要递归查找所有 Markdown 文件,并提取 Frontmatter 中的元数据。
| |
GitHub Actions 触发器
配置 Workflow 监听 content/** 的变更,一旦检测到 Push,立即触发同步。
| |
3. 边缘侧语义检索(Data Plane)
Worker 承载了前端的搜索请求,它的核心职责是“翻译”:将用户的自然语言查询翻译成向量,再去数据库中寻找“距离最近”的文章。
向量空间距离与阈值控制
在实现过程中,我们发现一个关键问题:RAG 总是倾向于返回结果,哪怕是完全不相关的。 例如搜“法学硕士”,向量数据库可能会强行返回一篇关于“Prometheus 监控”的文章,只是因为它们的某些隐含维度(如“学习”、“考试”)有一点点重合。
为了解决这个问题,我们在 Worker 层引入了动态阈值判定逻辑:
| |
这个 0.40 是经过多次测试得出的经验值。低于此分数的匹配通常是噪音。
4. Content Gap 洞察系统
这是本站 AI 搜索最独特的功能:不仅告诉用户有什么,还告诉作者缺什么。
我们利用 D1 数据库记录了每一次搜索的 has_results 状态。通过聚合查询 has_results = 0 的记录,我们可以生成一个**“待解答问题(Content Gaps)”**列表。
SQL 聚合分析
Worker 开放了一个 action=stats 接口,执行如下 SQL:
| |
前端会将其渲染为“大家都在问(待解答)”面板:
(示意图:左侧为热门有效搜索,右侧为用户感兴趣但本站缺失的内容)
这形成了一个完美的内容生产闭环:
- 用户搜索无果。
- 系统记录为 Content Gap。
- 作者在 Dashboard 看到需求。
- 作者撰写新文章。
- 自动同步向量,填补 Gap。
5. 总结
通过 Cloudflare 全家桶(Workers + Vectorize + D1),我们仅用不到 200 行代码就构建了一个具备企业级特性的 AI 搜索系统。它不仅极快(边缘计算),而且完全免费(对于个人博客的规模)。
最重要的是,它让博客从一个单向输出的静态站点,变成了一个能够感知用户需求、引导内容创作的动态系统。