向量数据库基础概念与分类
日期:2026年4月9日
什么是向量数据库
向量数据库是专门用于存储和检索高维向量数据的数据库系统,主要用于相似性搜索、推荐系统、语义搜索等AI应用场景。其核心目的是将各种数据转换为数值化的特征表示(向量),然后高效地进行相似性搜索和关联查询。
核心工作原理
特征提取(Embedding)
- 文本: 通过BERT、OpenAI Embedding等模型转换为向量
- 图像: 使用ResNet、CLIP等模型提取视觉特征
- 音频: 通过Whisper、VGGish等模型生成音频特征
- 结构化数据: 数值化编码后形成特征向量
相似性度量
- 余弦相似度: 最常用,关注方向而非大小
- 欧氏距离: 关注绝对距离
- 内积: 用于某些特定场景
高效检索
- 通过专门的近似最近邻(ANN)算法实现快速搜索
- 在百万/十亿级向量中毫秒级返回最相似结果
主要向量数据库分类
专用向量数据库
- Pinecone: 完全托管的向量数据库服务,API简单易用
- Weaviate: 开源向量搜索引擎,支持GraphQL查询
- Milvus: 开源向量数据库,CNCF项目,功能丰富
- Qdrant: Rust编写的开源向量搜索引擎,性能优秀
- Vespa: Yahoo开源的大规模文本和向量搜索平台
- Vald: Kubernetes原生的分布式向量搜索引擎
传统数据库的向量扩展
- PostgreSQL + pgvector: 最流行的向量扩展方案
- Redis + RedisVL: Redis的向量搜索模块
- Elasticsearch: 8.x版本开始支持向量搜索
- MongoDB Atlas: 支持向量搜索功能
- Oracle Database: 23c版本引入向量数据类型
- SQL Server: 支持向量函数
云服务商解决方案
- AWS OpenSearch: 支持k-NN搜索
- Google Vertex AI Matching Engine: Google Cloud的向量匹配服务
- Azure Cognitive Search: 支持向量搜索
- 阿里云OpenSearch: 支持向量检索
兼容性分析
API兼容性
大多数向量数据库不直接兼容,因为:
- 比如搜索"如何修理自行车"能匹配到"自行车维修指南"
去重和聚合
- 发现重复或相似的内容
- 自动分组相关文档/图片
为什么需要专门的向量数据库?
传统数据库在处理高维向量时效率极低:
- 维度灾难: 高维空间中距离概念失效
- 计算复杂度: 暴力搜索O(n)无法满足实时需求
- 内存效率: 专门的索引结构节省存储空间
向量数据库通过专门优化的数据结构和算法解决了这些问题,让AI应用能够实时处理大规模向量数据。
简单来说,向量数据库就是AI时代的"搜索引擎",只不过它搜索的是语义相似性而不是关键词匹配。
前端技术栈数据向量化方案推荐(DeepSeek 大模型)
核心场景
前端数据向量化主要覆盖以下场景:
| 场景 | 说明 | 典型应用 |
|---|---|---|
| 本地知识库搜索 | 用户文档/笔记的语义检索 | 个人知识管理、离线文档搜索 |
| 智能客服/FAQ | 产品文档向量化后供用户自然语言查询 | 官网帮助中心、AI客服 |
| 内容推荐 | 基于内容的语义相似度推荐 | 文章推荐、商品发现 |
| AI Copilot | 代码库/设计稿向量化辅助开发 | IDE插件、设计工具插件 |
方案一:纯前端向量化(浏览器端 Embedding)
适合隐私敏感、离线优先、轻量级场景。
┌─────────────────────────────────────────┐
│ 浏览器 │
│ ┌──────────┐ ┌───────────┐ ┌────────┐ │
│ │ 用户输入 │→│Transformers│→│ 向量存储 │ │
│ │ │ │.js 嵌入模型│ │(IndexedDB)│ │
│ └──────────┘ └───────────┘ └────────┘ │
└─────────────────────────────────────────┘
技术组件:
| 组件 | 推荐方案 | 说明 |
|---|---|---|
| Embedding 模型 | Xenova/all-MiniLM-L6-v2 |
轻量,适合浏览器运行 |
| Embedding 模型(中文) | Xenova/bge-small-zh-v1.5 |
BGE 中文小模型,384维 |
| 向量存储 | IndexedDB + 自定义索引 | 浏览器原生,无需服务端 |
| 运行时 | @xenova/transformers |
Transformers.js,WASM运行 |
示例代码:
import { pipeline } from '@xenova/transformers';
// 创建前端 embedding pipeline
const embedder = await pipeline(
'feature-extraction',
'Xenova/bge-small-zh-v1.5' // 中文轻量模型
);
// 文本转向量
const text = '如何配置DeepSeek API密钥?';
const output = await embedder(text, { pooling: 'mean', normalize: true });
const vector = Array.from(output.data); // 384维向量
// 存储到 IndexedDB(可用 idb 库)
// 搜索时计算余弦相似度,取 Top-K
优缺点:
- ✅ 零服务端成本,数据不出浏览器
- ✅ 离线可用,隐私安全
- ❌ 模型体积受限(几十MB),大模型无法运行
- ❌ 嵌入质量不如服务端大模型
方案二:DeepSeek API 向量化(推荐)
DeepSeek 提供与 OpenAI 兼容的 Embedding API,适合生产级应用。
┌──────────┐ HTTP/API ┌──────────────┐
│ 前端应用 │ ───────────────→ │ DeepSeek API │
│ (浏览器) │ ←─────────────── │ /v1/embeddings│
└──────────┘ └──────────────┘
│ │
│ 存储/检索向量 │
▼ ▼
┌──────────┐ ┌──────────────┐
│ BFF 层 │ ←──────────────→ │ 向量数据库 │
│ (Next.js) │ │ (pgvector等) │
└──────────┘ └──────────────┘
为什么需要 BFF(Backend For Frontend)层:
- API Key 不能暴露在前端
- 向量数据库通常不支持浏览器直连
- 需要做请求聚合、缓存、权限控制
DeepSeek Embedding API 调用:
// ===== BFF 层 (Next.js API Route / Express) =====
// POST /api/embed
export async function embedText(text: string) {
const response = await fetch('https://api.deepseek.com/v1/embeddings', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'deepseek-embedding', // DeepSeek 嵌入模型
input: text,
}),
});
const data = await response.json();
return data.data[0].embedding; // 返回向量数组
}
// 批量嵌入
export async function embedBatch(texts: string[]) {
const response = await fetch('https://api.deepseek.com/v1/embeddings', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'deepseek-embedding',
input: texts, // 支持数组输入
}),
});
const data = await response.json();
return data.data.map((item: any) => item.embedding);
}
前端调用示例(React):
// ===== 前端组件 =====
async function searchDocuments(query: string): Promise<SearchResult[]> {
// 1. 通过 BFF 获取查询向量
const embedRes = await fetch('/api/embed', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: query }),
});
const queryVector = await embedRes.json();
// 2. 通过 BFF 执行向量搜索
const searchRes = await fetch('/api/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ vector: queryVector, topK: 5 }),
});
return searchRes.json();
}
// React 组件中使用
function SearchBox() {
const [query, setQuery] = useState('');
const [results, setResults] = useState<SearchResult[]>([]);
const handleSearch = async () => {
const res = await searchDocuments(query);
setResults(res);
};
return (
<div>
<input value={query} onChange={e => setQuery(e.target.value)} />
<button onClick={handleSearch}>搜索</button>
{results.map(r => <ResultCard key={r.id} data={r} />)}
</div>
);
}
方案三:LangChain.js + DeepSeek 全链路方案
适合需要 Agent/RAG 能力的复杂前端应用。
┌────────────────────────────────────────────────┐
│ 前端 / Node.js BFF │
│ │
│ LangChain.js │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Document │→│ DeepSeek │→│ VectorStore │ │
│ │ Loader │ │ Embedding│ │ (pgvector/ │ │
│ │ (PDF/MD) │ │ │ │ Qdrant) │ │
│ └──────────┘ └──────────┘ └──────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────────┐ │
│ │ DeepSeek │←─│ Retriever │ │
│ │ Chat (LLM)│ │ │ │
│ └──────────┘ └──────────────┘ │
└────────────────────────────────────────────────┘
示例代码(Node.js BFF):
import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
import { PGVectorStore } from '@langchain/community/vectorstores/pgvector';
import { StringOutputParser } from '@langchain/core/output_parsers';
import { ChatPromptTemplate } from '@langchain/core/prompts';
import { createStuffDocumentsChain } from 'langchain/chains/combine_documents';
import { createRetrievalChain } from 'langchain/chains/retrieval';
// DeepSeek Embedding(兼容 OpenAI 接口)
const embeddings = new OpenAIEmbeddings({
model: 'deepseek-embedding',
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: 'https://api.deepseek.com/v1',
},
});
// DeepSeek Chat(大模型)
const llm = new ChatOpenAI({
model: 'deepseek-chat',
temperature: 0.7,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: 'https://api.deepseek.com/v1',
},
});
// 1. 文档向量化入库
async function indexDocuments(docs: string[]) {
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 500,
chunkOverlap: 50,
});
const splitDocs = await splitter.createDocuments(docs);
await PGVectorStore.fromDocuments(splitDocs, embeddings, {
tableName: 'documents',
connectionString: process.env.DATABASE_URL,
});
}
// 2. RAG 检索链
async function askWithContext(question: string): Promise<string> {
const vectorStore = await PGVectorStore.initialize(embeddings, {
tableName: 'documents',
connectionString: process.env.DATABASE_URL,
});
const retriever = vectorStore.asRetriever({ k: 5 });
const prompt = ChatPromptTemplate.fromTemplate(`
根据以下上下文回答问题。如果上下文中没有相关信息,请如实说明。
上下文:
{context}
问题:{input}
`);
const combineDocsChain = await createStuffDocumentsChain({
llm,
prompt,
outputParser: new StringOutputParser(),
});
const retrievalChain = await createRetrievalChain({
retriever,
combineDocsChain,
});
const result = await retrievalChain.invoke({ input: question });
return result.answer;
}
向量数据库选型(前端视角)
| 向量数据库 | 适用场景 | 前端接入方式 | 推荐度 |
|---|---|---|---|
| pgvector (PostgreSQL) | 已有 PG 的项目 | BFF → SQL 查询 | ⭐⭐⭐⭐⭐ |
| Qdrant | 高性能、独立部署 | BFF → REST/gRPC | ⭐⭐⭐⭐⭐ |
| LanceDB | 纯前端/边缘计算 | WASM 直连浏览器 | ⭐⭐⭐⭐ |
| Weaviate | 全功能、GraphQL | BFF → GraphQL | ⭐⭐⭐⭐ |
| Pinecone | 免运维、快速上线 | BFF → REST API | ⭐⭐⭐⭐ |
| Chroma | 本地开发/原型 | BFF → Python/JS SDK | ⭐⭐⭐ |
推荐方案总结
| 需求层级 | 推荐方案 | 技术组合 |
|---|---|---|
| 轻量原型/PoC | 纯前端 | Transformers.js + IndexedDB + 内积搜索 |
| 中小型应用 | DeepSeek API + pgvector | Next.js BFF + DeepSeek Embedding + pgvector |
| 生产级 RAG | LangChain.js 全链路 | Node.js BFF + DeepSeek Embedding + DeepSeek Chat + Qdrant/pgvector |
| 离线优先应用 | 混合模式 | Transformers.js(本地)+ DeepSeek(联网增强) |
关键注意事项
- API Key 安全:DeepSeek API Key 绝对不能暴露在前端代码中,必须通过 BFF 层中转
- 向量维度匹配:DeepSeek Embedding 输出维度需与向量数据库索引维度一致,更换模型后需重新建库
- 文档分块策略:前端展示时需考虑分块大小(建议 300-500 token),过大会稀释语义,过小会丢失上下文
- 流式输出:DeepSeek Chat 支持 SSE 流式返回,前端可使用
EventSource或fetch+ReadableStream实现打字机效果 - 缓存策略:高频查询的 Embedding 结果建议在 BFF 层缓存(Redis),减少 API 调用成本
- 降级方案:当 DeepSeek API 不可用时可切换到本地
Transformers.js嵌入模型作为 fallback
LLM 语义打分:一种轻量向量化方案
传统 Embedding 靠专用模型把数据"算"成高维向量(384~1536 维),而 LLM 方案是把向量化变成一个"理解后打分"的认知任务:人工定义一组语义维度,LLM 理解内容后逐个维度输出评分。
工作原理
文本 → DeepSeek Chat API
→ System Prompt 定义 N 个语义维度(如:技术性、实用性、AI相关性等)
→ LLM 对每个维度打分 [0.00 ~ 1.00]
→ 形成 N 维语义向量
示例:8 维语义维度
| 维度 | 说明 | 示例文本打分(前端向量化文章) |
|---|---|---|
| 技术性 | 涉及编程/工程实现的程度 | 0.85 |
| 实用性 | 可直接落地的程度 | 0.90 |
| 理论性 | 底层原理/数学推导的程度 | 0.25 |
| AI/ML 相关性 | 与人工智能的关联度 | 0.95 |
| 前端相关性 | 与前端/浏览器/UI 的关联度 | 0.88 |
| 后端相关性 | 与后端/服务端/数据库的关联度 | 0.15 |
| 入门友好度 | 对初学者易于理解的程度 | 0.80 |
| 创新性/前沿性 | 涉及新技术/新思路的程度 | 0.70 |
为什么传统 Embedding 不需要指定维度?
传统 Embedding 模型(BERT、BGE、OpenAI text-embedding 等)是专门为"文本→向量"这个任务训练的:
训练过程:
海量文本 → 让模型学会"语义相近的文本向量也接近"
→ 模型内部自动学会提取 768 维(或更多)特征
→ 每个维度代表模型"自己发现"的语义特征,人类看不懂
这些维度是模型在训练过程中自动涌现的,不是人工定义的。比如 BERT 的 768 维向量,第 127 维可能模糊地代表"与金融相关",但没人能确切说出它是什么——这就是"黑盒"。
为什么 LLM 方案必须指定维度?
LLM(如 DeepSeek)是通用对话模型,不是专用 Embedding 模型。它不会直接输出数值向量:
LLM 能做到: "这篇文章是关于前端的" ← 自然语言输出
LLM 做不到: 直接输出一个 [0.88, 0.15, ...] ← 没有这个原生能力
所以必须通过 prompt 把"输出向量"这个需求翻译成 LLM 能理解的"文字打分任务",人为定义每个维度的含义,LLM 才能执行。
两种方案本质区别
| 传统 Embedding 模型 | LLM 语义打分 | |
|---|---|---|
| 核心机制 | 模型自动提取语义特征 | 人工定义维度 → LLM 理解打分 |
| "谁定义维度" | 训练数据决定(人类不可控) | 人类显式定义 |
| 维度含义 | 黑盒,不可解释 | 白盒,每个维度有名称 |
| 实现方式 | 专用 Embedding API | Prompt + Chat API |
| 向量维度 | 384 ~ 1536(模型固定) | 8 ~ N(人类灵活调整) |
| 跨模态 | 需要为每种模态训练独立模型 | 天然统一:先转文字,再打同一套分 |
| 准确度 | 高(专门优化) | 中(依赖 LLM 理解能力) |
| 成本 | 低(专用 API 便宜) | 较高(走 Chat API,按 token 计费) |
| 适用场景 | 生产级语义搜索 | 原型验证、小数据集、需要可解释性、跨模态 |
优势:天然跨模态
传统 Embedding 需要为每种模态准备专用模型(文本用 BERT、图片用 CLIP、音频用 Whisper),不同模态产生的向量不在同一个语义空间。
LLM 语义打分方案天然统一:
图片 → VLM/OCR 描述成文字 → LLM 在统一维度上打分 → 同一向量空间
音频 → ASR 转文字 → LLM 在统一维度上打分 → 同一向量空间
视频 → 抽帧 + ASR 转文字 → LLM 在统一维度上打分 → 同一向量空间
文本 → 直接输入 → LLM 在统一维度上打分 → 同一向量空间
关键点:无论什么模态,最终都落入同一套语义维度空间,"搜图片找相关文档""用语音搜视频"等跨模态搜索天然成立。
关键注意事项
- 维度设计:维度必须覆盖业务关心的一切语义面,太少区分度不够,太多成本上升
- 确定性:
temperature=0,确保同一文本多次调用返回一致结果 - 大小写归一:输入前统一
.toLowerCase(),避免 LLM 对大小写产生不同的语义判断 - 适用边界:适合文档量 < 10000 的轻量场景,大数据量建议走专用 Embedding 模型
主流云端 Embedding API
如果你不需要自定义维度,只想做通用语义搜索,以下云端 API 可以直接调用:
| 服务商 | 推荐模型 | 维度 | 中文效果 | 成本 | 特点 |
|---|---|---|---|---|---|
| OpenAI | text-embedding-3-small |
512/1536 | ⭐⭐ | ~$0.02/百万token | 生态最完善 |
| OpenAI | text-embedding-3-large |
256/1024/3072 | ⭐⭐ | ~$0.13/百万token | 可调维度,精度最高 |
| Cohere | embed-multilingual-v3 |
1024 | ⭐⭐⭐⭐ | 有免费额度 | 多语言支持好 |
| Voyage AI | voyage-multilingual-2 |
1024 | ⭐⭐⭐⭐⭐ | ~$0.05/百万token | 中文日文韩文顶级 |
| Jina AI | jina-embeddings-v3 |
1024 | ⭐⭐⭐⭐ | 有免费额度 | 支持 8192 token 长文本 |
| 硅基流动 | BAAI/bge-large-zh-v1.5 |
1024 | ⭐⭐⭐⭐⭐ | 极便宜 | 兼容 OpenAI 格式,中文 SOTA |
本地开源模型(不需联网)
| 模型 | 维度 | 中文效果 | 适用场景 |
|---|---|---|---|
| BGE-large-zh-v1.5 | 1024 | ⭐⭐⭐⭐⭐ | 中文 SOTA,智源出品 |
| BGE-small-zh-v1.5 | 512 | ⭐⭐⭐⭐ | 轻量版,适合本地/边缘部署 |
| BGE-M3 | 1024 | ⭐⭐⭐⭐⭐ | 多语言 + sparse/dense 双模 |
| GTE-Qwen2 | 768/1536 | ⭐⭐⭐⭐⭐ | 阿里出品,新晋强手 |
| M3E | 768 | ⭐⭐⭐⭐ | 国产轻量,社区使用广泛 |
| text2vec-large-chinese | 1024 | ⭐⭐⭐⭐ | CoSENT 训练,经典方案 |
选型建议
- 个人项目/原型:硅基流动 API(BGE-large),免部署,一个月几块钱
- 公司内部应用:BGE-M3 本地部署,数据不出内网
- 英文/海外场景:OpenAI
text-embedding-3-small,生态最好 - 多语言混合:Voyage AI,中日韩效果最强
场景选择指南
核心判断标准:你的搜索是"通用语义相似"还是"带业务维度的偏好过滤"。
传统 Embedding 适用场景
特征:需求是通用的,不绑定特定业务视角。
| 场景 | 说明 |
|---|---|
| RAG 知识库问答 | 用户问"Redis 持久化有几种方式",从文档库召回最相关段落 |
| 代码搜索 | 输入代码片段,找出库中最相似实现 |
| 相似商品推荐 | 用户看了一双鞋,推荐其他类似的鞋 |
| 内容去重 | 找出数据库中语义重复的文章 |
| 翻译记忆库 | 做过类似翻译的句子检索 |
LLM 语义打分适用场景
特征:需要从特定角度评价/过滤内容,而且这个角度可能变化。
| 场景 | 说明 |
|---|---|
| 内容运营筛选 | 找"技术性高但入门友好度低"的文章(需要改写科普版) |
| 多模态素材库 | 图片/视频/音频/文档混在一起,按"前端相关性 + 入门友好度"统一检索 |
| 个性化搜索 | A 用户偏好理论深度,B 用户偏好实用教程,同一查询给不同维度权重 |
| 可解释推荐 | 结果附带"技术性 0.92, 实用性 0.88",用户知道为什么推荐 |
| MVP 快速验证 | 只有几百篇文档,不想搭 Embedding 服务 + 向量数据库 |
| 跨模态检索 | 图片/视频/音频都先转文字描述,再用同一套维度打分 |
一句话总结
| 需求 | 方案 | 原因 |
|---|---|---|
| "找和这段文字最像的内容" | 传统 | 不需要人工定义标准 |
| "按技术性高、入门度低筛选" | LLM | 带了业务维度过滤 |
| 万级文档,通用 RAG | 传统 | 量大 + 通用需求 |
| 百级文档 + 跨模态 | LLM | 量小 + 跨模态天然统一 |
| 需要告诉用户"为什么推荐" | LLM | 可解释性 |
| 不需要解释,结果对就行 | 传统 | 成本更低 |
两个方案不是替代关系——类似 搜索引擎 vs 标签筛选系统:日常 RAG 走传统 Embedding,当业务需要按特定视角过滤或 curation 时,LLM 打分更有优势。
示例
demo/deepseek_ts_embedding
评论
评论加载中…