ベクトルデータベースとは
ベクトルデータベースは、高次元のベクトルデータを効率的に保存・検索するために設計された専用データベースです。テキスト、画像、音声などを数値ベクトル(埋め込み)に変換し、意味的な類似性に基づいて検索できます。
flowchart LR
subgraph Input["入力データ"]
Text["テキスト"]
Image["画像"]
Audio["音声"]
end
subgraph Embedding["埋め込みモデル"]
Model["AI モデル<br/>(OpenAI, Cohere等)"]
end
subgraph VectorDB["ベクトルDB"]
Index["インデックス"]
Storage["ベクトル保存"]
end
subgraph Output["検索結果"]
Similar["類似データ"]
end
Text --> Model
Image --> Model
Audio --> Model
Model --> Index
Index --> Storage
Storage --> Similar
なぜベクトルデータベースが必要か
従来の検索 vs セマンティック検索
| 特徴 | キーワード検索 | ベクトル検索 |
|---|---|---|
| 検索方式 | 完全一致・部分一致 | 意味的類似度 |
| 「犬」で検索 | 「犬」を含む文書 | 「ワンちゃん」「柴犬」も発見 |
| 多言語対応 | 言語ごとに別処理 | 意味が同じなら言語不問 |
| 同義語 | 辞書登録が必要 | 自動的に理解 |
埋め込みベクトルの仕組み
ベクトル化の例
import { OpenAI } from 'openai';
const openai = new OpenAI();
// テキストをベクトルに変換
async function getEmbedding(text: string): Promise<number[]> {
const response = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: text,
});
return response.data[0].embedding; // 1536次元のベクトル
}
// 例: 類似度計算
function cosineSimilarity(a: number[], b: number[]): number {
const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
return dotProduct / (magnitudeA * magnitudeB);
}
// 使用例
const vec1 = await getEmbedding('プログラミングを学ぶ');
const vec2 = await getEmbedding('コーディングを習得する');
const vec3 = await getEmbedding('料理のレシピ');
console.log(cosineSimilarity(vec1, vec2)); // 0.92(高い類似度)
console.log(cosineSimilarity(vec1, vec3)); // 0.21(低い類似度)
主要な類似検索アルゴリズム
1. HNSW(Hierarchical Navigable Small World)
最も広く使われるアルゴリズムで、高速かつ高精度です。
flowchart TB
subgraph Layer2["レイヤー2(疎)"]
A2((A)) --- B2((B))
end
subgraph Layer1["レイヤー1(中間)"]
A1((A)) --- B1((B))
B1 --- C1((C))
A1 --- D1((D))
end
subgraph Layer0["レイヤー0(密)"]
A0((A)) --- B0((B))
B0 --- C0((C))
C0 --- E0((E))
A0 --- D0((D))
D0 --- F0((F))
end
A2 -.-> A1
B2 -.-> B1
A1 -.-> A0
B1 -.-> B0
C1 -.-> C0
D1 -.-> D0
2. IVF(Inverted File Index)
データをクラスタに分割し、検索範囲を絞り込みます。
# Faissでの IVF 使用例
import faiss
import numpy as np
# 100万件の1536次元ベクトル
vectors = np.random.random((1_000_000, 1536)).astype('float32')
# IVFインデックス作成(nlist=1000クラスタ)
quantizer = faiss.IndexFlatL2(1536)
index = faiss.IndexIVFFlat(quantizer, 1536, 1000)
# 学習とデータ追加
index.train(vectors)
index.add(vectors)
# 検索(nprobe=10クラスタを探索)
index.nprobe = 10
query = np.random.random((1, 1536)).astype('float32')
distances, indices = index.search(query, k=10)
アルゴリズム比較
| アルゴリズム | 検索速度 | メモリ使用量 | 精度 | 適用場面 |
|---|---|---|---|---|
| Flat(総当たり) | 遅い | 低い | 100% | 小規模データ |
| HNSW | 速い | 高い | 95%+ | 汎用 |
| IVF | 中程度 | 中程度 | 90%+ | 大規模データ |
| PQ(量子化) | 非常に速い | 非常に低い | 80%+ | 超大規模 |
主要なベクトルデータベース
1. Pinecone
import { Pinecone } from '@pinecone-database/pinecone';
const pinecone = new Pinecone({ apiKey: process.env.PINECONE_API_KEY });
const index = pinecone.Index('my-index');
// データ追加
await index.upsert([
{
id: 'doc1',
values: embedding,
metadata: { title: '記事タイトル', category: 'tech' },
},
]);
// 検索
const results = await index.query({
vector: queryEmbedding,
topK: 10,
filter: { category: { $eq: 'tech' } },
includeMetadata: true,
});
2. Weaviate
import weaviate from 'weaviate-ts-client';
const client = weaviate.client({
scheme: 'https',
host: 'your-instance.weaviate.network',
});
// スキーマ定義
await client.schema.classCreator().withClass({
class: 'Article',
vectorizer: 'text2vec-openai',
properties: [
{ name: 'title', dataType: ['text'] },
{ name: 'content', dataType: ['text'] },
],
}).do();
// セマンティック検索
const result = await client.graphql
.get()
.withClassName('Article')
.withFields('title content')
.withNearText({ concepts: ['機械学習入門'] })
.withLimit(5)
.do();
3. pgvector(PostgreSQL拡張)
-- 拡張を有効化
CREATE EXTENSION vector;
-- テーブル作成
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536)
);
-- インデックス作成(HNSW)
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops);
-- 類似検索
SELECT content, 1 - (embedding <=> query_embedding) AS similarity
FROM documents
ORDER BY embedding <=> query_embedding
LIMIT 10;
RAGでの活用
RAG(Retrieval-Augmented Generation)は、ベクトルデータベースとLLMを組み合わせた手法です。
flowchart LR
Query["ユーザー質問"] --> Embed["埋め込み変換"]
Embed --> Search["ベクトル検索"]
Search --> Context["関連文書取得"]
Context --> LLM["LLM"]
Query --> LLM
LLM --> Answer["回答生成"]
実装例
import { OpenAI } from 'openai';
import { Pinecone } from '@pinecone-database/pinecone';
async function ragQuery(question: string): Promise<string> {
const openai = new OpenAI();
const pinecone = new Pinecone();
const index = pinecone.Index('knowledge-base');
// 1. 質問をベクトル化
const embeddingResponse = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: question,
});
const queryVector = embeddingResponse.data[0].embedding;
// 2. 関連文書を検索
const searchResults = await index.query({
vector: queryVector,
topK: 5,
includeMetadata: true,
});
// 3. コンテキストを構築
const context = searchResults.matches
.map(match => match.metadata?.content)
.join('\n\n');
// 4. LLMで回答生成
const completion = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{
role: 'system',
content: `以下のコンテキストに基づいて質問に答えてください。\n\n${context}`,
},
{ role: 'user', content: question },
],
});
return completion.choices[0].message.content ?? '';
}
ベストプラクティス
1. チャンキング戦略
// 適切なチャンクサイズで分割
function chunkText(text: string, chunkSize = 500, overlap = 50): string[] {
const chunks: string[] = [];
let start = 0;
while (start < text.length) {
const end = Math.min(start + chunkSize, text.length);
chunks.push(text.slice(start, end));
start = end - overlap;
}
return chunks;
}
2. メタデータの活用
// フィルタリングで検索精度向上
const results = await index.query({
vector: queryVector,
topK: 10,
filter: {
$and: [
{ category: { $eq: 'documentation' } },
{ date: { $gte: '2024-01-01' } },
{ language: { $eq: 'ja' } },
],
},
});
3. ハイブリッド検索
// キーワード検索とベクトル検索を組み合わせ
const hybridResults = await weaviate.graphql
.get()
.withClassName('Article')
.withHybrid({
query: 'TypeScript 型安全',
alpha: 0.5, // 0=キーワード, 1=ベクトル
})
.withLimit(10)
.do();
関連記事
- RAGの最新動向 - RAG技術の発展
- SQL vs NoSQL - データベース選択
- AIコーディング - AI開発ツール
まとめ
ベクトルデータベースは、AI時代の検索基盤として不可欠な技術です。
- 埋め込みベクトル: テキストや画像を数値表現に変換
- 類似検索: HNSWやIVFで高速な近似最近傍探索
- RAG: LLMと組み合わせて知識ベースを構築
- ハイブリッド検索: キーワードとセマンティックの融合
適切なベクトルデータベースとアルゴリズムを選択し、AIアプリケーションの基盤を構築しましょう。
← 一覧に戻る