标题字典结构
向量条目结构¶
Cloudflare Vectorize 使用如下 TypeScript 接口结构存储向量:
interface VectorizeItem {
id: string; // 向量的唯一标识符
values: number[EMBED_DIM]; // 固定维度的向量值数组
metadata: MatchMeta; // 关联的元数据对象
namespace?: string; // 可选命名空间,用于数据隔离
}
核心组件解析¶
1. ID 字段(id: string
)¶
- 用途:索引中每个向量的唯一标识
- 格式:字符串标识(如 "doc-1-chunk-0", "article-123-section-2")
- 约束:在索引命名空间内必须唯一
- 最佳实践:建议包含源文档和分块信息,便于追溯
2. 值数组(values: number[EMBED_DIM]
)¶
- 用途:存储实际的向量嵌入值
- 类型:浮点数数组
- 维度:长度固定,需与
EMBED_DIM
配置一致 - 关键要求:数组长度必须严格等于索引维度
3. 元数据对象(metadata: MatchMeta
)¶
- 用途:存储与向量相关的可检索、可过滤信息
- 结构:
type MatchMeta = {
text?: string; // 原始文本内容
source?: string; // 源文件路径
title?: string; // 文档或章节标题
url?: string; // 关联 URL
language?: string; // 内容语言标识
}
EMBED_DIM(1024)维度对齐¶
维度配置说明¶
EMBED_DIM
的值 1024 是以下三者的关键对齐点:
- Vectorize 索引配置
- 嵌入模型输出
- 运行时向量操作
配置层级关系¶
graph TD
A([wrangler.toml]) -->|EMBED_DIM = 1024| B([环境变量])
B --> C([Worker 运行时])
C --> D([向量操作])
E([嵌入模型]) -->|输出:1024 维向量| F([生成嵌入])
F --> D
G([Vectorize 索引]) -->|配置:1024 维| H([存储结构])
H --> D
D --> I([校验检查])
I -->|✓ 匹配| J([操作成功])
I -->|✗ 不匹配| K([运行时错误])
模型与索引维度对齐¶
组件 | 维度 | 配置位置 | 校验点 |
---|---|---|---|
Qwen text-embedding-v4 | 1024(默认) | API 模型选择 | 嵌入生成 |
Vectorize 索引 | 1024 | Wrangler CLI 创建 | 索引创建 |
环境配置 | 1024 | wrangler.toml | 运行时校验 |
向量值数组 | 1024 | 运行时生成 | Upsert 操作 |
校验逻辑¶
系统通过多层校验确保维度一致性:
// worker.ts 运行时校验
const vectors = payload.items.map(item => {
if (!Array.isArray(item.vector) || item.vector.length !== Number(env.EMBED_DIM)) {
throw new Error(
`Invalid vector dimension: expected ${env.EMBED_DIM}, got ${item.vector?.length || 'undefined'}`
);
}
return {
id: item.id,
values: item.vector, // 必须正好 1024 个元素
metadata: { /* MatchMeta */ }
};
});
可视化映射表¶
ID ↔ 分块索引关系¶
向量 ID 生成与分块索引映射¶
向量 ID 采用哈希方案生成,确保唯一性和可追溯性:
- 输入数据:
baseUrl
(最终文档 URL)和sourcePath
(相对文件路径) - 唯一键:拼接为
${baseUrl}|${sourcePath}
- 哈希处理:对唯一键进行 SHA-256 哈希
- 短 ID 前缀:取哈希前 12 个十六进制字符
- 最终向量 ID:
${urlHash}-${chunkIndex}
(12 位哈希 + 分块索引)
示例:
baseUrl
:https://jimmysong.io/blog/kubernetes/
sourcePath
:zh/blog/kubernetes/index.md
- 唯一键:
https://jimmysong.io/blog/kubernetes/|zh/blog/kubernetes/index.md
- SHA-256 哈希前 12 位:
abc123def456
- 分块索引:
0
- 向量 ID:
abc123def456-0
设计理由:
- 唯一性:URL 与源路径组合,避免冲突
- 紧凑性:12 位哈希短小,碰撞概率低
- 可追溯性:分块索引区分同一文档不同部分
ID ↔ 分块索引表示例:
向量 ID | 分块索引 | 源文档 | 值长度 | 元数据字段 |
---|---|---|---|---|
abc123def456-0 | 0 | zh/blog/kubernetes/index.md | 1024 | text, source, title, url, language |
abc123def456-1 | 1 | zh/blog/kubernetes/index.md | 1024 | text, source, title, url, language |
def789abc012-0 | 0 | docs/guide/index.md | 1024 | text, source, title, url, language |
def789abc012-1 | 1 | docs/guide/index.md | 1024 | text, source, title, url, language |
向量结构流程¶
文档分块 → 嵌入模型 → 向量数组 → Vectorize 条目
↓ ↓ ↓ ↓
"Hello world" → [0.1, 0.2, ...] → 1024 浮点数 → { id, values, metadata }
维度对齐要求¶
1. 索引创建对齐¶
# 索引必须用匹配的维度创建
npx wrangler vectorize create website-rag --dimensions=1024 --metric=cosine
2. 模型配置对齐¶
// 嵌入模型输出必须为 1024 维向量
const embeddings = await embedder.embed(texts, 1024); // EMBED_DIM = 1024
3. 运行时校验对齐¶
// 向量校验确保维度一致
if (vector.length !== Number(env.EMBED_DIM)) {
throw new Error(`Dimension mismatch: expected ${env.EMBED_DIM}`);
}
4. 查询操作对齐¶
// 查询向量必须与索引维度一致
const queryVector = await embedder.embed([query], Number(env.EMBED_DIM));
const results = await VECTORIZE.query(queryVector[0], { topK: 5 });
常见维度不一致问题¶
问题 1:模型与索引不匹配¶
// ❌ 错误:索引创建为 1536,模型输出 1024
// 索引:1536 维
// 模型:1024 维
// 结果:Upsert 时运行错误
// ✅ 正确:维度一致
// 索引:1024 维
// 模型:1024 维
// 环境:EMBED_DIM = 1024
问题 2:配置不一致¶
// ❌ 错误:环境变量与实际需求不符
EMBED_DIM = 768 // 实际使用 1024 维模型
// ✅ 正确:所有配置一致
EMBED_DIM = 1024 // 与模型输出和索引配置一致
最佳实践¶
1. 维度一致性¶
- 始终确保模型输出维度与索引配置一致
- 使用环境变量统一维度引用
- 所有向量操作实现运行时校验
2. ID 设计模式¶
// 推荐 ID 设计
const vectorId = `${sourceDoc}-chunk-${chunkIndex}`;
const vectorId = `${namespace}:${documentId}:${chunkIndex}`;
const vectorId = `${timestamp}-${contentHash}-${index}`;
3. 元数据结构设计¶
// 完善元数据,提升检索效果
const metadata: MatchMeta = {
text: chunkContent, // 用于上下文检索
source: sourceFilePath, // 源文件归属
title: documentTitle, // 展示用标题
url: canonicalUrl, // 用户导航
language: contentLanguage // 语言过滤
};
4. 校验实现¶
function validateVectorDimensions(vectors: VectorItem[], expectedDim: number) {
for (const vector of vectors) {
if (vector.values.length !== expectedDim) {
throw new Error(
`Vector ${vector.id} has ${vector.values.length} dimensions, expected ${expectedDim}`
);
}
}
}
集成检查清单¶
- 索引创建:Vectorize 索引维度正确
- 模型选择:嵌入模型输出维度匹配目标
- 环境配置:
EMBED_DIM
变量设置正确 - 运行时校验:已实现向量维度校验
- 错误处理:维度不一致错误已捕获
- 测试:端到端维度对齐已验证
全面的维度对齐确保 RAG 系统管道中的向量操作可靠稳定。