cloudflare-vectorize
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCloudflare Vectorize
Cloudflare Vectorize
Complete implementation guide for Cloudflare Vectorize - a globally distributed vector database for building semantic search, RAG (Retrieval Augmented Generation), and AI-powered applications with Cloudflare Workers.
Status: Production Ready ✅
Last Updated: 2026-01-21
Dependencies: cloudflare-worker-base (for Worker setup), cloudflare-workers-ai (for embeddings)
Latest Versions: wrangler@4.59.3, @cloudflare/workers-types@4.20260109.0
Token Savings: ~70%
Errors Prevented: 14
Dev Time Saved: ~4 hours
完整的Cloudflare Vectorize实现指南——这是一个全球分布式向量数据库,可用于在Cloudflare Workers上构建语义搜索、RAG(检索增强生成)和AI驱动的应用。
状态:已就绪可用于生产 ✅
最后更新:2026-01-21
依赖项:cloudflare-worker-base(用于Worker设置)、cloudflare-workers-ai(用于生成嵌入向量)
最新版本:wrangler@4.59.3, @cloudflare/workers-types@4.20260109.0
Token节省率:约70%
预防的错误数量:14
节省的开发时间:约4小时
What This Skill Provides
本技能提供的内容
Core Capabilities
核心功能
- ✅ Index Management: Create, configure, and manage vector indexes
- ✅ Vector Operations: Insert, upsert, query, delete, and list vectors (list-vectors added August 2025)
- ✅ Metadata Filtering: Advanced filtering with 10 metadata indexes per index
- ✅ Semantic Search: Find similar vectors using cosine, euclidean, or dot-product metrics
- ✅ RAG Patterns: Complete retrieval-augmented generation workflows
- ✅ Workers AI Integration: Native embedding generation with @cf/baai/bge-base-en-v1.5
- ✅ OpenAI Integration: Support for text-embedding-3-small/large models
- ✅ Document Processing: Text chunking and batch ingestion pipelines
- ✅ Testing Setup: Vitest configuration with Vectorize bindings
- ✅ 索引管理:创建、配置和管理向量索引
- ✅ 向量操作:插入、更新插入、查询、删除和列出向量(list-vectors功能于2025年8月新增)
- ✅ 元数据过滤:每个索引支持10个元数据索引的高级过滤
- ✅ 语义搜索:使用余弦、欧几里得或点积度量查找相似向量
- ✅ RAG模式:完整的检索增强生成工作流
- ✅ Workers AI集成:与@cf/baai/bge-base-en-v1.5原生集成生成嵌入向量
- ✅ OpenAI集成:支持text-embedding-3-small/large模型
- ✅ 文档处理:文本分块和批量摄入流水线
- ✅ 测试设置:带有Vectorize绑定的Vitest配置
Templates Included
包含的模板
- basic-search.ts - Simple vector search with Workers AI
- rag-chat.ts - Full RAG chatbot with context retrieval
- document-ingestion.ts - Document chunking and embedding pipeline
- metadata-filtering.ts - Advanced filtering patterns
- basic-search.ts - 基于Workers AI的简单向量搜索
- rag-chat.ts - 带上下文检索的完整RAG聊天机器人
- document-ingestion.ts - 文档分块和嵌入向量流水线
- metadata-filtering.ts - 高级过滤模式
⚠️ Vectorize V2 Breaking Changes (September 2024)
⚠️ Vectorize V2重大变更(2024年9月)
IMPORTANT: Vectorize V2 became GA in September 2024 with significant breaking changes.
重要提示:Vectorize V2于2024年9月正式发布(GA),包含多项重大破坏性变更。
What Changed in V2
V2中的变更
Performance Improvements:
- Index capacity: 200,000 → 5 million vectors per index
- Query latency: 549ms → 31ms median (18× faster)
- TopK limit: 20 → 100 results per query
- Scale limits: 100 → 50,000 indexes per account
- Namespace limits: 100 → 50,000 namespaces per index
Breaking API Changes:
-
Async Mutations - All mutations now asynchronous:typescript
// 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 Parameter - Boolean → String enum:typescript
// ❌ V1 (deprecated) { returnMetadata: true } // ✅ V2 (required) { returnMetadata: 'all' | 'indexed' | 'none' } -
Metadata Indexes Required Before Insert:
- V2 requires metadata indexes created BEFORE vectors inserted
- Vectors added before metadata index won't be indexed
- Must re-upsert vectors after creating metadata index
V1 Deprecation Timeline:
- December 2024: Can no longer create V1 indexes
- Existing V1 indexes: Continue to work (other operations unaffected)
- Migration: Use flag for V1 operations
wrangler vectorize --deprecated-v1
Wrangler Version Required:
- Minimum: wrangler@3.71.0 for V2 commands
- Recommended: wrangler@4.54.0+ (latest)
性能提升:
- 索引容量:从20万 → 每个索引500万向量
- 查询延迟:从549ms → 中位数31ms(快18倍)
- TopK限制:从20 → 每次查询最多100个结果
- 规模限制:从100 → 每个账户最多50,000个索引
- 命名空间限制:从100 → 每个索引最多50,000个命名空间
破坏性API变更:
-
异步变更 - 所有变更操作现在都是异步的:typescript
// V2:返回mutationId const result = await env.VECTORIZE_INDEX.insert(vectors); console.log(result.mutationId); // "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" // 向量插入/删除可能需要几秒才会生效 -
returnMetadata参数 - 从布尔值改为字符串枚举:typescript
// ❌ V1(已弃用) { returnMetadata: true } // ✅ V2(必填) { returnMetadata: 'all' | 'indexed' | 'none' } -
插入向量前必须创建元数据索引:
- V2要求在插入向量前先创建元数据索引
- 在元数据索引创建前添加的向量无法被索引
- 创建元数据索引后必须重新插入或更新插入向量
V1弃用时间线:
- 2024年12月:无法再创建V1索引
- 现有V1索引:可继续使用(其他操作不受影响)
- 迁移:使用标志执行V1操作
wrangler vectorize --deprecated-v1
所需Wrangler版本:
- 最低版本:wrangler@3.71.0(用于V2命令)
- 推荐版本:wrangler@4.54.0+(最新版)
Check Mutation Status
检查变更状态
typescript
// 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 timestamptypescript
// 获取索引信息以检查最后处理的变更
const info = await env.VECTORIZE_INDEX.describe();
console.log(info.mutationId); // 最后一个变更ID
console.log(info.processedUpToMutation); // 最后处理的时间戳Critical Setup Rules
关键设置规则
⚠️ MUST DO BEFORE INSERTING VECTORS
⚠️ 插入向量前必须完成的操作
bash
undefinedbash
undefined1. Create the index with FIXED dimensions and metric
1. 创建具有固定维度和度量的索引
npx wrangler vectorize create my-index
--dimensions=768
--metric=cosine
--dimensions=768
--metric=cosine
npx wrangler vectorize create my-index
--dimensions=768
--metric=cosine
--dimensions=768
--metric=cosine
2. Create metadata indexes IMMEDIATELY (before inserting vectors!)
2. 立即创建元数据索引(在插入向量之前!)
npx wrangler vectorize create-metadata-index my-index
--property-name=category
--type=string
--property-name=category
--type=string
npx wrangler vectorize create-metadata-index my-index
--property-name=timestamp
--type=number
--property-name=timestamp
--type=number
**Why**: Metadata indexes MUST exist before vectors are inserted. Vectors added before a metadata index was created won't be filterable on that property.npx wrangler vectorize create-metadata-index my-index
--property-name=category
--type=string
--property-name=category
--type=string
npx wrangler vectorize create-metadata-index my-index
--property-name=timestamp
--type=number
--property-name=timestamp
--type=number
**原因**:元数据索引必须在插入向量前存在。在元数据索引创建前添加的向量无法通过该属性进行过滤。Index Configuration (Cannot Be Changed Later)
索引配置(创建后无法修改)
bash
undefinedbash
undefinedDimensions MUST match your embedding model output:
维度必须与嵌入向量模型的输出匹配:
- Workers AI @cf/baai/bge-base-en-v1.5: 768 dimensions
- Workers AI @cf/baai/bge-base-en-v1.5:768维度
- OpenAI text-embedding-3-small: 1536 dimensions
- OpenAI text-embedding-3-small:1536维度
- OpenAI text-embedding-3-large: 3072 dimensions
- OpenAI text-embedding-3-large:3072维度
Metrics determine similarity calculation:
度量方式决定相似度计算:
- cosine: Best for normalized embeddings (most common)
- cosine:最适合归一化嵌入向量(最常用)
- euclidean: Absolute distance between vectors
- euclidean:向量间的绝对距离
- dot-product: For non-normalized vectors
- dot-product:用于非归一化向量
undefinedundefinedWrangler Configuration
Wrangler配置
wrangler.jsonc:
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"
}
}wrangler.jsonc:
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 Types
TypeScript类型
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;
}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;
}Metadata Filter Operators (V2)
元数据过滤操作符(V2)
Vectorize V2 supports advanced metadata filtering with range queries:
typescript
// 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 }Vectorize V2支持带范围查询的高级元数据过滤:
typescript
// 相等(隐式$eq)
{ category: "docs" }
// 不等于
{ status: { $ne: "archived" } }
// 在/不在数组中
{ category: { $in: ["docs", "tutorials"] } }
{ category: { $nin: ["deprecated", "draft"] } }
// 范围查询(数字)- V2新增
{ timestamp: { $gte: 1704067200, $lt: 1735689600 } }
// 范围查询(字符串)- 前缀搜索
{ url: { $gte: "/docs/workers", $lt: "/docs/workersz" } }
// 使用点符号的嵌套元数据
{ "author.id": "user123" }
// 多条件(隐式AND)
{ category: "docs", language: "en", "metadata.published": true }Metadata Best Practices
元数据最佳实践
1. Cardinality Considerations
1. 基数考量
Low Cardinality (Good for $eq filters):
typescript
// Few unique values - efficient filtering
metadata: {
category: "docs", // ~10 categories
language: "en", // ~5 languages
published: true // 2 values (boolean)
}High Cardinality (Avoid in range queries):
typescript
// Many unique values - avoid large range scans
metadata: {
user_id: "uuid-v4...", // Millions of unique values
timestamp_ms: 1704067200123 // Use seconds instead
}低基数(适合$eq过滤):
typescript
// 唯一值少 - 过滤效率高
metadata: {
category: "docs", // 约10个分类
language: "en", // 约5种语言
published: true // 2个值(布尔型)
}高基数(避免用于范围查询):
typescript
// 唯一值多 - 避免大范围扫描
metadata: {
user_id: "uuid-v4...", // 数百万个唯一值
timestamp_ms: 1704067200123 // 改用秒级时间戳
}2. Metadata Limits
2. 元数据限制
- Max 10 metadata indexes per Vectorize index
- Max 10 KiB metadata per vector
- String indexes: First 64 bytes (UTF-8)
- Number indexes: Float64 precision
- Filter size: Max 2048 bytes (compact JSON)
- 每个Vectorize索引最多10个元数据索引
- 每个向量的元数据最大10 KiB
- 字符串索引:前64字节(UTF-8)
- 数字索引:Float64精度
- 过滤条件大小:最大2048字节(压缩JSON)
3. Vector Dimension Limit
3. 向量维度限制
Current Limit: 1536 dimensions per vector
Source: GitHub Issue #8729
Supported Embedding Models:
- Workers AI : 768 dimensions ✅
@cf/baai/bge-base-en-v1.5 - OpenAI : 1536 dimensions ✅
text-embedding-3-small - OpenAI : 3072 dimensions ❌ (requires dimension reduction)
text-embedding-3-large
Unsupported Models (>1536 dimensions):
- : 3584 dimensions
nomic-embed-code - : >1536 dimensions
Qodo-Embed-1-7B
Workaround:
Use dimensionality reduction (e.g., PCA) to compress embeddings to 1536 or fewer dimensions, though this may reduce semantic quality.
Feature Request: Higher dimension support is under consideration. Use Limit Increase Request Form if this blocks your use case.
当前限制:每个向量最多1536维度
来源:GitHub Issue #8729
支持的嵌入向量模型:
- Workers AI :768维度 ✅
@cf/baai/bge-base-en-v1.5 - OpenAI :1536维度 ✅
text-embedding-3-small - OpenAI :3072维度 ❌(需要降维)
text-embedding-3-large
不支持的模型(>1536维度):
- :3584维度
nomic-embed-code - :>1536维度
Qodo-Embed-1-7B
解决方法:
使用降维方法(如PCA)将嵌入向量压缩到1536或更少维度,但这可能会降低语义质量。
功能请求:正在考虑支持更高维度。如果此限制阻碍了你的使用,请使用限制提升请求表单。
4. Key Restrictions
4. 关键限制
typescript
// ❌ 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
}typescript
// ❌ 无效的元数据键
metadata: {
"": "value", // 空键
"user.name": "John", // 包含点(保留用于嵌套)
"$admin": true, // 以$开头
"key\"with\"quotes": 1 // 包含引号
}
// ✅ 有效的元数据键
metadata: {
"user_name": "John",
"isAdmin": true,
"nested": { "allowed": true } // 在过滤中以"nested.allowed"访问
}Best Practices
最佳实践
Batch Insert Performance
批量插入性能
Critical: Use batch size of 5000 vectors for optimal performance.
Performance Data:
- Individual inserts: 2.5M vectors in 36+ hours (incomplete)
- Batch inserts (5000): 4M vectors in ~12 hours
- 18× faster with proper batching
Why 5000?
- Vectorize's internal Write-Ahead Log (WAL) optimized for this size
- Avoids Cloudflare API rate limits
- Balances throughput and memory usage
Optimal Pattern:
typescript
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));
}
}
}Sources:
关键:使用5000个向量的批量大小以获得最佳性能。
性能数据:
- 单次插入:36小时以上插入250万向量(未完成)
- 批量插入(5000):约12小时插入400万向量
- 使用正确的批量大小快18倍
为什么是5000?
- Vectorize的内部预写日志(WAL)针对此大小优化
- 避免Cloudflare API速率限制
- 平衡吞吐量和内存使用
最优模式:
typescript
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(`插入批次 ${i / BATCH_SIZE + 1},mutationId: ${result.mutationId}`);
// 可选:速率限制延迟
if (i + BATCH_SIZE < vectors.length) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}
}来源:
Query Accuracy Modes
查询精度模式
Vectorize uses approximate nearest neighbor (ANN) search by default with ~80% accuracy compared to exact search.
Default Mode: Approximate scoring (~80% accuracy)
- Faster latency
- Good for RAG, search, recommendations
- topK up to 100
High-Precision Mode: Near 100% accuracy
- Enabled via
returnValues: true - Higher latency
- Limited to topK=20
Trade-off Example:
typescript
// 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
});When to Use High-Precision:
- Critical applications (fraud detection, legal compliance)
- Small result sets (topK < 20)
- Accuracy is higher priority than latency
Vectorize默认使用近似最近邻(ANN)搜索,与精确搜索相比精度约为80%。
默认模式:近似评分(约80%精度)
- 延迟更低
- 适合RAG、搜索、推荐
- topK最多100
高精度模式:接近100%精度
- 通过启用
returnValues: true - 延迟更高
- 限制topK=20
权衡示例:
typescript
// 快速,约80%精度,topK最多100
const results = await env.VECTORIZE.query(embedding, {
topK: 50,
returnValues: false // 默认
});
// 较慢,约100%精度,topK最大20
const preciseResults = await env.VECTORIZE.query(embedding, {
topK: 10,
returnValues: true // 高精度评分
});何时使用高精度模式:
- 关键应用(欺诈检测、合规性)
- 小结果集(topK < 20)
- 精度优先于延迟
Common Errors & Solutions
常见错误与解决方案
Error 1: Metadata Index Created After Vectors Inserted
错误1:元数据索引在插入向量后创建
Problem: Filtering doesn't work on existing vectors
Solution: Delete and re-insert vectors OR create metadata indexes BEFORE inserting问题:现有向量无法被过滤
解决方案:删除并重新插入向量 或 在插入向量前创建元数据索引Error 2: Dimension Mismatch
错误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问题:"Vector dimensions do not match index configuration"
解决方案:确保嵌入向量模型的输出与索引维度匹配:
- Workers AI bge-base: 768
- OpenAI small: 1536
- OpenAI large: 3072Error 3: Invalid Metadata Keys
错误3:无效的元数据键
Problem: "Invalid metadata key"
Solution: Keys cannot:
- Be empty
- Contain . (dot)
- Contain " (quote)
- Start with $ (dollar sign)问题:"Invalid metadata key"
解决方案:键不能:
- 为空
- 包含.(点)
- 包含"(引号)
- 以$(美元符号)开头Error 4: Filter Too Large
错误4:过滤条件过大
Problem: "Filter exceeds 2048 bytes"
Solution: Simplify filter or split into multiple queries问题:"Filter exceeds 2048 bytes"
解决方案:简化过滤条件或拆分为多个查询Error 5: Range Query on High Cardinality
错误5:高基数字段的范围查询
Problem: Slow queries or reduced accuracy
Solution: Use lower cardinality fields for range queries, or use seconds instead of milliseconds for timestamps问题:查询缓慢或精度降低
解决方案:使用低基数字段进行范围查询,或对时间戳使用秒级而非毫秒级Error 6: Insert vs Upsert Confusion
错误6:Insert与Upsert混淆
Problem: Updates not reflecting in index
Solution: Use upsert() to overwrite existing vectors, not insert()问题:更新未在索引中生效
解决方案:使用upsert()覆盖现有向量,而非insert()Error 7: Missing Bindings
错误7:缺少绑定
Problem: "VECTORIZE_INDEX is not defined"
Solution: Add [[vectorize]] binding to wrangler.jsonc问题:"VECTORIZE_INDEX is not defined"
解决方案:在wrangler.jsonc中添加[[vectorize]]绑定Error 8: Namespace vs Metadata Confusion
错误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问题:不清楚何时使用命名空间 vs 元数据过滤
解决方案:
- 命名空间:分区键,在元数据过滤前应用
- 元数据:命名空间内灵活的键值对过滤Error 9: V2 Async Mutation Timing (NEW in V2)
错误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问题:插入的向量无法立即查询到
解决方案:V2变更是异步的 - 向量可能需要几秒才会生效
- 使用mutationId跟踪变更状态
- 检查env.VECTORIZE_INDEX.describe()的processedUpToMutation时间戳Error 10: V1 returnMetadata Boolean (BREAKING in V2)
错误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' }问题:"returnMetadata must be 'all', 'indexed', or 'none'"
解决方案:V2将returnMetadata从布尔值改为字符串枚举:
- ❌ V1: { returnMetadata: true }
- ✅ V2: { returnMetadata: 'all' }Error 11: Wrangler --json Output Contains Log Prefix
错误11:Wrangler --json输出包含日志前缀
Error: output starts with log message, breaking JSON parsing
Source: GitHub Issue #11011
wrangler vectorize list --jsonAffected Commands:
wrangler vectorize list --jsonwrangler vectorize list-metadata-index --json
Problem:
bash
$ wrangler vectorize list --json
📋 Listing Vectorize indexes...
[
{ "created_on": "2025-10-18T13:28:30.259277Z", ... }
]The log message makes output invalid JSON, breaking piping to or other tools.
jqSolution: Strip first line before parsing:
bash
undefined错误:输出以日志消息开头,导致JSON解析失败
来源:GitHub Issue #11011
wrangler vectorize list --json受影响的命令:
wrangler vectorize list --jsonwrangler vectorize list-metadata-index --json
问题:
bash
$ wrangler vectorize list --json
📋 Listing Vectorize indexes...
[
{ "created_on": "2025-10-18T13:28:30.259277Z", ... }
]日志消息导致输出为无效JSON,无法通过等工具处理。
jq解决方案:解析前删除第一行:
bash
undefinedUsing tail
使用tail
wrangler vectorize list --json | tail -n +2 | jq '.'
wrangler vectorize list --json | tail -n +2 | jq '.'
Using sed
使用sed
wrangler vectorize list --json | sed '1d' | jq '.'
---wrangler vectorize list --json | sed '1d' | jq '.'
---Error 12: TypeScript Types Missing Filter Operators
错误12:TypeScript类型缺少过滤操作符
Error: generates incomplete type
Source: GitHub Issue #10092
Status: OPEN (tracked internally as VS-461)
wrangler typesVectorizeVectorMetadataFilterOpProblem:
Generated type only includes and , missing V2 operators: , , , , ,
$eq$ne$in$nin$lt$lte$gt$gteImpact:
TypeScript shows false errors when using valid V2 metadata filter operators:
typescript
const vectorizeRes = env.VECTORIZE.queryById(imgId, {
filter: { gender: { $in: genderFilters } }, // ❌ TS error but works!
topK,
returnMetadata: 'indexed',
});Workaround: Manual type override until wrangler types is fixed:
typescript
// 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;
}
>;错误:生成的类型不完整
来源:GitHub Issue #10092
状态:OPEN(内部跟踪编号VS-461)
wrangler typesVectorizeVectorMetadataFilterOp问题:
生成的类型仅包含和,缺少V2操作符:, , , , ,
$eq$ne$in$nin$lt$lte$gt$gte影响:
使用有效的V2元数据过滤操作符时,TypeScript会显示错误,但实际运行正常:
typescript
const vectorizeRes = env.VECTORIZE.queryById(imgId, {
filter: { gender: { $in: genderFilters } }, // ❌ TS错误但可正常运行!
topK,
returnMetadata: 'indexed',
});解决方法:在wrangler types修复前手动覆盖类型:
typescript
// 添加到你的类型文件
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;
}
>;Error 13: Windows Dev Registry Failure (FIXED)
错误13:Windows开发环境注册表失败(已修复)
Error: when running on Windows
Source: GitHub Issue #10383
Status: FIXED in wrangler@4.32.0
ENOENT: no such file or directorywrangler devProblem:
Wrangler attempted to create external worker files with colons in the name (invalid on Windows):
Error: ENOENT: ... '__WRANGLER_EXTERNAL_VECTORIZE_WORKER:<project>:<binding>'Solution:
Update to wrangler@4.32.0 or later:
bash
npm install -g wrangler@latest错误:在Windows上运行时出现
来源:GitHub Issue #10383
状态:在wrangler@4.32.0中已修复
wrangler devENOENT: no such file or directory问题:
Wrangler尝试创建名称包含冒号的外部Worker文件(Windows不支持):
Error: ENOENT: ... '__WRANGLER_EXTERNAL_VECTORIZE_WORKER:<project>:<binding>'解决方案:
更新到wrangler@4.32.0或更高版本:
bash
npm install -g wrangler@latestError 14: topK Limit Depends on returnValues/returnMetadata
错误14:topK限制取决于returnValues/returnMetadata
Error:
Source: Vectorize Limits
topK exceeds maximum allowed valueProblem: Maximum topK value changes based on query options:
| Configuration | Max topK |
|---|---|
| 100 |
| 20 |
| 100 |
Common Error:
typescript
// ❌ ERROR - topK too high with returnValues
query(embedding, {
topK: 100, // Exceeds limit!
returnValues: true // Max topK=20 when true
});Solution:
typescript
// ✅ OK - respects conditional limit
query(embedding, {
topK: 20,
returnValues: true
});
// ✅ OK - higher topK without values
query(embedding, {
topK: 100,
returnValues: false,
returnMetadata: 'indexed'
});错误:
来源:Vectorize限制
topK exceeds maximum allowed value问题:最大topK值根据查询选项变化:
| 配置 | 最大topK |
|---|---|
| 100 |
| 20 |
| 100 |
常见错误:
typescript
// ❌ 错误 - returnValues为true时topK过高
query(embedding, {
topK: 100, // 超过限制!
returnValues: true // 当为true时最大topK=20
});解决方案:
typescript
// ✅ 正确 - 遵守条件限制
query(embedding, {
topK: 20,
returnValues: true
});
// ✅ 正确 - 不返回值时使用更高的topK
query(embedding, {
topK: 100,
returnValues: false,
returnMetadata: 'indexed'
});V2 Migration Checklist
V2迁移检查清单
If migrating from V1 to V2:
- ✅ Update wrangler to 3.71.0+ ()
npm install -g wrangler@latest - ✅ Create new V2 index (can't upgrade V1 → V2)
- ✅ Create metadata indexes BEFORE inserting vectors
- ✅ Update boolean → string enum ('all', 'indexed', 'none')
returnMetadata - ✅ Handle async mutations (expect in responses)
mutationId - ✅ Test with V2 limits (topK up to 100, 5M vectors per index)
- ✅ Update error handling for async behavior
V1 Deprecation:
- After December 2024: Cannot create new V1 indexes
- Existing V1 indexes: Continue to work
- Use for V1 operations
wrangler vectorize --deprecated-v1
如果从V1迁移到V2:
- ✅ 将wrangler更新到3.71.0+()
npm install -g wrangler@latest - ✅ 创建新的V2索引(无法将V1升级到V2)
- ✅ 在插入向量前创建元数据索引
- ✅ 将从布尔值改为字符串枚举('all', 'indexed', 'none')
returnMetadata - ✅ 处理异步变更(响应中包含)
mutationId - ✅ 测试V2限制(topK最多100,每个索引500万向量)
- ✅ 更新针对异步行为的错误处理
V1弃用:
- 2024年12月后:无法创建新的V1索引
- 现有V1索引:可继续使用
- 执行V1操作使用
wrangler vectorize --deprecated-v1
Testing Considerations
测试注意事项
Vitest with Vectorize Bindings
使用Vectorize绑定的Vitest
Issue: Using with Vectorize or Workers AI bindings causes runtime failure.
Source: GitHub Issue #7434
@cloudflare/vitest-pool-workersError:
wrapped binding module can't be resolvedWorkaround:
- Create without Vectorize/AI bindings
wrangler-test.jsonc - Point vitest config to test-specific wrangler file
- Mock bindings in your tests
Example:
typescript
// 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或Workers AI绑定会导致运行时失败。
来源:GitHub Issue #7434
@cloudflare/vitest-pool-workers错误:
wrapped binding module can't be resolved解决方法:
- 创建不带Vectorize/AI绑定的
wrangler-test.jsonc - 将vitest配置指向测试专用的wrangler文件
- 在测试中模拟绑定
示例:
typescript
// wrangler-test.jsonc(无Vectorize绑定)
{
"name": "my-worker-test",
"main": "src/index.ts",
"compatibility_date": "2025-10-21"
// 无vectorize绑定
}
// vitest.config.ts
import { defineWorkersProject } from '@cloudflare/vitest-pool-workers/config';
export default defineWorkersProject({
test: {
poolOptions: {
workers: {
wrangler: {
configPath: "./wrangler-test.jsonc"
}
}
}
}
});
// 在测试中模拟
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" })
};
// 在测试中使用模拟
test('vector search', async () => {
const env = { VECTORIZE_INDEX: mockVectorize };
// ... 测试逻辑
});Community Tips
社区技巧
Note: These tips come from community discussions and official blog posts. Verify against your Vectorize version.
注意:这些技巧来自社区讨论和官方博客。请根据你的Vectorize版本进行验证。
Tip 1: Range Queries at Scale May Have Reduced Accuracy (Community-sourced)
技巧1:大规模范围查询可能降低精度(社区贡献)
Source: Query Best Practices
Confidence: MEDIUM
Applies to: Datasets with ~10M+ vectors
Range queries (, , , ) on large datasets may experience reduced accuracy.
$lt$lte$gt$gteOptimization Strategy:
typescript
// ❌ 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"]
}
}When This Matters:
- Time-based filtering over months/years
- User IDs, transaction IDs (UUID ranges)
- Any high-cardinality continuous data
Alternative: Use equality filters (, ) with bucketed values.
$eq$in来源:查询最佳实践
可信度:中等
适用场景:数据集约1000万+向量
在大型数据集上使用范围查询(, , , )可能会降低精度。
$lt$lte$gt$gte优化策略:
typescript
// ❌ 大规模高基数范围查询
metadata: {
timestamp_ms: 1704067200123
}
filter: { timestamp_ms: { $gte: 1704067200000 } }
// ✅ 分桶为离散值
metadata: {
timestamp_bucket: "2025-01-01-00:00", // 1小时分桶
timestamp_ms: 1704067200123 // 原始值(未索引)
}
filter: {
timestamp_bucket: {
$in: ["2025-01-01-00:00", "2025-01-01-01:00"]
}
}适用场景:
- 基于时间的跨月/年过滤
- 用户ID、交易ID(UUID范围)
- 任何高基数连续数据
替代方案:使用等值过滤(, )搭配分桶后的值。
$eq$inTip 2: List Vectors Operation (Added August 2025)
技巧2:列出向量操作(2025年8月新增)
Source: Vectorize Changelog
Vectorize V2 added support for the operation for paginated iteration through vector IDs.
list-vectorsUse Cases:
- Auditing vector collections
- Bulk vector operations
- Debugging index contents
API:
typescript
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);Limitations:
- Returns IDs only (not values or metadata)
- Max 1000 vectors per page
- Use cursor for pagination
Vectorize V2新增了操作,支持分页遍历向量ID。
list-vectors使用场景:
- 审计向量集合
- 批量向量操作
- 调试索引内容
API:
typescript
const result = await env.VECTORIZE_INDEX.list({
limit: 1000, // 每页最多1000个
cursor?: string
});
// result.vectors: Array<{ id: string }>
// result.cursor: string | undefined
// result.count: number
// 分页示例
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个向量
- 使用cursor进行分页
Official Documentation
官方文档
- Vectorize V2 Docs: https://developers.cloudflare.com/vectorize/
- V2 Changelog: https://developers.cloudflare.com/vectorize/platform/changelog/
- V1 to V2 Migration: https://developers.cloudflare.com/vectorize/reference/transition-vectorize-legacy/
- Metadata Filtering: https://developers.cloudflare.com/vectorize/reference/metadata-filtering/
- Workers AI Models: https://developers.cloudflare.com/workers-ai/models/
Status: Production Ready ✅ (Vectorize V2 GA - September 2024)
Last Updated: 2026-01-21
Token Savings: ~70%
Errors Prevented: 14 (includes V2 breaking changes, testing setup, TypeScript types)
Changes: Added 4 new errors (wrangler --json, TypeScript types, Windows dev, topK limits), batch performance best practices, query accuracy modes, testing setup, community tips on range queries and list-vectors operation.
- 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 GA - 2024年9月)
最后更新:2026-01-21
Token节省率:约70%
预防的错误数量:14(包括V2破坏性变更、测试设置、TypeScript类型问题)
变更:新增4类错误(wrangler --json、TypeScript类型、Windows开发、topK限制)、批量性能最佳实践、查询精度模式、测试设置、关于范围查询和list-vectors操作的社区技巧。