> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ja/llms.txt # 検索とインデックス作成 **追加バージョン:** `@mastra/core@1.1.0` 検索を使用すると、Agent はインデックス化された Workspace ファイルから関連するコンテンツを見つけられます。Agent が質問に回答したり情報を探したりする必要がある場合、すべてのファイルを読み込む代わりに、インデックス化されたコンテンツを検索できます。 ## 仕組み Workspace の検索には、インデックス作成とクエリの2つのフェーズがあります。 ### インデックス作成 コンテンツを検索するには、事前にインデックスを作成する必要があります。ドキュメントのインデックスを作成すると、次の処理が行われます。 - コンテンツがトークン化されます(検索可能な語に分割されます) - BM25 の場合: 単語の出現頻度とドキュメントの統計情報が計算されます - ベクトルの場合: embedder 関数を使用してコンテンツが埋め込みに変換され、ベクトルストアに保存されます インデックス化された各ドキュメントには、次の情報が含まれます。 - **id** - 一意の識別子(通常はファイルパス) - **content** - テキストコンテンツ - **metadata** - ドキュメントとともに保存される任意のキーと値のデータ ### クエリ 検索時には、次の処理が行われます。 1. インデックス作成時と同じトークン化または埋め込みを使用して、クエリが処理されます 2. クエリとの関連性に基づいてドキュメントにスコアが付けられます 3. 結果がスコア順に並べられ、一致したコンテンツとともに返されます Workspace は、BM25 キーワード検索、ベクトルセマンティック検索、およびその両方を組み合わせたハイブリッド検索という3つの検索モードをサポートします。 ## BM25 キーワード検索 BM25 は、単語の出現頻度とドキュメントの長さに基づいてドキュメントをスコアリングします。完全一致や特定の専門用語の検索に適しています。 ```typescript import { Workspace, LocalFilesystem } from '@mastra/core/workspace' const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, }) ``` BM25 のパラメーターをカスタマイズする場合(`k1` は単語頻度の飽和度、`b` はドキュメント長の正規化を表します)は、次のように設定します。 ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: { k1: 1.5, b: 0.75, }, }) ``` ## ベクトル検索 ベクトル検索では、埋め込みを使用して意味的に類似するコンテンツを検索します。ベクトルストアと embedder 関数が必要です。 ```typescript import { Workspace, LocalFilesystem } from '@mastra/core/workspace' import { PineconeVector } from '@mastra/pinecone' import { embed } from 'ai' import { openai } from '@ai-sdk/openai' const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), vectorStore: new PineconeVector({ apiKey: process.env.PINECONE_API_KEY, index: 'workspace-index', }), embedder: async (text: string) => { const { embedding } = await embed({ model: openai.embedding('text-embedding-3-small'), value: text, }) return embedding }, }) ``` ### バッチ埋め込み 上記の embedder は、一度に1つのテキストを受け取ります。数百のファイルを含む Workspace のインデックスを作成すると Provider が数百回呼び出されるため、時間とコストがかかります。 Provider がバッチ処理をサポートしている場合(OpenAI の `embedMany` など)は、テキストの配列を受け取り、1回の呼び出しで複数の埋め込みを返す embedder を渡します。この機能を有効にするには、関数に `batch: true` プロパティを設定します。Mastra は実行時にこのプロパティを確認し、バッチ処理に切り替えます。 次の例では、単一テキスト用の embedder をバッチ対応のものに置き換えています。embedder 関数は配列を受け取り、同じ順序で埋め込みの配列を返します。また、次の2つの追加プロパティを持ちます。 - `batch: true`: 関数がバッチ対応であることを示します。このプロパティがない場合、Mastra は一度に1つのテキストを渡して関数を呼び出します。 - `maxBatchSize`: Provider が1回の呼び出しで受け付ける最大の配列サイズです。Mastra は、それより大きなリクエストをこのサイズのチャンクに分割して並列送信します。Provider のドキュメントに記載された上限(OpenAI は 2048、Cohere は 96、Voyage は 128 など)を設定してください。保留中のすべてのテキストを1つのリクエストで送信する場合は省略します。 ```typescript import { Workspace, LocalFilesystem } from '@mastra/core/workspace' import { PineconeVector } from '@mastra/pinecone' import { embedMany } from 'ai' import { openai } from '@ai-sdk/openai' const model = openai.embedding('text-embedding-3-small') const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), vectorStore: new PineconeVector({ apiKey: process.env.PINECONE_API_KEY, index: 'workspace-index', }), embedder: Object.assign( async (texts: string[]) => { const { embeddings } = await embedMany({ model, values: texts }) return embeddings }, { batch: true as const, maxBatchSize: 2048 }, ), }) ``` `Object.assign` は、embedder 関数に `batch` プロパティと `maxBatchSize` プロパティを追加します。Mastra はこれらをメタデータとして読み取り、Provider に渡すことはありません。 単一テキスト用の embedder も引き続き使用できます。関数シグネチャ `(text: string) => Promise` は変わらないため、既存のコードは変更せずに動作し続けます。 ## ハイブリッド検索 BM25 検索とベクトル検索の両方を設定すると、キーワード一致と意味理解を組み合わせたハイブリッドモードが有効になります。 ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, vectorStore: pineconeVector, embedder: embedderFn, }) ``` ## カスタムインデックス名 デフォルトでは、検索インデックス名は Workspace ID から生成されます。カスタム名を設定するには、`searchIndexName` を使用します。 ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, searchIndexName: 'my_workspace_vectors', }) ``` インデックス名は有効な SQL 識別子でなければなりません。先頭は文字またはアンダースコアにし、使用できるのは文字、数字、またはアンダースコアのみで、長さは最大63文字です。 ## コンテンツのインデックス作成 ### 手動でのインデックス作成 `workspace.index()` を使用すると、プログラムから検索インデックスにコンテンツを追加できます。ファイルパスがドキュメント ID になります。ドキュメントごとにメタデータを渡すこともできます。 ```typescript // Basic indexing await workspace.index('/docs/guide.md', 'Content of the guide...') // Index with metadata for filtering or context await workspace.index('/docs/api.md', apiDocContent, { metadata: { category: 'api', version: '2.0', }, }) ``` 手動でのインデックス作成は、次の場合に便利です。 - ファイル以外のコンテンツ(データベースのレコードや API レスポンスなど)のインデックスを作成する場合 - インデックスを作成する前にコンテンツを前処理またはチャンク分割する場合 - ドキュメントにカスタムメタデータを追加する必要がある場合 ### 自動インデックス作成 `autoIndexPaths` を設定すると、Workspace の初期化時にファイルのインデックスが自動的に作成されます。各エントリには、ディレクトリパス(再帰的にインデックスを作成)または対象を選択するための glob パターンを指定できます。 ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, autoIndexPaths: ['docs', 'support/faq'], }) await workspace.init() ``` `init()` が呼び出されると、一致するすべてのファイルが読み込まれ、検索用のインデックスが作成されます。ファイルパスがドキュメント ID になります。 glob パターンを使用すると、特定のファイル形式を対象にインデックスを作成できます。 ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, autoIndexPaths: ['docs/**/*.md', 'support/**/*.txt'], }) ``` ## 検索 `workspace.search()` を使用して関連するコンテンツを検索します。結果は関連性スコアの順に並べられます。 ```typescript const results = await workspace.search('password reset') for (const result of results) { console.log(`${result.id}: ${result.score}`) console.log(result.content) } ``` ### 検索オプション オプションを使用して検索動作をカスタマイズできます。 ```typescript const results = await workspace.search('authentication flow', { topK: 10, mode: 'hybrid', minScore: 0.5, vectorWeight: 0.5, }) ``` | オプション | 説明 | | -------------- | ----------------------------------------------------------------------------------- | | `topK` | 返す結果の最大数。デフォルト: 5 | | `mode` | 検索モード: `'bm25'`、`'vector'`、または `'hybrid'`。デフォルトでは、設定に基づいて利用可能な最適なモードが選択されます。 | | `minScore` | このスコアしきい値(0〜1)を下回る結果を除外します。 | | `vectorWeight` | ハイブリッドモードで、BM25 スコアに対してベクトルスコアをどの程度重視するかを指定します。0 = すべて BM25、1 = すべてベクトル、0.5 = 同じ重み。 | ### 検索結果 各結果には、次の情報が含まれます。 ```typescript interface SearchResult { id: string // Document ID (typically file path) content: string // The matching content score: number // Relevance score (0-1) lineRange?: { // Lines where the match was found start: number end: number } metadata?: Record // Metadata stored with the document scoreDetails?: { // Score breakdown (hybrid mode only) vector?: number bm25?: number } } ``` **スコアの見方:** - スコアの範囲は0〜1で、1は完全一致を表します - BM25 スコアは、結果セット内の最も一致度が高い結果を基準に正規化されます - ベクトルスコアは、クエリの埋め込みとドキュメントの埋め込み間のコサイン類似度を表します - ハイブリッドモードでは、`vectorWeight` パラメーターを使用してスコアが組み合わされます ### 各モードを使用する場面 | モード | 適した用途 | クエリ例 | | -------- | ---------------- | -------------------------------------- | | `bm25` | 完全一致、技術的なクエリ、コード | "useState フック"、"404 エラー"、"config.yaml" | | `vector` | 概念的なクエリ、自然言語 | "ユーザー認証を処理する方法"、"エラー処理のベストプラクティス" | | `hybrid` | 一般的な検索、種類が不明なクエリ | Agent のほとんどのユースケース | ## Agent Tool Workspace に検索を設定すると、Agent はコンテンツの検索とインデックス作成に使用する Tool を受け取ります。詳しくは [Workspace クラスのリファレンス](https://mastra.zisheng.pro/ja/reference/workspace/workspace-class)を参照してください。 ## 関連情報 - [Workspace の概要](https://mastra.zisheng.pro/ja/docs/workspace/overview) - [RAG の概要](https://mastra.zisheng.pro/ja/guides/rag/overview) - [Workspace クラスのリファレンス](https://mastra.zisheng.pro/ja/reference/workspace/workspace-class)