実物を見ないとイメージが湧かない
ベクトルDBを含め、何かの勉強を始める時、
実物を見ないとイメージが湧かなくないですか?
わかります。僕もこれです。
例えば、エンジニアになって JSON を初めて知った時
- key value でデータを表すらしい
- API のリクエスト・レスポンスに使われるらしい
と言われるより、
こういうの ↓ が JSON です!
って見せられる方がイメージ湧きやすいですよね。
そもそも JSON を初めて聞く頃には key value の概念すら知らないこともあると思います。
このように、分からないこと(JSON)について、分からない概念(key value)で説明しても理解ができないものです。
そこで実物を見せることで、「これが key value か!」ということも併せて理解できてうれしい!ということになります。
{
"id": 12345, // 数値型のユーザーID
"username": "tanaka_taro", // ログインに使うユーザーネーム
"email": "taro.tanaka@example.com", // 連絡先メールアドレス
"isActive": true, // アカウント有効・無効フラグ
"createdAt": "2025-07-16T10:30:00Z", // ISO 8601形式の作成日時
"profile": {
// プロフィール情報のネストオブジェクト
"firstName": "太郎",
"lastName": "田中",
"birthday": "1990-05-20",
"address": {
"street": "1-2-3 Chiyoda",
"city": "Tokyo",
"postalCode": "100-0001",
"country": "Japan"
}
},
"roles": [
// ユーザー権限の配列
"user",
"editor"
],
"preferences": {
// オプション設定のネストオブジェクト
"language": "ja",
"timezone": "Asia/Tokyo",
"newsletter": false
}
}
今回のテーマ
今回はベクトルデータベースについて、
- 言葉は知っているけどよくわからない!
- AI はチャットとコーディングエージェントくらいしか使ってない!
- 用途のイメージが湧かない!
という人向けに、
明日から「ベクトルデータベース完全に理解した」と言えるように解説していきます。もちろんイメージしやすいよう実物もお見せします。
僕自身も、この記事を書き始めた時点ではよくわかっていないので、
書き終わる頃に完全に理解していた場合この記事を公開します。
※ただし、「ベクトルデータベース チョットワカル」まではいかないので、理解への第一歩というつもりで見てください。
ベクトルデータベースって何
まず、普通のデータベースとの違いから見てみましょう。
普通のデータベース(例:MySQL)
普通のデータベースはこんな感じでデータを保存します。
-- ユーザーテーブル
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100),
age INT
);
-- データ挿入
INSERT INTO users VALUES
(1, '田中太郎', 'tanaka@example.com', 25),
(2, '佐藤花子', 'sato@example.com', 30),
(3, '鈴木次郎', 'suzuki@example.com', 28);
-- データ検索
SELECT * FROM users WHERE age > 25;
このように、テキストや数値をそのまま保存して、完全一致や範囲検索で取得します。
ベクトルデータベース
一方、ベクトル DB は数値の配列(ベクトル) でデータを保存します。
こういうの ↓ がベクトルです!
{
"id": "doc_001",
"text": "今日は良い天気ですね",
"vector": [0.2, -0.5, 0.8, 0.1, -0.3, 0.9, ...]
// 注: 実際は数百〜数千次元
}
このベクトルは、文章の意味を数値で表現したものです。
似たような意味の文章は、似たようなベクトルになります。
[
{
"text": "今日は良い天気ですね",
"vector": [0.2, -0.5, 0.8, 0.1, -0.3, ...]
},
{
"text": "今日は晴れていて気持ちいいです",
"vector": [0.3, -0.4, 0.7, 0.2, -0.2, ...]
// 注: 似たベクトル!
},
{
"text": "pythonでAPIを作る方法",
"vector": [-0.8, 0.9, -0.1, 0.7, 0.4, ...]
// 注: 全然違うベクトル
}
]
比較表:普通のDBとベクトルDB
項目 | 普通のDB(MySQL等) | ベクトルDB |
---|---|---|
データ形式 | テキスト・数値そのまま | 数値の配列(ベクトル) |
検索方法 | 完全一致・範囲検索 | 意味の類似度検索 |
クエリ例 | WHERE name = '田中' |
「似た意味のドキュメントを探す」 |
得意分野 | 正確なデータ管理 | 意味理解・推薦・AI連携 |
何のために必要?
「意味」での検索に必要です!
問題:普通のデータベースだと「意味で検索」ができない
例えば、社内のナレッジベースで「エラーの対処法」を探したいとします。
普通のデータベースの場合
-- こんな検索しかできない
SELECT * FROM knowledge WHERE title LIKE '%エラー%';
SELECT * FROM knowledge WHERE content LIKE '%対処法%';
でも実際に欲しい情報は:
- 「トラブルシューティング」
- 「不具合解決」
- 「問題解決手順」
- 「バグの直し方」
のようなタイトルで保存されているかもしれません。この場合、キーワードが一致しないデータが見つかりません。
ベクトル DB の場合
「エラーの対処法を教えて」というクエリをベクトル化して、意味が似ているドキュメントを探せます!
# こんなイメージ
query = "エラーの対処法を教えて"
query_vector = embed_text(query) # [0.1, -0.7, 0.5, ...]
# 意味が似ているドキュメントを取得
similar_docs = vector_db.search(query_vector, top_k=5)
結果として、キーワードが違っても意味が似ている文書が取得できます:
[
{
"title": "システム障害時の初動対応手順",
"similarity": 0.89
},
{
"title": "バグ調査のベストプラクティス",
"similarity": 0.85
},
{
"title": "トラブルシューティングガイド",
"similarity": 0.82
}
]
検索の高速化に関わる技術
発展)ハイブリッド検索
キーワード検索(BM25 など)とベクトル検索(意味ベース)を同時に走らせて結果を融合し、双方の強み(厳密一致と意味理解)を一つのランキングにまとめる手法です。多くの検索エンジンやベクトル DB が公式にサポートしています。
発展)ANN と HNSW
ANN(Approximate Nearest Neighbor)
ベクトル本数が増えると、全件(厳密)探索は重いです。
ANN は “検索精度を少しだけ妥協”して大幅に速く します。多くのベクトル DB/検索基盤が ANN を採用しています。
HNSW(Hierarchical Navigable Small Worlds)
HNSW アルゴリズムは、ANN 検索で最も良く使われるアルゴリズムの 1 つです。まずは「迷ったら HNSW」くらいで OK です。(選定は要件次第で)
Elastic / OpenSearchでも使用されています。
OpenSearch における 10 億規模のユースケースに適した k-NN アルゴリズムの選定
ナレッジベースって何
前の項で「ナレッジベース」という単語が例として出ていましたね。
ナレッジベースは企業や組織の業務に関する知識を蓄積したデータベースのことです。
具体例:IT 企業のナレッジベース
従来の問題
# よくある質問集(従来版)
## Q1: API が 500 エラーを返す
A: サーバーログを確認してください
## Q2: データベース接続エラー
A: 接続文字列を確認してください
## Q3: デプロイが失敗する
A: 環境変数を確認してください
新入社員が「なんかサーバーが動かない」と相談したとき、どの質問が関連するかわからない!
ベクトル DB バージョン
# 実際の検索例
user_question = "サーバーが動かなくて困っています"
# ベクトルDBが意味を理解して関連する情報を返す
results = [
{
"content": "APIが500エラーを返す場合の対処法...",
"similarity": 0.87,
"tags": ["API", "エラー", "サーバー"]
},
{
"content": "サーバー起動時のよくあるトラブル...",
"similarity": 0.84,
"tags": ["サーバー", "起動", "トラブル"]
}
]
曖昧な質問でも適切な回答が見つかる! これがベクトル DB の嬉しいところです。
ベクトル DB の基本概念
ここでは、ベクトル DB の基本的な概念について説明します。
ベクトルって何
高校で習ったベクトル
高校の数学で習いましたね。覚えてますか?
こういうの ↓ でした!
# 2次元ベクトル
A = (3, 4) // x方向に3、y方向に4
# 3次元ベクトル
B = (1, 2, 3) // x方向に1、y方向に2、z方向に3
これらは物理的な空間の位置や力を表現していました。
数学的には、ベクトルとは大きさと向きを持つ量のことです。
例えば、2 次元空間では以下のように表現されます:
A(1, 2) // 原点からx方向に1、y方向に2のベクトル
このベクトルは、原点から点 A までの最短距離と方向を示しています。
具体例:力のベクトル
風の力 = (東に5m/s, 北に3m/s)
位置 = (x座標: 10, y座標: 20)
ベクトル DB のベクトル
一方、ベクトル DB で使うベクトルは用途や次元が高校数学とは異なります!
こういうの ↓ です!
# Embeddingベクトル(実際のOpenAI APIの結果)
sentence = "今日は良い天気ですね"
embedding = [
0.0023, -0.0089, 0.0156, 0.0234, -0.0067, 0.0145,
0.0098, -0.0123, 0.0187, 0.0045, -0.0156, 0.0234,
# 注: 1536次元まで続く!
]
print(f"次元数: {len(embedding)}") # 1536次元
高校数学のベクトルとの違い
項目 | 高校数学のベクトル | Embedding ベクトル |
---|---|---|
次元数 | 2 次元・3 次元 | 数百〜数千次元 |
軸の意味 | 物理的(x, y, z 座標) | 抽象的(意味的特徴) |
可視化 | 簡単(グラフで描ける) | 困難(高次元すぎる) |
用途 | 位置・力・速度 | 文章・画像の意味 |
実際の比較例
# 高校数学のベクトル:物理的な意味
position_vector = (10, 20, 5) # x=10m, y=20m, z=5m の位置
# Embeddingベクトル:意味的な特徴
text_vector = [
0.123, # 「感情」の特徴?
-0.456, # 「時間」の特徴?
0.789, # 「天気」の特徴?
0.234, # 「肯定/否定」の特徴?
# 注: 各次元が何を表すかは人間にはわからない!
]
なぜこんなに高次元なのか?
言葉の意味を表現するには、たくさんの特徴が必要だから
sentence_features = {
"感情": 0.8, # ポジティブ
"時制": 0.2, # 現在
"主語": 0.1, # 暗示的
"天気": 0.9, # 天気関連
"季節": 0.3, # 特定なし
"場所": 0.0, # 特定なし
# 注: 実際は数千の特徴が必要!
}
# だから1536次元のベクトルになる
print("1536次元 = 1536個の意味的特徴")
高次元ベクトルの利点
似た意味の文章が、似た高次元ベクトルになること。
sentences = [
"今日は良い天気ですね",
"今日は晴れていて気持ちいいです", # 似た意味
"Pythonでプログラミングしよう" # 全然違う意味
]
# 実際のベクトル化(簡略表示)
vectors = [
[0.8, 0.2, 0.9, 0.1, ...], # 天気に関する特徴が強い
[0.7, 0.3, 0.8, 0.2, ...], # 似たパターン!
[-0.1, 0.9, 0.1, 0.8, ...], # 全然違うパターン
]
# 類似度計算
similarity_weather = cosine_similarity(vectors[0], vectors[1]) # 0.89(高い!)
similarity_program = cosine_similarity(vectors[0], vectors[2]) # 0.12(低い)
print(f"天気同士の類似度: {similarity_weather}")
print(f"天気とプログラミング: {similarity_program}")
重要なポイント:
- 高次元 = より複雑な意味を表現できる
- 各次元が「抽象的な意味の特徴」を表す
- 人間には理解できないが、AI には意味がある
数学的な定義は置いておいて...
数学では「大きさと向きを持つ量」などと言いますが、
プログラマーにとって、ベクトルは「数値の配列」として理解すれば十分です。
ただの配列です! 難しく考える必要はありません。
# これがベクトル
vector = [0.1, -0.5, 0.8, 0.2, -0.3]
Embedding(埋め込み) って何
Embedding は 「テキストを学習済みモデルで固定長ベクトルに写像する処理」 です。
例:OpenAI の最新モデル text-embedding-3-small(既定 1536 次元)や text-embedding-3-large(既定 3072 次元)を使うと、文章をそのままベクトルに変換できます。次元数はパラメータで縮小も可能です。
こういうの ↓ が Embedding です!
# 文章
text = "猫が好きです"
# Embedding後
embedding_vector = [0.2, -0.1, 0.5, 0.8, -0.3, 0.7, ...]
# ↑この数値の配列が「猫が好きです」の意味を表現している
Embedding のプロセス図
実際の Embedding 例
import openai
# 実際のEmbedding例
# OpenAI Python SDK v1系の例
from openai import OpenAI
import numpy as np
client = OpenAI()
texts = ["猫が好きです", "犬が好きです", "今日は雨です"]
def embed(t):
# OpenAIのEmbeddingモデルを使用(1536次元のベクトルを生成)
# この数値が大きいほど、より詳細な意味を表現できる
return client.embeddings.create(
model="text-embedding-3-small", # 軽量で高速なEmbeddingモデル
input=t # 変換したい文章を入力
).data[0].embedding # 生成されたベクトル(数値の配列)を取得
vecs = [np.array(embed(t)) for t in texts] # 各文章をベクトルに変換してリスト化
def cosine(a, b):
# コサイン類似度を計算(-1〜1の範囲、1に近いほど似ている)
return float(a @ b / (np.linalg.norm(a) * np.linalg.norm(b)))
# 各文章ペアの類似度を計算・表示
print("猫 vs 犬:", cosine(vecs[0], vecs[1])) # 似た概念同士を比較
print("猫 vs 雨:", cosine(vecs[0], vecs[2])) # 全く違う概念同士を比較
# 実行結果例:
# 猫 vs 犬: 0.85 # 似た意味なので高い類似度!
# 猫 vs 雨: 0.23 # 全然違う意味なので低い類似度
# 各文章のベクトル例(最初の5次元のみ表示):
# '猫が好きです' → [0.023, -0.089, 0.156, 0.034, -0.012, ...]
# '犬が好きです' → [0.031, -0.076, 0.142, 0.028, -0.018, ...] # '猫が好きです'と似たパターン!
# '今日は雨です' → [-0.102, 0.245, -0.087, 0.156, 0.089, ...] # 全然違うパターン
重要なポイント: 似た意味の文章は、似たようなベクトルになります!
なぜ Embedding が必要なのか
問題:コンピュータには文章の意味がわからない
# コンピュータから見ると、これらは全部「ただの文字列」
text1 = "犬が好き"
text2 = "わんちゃんが好き"
text3 = "イヌが好き"
# 人間には「同じ意味」だとわかるけど、コンピュータには...
print(text1 == text2) # False (文字列として違う)
print(text1 == text3) # False (文字列として違う)
解決:Embedding で意味を数値化
# Embeddingで変換すると...
vec1 = embed_text("犬が好き") # [0.2, 0.8, -0.1, ...]
vec2 = embed_text("わんちゃんが好き") # [0.3, 0.7, -0.2, ...]
vec3 = embed_text("イヌが好き") # [0.1, 0.9, -0.1, ...]
# 類似度で比較
print(cosine_similarity(vec1, vec2)) # 0.92 (超似てる!)
print(cosine_similarity(vec1, vec3)) # 0.89 (似てる!)
実際の応用例
# 社内チャットボットの例
user_questions = [
"ログインできません",
"サインインできない",
"アクセスできない",
"入れません"
]
# 全部違う文字列だけど、Embeddingで変換すると...
for question in user_questions:
vector = embed_text(question)
# 「ログイン関連のトラブル」として似たベクトルになる!
# だから同じ回答を返せる
answer = search_knowledge_base(vector) # 「ログイン手順はこちら...」
※なぜ「Embedding(テキスト埋め込み)」と言うのか? 「テキストのベクトル化」でよくない?
Embeddingは、意味を保った状態でテキストを数値ベクトル空間に “埋め込む”ように配置する 操作をイメージしています。
一方でベクトル化とは、テキストを数値ベクトルに直接変換することです。各単語を独立したエンティティとして扱い、文脈や単語間の関係は考慮されません。
なぜ Embedding が必要かのまとめ
- 文字列の限界: 「犬」と「わんちゃん」は文字として違うけど意味は同じ
- 意味の数値化: Embedding で意味を数値として表現できる
- 計算可能: 数値なので類似度計算ができる
- スケール: 大量のテキストでも高速に意味比較できる
# Before: 文字列比較(意味を理解できない)
if user_input == "ログインできません":
return login_help()
elif user_input == "サインインできない": # これは別の条件として書く必要が...
return login_help()
# ...無限に条件が増える
# After: Embedding + ベクトル検索(意味を理解)
user_vector = embed_text(user_input)
similar_docs = vector_db.search(user_vector)
return generate_answer(similar_docs) # どんな表現でも適切な回答!
これが Embedding の嬉しい点です! 文章を数値に変換することで、コンピュータが「意味」を理解できるようになります。
実際のベクトルデータ例
実際のベクトルデータがどのようなものか、具体例を見てみましょう。
簡潔な例(理解用)
# 短い文章の場合
sentence = "今日は良い天気ですね"
embedding = [
0.0023, -0.0089, 0.0156, 0.0234, -0.0067, 0.0145,
0.0098, -0.0123, 0.0187, 0.0045, -0.0156, 0.0234,
# 注: 実際は1536次元まで続く
]
print(f"次元数: {len(embedding)}") # 1536次元
実際のプロダクション例
{
"id": "doc_001",
"text": "技術仕様書の内容(約500文字)",
"vector": [
-0.01566, -0.00231, 0.06037, 0.08317, 0.09294, -0.01108, 0.02193, 0.00155,
0.0554, -0.02078
// 1536次元の完全なベクトル(実際は非常に長い)
],
"metadata": {
"category": "technical_document",
"language": "ja",
"word_count": 500
}
}
重要なポイント:
- 実際のベクトルは非常に長い(数百〜数千次元)
- 人間には意味不明でも、AI には意味のある数値配列
- メタデータと組み合わせて管理される
より実用的なベクトルデータ例
ベクトルデータベースでの実用的な例を以下に示します:
{
"id": "news_001",
"text": "AI技術が医療現場で活用され、診断精度が向上している",
"vector": [0.12, -0.04, 0.87, 0.23, -0.56, 0.41, 0.08, -0.13],
"metadata": {
"category": "technology",
"date": "2024-03-15",
"keywords": ["AI", "医療", "診断"]
}
}
距離・類似度
ベクトル DB では、データ間の距離や類似度を計算して、関連するデータを検索します。
一般的な距離・類似度の指標には以下があります:
- ユークリッド距離: 2 点間の直線距離
- コサイン類似度: ベクトルの方向の類似性(-1〜1 の値)
最も一般的に使われるコサイン類似度については、後述の「ベクトルの「似ている度」を測る」セクションで詳しく説明します。
指標 | 直感 | 使いどころ |
---|---|---|
コサイン類似度 | 角度の近さ(1 に近いほど似る) | テキストの意味比較の定番 |
内積(dot product) | 長さと方向の近さ | レコメンドなど、ベクトル長も効かせたい時 |
L2 距離(ユークリッド) | 直線距離(小さいほど近い) | 正規化済みベクトルや画像特徴量など |
※DB やツールによっては distance(小さいほど近い)を返すものがあります(例:Weaviate の distance メタデータ)。本記事では読みやすさのため “類似度”表記(大きいほど近い) で統一します。
実際の開発では Embedding API を使う
文章がベクトルになる仕組みについては、前述の「Embedding とは」で詳しく説明しました。
実際の開発では、複雑な変換プロセスを自分で実装する必要はありません:
from openai import OpenAI
client = OpenAI() # OpenAI APIクライアントを初期化
# これで文章がベクトルになる!
res = client.embeddings.create(
model="text-embedding-3-small", # 使用するEmbeddingモデルを指定
input="今日は良い天気ですね" # ベクトル化したい文章
)
vector = res.data[0].embedding # 生成されたベクトルを取得
print(len(vector)) # 1536次元のベクトル(OpenAIの標準サイズ)
print(vector[:5]) # 最初の5つの数値を表示 [0.0023, -0.0089, 0.0056, ...]
重要なポイント:
- API 一回の呼び出しで完了
- 高品質な事前学習済みモデルを利用
- トークン化や単語ベクトルの組み合わせはすべて自動処理
ベクトルの「似ている度」を測る
ベクトル DB で最も重要な概念の一つが、ベクトル間の類似度計算です。
実装例
import numpy as np
def cosine_similarity(vec1, vec2):
"""コサイン類似度を計算(-1〜1の値)"""
dot_product = np.dot(vec1, vec2) # 内積を計算
norm1 = np.linalg.norm(vec1) # ベクトル1の長さ(ノルム)
norm2 = np.linalg.norm(vec2) # ベクトル2の長さ(ノルム)
return dot_product / (norm1 * norm2) # コサイン類似度の公式
# 実際の例(embed_text関数は事前に定義されているとします)
vec1 = embed_text("今日は良い天気ですね") # 天気に関する文章
vec2 = embed_text("今日は晴れていて気持ちいいです") # 同じく天気の文章
vec3 = embed_text("pythonでAPIを作る方法") # 全く違う分野の文章
print(cosine_similarity(vec1, vec2)) # 0.85 (似ている!)
print(cosine_similarity(vec1, vec3)) # 0.12 (似ていない)
コサイン類似度とは
コサイン類似度は、2 つのベクトルがどれだけ似た方向を向いているかを測る指標です。
- 値の範囲: -1 〜 1
- 1 に近い: 非常に似ている
- 0 に近い: 関連性が低い
- -1 に近い: 正反対の意味
scikit-learn(サイキット - ラーン) を使う場合
from sklearn.metrics.pairwise import cosine_similarity
# より簡単な方法
similarity = cosine_similarity(
vec1.reshape(1, -1),
vec2.reshape(1, -1)
)[0][0]
print(f"類似度: {similarity:.3f}")
実用的な類似度の目安
- 0.9 以上: ほぼ同じ意味
- 0.7-0.9: とても似ている
- 0.5-0.7: 関連性あり
- 0.3-0.5: 少し関連
- 0.3 未満: 関連性なし
この類似度計算により、ベクトル DB は「意味が似ているデータ」を効率的に検索できるのです。
※しきい値はモデルとデータで大きく変わるため、プロジェクトごとに検証してください。
誰が、どのようにデータを使う?
データ取得方法
誰がクエリを投げる?
実際のアプリケーションでは、こんな感じで使われます:
例: AI が必要に応じてクエリを投げる
# ChatGPTのようなAIアシスタント
user_message = "AWSのS3バケットの権限設定方法を教えて"
# AIが関連情報を検索
relevant_docs = vector_db.search(
query=user_message,
top_k=3,
filter={"category": "AWS"}
)
# 検索結果を使ってAIが回答生成
answer = llm.generate_answer(
question=user_message,
context=relevant_docs
)
どんなクエリを投げる?(一般的な VectorDB)
基本的なベクトル検索
# Pinecone(人気のベクトルDB)の例
import pinecone
# ベクトルDBへの接続を確立
pc = Pinecone(api_key="YOUR_API_KEY") # API認証
index = pc.Index("knowledge-base") # 使用するインデックス(データベース)を指定
# クエリベクトルを作成
query_text = "JavaScriptのPromiseについて教えて" # ユーザーの質問
query_vector = embed_text(query_text) # 質問文をベクトルに変換
# 検索実行
results = index.query(
vector=query_vector, # 検索に使うベクトル
top_k=5, # 上位5件の結果を取得
include_metadata=True, # メタデータ(タイトル、日付等)も含める
filter={ # 検索条件でフィルタリング
"language": {"$eq": "ja"}, # 日本語のドキュメントのみ
"category": {"$eq": "programming"} # プログラミング関連のみ
}
)
print(results) # 類似度の高い関連ドキュメントが返される
フィルタリング付きの検索
# Chroma(オープンソースのベクトルDB)の例
import chromadb
client = chromadb.Client()
collection = client.get_collection("documents")
# メタデータでフィルタリングしながら検索
results = collection.query(
query_texts=["ReactのuseEffectについて"],
n_results=10,
where={
"author": {"$eq": "田中太郎"},
"created_at": {"$gte": "2024-01-01"}
}
)
どんなデータが取得できる?
人間が読めるデータが返ってきます!
# 実際の検索結果例
results = {
"data": {
"Get": {
"Article": [
{
"title": "React Hooksの使い方完全ガイド",
"content": "React Hooksは関数コンポーネントでstateや副作用を扱える機能です。useState, useEffect, useContext...",
"author": "山田太郎",
"_additional": {
"certainty": 0.89, # 類似度(0-1)
"distance": 0.22 # 距離(小さいほど似ている)
}
},
{
"title": "useStateとuseEffectの実践的な使い分け",
"content": "useStateはコンポーネントの状態管理に、useEffectは副作用の処理に使います...",
"author": "佐藤花子",
"_additional": {
"certainty": 0.84,
"distance": 0.32
}
}
]
}
}
}
メタデータも一緒に取得
{
"id": "doc_12345",
"content": "TypeScriptの型定義について説明します...",
"metadata": {
"title": "TypeScript入門",
"author": "田中次郎",
"created_at": "2024-07-15T10:30:00Z",
"tags": ["TypeScript", "JavaScript", "型安全"],
"category": "programming",
"language": "ja",
"word_count": 1500,
"difficulty": "beginner"
},
"similarity_score": 0.87
}
取得したデータをどのように使う?
誰がデータを使う?
1. エンドユーザー(社員・顧客)
# 社内チャットボット
user_question = "新しいプロジェクトの始め方を教えて"
# 関連ドキュメントを検索
docs = vector_db.search(user_question, top_k=3)
# AIが回答を生成
response = f"""
{user_question}について、以下の情報が見つかりました:
1. {docs[0]['title']}
{docs[0]['summary']}
2. {docs[1]['title']}
{docs[1]['summary']}
詳細は社内ポータルで確認できます。
"""
2. 開発者(アプリケーション)
# ECサイトの商品推薦システム
user_query = "夏に着る薄手のシャツ"
# 商品ベクトルDBから類似商品を検索
similar_products = product_vector_db.search(
query=user_query,
filter={
"season": "summer",
"in_stock": True
},
top_k=12
)
# レコメンド結果をユーザーに表示
return render_recommendations(similar_products)
3. AI エージェント
# コーディング支援AI
code_question = "Pythonでファイルを非同期で読み込む方法"
# コードサンプルDBから検索
code_examples = code_vector_db.search(
query=code_question,
filter={"language": "python", "verified": True}
)
# AIがコード例を参考に回答生成
ai_response = generate_code_answer(
question=code_question,
examples=code_examples
)
どのようにデータを使う?
RAG(Retrieval-Augmented Generation)パターン
def answer_question(user_question):
# 1. 関連情報を検索
relevant_docs = vector_db.search(
query=user_question,
top_k=5
)
# 2. 検索結果をコンテキストとしてLLMに渡す
context = "\n".join([doc['content'] for doc in relevant_docs])
prompt = f"""
以下の情報を参考に質問に答えてください:
【参考情報】
{context}
【質問】
{user_question}
【回答】
"""
# 3. LLMが回答生成
response = llm.generate(prompt)
return {
"answer": response,
"sources": [doc['title'] for doc in relevant_docs]
}
実行例
# 使用例
question = "Dockerコンテナのメモリ制限を設定する方法は?"
result = answer_question(question)
print(result)
# {
# "answer": "Dockerコンテナのメモリ制限は--memoryオプションで設定できます。例えば、docker run --memory=512m nginx とすると512MBに制限されます...",
# "sources": ["Docker運用ガイド", "コンテナ最適化のベストプラクティス"]
# }
実際のアプリに使うとしたらどんな構成になる?
基本的な RAG アプリケーション構成
この構成の仕組み
この RAG(Retrieval-Augmented Generation)アプリケーションは、以下の 2 つのフローで動作します:
📥 データ準備フロー(事前処理)
1. ドキュメント投入
PDF/Markdown → Embedding API → ベクトルDB
社内文書やマニュアルを事前にベクトル化して保存
🔍 質問回答フロー(ユーザー利用時)
1. ユーザーが質問入力
フロントエンド → バックエンドAPI
2. 関連情報を検索
バックエンドAPI → ベクトルDB
質問に意味的に近いドキュメントを取得
3. AIが回答生成
バックエンドAPI → LLM API
検索結果を参考にして回答を生成
4. ユーザーに結果表示
バックエンドAPI → フロントエンド → ユーザー
🎯 各コンポーネントの役割
🖥️ フロントエンド (React/Vue)
- ユーザーインターフェース
- 質問入力と回答表示
⚙️ バックエンドAPI (FastAPI/Express)
- 質問処理とベクトル検索
- LLMとの連携
- 結果の整形
🗄️ ベクトルDB (Pinecone/Weaviate)
- ドキュメントのベクトル保存
- 高速類似度検索
🤖 LLM API (OpenAI/Claude)
- 自然な回答文の生成
- 検索結果の要約と整理
📄 Embedding API (OpenAI)
- ドキュメントのベクトル化
- 質問文のベクトル化
この構成により、「キーワード検索では見つからない情報」も「意味」で検索して、AI が自然な回答を生成できるシステムが実現できます。
まとめ:明日から使えるベクトル DB
ベクトル DB のポイント
- 普通の DB との違い: キーワード一致ではなく「意味」で検索
- ベクトルとは: 文章を数値の配列で表現したもの
- 主な用途: ナレッジベース、チャットボット、推薦システム
- 実装: Embedding API + ベクトル DB + LLM = RAG アプリ
この記事の執筆にはGithub Copilot Agent(VSCode)を使用しています。
以下の流れで作成しています。
4,5,6を繰り返すことで、自分自身の勉強にもなりますね。
- テーマを決める
- 雛形・見出しをざっくり決める
- 記事を書いてもらう
- 書かれた記事を読む
- 4で気づいた点の指摘 + Copilotによるセルフレビュー
- 5で得られた指摘事項を修正してもらう
- 4, 5, 6の繰り返し