嵌入模型与向量数据库的关系与使用

嵌入模型(Embedding Model)与向量数据库(Vector Database)是RAG系统中密不可分的两个核心组件。它们的关系可以这样理解:嵌入模型负责“编码”,向量数据库负责“存储与检索”

简单来说,嵌入模型赋予数据“灵魂”(语义),向量数据库则提供了容纳和匹配这些“灵魂”的“家园”。要构建一个基于私有知识的智能应用,两者缺一不可。

嵌入模型与向量数据库的关系

  • 嵌入模型 (Embedding Model):是 “语义转换器”—— 把文本、图片、音频等非结构化数据,转换成一串能表达语义/特征的数字(即向量/嵌入向量)。这是一个高维度的数字数组,它捕捉了数据的语义信息。比如 “猫” 和 “猫咪” 的向量高度相似,而 “猫” 和 “狗” 的向量差异较大。

  • 向量数据库(Vector Database):是 “向量存储仓库 + 高效检索工具”,高效存储由嵌入模型生成的海量向量,并通常关联其原始数据(如原文、ID、元数据)。当接收到一个查询向量(比如用户问题的向量)时,它能以极快的速度执行相似性搜索,在庞大的向量库中找到与之最相似的Top K个向量(即最相关的内容)。

    普通数据库(如 MySQL)无法高效计算向量间的相似性,而向量数据库专门优化了向量的存储、索引(如 HNSW 索引)和相似性算法(余弦相似度、欧氏距离等),能在海量向量中毫秒级找到相似向量。

组件 核心职责 类比
嵌入模型 将文本、图像等非结构化数据转换为高维向量(即一系列浮点数),这个向量捕捉了数据的语义特征。 就像一个翻译官,把人类语言翻译成机器能计算的数字。
向量数据库 专门用于存储、索引和检索这些高维向量,
并提供基于向量距离的相似性搜索功能。
就像一个超级索引库,能根据语义快速找到最相关的内容。

嵌入模型负责 “生成向量”(上游),向量数据库负责 “存储向量 + 快速检索相似向量”(下游),二者缺一不可 —— 没有嵌入模型,向量数据库无数据可存;没有向量数据库,生成的向量无法高效复用(手动遍历上万向量算相似度会极慢)。

在RAG流程中的协作关系

  1. 写入阶段(索引)

    • 原始文档 → 切成小块(Chunking) → 嵌入模型 → 生成向量 → 存入向量数据库(同时保存原始文本和元数据)
    • 这个过程通常只需执行一次,或在知识库更新时进行。
  2. 查询阶段(检索)

    • 用户问题 → 同一个嵌入模型 → 生成查询向量 → 发给向量数据库 → 数据库返回最相似的K个向量 → 取出对应的原始文本 → 交给大模型生成答案

关键注意事项

  • 模型必须一致:用于查询的嵌入模型必须与建库时使用的模型相同,否则向量不在同一个语义空间中,检索结果会完全不可用。
  • 索引优化:数据量超 10 万条时,需为向量数据库配置索引(如 Chroma 默认的 HNSW 索引),提升检索速度。

嵌入模型与向量数据库配合使用

下面通过一个完整的示例,展示如何将嵌入模型与向量数据库配合使用。这里使用OpenAI的嵌入模型 + Chroma向量数据库(轻量级,适合本地开发)。

LangChain示例一

  • 嵌入模型:OpenAIEmbeddings(开源、轻量、效果佳)

  • 向量数据库:Chroma(无依赖、内存模式、开箱即用)

安装依赖

1
pip install langchain langchain-openai chromadb

设置API密钥

1
2
import os
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"

选择并初始化嵌入模型

1
2
3
4
from langchain_openai import OpenAIEmbeddings

# 初始化嵌入模型
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

初始化向量数据库

这里使用Chroma

1
2
3
4
5
6
7
8
from langchain_chroma import Chroma

# 创建一个持久化的向量数据库(数据会保存在本地目录)
vector_store = Chroma(
collection_name="my_knowledge_base",
embedding_function=embeddings,
persist_directory="./chroma_db" # 本地存储路径
)

准备文档并存入向量库

1
2
3
4
5
6
7
8
9
10
11
12
from langchain_core.documents import Document

# 模拟一批文档
documents = [
Document(page_content="苹果是一种常见的水果,富含维生素C。", metadata={"source": "fruit百科"}),
Document(page_content="香蕉含有丰富的钾元素,有助于维持血压稳定。", metadata={"source": "fruit百科"}),
Document(page_content="Python是一种解释型、面向对象的编程语言。", metadata={"source": "编程教程"}),
]

# 将文档添加到向量库
# 这一步会自动调用嵌入模型将 page_content 转换为向量并存储
vector_store.add_documents(documents)

执行相似性搜索(检索)

1
2
3
4
5
6
7
8
9
10
# 查询问题
query = "哪种水果对血压好?"

# 执行语义搜索,返回最相似的2个文档
results = vector_store.similarity_search(query, k=2)

# 输出结果
for doc in results:
print(f"内容: {doc.page_content}")
print(f"来源: {doc.metadata}\n")

预期输出(根据语义,会优先匹配到“香蕉”):

1
2
3
4
5
内容: 香蕉含有丰富的钾元素,有助于维持血压稳定。
来源: {'source': 'fruit百科'}

内容: 苹果是一种常见的水果,富含维生素C。
来源: {'source': 'fruit百科'}

可选:带分数的搜索

如果想查看相似度分数,可以使用:

1
2
3
results_with_scores = vector_store.similarity_search_with_relevance_scores(query, k=2)
for doc, score in results_with_scores:
print(f"分数: {score:.2f} | 内容: {doc.page_content}")

LangChain示例二

安装依赖

1
pip install sentence-transformers chromadb

完整示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from sentence_transformers import SentenceTransformer
import chromadb

# 1. 初始化嵌入模型(选轻量级的all-MiniLM-L6-v2,生成384维向量)
model = SentenceTransformer('all-MiniLM-L6-v2')

# 2. 准备原始文本数据(示例:商品描述)
raw_docs = [
"小米SU7 纯电轿车,续航700km,支持800V快充",
"华为Mate 70 Pro,麒麟9100芯片,鸿蒙4.2系统",
"苹果AirPods Pro 2,主动降噪,无线充电盒",
"特斯拉Model Y,全轮驱动,续航615km",
"苹果iPhone 15,A17芯片,6.1英寸超视网膜屏"
]

# 3. 数据向量化(嵌入模型核心功能)
# 将文本转成向量,shape为 (5, 384) → 5个文本,每个384维向量
doc_embeddings = model.encode(raw_docs)

# 4. 初始化向量数据库并存入数据
# 创建Chroma客户端(内存模式,无需持久化)
client = chromadb.Client()
# 创建集合(类似数据库的“表”)
collection = client.create_collection(name="product_collection")

# 存入向量+原始文本(需指定唯一ID)
collection.add(
ids=["1", "2", "3", "4", "5"], # 每个数据的唯一标识
embeddings=doc_embeddings.tolist(), # 向量转list(Chroma要求)
documents=raw_docs # 关联原始文本,方便检索后查看
)

# 5. 相似性检索(向量数据库核心功能)
query_text = "苹果无线耳机" # 要搜索的文本
# 第一步:查询文本向量化(必须和入库用同一个模型!)
query_embedding = model.encode([query_text])

# 第二步:检索相似向量(返回前2个最相似结果)
results = collection.query(
query_embeddings=query_embedding.tolist(),
n_results=2,
include=["documents", "distances"] # 返回原始文本+相似度距离(越小越相似)
)

# 6. 输出结果
print("检索结果:")
for idx, doc in enumerate(results["documents"][0]):
distance = results["distances"][0][idx]
print(f"排名{idx+1}{doc} | 相似度距离:{distance:.4f}")

执行结果

1
2
3
检索结果:
排名1:苹果AirPods Pro 2,主动降噪,无线充电盒 | 相似度距离:0.2189
排名2:苹果iPhone 15,A17芯片,6.1英寸超视网膜屏 | 相似度距离:0.6923

生产环境中的注意事项

考量点 说明
嵌入模型选型 根据语言(中文/多语言)、维度大小、延迟要求、成本选择。常用:
OpenAI text-embedding-3-small
Cohere embed-english-v3
HuggingFace开源的 BAAI/bge-large-zh 等。
向量数据库选型 根据数据规模、运维能力选择。
小规模用Chroma/PGVector,
大规模用Milvus/Qdrant或云服务。
索引优化 数据量超过10万时,务必创建索引(如HNSW、IVFFlat),否则查询会很慢。
元数据过滤 可通过metadatas参数添加标签,大多数向量库支持在搜索时加上 filter 条件。
实际业务中常需要按来源、日期、标签等过滤。
metadatas=[{"brand":"苹果"}, {"brand":"华为"}]),
支持按标签过滤检索(比如只查 “华为” 产品)。
批量处理 大量文档入库时,使用 add_documents 批量添加,避免逐个调用的开销。

总结

  • 嵌入模型:是向量数据库的“上游”,负责把文本转化为可计算的向量。
  • 向量数据库:是嵌入模型的“容器”,负责高效存储和检索这些向量。
  • 使用流程:选好嵌入模型 → 初始化向量库(绑定模型) → Embedding 向量化→ 存入文档(自动生成向量) → 查询时用同一模型生成查询向量 → 向量库返回相似结果。
  • 分工明确:Embedding 模型负责将非结构化数据转成语义向量,向量数据库负责向量的存储和高效相似性检索,二者是语义搜索 / RAG 的核心组合。
    嵌入模型负责“编码 和 理解”,向量数据库负责“速度与规模”,二者结合,才能实现实时的语义搜索。
作者

光星

发布于

2026-03-22

更新于

2026-03-22

许可协议

评论