关于 cloudflare-vectorize
面向开发者的 Cloudflare Vectorize 实现指南,用于在 Workers 应用中管理向量并构建语义搜索与 RAG 流程。内容涵盖元数据过滤、向量摄取、嵌入和测试配置。
主要功能
- 01创建和管理向量索引
- 02插入、查询及删除向量
- 03按元数据过滤搜索结果
- 04构建语义搜索与 RAG 流程
- 05文档分块和批量摄取
适用场景
- 01为 Workers 应用添加语义搜索
- 02搭建基于检索的问答流程
- 03分块并批量导入文档向量
- 04按类别或状态筛选搜索结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jezweb/ claude-skills --skill cloudflare-vectorize安装后在 Claude Code 中输入/cloudflare-vectorize确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.md.claude-plugin/plugin.jsonreferences/embedding-models.mdindex-operations.mdintegration-openai-embeddings.mdintegration-workers-ai-bge-base.mdmetadata-guide.mdvector-operations.mdwrangler-commands.mdrules/cloudflare-vectorize.mdtemplates/basic-search.tsdocument-ingestion.tsmetadata-filtering.tsrag-chat.ts详细介绍
Cloudflare Vectorize
Cloudflare Vectorize 完整实现指南——借助 Cloudflare Workers 构建语义搜索、RAG(检索增强生成)和 AI 驱动应用的全球分布式向量数据库。
状态:已可用于生产环境 ✅ 最后更新:2026-01-21 依赖项:cloudflare-worker-base(用于 Worker 设置)、cloudflare-workers-ai(用于嵌入) 最新版本:[email protected]、@cloudflare/[email protected] 节省令牌:约 70% 避免的错误:14 节省的开发时间:约 4 小时
此技能提供的内容
核心功能
- ✅ 索引管理:创建、配置和管理向量索引
- ✅ 向量操作:插入、更新、查询、删除和列出向量(2025 年 8 月新增列出向量功能)
- ✅ 元数据筛选:每个索引支持 10 个元数据索引的高级筛选
- ✅ 语义搜索:使用余弦、欧几里得或点积指标查找相似向量
- ✅ RAG 模式:完整的检索增强生成工作流
- ✅ Workers AI 集成:使用 @cf/baai/bge-base-en-v1.5 原生生成嵌入
- ✅ OpenAI 集成:支持 text-embedding-3-small/large 模型
- ✅ 文档处理:文本分块和批量导入管道
- ✅ 测试设置:配置带有 Vectorize 绑定的 Vitest
包含的模板
- basic-search.ts - 使用 Workers AI 的简单向量搜索
- rag-chat.ts - 具备上下文检索功能的完整 RAG 聊天机器人
- document-ingestion.ts - 文档分块和嵌入管道
- metadata-filtering.ts - 高级筛选模式
⚠️ Vectorize V2 破坏性变更(2024 年 9 月)
重要:Vectorize V2 于 2024 年 9 月正式发布,并带来了重大破坏性变更。
V2 中的变更
性能改进:
- 索引容量:每个索引从 200,000 增至 500 万个向量
- 查询延迟:中位数从 549ms 降至 31ms(快 18 倍)
- TopK 限制:每次查询的结果数从 20 增至 100
- 扩展限制:每个账户的索引数从 100 增至 50,000
- 命名空间限制:每个索引的命名空间数从 100 增至 50,000
API 破坏性变更:
-
异步变更操作 - 所有变更操作现在均为异步:
// V2: Returns mutationId const result = await env.VECTORIZE_INDEX.insert(vectors); console.log(result.mutationId); // "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" // Vector inserts/deletes may take a few seconds to be reflected -
returnMetadata 参数 - 从布尔值改为字符串枚举:
// ❌ V1 (deprecated) { returnMetadata: true } // ✅ V2 (required) { returnMetadata: 'all' | 'indexed' | 'none' } -
插入前必须创建元数据索引:
- V2 要求在插入向量之前创建元数据索引
- 在创建元数据索引之前添加的向量不会被编入索引
- 创建元数据索引后,必须重新更新向量
V1 弃用时间表:
- 2024 年 12 月:无法再创建 V1 索引
- 现有 V1 索引:继续正常工作(其他操作不受影响)
- 迁移:对 V1 操作使用
wrangler vectorize --deprecated-v1标志
所需 Wrangler 版本:
- 最低版本:用于 V2 命令的 [email protected]
- 推荐版本:[email protected]+(最新版本)
检查变更状态
// Get index info to check last mutation processed
const info = await env.VECTORIZE_INDEX.describe();
console.log(info.mutationId); // Last mutation ID
console.log(info.processedUpToMutation); // Last processed timestamp
关键设置规则
⚠️ 必须在插入向量之前执行
# 1. Create the index with FIXED dimensions and metric
npx wrangler vectorize create my-index \
--dimensions=768 \
--metric=cosine
# 2. Create metadata indexes IMMEDIATELY (before inserting vectors!)
npx wrangler vectorize create-metadata-index my-index \
--property-name=category \
--type=string
npx wrangler vectorize create-metadata-index my-index \
--property-name=timestamp \
--type=number
原因:插入向量之前,必须先创建元数据索引。在创建元数据索引之前添加的向量,无法按该属性进行筛选。
索引配置(之后无法更改)
# Dimensions MUST match your embedding model output:
# - Workers AI @cf/baai/bge-base-en-v1.5: 768 dimensions
# - OpenAI text-embedding-3-small: 1536 dimensions
# - OpenAI text-embedding-3-large: 3072 dimensions
# Metrics determine similarity calculation:
# - cosine: Best for normalized embeddings (most common)
# - euclidean: Absolute distance between vectors
# - dot-product: For non-normalized vectors
Wrangler 配置
wrangler.jsonc:
{
"name": "my-vectorize-worker",
"main": "src/index.ts",
"compatibility_date": "2025-10-21",
"vectorize": [
{
"binding": "VECTORIZE_INDEX",
"index_name": "my-index"
}
],
"ai": {
"binding": "AI"
}
}
TypeScript 类型
export interface Env {
VECTORIZE_INDEX: VectorizeIndex;
AI: Ai;
}
interface VectorizeVector {
id: string;
values: number[] | Float32Array | Float64Array;
namespace?: string;
metadata?: Record<string, string | number | boolean | string[]>;
}
interface VectorizeMatches {
matches: Array<{
id: string;
score: number;
values?: number[];
metadata?: Record<string, any>;
namespace?: string;
}>;
count: number;
}
元数据筛选运算符(V2)
Vectorize V2 支持使用范围查询进行高级元数据筛选:
// Equality (implicit $eq)
{ category: "docs" }
// Not equals
{ status: { $ne: "archived" } }
// In/Not in arrays
{ category: { $in: ["docs", "tutorials"] } }
{ category: { $nin: ["deprecated", "draft"] } }
// Range queries (numbers) - NEW in V2
{ timestamp: { $gte: 1704067200, $lt: 1735689600 } }
// Range queries (strings) - prefix searching
{ url: { $gte: "/docs/workers", $lt: "/docs/workersz" } }
// Nested metadata with dot notation
{ "author.id": "user123" }
// Multiple conditions (implicit AND)
{ category: "docs", language: "en", "metadata.published": true }
元数据最佳实践
1. 基数注意事项
低基数(适合 $eq 筛选):
// Few unique values - efficient filtering
metadata: {
category: "docs", // ~10 categories
language: "en", // ~5 languages
published: true // 2 values (boolean)
}
高基数(避免用于范围查询):
// Many unique values - avoid large range scans
metadata: {
user_id: "uuid-v4...", // Millions of unique values
timestamp_ms: 1704067200123 // Use seconds instead
}
2. 元数据限制
- 元数据索引最多 10 个(每个 Vectorize 索引)
- 每个向量的元数据最多 10 KiB
- 字符串索引:前 64 字节(UTF-8)
- 数字索引:Float64 精度
- 筛选器大小:最多 2048 字节(紧凑 JSON)
3. 向量维度限制
当前限制:每个向量最多 1536 维 来源:GitHub Issue #8729
支持的嵌入模型:
- Workers AI
@cf/baai/bge-base-en-v1.5:768 维 ✅ - OpenAI
text-embedding-3-small:1536 维 ✅ - OpenAI
text-embedding-3-large:3072 维 ❌(需要降维)
不支持的模型(>1536 维):
nomic-embed-code:3584 维Qodo-Embed-1-7B:>1536 维
解决方法: 使用降维方法(例如 PCA)将嵌入压缩至 1536 维或更少,但这可能会降低语义质量。
功能请求:目前正在考虑支持更高维度。如果这会阻碍你的使用场景,请使用限制提升申请表。
4. 关键限制
// ❌ INVALID metadata keys
metadata: {
"": "value", // Empty key
"user.name": "John", // Contains dot (reserved for nesting)
"$admin": true, // Starts with $
"key\"with\"quotes": 1 // Contains quotes
}
// ✅ VALID metadata keys
metadata: {
"user_name": "John",
"isAdmin": true,
"nested": { "allowed": true } // Access as "nested.allowed" in filters
}
最佳实践
批量插入性能
关键提示:使用 5000 个向量的批次大小,以获得最佳性能。
性能数据:
- 单独插入:250 万个向量耗时 36 小时以上(未完成)
- 批量插入(5000):400 万个向量约耗时 12 小时
- 正确分批后快 18 倍
为什么是 5000?
- Vectorize 的内部预写日志(WAL)针对该大小进行了优化
- 避免触发 Cloudflare API 速率限制
- 平衡吞吐量与内存使用
最佳模式:
const BATCH_SIZE = 5000;
async function insertVectors(vectors: VectorizeVector[]) {
for (let i = 0; i < vectors.length; i += BATCH_SIZE) {
const batch = vectors.slice(i, i + BATCH_SIZE);
const result = await env.VECTORIZE.insert(batch);
console.log(`Inserted batch ${i / BATCH_SIZE + 1}, mutationId: ${result.mutationId}`);
// Optional: Rate limiting delay
if (i + BATCH_SIZE < vectors.length) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}
}
来源:
查询准确度模式
Vectorize 默认使用近似最近邻(ANN)搜索,与精确搜索相比,准确度约为 80%。
默认模式:近似评分(准确度约为 80%)
- 延迟更低
- 适用于 RAG、搜索和推荐
- topK 最高为 100
高精度模式:准确度接近 100%
- 通过
returnValues: true启用 - 延迟更高
- topK 限制为 20
权衡示例:
// Fast, ~80% accuracy, topK up to 100
const results = await env.VECTORIZE.query(embedding, {
topK: 50,
returnValues: false // Default
});
// Slower, ~100% accuracy, topK max 20
const preciseResults = await env.VECTORIZE.query(embedding, {
topK: 10,
returnValues: true // High-precision scoring
});
何时使用高精度模式:
- 关键应用(欺诈检测、法律合规)
- 结果集较小(topK < 20)
- 准确度优先于延迟
来源:Cloudflare 博客 - 构建 Vectorize
常见错误与解决方法
错误 1:插入向量后才创建元数据索引
Problem: Filtering doesn't work on existing vectors
Solution: Delete and re-insert vectors OR create metadata indexes BEFORE inserting
错误 2:维度不匹配
Problem: "Vector dimensions do not match index configuration"
Solution: Ensure embedding model output matches index dimensions:
- Workers AI bge-base: 768
- OpenAI small: 1536
- OpenAI large: 3072
错误 3:元数据键无效
Problem: "Invalid metadata key"
Solution: Keys cannot:
- Be empty
- Contain . (dot)
- Contain " (quote)
- Start with $ (dollar sign)
错误 4:筛选条件过大
Problem: "Filter exceeds 2048 bytes"
Solution: Simplify filter or split into multiple queries
错误 5:对高基数数据执行范围查询
Problem: Slow queries or reduced accuracy
Solution: Use lower cardinality fields for range queries, or use seconds instead of milliseconds for timestamps
错误 6:混淆 insert 与 upsert
Problem: Updates not reflecting in index
Solution: Use upsert() to overwrite existing vectors, not insert()
错误 7:缺少绑定
Problem: "VECTORIZE_INDEX is not defined"
Solution: Add [[vectorize]] binding to wrangler.jsonc
错误 8:混淆命名空间与元数据
Problem: Unclear when to use namespace vs metadata filtering
Solution:
- Namespace: Partition key, applied BEFORE metadata filters
- Metadata: Flexible key-value filtering within namespace
错误 9:V2 异步变更时序(V2 中新增)
Problem: Inserted vectors not immediately queryable
Solution: V2 mutations are asynchronous - vectors may take a few seconds to be reflected
- Use mutationId to track mutation status
- Check env.VECTORIZE_INDEX.describe() for processedUpToMutation timestamp
错误 10:V1 的 returnMetadata 布尔值(V2 中为破坏性变更)
Problem: "returnMetadata must be 'all', 'indexed', or 'none'"
Solution: V2 changed returnMetadata from boolean to string enum:
- ❌ V1: { returnMetadata: true }
- ✅ V2: { returnMetadata: 'all' }
错误 11:Wrangler --json 输出包含日志前缀
错误:wrangler vectorize list --json 的输出以日志消息开头,导致 JSON 解析失败
来源:GitHub Issue #11011
受影响的命令:
wrangler vectorize list --jsonwrangler vectorize list-metadata-index --json
问题:
$ wrangler vectorize list --json
📋 Listing Vectorize indexes...
[
{ "created_on": "2025-10-18T13:28:30.259277Z", ... }
]
日志消息会导致输出不是有效的 JSON,因此无法将输出通过管道传递给 jq 或其他工具。
解决方法:解析前移除第一行:
# Using tail
wrangler vectorize list --json | tail -n +2 | jq '.'
# Using sed
wrangler vectorize list --json | sed '1d' | jq '.'
错误 12:TypeScript 类型缺少筛选运算符
错误:wrangler types 生成的 VectorizeVectorMetadataFilterOp 类型不完整
来源:GitHub Issue #10092
状态:OPEN(内部跟踪编号为 VS-461)
问题:
生成的类型仅包含 $eq 和 $ne,缺少 V2 运算符:$in、$nin、$lt、$lte、$gt、$gte
影响: 使用有效的 V2 元数据筛选运算符时,TypeScript 会显示误报错误:
const vectorizeRes = env.VECTORIZE.queryById(imgId, {
filter: { gender: { $in: genderFilters } }, // ❌ TS error but works!
topK,
returnMetadata: 'indexed',
});
解决方法:在修复 wrangler types 之前手动覆盖类型:
// Add to your types file
type VectorizeMetadataFilter = Record<string,
| string
| number
| boolean
| {
$eq?: string | number | boolean;
$ne?: string | number | boolean;
$in?: (string | number | boolean)[];
$nin?: (string | number | boolean)[];
$lt?: number | string;
$lte?: number | string;
$gt?: number | string;
$gte?: number | string;
}
>;
错误 13:Windows 开发注册表故障(已修复)
错误:在 Windows 上运行 wrangler dev 时出现 ENOENT: no such file or directory
来源:GitHub Issue #10383
状态:已在 [email protected] 中修复
问题: Wrangler 尝试创建文件名中包含冒号的外部 Worker 文件(在 Windows 上无效):
Error: ENOENT: ... '__WRANGLER_EXTERNAL_VECTORIZE_WORKER:<project>:<binding>'
解决方案: 更新到 [email protected] 或更高版本:
npm install -g wrangler@latest
错误 14:topK 限制取决于 returnValues/returnMetadata
错误:topK exceeds maximum allowed value
来源:Vectorize 限制
问题:topK 的最大值会根据查询选项而变化:
| 配置 | topK 最大值 |
|---|---|
returnValues: false、returnMetadata: 'none' | 100 |
returnValues: true 或 returnMetadata: 'all' | 20 |
returnMetadata: 'indexed' | 100 |
常见错误:
// ❌ ERROR - topK too high with returnValues
query(embedding, {
topK: 100, // Exceeds limit!
returnValues: true // Max topK=20 when true
});
解决方案:
// ✅ OK - respects conditional limit
query(embedding, {
topK: 20,
returnValues: true
});
// ✅ OK - higher topK without values
query(embedding, {
topK: 100,
returnValues: false,
returnMetadata: 'indexed'
});
V2 迁移清单
如果从 V1 迁移到 V2:
- ✅ 将 wrangler 更新到 3.71.0+(
npm install -g wrangler@latest) - ✅ 创建新的 V2 索引(无法将 V1 升级为 V2)
- ✅ 在插入向量之前创建元数据索引
- ✅ 将
returnMetadata从布尔值改为字符串枚举('all'、'indexed'、'none') - ✅ 处理异步变更(预期响应中会包含
mutationId) - ✅ 按 V2 限制进行测试(topK 最高为 100,每个索引最多 5M 个向量)
- ✅ 更新错误处理以适应异步行为
V1 弃用:
- 2024 年 12 月之后:无法创建新的 V1 索引
- 现有 V1 索引:继续可用
- 使用
wrangler vectorize --deprecated-v1执行 V1 操作
测试注意事项
使用 Vectorize 绑定的 Vitest
问题:将 @cloudflare/vitest-pool-workers 与 Vectorize 或 Workers AI 绑定搭配使用会导致运行时故障。
来源:GitHub Issue #7434
错误:wrapped binding module can't be resolved
解决方法:
- 创建不包含 Vectorize/AI 绑定的
wrangler-test.jsonc - 将 vitest 配置指向专用于测试的 wrangler 文件
- 在测试中模拟绑定
示例:
// wrangler-test.jsonc (no Vectorize binding)
{
"name": "my-worker-test",
"main": "src/index.ts",
"compatibility_date": "2025-10-21"
// No vectorize binding
}
// vitest.config.ts
import { defineWorkersProject } from '@cloudflare/vitest-pool-workers/config';
export default defineWorkersProject({
test: {
poolOptions: {
workers: {
wrangler: {
configPath: "./wrangler-test.jsonc"
}
}
}
}
});
// Mock in tests
import { vi } from 'vitest';
const mockVectorize = {
query: vi.fn().mockResolvedValue({
matches: [
{ id: 'test-1', score: 0.95, metadata: { category: 'docs' } }
],
count: 1
}),
insert: vi.fn().mockResolvedValue({ mutationId: "test-mutation-id" }),
upsert: vi.fn().mockResolvedValue({ mutationId: "test-mutation-id" })
};
// Use mock in tests
test('vector search', async () => {
const env = { VECTORIZE_INDEX: mockVectorize };
// ... test logic
});
社区提示
注意:这些提示来自社区讨论和官方博客文章。请根据你的 Vectorize 版本进行核实。
提示 1:大规模范围查询的准确性可能会降低(来源:社区)
来源:查询最佳实践 可信度:中 适用于:包含约 10M+ 个向量的数据集
大型数据集上的范围查询($lt、$lte、$gt、$gte)可能会出现准确性下降。
优化策略:
// ❌ High-cardinality range at scale
metadata: {
timestamp_ms: 1704067200123
}
filter: { timestamp_ms: { $gte: 1704067200000 } }
// ✅ Bucketed into discrete values
metadata: {
timestamp_bucket: "2025-01-01-00:00", // 1-hour buckets
timestamp_ms: 1704067200123 // Original (non-indexed)
}
filter: {
timestamp_bucket: {
$in: ["2025-01-01-00:00", "2025-01-01-01:00"]
}
}
适用场景:
- 按时间筛选数月或数年的数据
- 用户 ID、交易 ID(UUID 范围)
- 任何高基数连续数据
替代方案:使用相等筛选($eq、$in)和分桶值。
提示 2:列出向量操作(2025 年 8 月新增)
Vectorize V2 新增了对 list-vectors 操作的支持,可分页遍历向量 ID。
使用场景:
- 审计向量集合
- 批量向量操作
- 调试索引内容
API:
const result = await env.VECTORIZE_INDEX.list({
limit: 1000, // Max 1000 per page
cursor?: string
});
// result.vectors: Array<{ id: string }>
// result.cursor: string | undefined
// result.count: number
// Pagination example
let cursor: string | undefined;
const allVectorIds: string[] = [];
do {
const result = await env.VECTORIZE_INDEX.list({
limit: 1000,
cursor
});
allVectorIds.push(...result.vectors.map(v => v.id));
cursor = result.cursor;
} while (cursor);
限制:
- 仅返回 ID(不返回值或元数据)
- 每页最多 1000 个向量
- 使用游标进行分页
官方文档
- Vectorize V2 文档:https://developers.cloudflare.com/vectorize/
- V2 更新日志:https://developers.cloudflare.com/vectorize/platform/changelog/
- 从 V1 迁移到 V2:https://developers.cloudflare.com/vectorize/reference/transition-vectorize-legacy/
- 元数据筛选:https://developers.cloudflare.com/vectorize/reference/metadata-filtering/
- Workers AI 模型:https://developers.cloudflare.com/workers-ai/models/
状态:可用于生产 ✅(Vectorize V2 正式发布 - 2024 年 9 月) 最后更新:2026-01-21 Token 节省:约 70% 避免的错误:14 项(包括 V2 破坏性变更、测试设置、TypeScript 类型) 变更:新增 4 项错误(wrangler --json、TypeScript 类型、Windows 开发、topK 限制),批处理性能最佳实践、查询准确度模式、测试设置,以及社区分享的范围查询和 list-vectors 操作技巧。