Chromaでベクトル検索

Chromaとは

  • 高次元のベクトルデータを効率的に保存・検索するために設計されたOSSのベクトルデータベースです
  • 近似最近傍探索(ANN)アルゴリズムを利用し、大規模なデータセットでも高速に検索可能です
  • LangChainのVector storesコンポーネントとして統合されており、テキストやその他のデータのベクトル表現を保存・検索するために使用できます。例えば、前回紹介したRAGアプリケーションでドキュメントをベクトル化してChromaに保存し、ユーザーの質問に基づいて関連ドキュメントを検索し、LLMが回答を生成するようなフローを構築できます

Vector Storeの永続化とドキュメントの追加

  • 以下サンプルコードはGitHubで公開しています
  • persist_directoryはChromaがデータベースファイルをディスク上に保存し、起動時に読み込む場所を指定します
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# Chroma は、OpenAI の埋め込み API を包む便利なラッパーを提供します。
vector_store = Chroma(
    collection_name="qa_chat_collection",
    embedding_function=embeddings,
    persist_directory=".chroma_db/", 
)
  • 以下のコードは、webからドキュメントを取得してチャンクに分割します
loader = WebBaseLoader(
    web_path="https://www.clue-tec.com",
)
pages = loader.load()
text_splitter = CharacterTextSplitter(
    chunk_size=200, 
    separator='\n', 
    chunk_overlap=50
)
documents = text_splitter.split_documents(pages)
  • チャンクされたドキュメントをadd_documents()関数を使用して、メタデータと一意の ID を含むテキスト データをVector Storeに追加します
from uuid import uuid4
uuids = [str(uuid4()) for _ in range(len(documents))]
vector_store.add_documents(documents=documents,ids=uuids)

自然言語による類似検索

  • 類似検索を実行するには、similarity_search()関数を使用して自然言語で質問します
  • クエリを埋め込みに変換し、類似アルゴリズムを使用して類似の結果を検索します
  • この例では、3 つの類似した結果が返されています
results = vector_store.similarity_search(
    "Databricksの導入支援実績は?",
    k=3,
    filter={"source": "https://www.clue-tec.com"},
)
for res in results:
    print(f"* {res.page_content} [{res.metadata}]")
  • langchain内での使用を容易にするために、Vector Storeをretrieverに変換することもできます
  • 渡すことができるさまざまな検索タイプと kwargs の詳細については、公式のAPI リファレンスを参照してください。
retriever = vector_store.as_retriever(
    search_type="mmr", search_kwargs={"k": 1, "fetch_k": 5}
)
response = retriever.invoke("Databricksの導入支援実績は?", filter={"source": "https://www.clue-tec.com"})

Chromaの良い点

Chromaはlangchainと統合されており、上記のように簡単に利用することができます。また、PKとなるidをキーにドキュメントの更新や削除も可能となっており、差分更新が可能な点が挙げられます。またメタデータの管理やフィルタリングの機能も便利だと思います。