Skip to content

标题字典结构

向量条目结构

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 是以下三者的关键对齐点:

  1. Vectorize 索引配置
  2. 嵌入模型输出
  3. 运行时向量操作

配置层级关系

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

设计理由:

  1. 唯一性:URL 与源路径组合,避免冲突
  2. 紧凑性:12 位哈希短小,碰撞概率低
  3. 可追溯性:分块索引区分同一文档不同部分

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 系统管道中的向量操作可靠稳定。