catsu について
Catsuは、複数のプロバイダーで埋め込みを生成・比較する開発者向けの統合APIクライアントです。PythonとRustのインターフェース、モデル検索、自動リトライ、利用コストの追跡に対応します。
主な機能
- 01複数の埋め込みプロバイダーを統一APIで利用
- 02モデルの検索と比較
- 03非同期・バッチ埋め込み呼び出し
- 04一時的なエラーの自動リトライ
- 05次元数と入力タイプの指定
- 06トークン使用量とコストの追跡
活用シーン
- 01コードを変えずに埋め込みプロバイダーを切り替え
- 02RAGや検索ワークフローへのベクトル追加
- 03コストや品質によるモデル比較
- 04保存容量削減のためのベクトル次元数の縮小
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ feyninc/ skills --skill catsuインストール後、Claude Code で/catsuを入力して読み込まれたか確認します。
同梱ファイルreferences/model_comparison.md
詳細
Catsu — 統合埋め込み API クライアント
Catsu は、11 のプロバイダーと 35 以上のモデルで埋め込みを生成するための、統一された一貫性のあるインターフェースを提供します。組み込みの再試行ロジック、コスト追跡、モデル検出により、プロバイダー固有の SDK は不要です。
このスキルを使う場面
次のような要望がある場合に、このスキルを使用してください。
- 統合 API を通じて、任意のプロバイダーから埋め込みを生成する
- プロバイダー間で埋め込みモデルを比較する(コスト、品質、次元数)
- RAG パイプライン、検索システム、レコメンデーションエンジンに埋め込みを追加する
- アプリケーションコードを変更せずにプロバイダーを切り替える
- 埋め込み呼び出し全体でトークン使用量とコストを追跡する
- ストレージを最適化するために Matryoshka 埋め込み(次元数の削減)を使用する
インストール
# Python
pip install catsu
# Requires Python 3.10+
# Rust
# Add to Cargo.toml:
# [dependencies]
# catsu = "0.1"
# tokio = { version = "1", features = ["full"] }
セットアップ — API キー
使用するプロバイダーの環境変数を設定してください。
export OPENAI_API_KEY=<your-openai-key>
export VOYAGE_API_KEY=<your-voyage-key>
export COHERE_API_KEY=<your-cohere-key>
export JINA_API_KEY=<your-jina-key>
export MISTRAL_API_KEY=<your-mistral-key>
export GOOGLE_API_KEY=<your-google-key> # or GEMINI_API_KEY
export TOGETHER_API_KEY=<your-together-key>
export MIXEDBREAD_API_KEY=<your-mixedbread-key>
export NOMIC_API_KEY=<your-nomic-key>
export DEEPINFRA_API_KEY=<your-deepinfra-key>
export CLOUDFLARE_API_TOKEN=<your-cloudflare-token> # + CLOUDFLARE_ACCOUNT_ID
実際に呼び出すプロバイダーのキーだけが必要です。
基本的な使い方
Python
from catsu import Client
client = Client()
# Embed text — provider:model format
response = client.embed(
model="openai:text-embedding-3-small",
input=["Hello, world!", "How are you?"]
)
print(response.embeddings) # [[0.012, -0.034, ...], [...]]
print(response.dimensions) # 1536
print(response.usage.tokens) # 10
print(response.usage.cost) # 0.000002
print(response.latency_ms) # 142.5
Rust
use catsu::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new()?;
let response = client.embed(
"openai:text-embedding-3-small",
vec!["Hello, world!".to_string()],
).await?;
println!("Dimensions: {}", response.dimensions);
println!("Cost: ${}", response.usage.cost.unwrap_or(0.0));
Ok(())
}
モデルの指定
使用するモデルを指定する方法は 3 つあります。
client = Client()
# 1. Provider prefix (recommended)
response = client.embed(model="voyageai:voyage-3", input="hello")
# 2. Explicit provider parameter
response = client.embed(provider="voyageai", model="voyage-3", input="hello")
# 3. Auto-detection (if model name is unique across providers)
response = client.embed(model="voyage-3", input="hello")
入力タイプ — クエリとドキュメント
多くのプロバイダーは、検索クエリと保存済みドキュメントで埋め込みを異なる方法で最適化しています。
# For search queries (short, question-like)
response = client.embed(
model="voyageai:voyage-3",
input=["what is attention?"],
input_type="query",
)
# For documents being indexed (longer content)
response = client.embed(
model="voyageai:voyage-3",
input=["The attention mechanism allows models to..."],
input_type="document",
)
入力タイプに対応するプロバイダー:VoyageAI、Cohere(v3 以降では必須)、Jina、Mistral、Gemini、Nomic。
カスタム次元(Matryoshka 埋め込み)
品質を多少犠牲にして、ストレージや速度のために埋め込みの次元数を減らせます。
# OpenAI: 1536 → 256 dimensions
response = client.embed(
model="openai:text-embedding-3-small",
input=["hello"],
dimensions=256,
)
print(response.dimensions) # 256
カスタム次元に対応するプロバイダー:OpenAI、VoyageAI、Cohere、Jina、Mistral、Gemini、Nomic。
対応プロバイダーとモデル
| プロバイダー | モデル | 次元数 | 最大トークン数 | 入力タイプ | カスタム次元 |
|---|---|---|---|---|---|
| OpenAI | text-embedding-3-small, 3-large, ada-002 | 1536, 3072, 1536 | 8191 | いいえ | はい |
| VoyageAI | voyage-3, voyage-code-3, voyage-finance-2, voyage-law-2, voyage-multilingual-2, voyage-multimodal-3 | 1024 | 32000 | はい | はい |
| Cohere | embed-v4.0, embed-english-v3.0, embed-multilingual-v3.0 | 1024 | 128000 | 必須(v3 以降) | はい |
| Jina | jina-embeddings-v4, v3, jina-code-v2 | 1024 | 32768 | はい | はい |
| Mistral | mistral-embed, codestral-embed-2505 | 1024 | 32768 | はい | はい |
| Gemini | gemini-embedding-001 | 768 | 2048 | はい | はい(128-3072) |
| Together AI | BAAI/bge models | 1024 | 8192 | いいえ | いいえ |
| Mixedbread | mxbai-embed models | 1024 | 512 | いいえ | いいえ |
| Nomic | nomic-embed-text-v1.5 | 768 | 8192 | はい | はい |
| DeepInfra | BAAI/bge models | 1024 | 8192 | いいえ | いいえ |
| Cloudflare | BGE, Qwen models | 768-1024 | 512-8192 | いいえ | いいえ |
モデルの検出
from catsu import Client
# List all available models
all_models = Client.list_models()
# Filter by provider
openai_models = Client.list_models("openai")
for m in openai_models:
print(f"{m.name}: {m.dimensions}d, ${m.cost_per_million_tokens}/M tokens")
# Get specific model info
model = Client.get_model("openai", "text-embedding-3-small")
print(f"Max tokens: {model.max_tokens}")
print(f"Supports dimensions: {model.supports_dimensions}")
# Find model by name (auto-detect provider)
model = Client.find_model_by_name("voyage-3")
print(f"Provider: {model.provider}")
モデル選択ガイド
| 用途 | 推奨モデル | 理由 |
|---|---|---|
| 汎用、低コスト | openai:text-embedding-3-small | 価格と性能の比率が最良 |
| 最高品質の検索 | voyageai:voyage-3 | MTEB スコアがトップ |
| コード検索 | voyageai:voyage-code-3 または jina:jina-code-v2 | コードに最適化された学習 |
| 法律/金融分野 | voyageai:voyage-law-2 / voyage-finance-2 | 分野に特化 |
| 多言語コンテンツ | cohere:embed-multilingual-v3.0 または voyageai:voyage-multilingual-2 | 100 以上の言語に対応 |
| 長文書(128K) | cohere:embed-v4.0 | 128K トークンのコンテキスト |
| 無料/セルフホスト可能 | together:BAAI/bge-large-en-v1.5 | オープンモデル、低コスト |
| マルチモーダル(テキスト+画像) | voyageai:voyage-multimodal-3 または jina:jina-embeddings-v4 | 混在コンテンツ |
詳細なベンチマークとコスト分析については、references/model_comparison.md を参照してください。
再試行とエラー処理
Catsu は一時的な障害を自動的に処理します。
client = Client(
max_retries=5, # Default: 3
timeout=60, # Default: 30 seconds
)
# Retries automatically on: 429, 408, 409, 500, 502, 503, 504
# Uses exponential backoff with jitter
# Respects Retry-After headers
明示的なエラー処理
from catsu.utils.errors import (
RateLimitError,
AuthenticationError,
ModelNotFoundError,
MissingApiKeyError,
)
try:
response = client.embed(model="voyage-3", input="hello")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except AuthenticationError:
print("Invalid API key")
except ModelNotFoundError as e:
print(f"Unknown model: {e}")
except MissingApiKeyError as e:
print(f"Set {e.provider} API key")
高度な設定
リクエストごとの API キーの上書き
import os
response = client.embed(
model="openai:text-embedding-3-small",
input="hello",
api_key=os.environ["ALTERNATE_OPENAI_KEY"],
)
HTTP プロキシとカスタム CA
# Python
client = Client(proxy="http://proxy:8080")
# Rust
let config = HttpConfig {
proxy: Some("http://proxy:8080".to_string()),
ca_cert_pem: Some(cert_pem_string),
..Default::default()
};
let client = Client::with_config(config)?;
クリーンアップ用のコンテキストマネージャー
# Sync
with Client() as client:
response = client.embed("voyage-3", "hello")
# Async
async with Client() as client:
response = await client.aembed("voyage-3", "hello")
NumPy への変換
response = client.embed("voyage-3", ["text1", "text2"])
arr = response.to_numpy() # shape: (2, 1024)
非同期処理のサポート
import asyncio
from catsu import Client
async def embed_batch():
async with Client() as client:
response = await client.aembed(
model="openai:text-embedding-3-small",
input=["text1", "text2", "text3"],
)
return response.embeddings
embeddings = asyncio.run(embed_batch())
Chonkie との統合
Catsu は Chonkie の RAG パイプラインの埋め込みプロバイダーとして機能します。
pip install "chonkie[catsu]"
from chonkie import Pipeline
# Use catsu as the embedding backend
docs = (Pipeline()
.chunk_with("recursive", chunk_size=512)
.refine_with("embeddings", embedding_model="catsu:voyage-3")
.store_in("qdrant", url="http://localhost:6333", collection="docs")
.run(texts=documents)
)
または、Catsu の埋め込みを Chonkie の AutoEmbeddings で直接使用できます。
from chonkie import AutoEmbeddings
embed = AutoEmbeddings.get_embeddings("catsu:openai:text-embedding-3-small")
vectors = embed.embed_batch(["text1", "text2"])