揭露 Vectorize 按「存储向量维度 + 查询向量维度」双重计费的反直觉定价模式:查询费用 = (索引向量数 + 查询次数) × 维度数,而非单纯的查询次数 × 维度数,实测大多数估算错一个数量级且偏高。
Vectorize 按维度计费,而非按向量数量,也非按查询次数。两个计费单位中,有一个的定义相当反直觉,以至于大多数人对 Vectorize 费用的估算都朝着同一个方向错了一个数量级。
Cloudflare 的 Vectorize 定价页面定义了两个概念:
存储向量维度(Stored vector dimensions)——索引中所有向量的维度总和。Cloudflare 的示例:1,000 个维度为 1,536 的向量 = 153.6 万存储向量维度。
查询向量维度(Queried vector dimensions)——Cloudflare 的示例:一个包含 10,000 个维度为 384 的向量的索引,查询 100 次,总计 387.8 万查询向量维度。
先停在这个示例上,因为它就是整页的核心。100 次查询 × 384 维度 = 38,400。Cloudflare 给出的数字是 3,878,400——大了整整 100 倍。多出来的部分是索引本身:10,000 × 384 = 3,840,000,加上查询的 38,400。
Cloudflare 声明的计费公式为:((查询向量 + 存储向量) × 维度 × ($0.01 / 1,000,000)) + (存储向量 × 维度 × ($0.05 / 100,000,000))。因此查询向量维度 =(索引中的向量数 + 查询次数)× 维度,而非查询次数 × 维度。
这是最值得记住的事实。你的查询计费项与索引大小成正比,而不仅仅与查询量成正比,因为一次查询在概念上要和整个索引做比对。一个月只查一次的索引,仍然要按自身大小积累查询维度。
撰写时的公开额度:Workers Free 每月包含 3,000 万查询向量维度和 500 万存储向量维度。Workers Paid 每月包含前 5,000 万查询向量维度(超出后 $0.01/百万),以及前 1,000 万存储向量维度(超出后 $0.05/亿)。
本节所有数字均为撰写时 Cloudflare 的公开数值。在将其纳入预算前,请务必对照 Cloudflare Vectorize 定价页面进行核实。
假设条件列明,方便你替换为自己的数字:索引含 20 万个维度为 768 的向量(一个文档语料库分块到约一段文字、用 768 维模型做嵌入),当月 5 万次查询,使用 Workers Paid。以下均非实测,而是对公开费率的算术运算。
queried vector dimensions
= (200,000 stored + 50,000 queries) x 768
= 192,000,000
stored vector dimensions
= 200,000 x 768
= 153,600,000
query charge
= (192,000,000 - 50,000,000 included) / 1,000,000 x $0.01
= 142 x $0.01
= $1.42
storage charge
= (153,600,000 - 10,000,000 included) / 100,000,000 x $0.05
= 1.436 x $0.05
= $0.07
total = $1.49 per month
在这个推算中有两件事是"按查询计费"心智模型看不到的。查询费用占账单的 95%,尽管存储的原始数字更大,因为两个费率相差 20 倍。在 1.92 亿查询维度中,9,600 万来自索引本身的存在,只有 0.038 万来自查询——查询相对于索引大小来说只是舍入误差。
用同一个语料库跑 Free 计划的每月 3,000 万查询维度额度,容纳不下:1.92 亿是额度的六倍多。20 万向量的索引,无论流量多少,都是付费工作负载。
Free 计划的两项额度分别是每月 3,000 万查询向量维度和 500 万存储向量维度。由于两者都与同一个维度数字成正比,可以直接换算出最大语料库规模——而答案并非人们预期的那样,因为看起来较小的那个额度反而先触及上限。
storage ceiling (the binding one)
5,000,000 / 384 = ~13,020 vectors at 384 dimensions
5,000,000 / 768 = ~6,510 vectors at 768 dimensions
5,000,000 / 1024 = ~4,880 vectors at 1024 dimensions
query ceiling, for an index already at the storage ceiling
30,000,000 / 768 = 39,062 total (stored + queries)
minus 6,510 stored = ~32,550 queries per month
= ~1,085 queries per day
因此 Free 计划在 768 维度下约能容纳 6,500 个向量——相当于几百页文档分块到段落的量——且在这个规模下每天约一千次查询。将维度减半到 384,两个数字同时翻倍,这是维度作为主导杠杆最清晰的例证。
注意第二个计算依赖第一个。由于查询维度包含了索引自身大小,更小的索引能为实际查询留出更多 3,000 万额度中的空间。一个含 1,000 个 768 维向量的索引在第一次查询前就消耗了 0.0768 万额度,然后还能吸收约 3.8 万次查询;而达到存储上限的索引消耗 500 万额度,只能再吸收约 3.25 万次。两个额度是耦合的,将它们视为独立预算会高估实际可用量。
Cloudflare 文档记载向量最大支持 1,536 维度(32 位精度)。这是模型选择的硬性约束,而非计费问题,且是人们最晚才发现的第二件事。
超过 1,536 维的嵌入模型无法直接存储。如果某个提供商支持请求更短的输出——部分模型的训练方式使得截断后的前缀向量仍然可用——那是官方支持的路径。如果不支持,对未设计为此用途的模型随意截断会以难以察觉、更难归因的方式损害检索质量。
Cloudflare 自有的嵌入模型在 384、768 和 1024 维度上都稳稳处于该上限以内,所以只有引入第三方模型时这才会成为实际问题。
给定公式后,杠杆只有三个,且并非同等有用:
维度(Dimension)。它同时乘以两项。将维度从 768 降到 384,同等数据和同等流量下账单减半。这是最大的单一杠杆,且只在创建索引前可用,因为维度是不可变的。
向量数量(Vector count)。同样乘以两项。分块策略既是检索决策也是成本决策:400 token 的分块相较于 200 token 的分块,在同等语料下将向量数量减半。
查询量(Query volume)。直到接近索引规模之前几乎没有影响。在上述例子中,将查询量增加两倍(从 5 万到 15 万)只增加了 7,680 万,相对于 1.92 亿来说是真实的,但相对于上述两项是二阶的。
反直觉的结论是:在 Vectorize 上缓存查询几乎省不了多少钱,而从索引中删除过期向量则能为当月每次查询节省费用。从示例索引中删除 5 万个向量,会减少 3,840 万查询维度和 3,840 万存储维度,账单削减约四分之一。关于这如何与旁边的推理费用共同作用,参见 Workers AI pricing and neuron limits。
Creating a Vectorize Index on Cloudflare
Cloudflare Workers AI Pricing and Neuron Limits
Querying Cloudflare Vectorize From a Worker