你是否曾想过:让 AI 不再只背维基百科,而是真正“吃懂”你自己的博客公司文档或产品手册,然后以对话式可追溯的方式为访客服务?借助 Cloudflare 的 Workers AI + Vectorize + Pages,无服务器低成本易扩展的 AutoRAG(检索增强生成)系统完全可以实现 — 并且做得非常好玩。

下面这篇文章在你已有内容的基础上做了必要的扩展:补全实战细节增加生产建议排查清单与示例 prompt,保留并扩展了你的每一章要点。阅读完它,你会拿到一套可复用的工程化方法论——从抓取向量化检索到前端体验部署与运维,一条龙落地。


第一章:地基与蓝图 —— 理解核心技术与准备环境

什么是 RAG(检索增强生成)——一句话理解

RAG 就像给 LLM 发放你自己写的“小抄”:当用户提问时,系统先从你准备的知识库检索最相关段落(Retrieval),把这些段落连同提问和历史对话一起供给 LLM(Augmented),让 LLM 在受限且有来源的材料上生成回答(Generation)。

为什么用 Cloudflare AutoRAG?

  • 无服务器近用户:Workers 在 Cloudflare 边缘运行,延迟小。
  • 内建向量库(Vectorize):无需自己架向量数据库。
  • Workers AI:把 embeddingreranker生成模型放在同一平台,端到端简单。

环境准备(必备)

  • Cloudflare 账号(绑定 WorkersPagesVectorize)
  • Node.js & npm(脚本与构建)
  • Wrangler CLI:npm install -g wrangler,并 wrangler login
  • 本地工具:cheerio(HTML 解析)dotenv(管理密钥)

第二章:原料加工 —— 智能地喂养你的 AI

AI 的聪明来自于「好食材」与「好加工」。抓取清洗分块与 embedding 是质量核心。

2.1 抓取(Scrape)与增量更新

  • 读取站点 sitemap.xml,与本地状态 .scrape_state.json 比对,只抓取新增/更新页面,支持增量更新,节省请求配额与时间。
  • 抓取策略:优先抓文章正文标题发布时间canonical URL,忽略评论/广告脚本。

2.2 智能分块(Chunking)与标题注入

Cloudflare Vectorize 对 metadata 有 10240 字节 限制。避免超限并提升相关性的方法:

  • 分块大小CHUNK_SIZE = 1024(字符)是安全且常用的值若你内容短则更细,长则可适当放大但务必测试 metadata 长度。
  • 标题注入:在每块前注入 这篇文章的标题是《xxx》。内容片段如下:...,让检索时每块自带上下文来源信息,极大提升检索准确性。
  • 智能切点:以句/段为单元切分,避免把一句话硬切成两半。

伪代码(分块示意):

function chunkText(title body CHUNK_SIZE=1024) {
  const prefix = `这篇文章的标题是《${title}》。内容片段如下:`
  const maxBodyPerChunk = CHUNK_SIZE - prefix.length
  let chunks = []
  for (let i = 0 i < body.length i += maxBodyPerChunk) {
    const slice = body.slice(i i + maxBodyPerChunk)
    chunks.push({ text: prefix + slice source_title: title })
  }
  return chunks
}

2.3 向量化(Embedding)

  • 使用 Cloudflare 的中文 embedding(如 @cf/baai/bge-m3),把每个 chunk 转成向量(例如 1024 维)。
  • 生成 metadata 包括 url title published_at chunk_index 等,便于来源追溯与后续过滤(按时间标签等)。
  • 批量插入时使用 wrangler vectorize insert,脚本中加上重试与速率限制(sleep分批次)以避免 API 限流。

2.4 抓取脚本要点(robustness)

  • 自动重试与指数退避(exponential backoff)
  • 降速(throttling)与并发限制,避免短时间内耗尽免费额度或被封 IP
  • 增量文件 .scrape_state.json 的幂等设计(记录每页 hash 或 last_mod)

第三章:搭建“大脑” —— Cloudflare Worker API(src/index.ts)

后端 Worker 是 RAG 流程的核心。它需要实现从 query 到答复的全流程并处理边界情况。

3.1 项目结构(建议)

src/
  index.ts        // Worker entry — RAG orchestrator
  utils.ts        // 工具函数(embeddings query vec formatting)
  prompts.ts      // system prompt 与模板
scripts/
  scrape-and-embed.mjs
public/
  index.html
  script.js
wrangler.toml

3.2 RAG 流程(实现细节)

  1. 意图识别(Intent)

    • 预定义“人设问答”(比如 “你是谁?”)直接返回静态响应,避免消耗模型调用。
  2. 向量化查询

    • 使用同一 embedding 模型(bge-m3)把用户问题向量化(保持 embedding 与索引一致)。
  3. 两阶段检索(粗召回 + 精排序)

    • 粗召回VECTORIZE_INDEX.query(queryVec { topK: 20 }) → 得到 20 个候选 chunk。
    • 精排序(reranker):把 20 个候选和原问题发给 bge-reranker-base,得到排序并选 topK(例如 5)。
  4. 构建 prompt(Prompt Engineering)

    • 把 topN 段按得分排序拼入 system prompt,附带严格规则:仅使用下列材料回答必须给出来源 URL长度或格式限制等。
  5. 生成(LLM)

    • 使用 @cf/meta/llama-3.1-8b-instruct-fast 或其他合适模型生成。注意上下文窗口(例如 8192 tokens)限制,必要时降低 topN 或做摘要(summarize each chunk)再供给模型。
  6. 流式响应

    • 打开 stream: true 让前端能一边拿到答复一边显示(更好体验)。

3.3 示例 Prompt(简化版)

System:
你是公司文档的问答助手。**只允许使用下面提供的文档段落回答问题。** 回答要简洁准确,并在回答末尾列出引用来源(标题 + URL)。

Documents:
[1] 标题: xxx
内容: ...
来源: https://your.site/xxx

User: <用户问题>
Assistant: 

第四章:赋予“面容” —— 前端聊天界面(Pages + 静态文件)

一个好的 UI 会显著提升访客转化率和体验。你已经有了基本架构(index.htmlstyle.cssscript.js),下面补充一些实用细节。

前端关键点

  • 打字机效果(流式):通过 Fetch 的 ReadableStream 或 Server-Sent Events(SSE)消费 Worker 的流式响应,分段渲染。
  • Markdown 渲染:用 marked.js 将回答中的链接渲染成可点击 <a>,并对来源链接做 target _blank 防逃逸。
  • 引导问题:前端可以从 article_titles.json 随机挑选若干句作为“示例问题”提升触发率。
  • 多轮对话:维护对话历史(localStorage 或 session),把历史短时加入每次后端请求中,注意控制历史长度以免超上下文。
  • 错误提示与重试:友好显示网络错误速率限制,并提供“重试”或“发送到邮箱”的选项。

第五章:部署与运维(包含免费额度速率限制策略)

首次部署(从零重建知识库)

  1. 清理云端索引:wrangler vectorize delete my-knowledge-base

  2. 清理本地状态与缓存:删除 .scrape_state.jsonvectors.jsonlarticle_titles.json(如需要)

  3. 创建索引:

    wrangler vectorize create my-knowledge-base --dimensions=1024 --metric=cosine
    
  4. 生成全量 vectors:node scrape-and-embed.mjs

  5. 注入数据:wrangler vectorize insert my-knowledge-base --file=vectors.jsonl(分批上传以防限流,多次传入cloudflare  Vectorize不会覆盖,是追加(append),训练数据利用这种规则)

  6. 部署后端:wrangler deploy

  7. 部署前端(Cloudflare Pages):上传 public/ 内容

 

日常更新流程(发布新文章后的轻流程)

  1. node scrape-and-embed.mjs(脚本自动只抓新文章)
  2. wrangler vectorize insert my-knowledge-base --file=vectors.jsonl(插入增量)
  3. 如果 article_titles.json 更新,重新部署 Pages(或通过 CI 更新静态文件)

监控与调试

  • 查看索引大小:Cloudflare 控制台 → Vectorize → 索引详情(Vectors 总数)。
  • 实时日志wrangler tail 可以实时查看 Worker 日志。
  • 速率限制:脚本应实现退避与分批提交(每批 N 条,间隔 t 秒)。

成本与免费额度注意

  • Cloudflare 对 Workers AI + Vectorize 有免费额度,适合个人博客和中小项目。但在全量注入或大量生成时会消耗配额,务必在脚本里限制并批量分发以避免短时大量调用。

第六章:进阶要点(安全质量提示工程故障排查)

安全与权限

  • 密钥管理:使用 Cloudflare 的 Secret 或 Wrangler 环境变量,不要在前端或公开仓库暴露 API Key。
  • 访问控制:若知识库或对话包含敏感信息,给 Worker 加上认证(JWTAPI KeyCloudflare Access)。
  • 输入过滤:对用户输入做长度频率限制与 XSS 防护(前端渲染时对 HTML 进行消毒)。

质量评估(离线与在线)

  • 离线测试:准备一组问题-参考答案集合,计算召回率(Recall@K)精确率(Precision)与最终生成质量(人工打分)。
  • A/B 测试:在不同 prompt / topK / reranker 配置间进行线上 A/B,观察用户满意率与点击来源链接率。
  • 自动化回归:每次大规模 reindex 或模型切换后跑一遍测试集。

Prompt Engineering 提示

  • 强制模型 只引用给定材料,并列出来源
  • 限制输出格式(例如 JSON with answer and sources),便于前端解析显示与埋点统计。
  • 对长内容场景,优先做 “摘要后检索” 或 “两阶段:先召回再摘要” 的流程,减少 token 使用并提升一致性。

常见故障与排查(快速清单)

  • CORS 错误:确保 Worker 响应带 Access-Control-Allow-Origin(或由 Pages 代理)。

  • oversized metadata(元数据超限):减小标题/metadata,或把长 metadata(如全文)移动到 content,并只把必要字段放入 metadata。使用智能分块并注入短标题。

  • 速率限制:加入分批延时与重试策略尽量在非高峰时间(或用后端任务队列)做全量注入。

  • 检索失败(RAG 中的核心问题)

    • 检查 embedding 模型是否与索引一致(相同模型/规范)。
    • 调整 topKreranker 阈值与 chunking 策略(过小或过大的 chunk 都会影响召回)。
    • 在检索结果不足时,返回“未找到符合你问题的来源”,并建议用户放宽或重述问题。
  • 上下文超限:对历史对话或候选文本做摘要,或将对话状态保存在外部存储并按需裁剪。


第七章:实用模板与示例(快速复制粘贴)

wrangler.toml(示例片段)

name = "my-autorag-bot"
main = "src/index.ts"
compatibility_date = "2024-04-05"

[ai]
binding = "AI"

[[vectorize]]
binding = "VECTORIZE_INDEX"
index_name = "my-knowledge-base"

常用 shell 命令汇总

# 创建索引
wrangler vectorize create my-knowledge-base --dimensions=1024 --metric=cosine

# 插入数据(若大文件请分批)
wrangler vectorize insert my-knowledge-base --file=vectors.jsonl

# 删除索引(谨慎)
wrangler vectorize delete my-knowledge-base

# 部署 Worker
wrangler deploy

# 实时 tail 日志
wrangler tail

推荐系统 prompt(更完整)

System:
你是面向用户的文档问答助手。**绝对只能使用以下材料回答**。如果材料不足以直接回答,请直接说明并提供可点击的来源链接。回答要简洁明确,最后给出“来源标题 — URL”。

[DOCUMENTS]
1) 标题: ...
内容: ...
URL: ...

User: <问题>
Assistant:

最后检查清单(部署前必做)

  • 抓取脚本是否已经做过全量跑通并生成 vectors.jsonl?
  • 是否用增量模式验证过 .scrape_state.json
  • metadata 字段是否小于 10240 字节?是否做好标题注入?
  • Worker 的 prompt 是否强制要求来源并限制输出格式?
  • 已实现速率限制/分批上传与重试?
  • 前端是否支持流式输出并已做好 XSS 过滤?
  • 密钥是否放到了 Cloudflare Secrets?前端没有暴露任何敏感信息?
  • 已在测试集上跑过召回+生成质量评估?

结语 — 把“AI 助手”当作产品来打磨

把你的网站数据变成一个智能可对话的助手,不只是技术实现,更是一项产品工作:数据治理检索策略Prompt 设计用户体验与监控都要一并考虑。Cloudflare 提供了非常便捷且经济的工具链,把这些环节串起来后,你会发现,即使是个人博客,也能拥有近乎企业级的智能问答体验。