GitHub概要

chroma-core/chroma

the AI-native open-source embedding database

スター21,359
ウォッチ114
フォーク1,693
作成日:2022年10月5日
言語:Rust
ライセンス:Apache License 2.0

トピックス

document-retrievalembeddingsllms

スター履歴

chroma-core/chroma Star History
データ取得日時: 2025/7/30 00:10

データベース

Chroma

概要

ChromaはAIネイティブなオープンソースの埋め込みデータベースで、LLMアプリケーションの開発を簡素化することを目的として設計されています。開発者フレンドリーなAPIとシンプルな設計により、プロトタイピングから本番環境まで迅速に移行できるベクトルデータベースです。RAG(Retrieval-Augmented Generation)開発に最適化されており、知識、事実、スキルをLLMにプラグイン可能にすることで、ハルシネーションを回避し、より正確なAIアプリケーションの構築を支援します。

詳細

ChromaはPythonノートブックで動作するAPIが、そのままクラスタにスケールできるよう設計されています。インメモリストレージメカニズムを活用することで、ディスクベースのシステムに関連するレイテンシなしに、データへの迅速なアクセスを保証します。開発、テスト、本番環境で同じAPIを使用でき、ローカル開発からクラウドデプロイメントまでシームレスに移行できます。

Chromaの主な特徴:

  • バッテリー同梱: ストレージ、埋め込み、クエリに必要なすべてを含む
  • シンプルなAPI: 直感的で習得しやすいインターフェース
  • マルチモーダル対応: テキスト、画像、音声など様々なデータタイプをサポート
  • フィルタリング機能: メタデータによる高度なフィルタリング
  • 全文検索: ベクトル検索と全文検索の統合
  • ドキュメントストレージ: 元のドキュメントも同時に管理
  • 複数の言語サポート: Python、JavaScript/TypeScriptクライアント
  • 柔軟なデプロイメント: インメモリ、ローカルディスク、サーバー、クラウド対応
  • オープンソース: 透明性とカスタマイズ性を提供
  • 活発なコミュニティ: 継続的な改善と豊富なエコシステム

アーキテクチャ

Chromaはサービス指向アーキテクチャを採用:

  1. フロントエンドサービス: APIリクエスト処理、認証、認可、ルーティング
  2. クエリサービス: ベクトル類似性検索とフィルタリング操作の処理
  3. コンパクションサービス: データの整理とストレージ最適化
  4. システムデータベース(SysDB): コレクション、セグメント、テナント、データベースのメタデータ管理
  5. ストレージレイヤー: ベクトルデータ、メタデータ、ドキュメントの永続化

メリット・デメリット

メリット

  • 開発者フレンドリー: シンプルなAPIで学習コストが低い
  • 高速プロトタイピング: pip installからすぐに使い始められる
  • コスト効率: 無料のオープンソースで、クラウドコストなしで実験可能
  • 柔軟なデプロイメント: ローカルからクラウドまで様々な環境に対応
  • 統合が容易: LangChain、LlamaIndex、Hugging Faceとの統合
  • 効率的な類似性検索: 大規模データセットでも高速な検索を実現
  • カスタマイズ可能: オープンソースで透明性が高く、必要に応じて拡張可能

デメリット

  • スケーラビリティの制限: 100万ベクトルポイントまでの上限
  • エンタープライズ機能の不足: RBACサポートなし
  • データ管理の注意点: ドキュメントIDの重複処理、埋め込み次元の一致が必要
  • 運用の複雑性: 大規模環境では手動管理が必要
  • 完全なACIDサポートなし: トランザクション機能に制限
  • マネージドサービスが限定的: セルフホスティングが主体

主要リンク

書き方の例

インストール・セットアップ

# Python SDK インストール
pip install chromadb

# JavaScript/TypeScript SDK インストール
npm install chromadb
# または
yarn add chromadb

# Docker での実行
docker pull chromadb/chroma
docker run -p 8000:8000 chromadb/chroma

# 開発用サーバーの起動
chroma run --path ./chroma_data

基本操作(Python)

import chromadb

# クライアント初期化(各種タイプ)
# インメモリ(開発・テスト用)
client = chromadb.EphemeralClient()

# ローカルディスク永続化
client = chromadb.PersistentClient(path="./chroma_db")

# HTTPクライアント(リモートサーバー接続)
client = chromadb.HttpClient(host="localhost", port=8000)

# 非同期HTTPクライアント
import asyncio
async def main():
    client = await chromadb.AsyncHttpClient()
    collection = await client.create_collection(name="async_collection")

# コレクション作成
collection = client.create_collection(
    name="my_collection",
    metadata={"description": "私の最初のコレクション"}
)

# 既存のコレクションを取得または作成
collection = client.get_or_create_collection(name="my_collection")

# ドキュメント追加
collection.add(
    documents=[
        "ChromaはAIネイティブな埋め込みデータベースです",
        "LLMアプリケーション開発を簡単にします",
        "RAGシステムの構築に最適です"
    ],
    metadatas=[
        {"source": "docs", "category": "database"},
        {"source": "blog", "category": "ai"},
        {"source": "tutorial", "category": "rag"}
    ],
    ids=["doc1", "doc2", "doc3"]
)

# クエリ実行
results = collection.query(
    query_texts=["ベクトルデータベースについて教えて"],
    n_results=2,
    where={"category": "database"}
)

print(results)

埋め込み関数の使用

from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction
from chromadb.utils.embedding_functions import SentenceTransformerEmbeddingFunction

# OpenAI埋め込み
openai_ef = OpenAIEmbeddingFunction(
    api_key="your-api-key",
    model_name="text-embedding-3-small"
)

# Sentence Transformers(ローカル)
sentence_ef = SentenceTransformerEmbeddingFunction(
    model_name="all-MiniLM-L6-v2"
)

# カスタム埋め込み関数でコレクション作成
collection = client.create_collection(
    name="custom_embeddings",
    embedding_function=openai_ef
)

# テキストから自動的に埋め込みを生成
collection.add(
    documents=["Chromaの使い方", "ベクトル検索の実装"],
    ids=["id1", "id2"]
)

高度な検索機能

# メタデータフィルタリング
results = collection.query(
    query_texts=["機械学習について"],
    n_results=5,
    where={
        "$and": [
            {"source": "docs"},
            {"year": {"$gte": 2023}}
        ]
    }
)

# 複数のクエリテキスト(バッチ処理)
results = collection.query(
    query_texts=[
        "ベクトルデータベースとは",
        "RAGの実装方法",
        "LLMの活用事例"
    ],
    n_results=3
)

# 埋め込みベクトルを直接使用
import numpy as np
query_embeddings = [np.random.rand(384).tolist()]
results = collection.query(
    query_embeddings=query_embeddings,
    n_results=5
)

# 結果に含めるフィールドを指定
results = collection.query(
    query_texts=["ChromaDB"],
    n_results=10,
    include=["metadatas", "documents", "distances"]
)

JavaScript/TypeScriptでの使用

import { ChromaClient } from 'chromadb';

// クライアント初期化
const client = new ChromaClient({
    path: "http://localhost:8000"
});

// コレクション作成
const collection = await client.createCollection({
    name: "js_collection",
    metadata: { description: "JavaScriptコレクション" }
});

// ドキュメント追加
await collection.add({
    ids: ["id1", "id2"],
    documents: [
        "ChromaはJavaScriptでも使えます",
        "TypeScriptサポートも完備"
    ],
    metadatas: [
        { lang: "ja", type: "intro" },
        { lang: "ja", type: "feature" }
    ]
});

// クエリ実行
const results = await collection.query({
    queryTexts: ["JavaScriptでの使い方"],
    nResults: 2,
    where: { type: "intro" }
});

console.log(results);

RAGアプリケーションの実装

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI

# ドキュメントの準備
documents = [...] # あなたのドキュメント
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
texts = text_splitter.split_documents(documents)

# Chromaベクトルストア作成
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
    documents=texts,
    embedding=embeddings,
    persist_directory="./chroma_db"
)

# RAGチェーン構築
llm = ChatOpenAI(temperature=0)
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
    return_source_documents=True
)

# 質問応答
query = "Chromaの主な特徴は何ですか?"
result = qa_chain({"query": query})
print(result["result"])

データ管理

# データ更新(upsert)
collection.upsert(
    ids=["doc1", "doc2"],
    documents=[
        "更新されたドキュメント1",
        "更新されたドキュメント2"
    ],
    metadatas=[
        {"version": "2.0"},
        {"version": "2.0"}
    ]
)

# データ取得
results = collection.get(
    ids=["doc1", "doc2"],
    include=["documents", "metadatas", "embeddings"]
)

# データ削除
collection.delete(
    ids=["doc3"],
    where={"category": "outdated"}
)

# コレクション情報取得
print(f"件数: {collection.count()}")
print(f"コレクション名: {collection.name}")

# コレクション一覧
collections = client.list_collections()
for col in collections:
    print(col.name)

# コレクション削除
client.delete_collection(name="old_collection")

マルチモーダル検索の例

from chromadb.utils.embedding_functions import OpenCLIPEmbeddingFunction
from PIL import Image

# OpenCLIP埋め込み関数(画像・テキスト対応)
embedding_function = OpenCLIPEmbeddingFunction()

# マルチモーダルコレクション作成
collection = client.create_collection(
    name="multimodal",
    embedding_function=embedding_function
)

# 画像とテキストを追加
collection.add(
    ids=["img1", "txt1"],
    images=["path/to/image.jpg"],  # 画像パス
    documents=["美しい夕日の写真"],  # テキスト説明
    metadatas=[
        {"type": "image", "location": "海岸"},
        {"type": "text", "topic": "風景"}
    ]
)

# テキストで画像を検索
results = collection.query(
    query_texts=["夕日"],
    n_results=5
)

# 画像で類似画像を検索
results = collection.query(
    query_images=["path/to/query_image.jpg"],
    n_results=5
)

パフォーマンス最適化

# バッチ処理での高速化
batch_size = 100
all_documents = [...]  # 大量のドキュメント

for i in range(0, len(all_documents), batch_size):
    batch = all_documents[i:i+batch_size]
    collection.add(
        documents=[doc["text"] for doc in batch],
        ids=[doc["id"] for doc in batch],
        metadatas=[doc["metadata"] for doc in batch]
    )

# 永続化設定の最適化
client = chromadb.PersistentClient(
    path="./chroma_db",
    settings=chromadb.Settings(
        anonymized_telemetry=False,
        allow_reset=True,
        is_persistent=True
    )
)

# メモリ効率的なクエリ
# 必要なフィールドのみを取得
results = collection.query(
    query_texts=["検索クエリ"],
    n_results=100,
    include=["documents", "distances"]  # embeddingsを除外
)