langchain构建向量数据库和检索器

本文先以Chroma为例,后续再用Faiss,下面简单说下区别:

Faiss(Facebook AI Similarity Search)和Chroma是两种流行的向量数据库/库,主要用于高效相似性搜索和向量存储,但它们在设计目标、功能特性和适用场景上有显著差异。以下是两者的核心区别:

1. 开发背景与定位

Faiss

由Meta(Facebook)AI团队开发,专注于大规模向量相似性搜索,尤其适合高维稠密向量(如神经网络嵌入)。

核心优势:高性能的近似最近邻(ANN)搜索算法,支持GPU加速,适合工业级大规模数据(如十亿级向量)。

局限性:原生不支持持久化存储或元数据管理,需结合其他工具(如Redis)扩展功能。

Chroma

专为**AI应用(如LLM、RAG)**设计,内置对向量和关联元数据(如文本、标签)的存储与管理。

核心优势:开箱即用的轻量级解决方案,支持动态更新、过滤查询(基于元数据),适合中小规模场景。

局限性:性能优化不如Faiss,大规模向量搜索时可能需额外扩展。

2. 功能对比

特性FaissChroma

搜索算法多种ANN算法(IVF、HNSW、PQ等)基于HNSW或暴力搜索(可配置)

持久化存储需手动保存/加载索引文件内置SQLite或ClickHouse持久化

元数据支持不支持支持向量关联的JSON元数据存储与过滤

动态更新部分索引类型支持增量添加支持实时插入、删除和更新

多模态查询仅向量搜索支持向量+元数据混合查询(如过滤)

部署复杂度需自行搭建服务层(如gRPC/HTTP)内置REST API,快速部署

3. 性能与扩展性

Faiss

优势:在十亿级向量上仍能保持毫秒级响应,支持多GPU并行计算(如IndexShards)。

适用场景:推荐系统、图像检索等需要低延迟、高吞吐的场景。

Chroma

优势:简化了开发流程,适合快速原型开发或中小规模应用(如千万级向量)。

适用场景:聊天机器人(RAG)、文档检索等需要结合语义和结构化过滤的场景。

4. 生态系统与集成

Faiss

需通过Python/C++ API直接调用,或结合Milvus、Weaviate等扩展为完整数据库。

社区提供丰富的预训练索引配置(如faiss-wheels)。

Chroma

原生集成LangChain、LlamaIndex等AI工具链,适合与大模型生态无缝协作。

提供客户端-服务器模式,支持分布式部署(但性能优化有限)。

5. 如何选择?

选Faiss

需要极致搜索性能或处理超大规模数据。

愿意自行处理元数据管理和服务化封装。

选Chroma

需要快速构建AI应用(如RAG),且希望内置元数据支持。

数据规模在千万级以下,优先考虑开发效率而非极限性能。

一、安装langchain-chroma

pip install langchain-chroma

二、准备多个Document

documents = [

    Document(page_content="狗是人类永恒的守护者,无论风雨晦明,它用摇动的尾巴和炽热的眼神,将忠诚写成跨越千年的契约"),

    Document(page_content="猫是人类优雅的伴侣,时而高冷疏离,时而温柔依偎,用灵动的身影点亮生活的静谧。"),

    Document(page_content="猪是人类朴实的帮手,憨厚的外表下藏着聪慧,以无私的奉献成为农耕文化的重要符号。"),

    Document(page_content="鸡是人类勤劳的闹钟,破晓的啼鸣唤醒沉睡的村庄,用羽翼和蛋壳滋养千家万户。"),

    Document(page_content="鱼是人类悠然的诗意,在碧波中舞动生命的韵律,既是餐桌的馈赠,也是文化的象征。")

]

三、向量化,这里用bge-samll-zh-v1.5为例,下载地址:https://modelscope.cn/models/BAAI/bge-small-zh-v1.5/files

pip install sentence-transformers

pip install langchain-huggingface

代码:

# from langchain.embeddings import HuggingFaceEmbeddings #废弃了 下面那个

from langchain_huggingfaceimport HuggingFaceEmbeddings

# 指定本地模型路径(假设模型文件存储在 ./models/bge-small-en-v1.5 下)

embeddings = HuggingFaceEmbeddings(

    model_name="./bge-small-zh-v1.5",# 替换为实际路径

    model_kwargs={"device":"cpu"}# 可选:指定运行设备(cpu/cuda)

)

# 这个

vector_store = Chroma.from_documents(documents,embedding=embeddings)

print(vector_store.similarity_search_with_score("哈巴狗"))  #这个有匹配值,在Chroma中值越小代表匹配度越高

打印结果:

[(Document(id='fb91cbfd-a1ba-4cd2-9c60-f165bba54fe1', metadata={}, page_content='狗是人类永恒的守护者,无论风雨晦明,它用摇动的尾巴和炽热的眼神,将忠诚写成跨越千年的契约'), 1.0324569940567017), 

四、创建检索器

retriever = RunnableLambda(vector_store.similarity_search_with_score).bind(k=1)  #最相似的 第一个

调用一次:

print(retriever.invoke("加菲猫"))

[(Document(id='f3c2dfd8-4a32-4619-9f6e-865cf4bdb14a', metadata={}, page_content='猫是人类优雅的伴侣,时而高冷疏离,时而温柔依偎,用灵动的身影点亮生活的静谧。'), 0.9588874578475952)]

批量调用:

print(retriever.batch(["加菲猫","汪汪队"]))

[[(Document(id='f3c2dfd8-4a32-4619-9f6e-865cf4bdb14a', metadata={}, page_content='猫是人类优雅的伴侣,时而高冷疏离,时而温柔依偎,用灵动的身影点亮生活的静谧。'), 0.9588874578475952)], [(Document(id='fb91cbfd-a1ba-4cd2-9c60-f165bba54fe1', metadata={}, page_content='狗是人类永恒的守护者,无论风雨晦明,它用摇动的尾巴和炽热的眼神,将忠诚写成跨越千年的契约'), 1.3173881769180298)]]

五、完整代码

from langchain_ollamaimport OllamaLLM

from langchain.schemaimport HumanMessage,SystemMessage

from langchain_core.promptsimport ChatPromptTemplate, MessagesPlaceholder

from langchain_core.output_parsersimport StrOutputParser

from langchain_community.chat_message_historiesimport ChatMessageHistory

from langchain_core.documentsimport Document

from langchain_chromaimport Chroma

# from langchain.embeddings import HuggingFaceEmbeddings  #废弃了 下面那个

from langchain_huggingfaceimport HuggingFaceEmbeddings

llm = OllamaLLM(base_url = OLLAMA_HOST,model = MODEL_NAME)

documents = [

    Document(page_content="狗是人类永恒的守护者,无论风雨晦明,它用摇动的尾巴和炽热的眼神,将忠诚写成跨越千年的契约"),

    Document(page_content="猫是人类优雅的伴侣,时而高冷疏离,时而温柔依偎,用灵动的身影点亮生活的静谧。"),

    Document(page_content="猪是人类朴实的帮手,憨厚的外表下藏着聪慧,以无私的奉献成为农耕文化的重要符号。"),

    Document(page_content="鸡是人类勤劳的闹钟,破晓的啼鸣唤醒沉睡的村庄,用羽翼和蛋壳滋养千家万户。"),

    Document(page_content="鱼是人类悠然的诗意,在碧波中舞动生命的韵律,既是餐桌的馈赠,也是文化的象征。")

]

# 指定本地模型路径(假设模型文件存储在 ./models/bge-small-en-v1.5 下)

embeddings = HuggingFaceEmbeddings(

model_name="./bge-small-zh-v1.5",# 替换为实际路径

    model_kwargs={"device":"cpu"}# 可选:指定运行设备(cpu/cuda)

)

# 这个

vector_store = Chroma.from_documents(documents,embedding=embeddings)

print(vector_store.similarity_search_with_score("哈巴狗"))

# 检索器

retriever = RunnableLambda(vector_store.similarity_search_with_score).bind(k=1)

res1 = retriever.invoke("加菲猫")

print(res1)

res2 = retriever.batch(["加菲猫","汪汪队"])

print(res2)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容