一架梯子,一头程序猿,仰望星空!
LangChain教程(JS版本) > 内容正文

向量存储


向量存储

存储和搜索结构化数据最常见的方法之一是将文本进行向量化表示(文本嵌入),然后将向量数据存储到向量存储引擎,通过向量存储引擎进行文本相似度搜索。

提示:文本嵌入理解很拗口,可以简单的理解为计算文本的特征向量。

入门

这个步骤展示了与向量存储相关的基本功能。与向量存储一起工作的一个关键部分是创建要放入存储中的向量,通常是通过嵌入实现的。因此,在深入了解之前,建议您先熟悉文本嵌入模型接口。

这个步骤使用了一个基本的、未经优化的实现,称为MemoryVectorStore,它将嵌入存储在内存中,并对最相似的嵌入进行了精确的线性搜索。

使用方法

从文本创建新索引

import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";

const vectorStore = await MemoryVectorStore.fromTexts(
  ["Hello world", "Bye bye", "hello nice world"],
  [{ id: 2 }, { id: 1 }, { id: 3 }],
  new OpenAIEmbeddings()
);

const resultOne = await vectorStore.similaritySearch("hello world", 1);
console.log(resultOne);

/*
  [
    Document {
      pageContent: "Hello world",
      metadata: { id: 2 }
    }
  ]
*/

从加载器创建新的索引

import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { TextLoader } from "langchain/document_loaders/fs/text";

// 使用加载器创建文档
const loader = new TextLoader("src/document_loaders/example_data/example.txt");
const docs = await loader.load();

// 将文档加载到向量存储中
const vectorStore = await MemoryVectorStore.fromDocuments(
  docs,
  new OpenAIEmbeddings()
);

// 搜索最相似的文档
const resultOne = await vectorStore.similaritySearch("hello world", 1);

console.log(resultOne);

/*
  [
    Document {
      pageContent: "Hello world",
      metadata: { id: 2 }
    }
  ]
*/

以下是当前所有向量存储共享的基础接口:

interface VectorStore {
  /**
   * 向现有的向量存储中添加更多文档。
   * 有些提供商支持额外的参数,例如关联自定义 id 的文档或更改批量插入的批量大小。
   * 返回文档的 id 数组或无返回值。
   */
  addDocuments(
    documents: Document[],
    options?: Record
  ): Promise;

  /**
   * 搜索与查询最相似的文档
   */
  similaritySearch(
    query: string,
    k?: number,
    filter?: object | undefined
  ): Promise;

  /**
   * 搜索与查询最相似的文档,
   * 并返回它们的相似度分数
   */
  similaritySearchWithScore(
    query: string,
    k = 4,
    filter: object | undefined = undefined
  ): Promise;

  /**
   * 将一个向量存储转换为检索器
   */
  asRetriever(k?: number): BaseRetriever;

  /**
   * 删除与传入参数匹配的嵌入文档。
   * 不是每个提供商都支持此功能。
   */
  delete(params?: Record): Promise;

  /**
   * 高级:当您已经有文档的嵌入时,
   * 向现有的向量存储中添加更多文档
   */
  addVectors(
    vectors: number[][],
    documents: Document[],
    options?: Record
  ): Promise;

  /**
   * 高级:当您已经有查询的嵌入时,
   * 搜索与查询最相似的文档
   */
  similaritySearchVectorWithScore(
    query: number[],
    k: number,
    filter?: object
  ): Promise;
}

你可以根据文档的列表或文本和相应的元数据列表来创建一个向量存储。
也可以从现有索引创建一个向量存储,此方法的签名取决于你使用的向量存储,查看你所感兴趣的向量存储的文档。

abstract class BaseVectorStore implements VectorStore {
  static fromTexts(
    texts: string[],
    metadatas: object[] | object,
    embeddings: Embeddings,
    dbConfig: Record
  ): Promise;

  static fromDocuments(
    docs: Document[],
    embeddings: Embeddings,
    dbConfig: Record
  ): Promise;
}

选择哪一个向量存储引擎?

以下是一个快速指南,帮助您选择适合您使用情况的向量存储:

  • 如果您只是想在Node.js应用程序中内存中运行,而不需要其他服务器,那么可以选择HNSWLib、Faiss或LanceDB。
  • 如果您正在寻找可以在类似于浏览器的环境中内存运行的解决方案,则可以选择MemoryVectorStore。
  • 如果您熟悉Python,并且正在寻找与FAISS类似的解决方案,可以尝试HNSWLib或Faiss。
  • 如果您需要本地运行在docker容器中的开源全功能向量数据库,可以选择Chroma。
  • 如果您需要支持低延迟、本地嵌入文档以及支持边缘端应用的开源向量数据库,可以选择Zep。
  • 如果您需要在本地(在docker容器中)或云端运行的开源生产就绪的向量数据库,可以选择Weaviate。
  • 如果您已经使用Supabase,那么可以考虑使用Supabase向量存储,以便使用同一个Postgres数据库进行嵌入。
  • 如果您正在寻找无需自己托管的生产就绪的向量存储,可以选择Pinecone。
  • 如果您已经使用SingleStore,或者需要一个分布式高性能数据库,可以考虑SingleStore向量存储。
  • 如果您正在寻找一个在线的MPP(大规模并行处理)数据仓库服务,可以考虑AnalyticDB向量存储。
  • 如果您正在寻找一种经济实惠的向量数据库,可以使用SQL进行向量搜索,那么MyScale就是您的选择。


关联主题