RAGシステムにおける検索
埋め込みを保存した後、ユーザークエリに回答するために関連するチャンクを検索する必要があります。
Mastraは、セマンティック検索、フィルタリング、再ランキングをサポートする柔軟な検索オプションを提供します。
検索の仕組み
- ユーザーのクエリは、ドキュメント埋め込みに使用されるのと同じモデルを使用して埋め込みに変換されます
- この埋め込みはベクトル類似性を使用して保存された埋め込みと比較されます
- 最も類似したチャンクが取得され、オプションで以下の処理が可能です:
- メタデータによるフィルタリング
- より良い関連性のための再ランク付け
- ナレッジグラフを通じた処理
基本的な検索
最もシンプルなアプローチは直接的な意味検索です。この方法では、ベクトル類似性を使用してクエリに意味的に類似したチャンクを見つけます:
import { openai } from "@ai-sdk/openai";
import { embed } from "ai";
import { PgVector } from "@mastra/pg";
// Convert query to embedding
const { embedding } = await embed({
value: "What are the main points in the article?",
model: openai.embedding('text-embedding-3-small'),
});
// Query vector store
const pgVector = new PgVector(process.env.POSTGRES_CONNECTION_STRING);
const results = await pgVector.query({
indexName: "embeddings",
queryVector: embedding,
topK: 10,
});
// Display results
console.log(results);
結果にはテキストコンテンツと類似度スコアの両方が含まれます:
[
{
text: "Climate change poses significant challenges...",
score: 0.89,
metadata: { source: "article1.txt" }
},
{
text: "Rising temperatures affect crop yields...",
score: 0.82,
metadata: { source: "article1.txt" }
}
// ... more results
]
基本的な検索方法の使用例については、結果の取得の例を参照してください。
高度な検索オプション
メタデータフィルタリング
メタデータフィールドに基づいて結果をフィルタリングし、検索範囲を絞り込みます。これは、異なるソース、時間帯、または特定の属性を持つドキュメントがある場合に役立ちます。Mastraは、サポートされているすべてのベクトルストアで動作する統一されたMongoDB形式のクエリ構文を提供しています。
利用可能な演算子と構文の詳細については、メタデータフィルターリファレンスを参照してください。
基本的なフィルタリングの例:
// Simple equality filter
const results = await pgVector.query({
indexName: "embeddings",
queryVector: embedding,
topK: 10,
filter: {
source: "article1.txt"
}
});
// Numeric comparison
const results = await pgVector.query({
indexName: "embeddings",
queryVector: embedding,
topK: 10,
filter: {
price: { $gt: 100 }
}
});
// Multiple conditions
const results = await pgVector.query({
indexName: "embeddings",
queryVector: embedding,
topK: 10,
filter: {
category: "electronics",
price: { $lt: 1000 },
inStock: true
}
});
// Array operations
const results = await pgVector.query({
indexName: "embeddings",
queryVector: embedding,
topK: 10,
filter: {
tags: { $in: ["sale", "new"] }
}
});
// Logical operators
const results = await pgVector.query({
indexName: "embeddings",
queryVector: embedding,
topK: 10,
filter: {
$or: [
{ category: "electronics" },
{ category: "accessories" }
],
$and: [
{ price: { $gt: 50 } },
{ price: { $lt: 200 } }
]
}
});
メタデータフィルタリングの一般的なユースケース:
- ドキュメントのソースまたはタイプによるフィルタリング
- 日付範囲によるフィルタリング
- 特定のカテゴリやタグによるフィルタリング
- 数値範囲(例:価格、評価)によるフィルタリング
- 精密なクエリのための複数の条件の組み合わせ
- ドキュメント属性(例:言語、著者)によるフィルタリング
メタデータフィルタリングの使用例については、ハイブリッドベクトル検索の例を参照してください。
ベクトルクエリツール
エージェントにベクトルデータベースを直接クエリする能力を与えたい場合があります。ベクトルクエリツールを使用すると、エージェントが検索の決定を担当し、ユーザーのニーズに対するエージェントの理解に基づいて、意味検索とオプションのフィルタリングおよび再ランク付けを組み合わせることができます。
const vectorQueryTool = createVectorQueryTool({
vectorStoreName: 'pgVector',
indexName: 'embeddings',
model: openai.embedding('text-embedding-3-small'),
});
ツールを作成する際は、ツールの名前と説明に特に注意してください - これらはエージェントが検索機能をいつどのように使用するかを理解するのに役立ちます。例えば、「SearchKnowledgeBase」と名付け、「Xトピックに関連する情報を見つけるために私たちのドキュメントを検索する」と説明することができます。
これは特に以下の場合に役立ちます:
- エージェントが取得する情報を動的に決定する必要がある場合
- 検索プロセスが複雑な意思決定を必要とする場合
- コンテキストに基づいて複数の検索戦略を組み合わせたい場合
詳細な設定オプションと高度な使用法については、ベクトルクエリツールリファレンスを参照してください。
ベクトルストアプロンプト
ベクトルストアプロンプトは、各ベクトルデータベース実装のクエリパターンとフィルタリング機能を定義します。 フィルタリングを実装する場合、これらのプロンプトは各ベクトルストア実装の有効な演算子と構文を指定するためにエージェントの指示に必要です。
Pg Vector
import { openai } from '@ai-sdk/openai';
import { PGVECTOR_PROMPT } from "@mastra/pg";
export const ragAgent = new Agent({
name: 'RAG Agent',
model: openai('gpt-4o-mini'),
instructions: `
Process queries using the provided context. Structure responses to be concise and relevant.
${PGVECTOR_PROMPT}
`,
tools: { vectorQueryTool },
});
再ランキング
初期のベクトル類似性検索では、微妙な関連性を見逃すことがあります。再ランキングはより計算コストが高いプロセスですが、より正確なアルゴリズムで結果を改善します:
- 単語の順序と完全一致を考慮
- より洗練された関連性スコアリングを適用
- クエリとドキュメント間のクロスアテンションと呼ばれる方法を使用
再ランキングの使用方法は次のとおりです:
import { openai } from "@ai-sdk/openai";
import { rerank } from "@mastra/rag";
// Get initial results from vector search
const initialResults = await pgVector.query({
indexName: "embeddings",
queryVector: queryEmbedding,
topK: 10,
});
// Re-rank the results
const rerankedResults = await rerank(initialResults, query, openai('gpt-4o-mini'));
注意: 再ランキング中にセマンティックスコアリングが正しく機能するためには、各結果に
metadata.text
フィールドにテキストコンテンツが含まれている必要があります。
再ランキングされた結果は、ベクトル類似性とセマンティック理解を組み合わせて検索品質を向上させます。
再ランキングの詳細については、rerank()メソッドを参照してください。
再ランキングメソッドの使用例については、結果の再ランキングの例を参照してください。
グラフベースの検索
複雑な関係を持つドキュメントの場合、グラフベースの検索はチャンク間の接続をたどることができます。これは以下の場合に役立ちます:
- 情報が複数のドキュメントに分散している
- ドキュメントが互いに参照している
- 完全な回答を見つけるために関係性をたどる必要がある
セットアップ例:
const graphQueryTool = createGraphQueryTool({
vectorStoreName: 'pgVector',
indexName: 'embeddings',
model: openai.embedding('text-embedding-3-small'),
graphOptions: {
threshold: 0.7,
}
});
グラフベースの検索の詳細については、GraphRAGクラスとcreateGraphQueryTool()関数を参照してください。
グラフベースの検索方法の使用例については、グラフベースの検索の例を参照してください。