upstash-vector-db-skills について
upstash-vector-db-skills は、Upstash Vector と Node.js/TypeScript SDK を使ったアプリ開発のガイドです。インデックス作成、セマンティック検索、埋め込みモデル、名前空間によるデータ分離を扱い、検索や RAG の実装に役立ちます。
主な機能
- 01ベクトルとテキスト文書の登録
- 02メタデータを使った意味検索
- 03名前空間によるデータ分離
- 04埋め込みモデルの設定
- 05一括登録とベクトル管理
活用シーン
- 01文書のセマンティック検索構築
- 02RAG ワークフロー向けの文脈検索
- 03テナントごとの検索データ分離
- 04インデックスへのベクトル一括登録
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ gocallum/ nextjs16-agent-skills --skill upstash-vector-db-skillsインストール後、Claude Code で/upstash-vector-db-skillsを入力して読み込まれたか確認します。
詳細
リンク
- ドキュメント:https://upstash.com/docs/vector
- はじめに:https://upstash.com/docs/vector/overall/getstarted
- セマンティック検索チュートリアル:https://upstash.com/docs/vector/tutorials/semantic_search
- 名前空間:https://upstash.com/docs/vector/features/namespaces
- 埋め込みモデル:https://upstash.com/docs/vector/features/embeddingmodels
- MixBread AI:https://www.mixbread.ai/(推奨される埋め込みプロバイダー)
クイックセットアップ
1. ベクトルインデックスを作成する(Upstash Console)
- Upstash Console にアクセスします
- ベクトルインデックスを作成します:名前、リージョン(アプリに最も近いもの)、タイプ(セマンティック検索には Dense)
- 埋め込みモデルを選択します:MixBread AI を推奨(または Upstash 組み込みモデルを使用)
UPSTASH_VECTOR_REST_URLとUPSTASH_VECTOR_REST_TOKENを.envにコピーします
2. SDK をインストールする
pnpm add @upstash/vector
3. 環境
UPSTASH_VECTOR_REST_URL=your_url
UPSTASH_VECTOR_REST_TOKEN=your_token
コード例
クライアントを初期化する(Node.js / TypeScript)
import { Index } from "@upstash/vector";
const index = new Index({
url: process.env.UPSTASH_VECTOR_REST_URL,
token: process.env.UPSTASH_VECTOR_REST_TOKEN,
});
ドキュメントをアップサートする(自動埋め込み)
インデックスで埋め込みモデルを使用すると、テキストは自動的に埋め込まれます:
// Single document
await index.upsert({
id: "doc-1",
data: "Upstash provides serverless vector database solutions.",
metadata: { source: "docs", category: "intro" },
});
// Batch
await index.upsert([
{ id: "doc-2", data: "Vector search powers semantic similarity.", metadata: { source: "docs" } },
{ id: "doc-3", data: "MixBread AI provides high-quality embeddings.", metadata: { source: "blog" } },
]);
クエリ/セマンティック検索
// Semantic search with auto-embedding
const results = await index.query({
data: "What is semantic search?",
topK: 5,
includeMetadata: true,
});
results.forEach((result) => {
console.log(`ID: ${result.id}, Score: ${result.score}, Metadata:`, result.metadata);
});
名前空間を使用する(データ分離)
名前空間を使うと、単一のインデックスを分離されたサブセットに分割できます。マルチテナントまたは複数ドメインのアプリに便利です。
// Upsert in namespace "blog"
await index.namespace("blog").upsert({
id: "post-1",
data: "Next.js tutorial for Vercel deployment",
metadata: { author: "user-123" },
});
// Query only "blog" namespace
const blogResults = await index.namespace("blog").query({
data: "Vercel deployment",
topK: 3,
includeMetadata: true,
});
// List all namespaces
const namespaces = await index.listNamespaces();
console.log(namespaces);
// Delete namespace
await index.deleteNamespace("blog");
セマンティック検索の完全な例(Vercel Function)
// api/search.ts (Vercel Edge Function or Serverless Function)
import { Index } from "@upstash/vector";
export const config = {
runtime: "nodejs", // or "edge"
};
const index = new Index({
url: process.env.UPSTASH_VECTOR_REST_URL,
token: process.env.UPSTASH_VECTOR_REST_TOKEN,
});
export default async function handler(req, res) {
if (req.method !== "POST") {
return res.status(405).json({ error: "Method not allowed" });
}
const { query, namespace = "", topK = 5 } = req.body;
try {
const searchIndex = namespace ? index.namespace(namespace) : index;
const results = await searchIndex.query({
data: query,
topK,
includeMetadata: true,
});
return res.status(200).json({ results });
} catch (error) {
console.error("Search error:", error);
return res.status(500).json({ error: "Search failed" });
}
}
インデックス操作
// Reset (clear all vectors in index or namespace)
await index.reset();
// Or reset a specific namespace
await index.namespace("old-data").reset();
// Delete a single vector
await index.delete("doc-1");
// Delete multiple vectors
await index.delete(["doc-1", "doc-2", "doc-3"]);
埋め込みモデル
Upstash で利用可能
BAAI/bge-large-en-v1.5(1024 次元、最高の性能、MTEB スコア約 64.23)BAAI/bge-base-en-v1.5(768 次元、バランスに優れています)BAAI/bge-small-en-v1.5(384 次元、軽量)BAAI/bge-m3(1024 次元、スパース+デンスのハイブリッド)
推奨:MixBread AI
MixBread を埋め込みプロバイダーとして使用する場合:
- https://www.mixbread.ai/ で MixBread API キーを作成します
- Upstash インデックスの作成時に、埋め込みモデルとして MixBread を選択します。
- MixBread がトークン化とセマンティック品質を自動的に処理します。
- コードで追加のセットアップは不要です。テキストを直接指定して
index.upsert()/index.query()を使用します。
ベストプラクティス
Vercel へのデプロイ
- 認証情報は Vercel 環境変数(プロジェクト設定または
.env.local)に保存します。 - 低レイテンシーでアクセスできるよう、Edge Functions または Serverless Functions を使用します。
- Upstash のクォータ内に収めるため、リクエストのレート制限を実装します。
名前空間の戦略
- 名前空間を使って、テナント、ドメイン、またはユースケースごとにデータを分離します。
- 例:ユーザーごとの検索には
namespace("user-123")を使用します。 - ストレージの肥大化を防ぐため、古い名前空間を整理します。
クエリのパフォーマンス
topKは妥当な値にします(通常は 5~10 で十分です)。- 可能であれば、メタデータフィルタリングを使って結果を事前に絞り込みます。
- Upstash は結果整合性のため、アップサート後にわずかな遅延が発生することがあります。
エラー処理
try {
const results = await index.query({
data: userQuery,
topK: 5,
includeMetadata: true,
});
} catch (error) {
if (error.status === 401) {
console.error("Invalid credentials");
} else if (error.status === 429) {
console.error("Rate limited");
} else {
console.error("Query error:", error);
}
}
よくあるパターン
RAG(検索拡張生成)
- ドキュメント/ナレッジベースを Upstash にアップサートします。
- ユーザーのクエリに応じて、セマンティック検索で類似度の高い上位 k 件のドキュメントを取得します。
- 取得したドキュメントとユーザーのクエリを LLM に渡し、より適切なコンテキストを提供します。
const docs = await index.query({ data: userQuestion, topK: 3 });
const context = docs.map((d) => d.metadata?.text).join("\n");
// Pass context to LLM
マルチテナント検索
名前空間を使って、各テナントのベクトルを分離します:
const userNamespace = `tenant-${userId}`;
await index.namespace(userNamespace).upsert({ id, data, metadata });
// Queries only see that tenant's data
バッチインデックス作成
一括インポートでは、バッチ単位でアップサートします:
const batchSize = 100;
for (let i = 0; i < documents.length; i += batchSize) {
const batch = documents.slice(i, i + batchSize);
await index.upsert(batch);
console.log(`Indexed batch ${i / batchSize + 1}`);
}
トラブルシューティング
- 結果が返されない:ドキュメントがインデックスに登録され、埋め込みモデルが有効になっていることを確認します。
- クエリが遅い:クォータ制限を確認します。プランのアップグレード、またはデータセットのサイズ縮小を検討してください。
- データが古い:Upstash は結果整合性のため、新しいデータを挿入してからクエリを実行するまで 1~2 秒待ちます。
- 名前空間が機能しない:名前空間が存在する(最初のアップサート時に作成される)ことを確認するか、デフォルトの
""を使用します。
コメント
Markdown 対応