用 Cloudflare 免费额度搭一套私有知识库
架构一览
Markdown 仓库(私有) |
选这套的原因很朴素:没有一个组件需要常驻服务器。
Neo4j、OpenSPG 这类图数据库确实更强,但要一台机器一直开着,就不符合”零成本”。
四个撞过的硬限制
1. 嵌入请求有 6 万 token 的总上限
第一次跑索引,第一批就 400:
AiError: Max context reached 99392 tokens but model supports only 60000 |
原因是按固定 64 条一批,而中文分片每片接近 900 token,64 × 900 直接顶破。
改成按估算 token 预算动态分批,并对单条做字符上限保护;仍失败就二分重试。
2. KV 的单键上限是 25 MiB
索引产物里有一份 embeddings.jsonl,88 MB,PUT 直接 413:
content size of 87905171 bytes exceeds maximum allowed size of 27MiB |
后来发现这个键运行时根本没人读——向量在 Vectorize 里,Worker 只读docs.json 和 meta.json。删掉即可。先查清楚谁在读,再决定怎么存。
3. D1 单条语句的绑定参数有上限
想在一条 SQL 里从 300 个节点取边:
WHERE e.src IN (?,?,...) OR e.dst IN (?,?,...) -- 600 个参数 |
直接 500。官方文档没写这个数,实测大约 100。改成拆两条 SQL、每批 50 个 id,
再用 id 去重合并。
4. 免费神经元额度是 10,000/天
全量重建一次约 3000 neurons(4290 片 × 约 700 token),
所以一天最多重建三次。这直接决定了:增量索引不是”优化”,是”必需”。
一个反直觉的设计:判定放在离线
一开始我想把规则引擎放进 Worker,请求时现算。算了一下:1187 篇 × 13 条规则 ≈ 1.5 万条判定,
而 Workers 免费档单请求 CPU 只有 10 ms——跑不完,也写不完。
于是把判定挪到管线里离线跑(一次约 3 秒),Worker 只做”读”。
副产品是:判定结果成了可查看的历史快照,而不是每次请求都变的临时值。
代价与收益
| 项 | 结果 |
|---|---|
| 月成本 | 0 元 |
| 全量索引耗时 | 约 4 分钟(Actions) |
| 查询延迟 | 毫秒级(D1 / KV 命中) |
| 规模上限 | Vectorize 5M 维度,当前已用 87.8% |
最后一行是唯一的隐患:知识库再涨约 14%,语义检索就会超限。
到那天的退路已经想好了——降级成纯关键词检索,功能不崩,只是没那么”聪明”。
小结
免费额度的真正价值不是”省钱”,而是逼你把架构想清楚:
不能堆组件,就得想清楚每一层到底在解决什么问题。
这套系统里,真正不可替代的只有两件事——分片策略和规则。
其余的,都是可以替换的实现细节。


