向量数据库:Chroma与FAISS实战教程

在大语言模型应用开发中,向量数据库是实现文本语义检索的核心组件。本文将结合实战代码,手把手教你基于LangChain框架整合Chroma和FAISS两款主流向量数据库,实现中文文本的嵌入存储与相似度检索,同时讲解自定义嵌入模型的适配技巧。

一、核心概念与技术栈

1. 关键组件说明

  • LangChain:一站式LLM应用开发框架,提供统一的向量数据库接口和Document数据结构
  • 向量数据库:Chroma(轻量级、开箱即用)、FAISS(高性能、大规模检索)
  • 嵌入模型:本地化部署的Qwen3和BGE模型,实现中文文本向量化

2. 环境准备

1
2
3
4
5
6
# 基础依赖
pip install langchain-core langchain-chroma langchain-community
# 向量数据库
pip install chroma-hnswlib faiss-cpu # faiss-gpu可选
# 嵌入模型相关
pip install torch sentence-transformers

二、自定义嵌入模型(适配LangChain接口)

自定义Qwen3嵌入类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import torch
from langchain_core.embeddings import Embeddings
from sentence_transformers import SentenceTransformer

LOCAL_MODEL_PATH_QWEN3 = "./models/qwen3-embedding"

class CustomQwen3Embeddings(Embeddings):
"""适配LangChain的自定义Qwen3嵌入模型类"""
def __init__(self):
self.qwen3_embedding = SentenceTransformer(
LOCAL_MODEL_PATH_QWEN3,
model_kwargs={"torch_dtype": torch.float32, "trust_remote_code": True},
tokenizer_kwargs={"padding_side": "left"}
)

def embed_query(self, text: str) -> list[float]:
return self.embed_documents([text])[0]

def embed_documents(self, texts: list[str]) -> list[list[float]]:
return self.qwen3_embedding.encode(texts).tolist()

BGE模型快速适配

1
2
3
4
5
6
7
8
9
10
11
12
from langchain_community.embeddings import HuggingFaceEmbeddings

LOCAL_MODEL_PATH_BGE = "./models/bge-large-zh-v1.5"
model_kwargs = {"device": "cpu", "trust_remote_code": True}
encode_kwargs = {"normalize_embeddings": True}

bge_hf_embeddings = HuggingFaceEmbeddings(
model_name=LOCAL_MODEL_PATH_BGE,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs,
cache_folder=None
)

三、Chroma向量数据库实战

1. 初始化与数据加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from langchain_chroma import Chroma
from langchain_core.documents import Document

qwen_embedding = CustomQwen3Embeddings()

vector_store = Chroma(
collection_name='t_news',
embedding_function=qwen_embedding,
persist_directory='../chroma_db'
)

documents = [
Document(page_content="今天早餐我吃了巧克力薄煎饼和炒蛋。", metadata={"source": "tweet", "time": "上午"}),
Document(page_content="明天的天气预报是阴天多云,最高气温62华氏度。", metadata={"source": "news"}),
Document(page_content="劫匪闯入城市银行,盗走了100万美元现金。", metadata={"source": "news"}),
]

ids = ['id'+str(i+1) for i in range(len(documents))]
vector_store.add_documents(documents, ids=ids)

2. 相似度检索

1
2
3
4
5
results = vector_store.similarity_search('有美食相关的吗', k=2)

for res in results:
print(f"文本内容:{res.page_content}")
print(f"元数据:{res.metadata}\n")

四、FAISS向量数据库实战

1. 初始化与数据加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import faiss
from langchain_community.vectorstores import FAISS
from langchain_community.docstore import InMemoryDocstore

index = faiss.IndexFlatL2(len(bge_hf_embeddings.embed_query('hello')))

vector_store = FAISS(
embedding_function=bge_hf_embeddings,
index=index,
docstore=InMemoryDocstore(),
index_to_docstore_id={}
)

vector_store.add_documents(documents, ids=ids)

2. 相似度检索

1
2
3
4
5
results = vector_store.similarity_search('今天的投资建议', k=2)

for res in results:
print(f"文本内容:{res.page_content}")
print(f"元数据:{res.metadata}\n")

五、对比与选型建议

特性 Chroma FAISS
易用性 极高(零配置) 中等(需手动初始化)
持久化 原生支持 需手动save/load
适用场景 中小规模、快速原型 大规模数据、高性能检索
元数据 原生支持 需结合Docstore

选型建议

  • Chroma:快速开发、中小数据、需要开箱即用持久化
  • FAISS:大规模向量、极致性能、可接受手动管理持久化

六、总结

本文通过实战代码演示了基于LangChain整合Chroma和FAISS的核心流程:

  1. 适配LangChain的Embeddings接口,实现本地化嵌入模型
  2. 统一的Document数据结构,实现数据源复用
  3. 简洁的相似度检索API

扩展方向:FAISS持久化、元数据过滤、替换OpenAI Embeddings、批量处理优化等。