> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-TW/llms.txt # 搜尋與索引 **新增於:** `@mastra/core@1.1.0` 搜尋功能可讓 Agent 在已建立索引的 Workspace 檔案中找出相關內容。Agent 需要回答問題或尋找資訊時,可以搜尋索引內容,不必讀取每個檔案。 ## 運作方式 Workspace 搜尋分成兩個階段:建立索引與查詢。 ### 建立索引 內容必須先建立索引才能搜尋。為文件建立索引時: - 內容會被 Tokenize(拆分成可搜尋的詞彙) - BM25:計算詞頻與文件統計資料 - 向量:使用 Embedder 函式將內容嵌入,並儲存在向量儲存區 每份已建立索引的文件包含: - **id** - 唯一識別碼(通常是檔案路徑) - **content** - 文字內容 - **metadata** - 與文件一同儲存的選用鍵值資料 ### 查詢 搜尋時: 1. 查詢會使用與建立索引時相同的 Tokenization/Embedding 方式處理 2. 依文件與查詢的相關性評分 3. 依分數排序結果,並連同相符內容傳回 Workspace 支援三種搜尋模式:BM25 關鍵字搜尋、向量語意搜尋,以及結合兩者的混合搜尋。 ## 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, }, }) ``` ## 向量搜尋 向量搜尋使用 Embedding 尋找語意相似的內容,需要向量儲存區與 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 }, }) ``` ### 批次 Embedding 上述 Embedder 每次接收一段文字。為含數百個檔案的 Workspace 建立索引時,會呼叫 Provider 數百次,既緩慢又昂貴。 當 Provider 支援批次處理時(例如 OpenAI 的 `embedMany`),請傳入接收文字陣列並能在單次呼叫中取回多個 Embedding 的 Embedder。若要選用此功能,請在函式上設定 `batch: true` 屬性。Mastra 會在執行階段檢查該屬性,並切換至批次路徑。 以下範例將單一文字 Embedder 改為批次 Embedder。此函式接收陣列,並以相同順序傳回 Embedding 陣列,另帶有兩個額外屬性: - `batch: true`:標示函式支援批次處理。若缺少此屬性,Mastra 會逐段文字呼叫函式。 - `maxBatchSize`:Provider 單次呼叫可接受的最大陣列。Mastra 會依此大小分割較大的請求並平行傳送。請設為 Provider 文件中的限制(例如 OpenAI 為 2048、Cohere 為 96、Voyage 為 128)。省略時,所有待處理文字會在單一請求中送出。 ```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` 會將 `batch` 與 `maxBatchSize` 屬性加入 Embedder 函式。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 分數會依結果集中的最佳相符項目正規化 - 向量分數代表查詢與文件 Embedding 之間的餘弦相似度 - 在混合模式中,系統會使用 `vectorWeight` 參數合併分數 ### 各模式的適用時機 | 模式 | 最適合 | 查詢範例 | | -------- | ------------- | -------------------------------------- | | `bm25` | 精確詞彙、技術查詢、程式碼 | "useState Hook"、"404 錯誤"、"config.yaml" | | `vector` | 概念式查詢、自然語言 | "如何處理使用者驗證"、"錯誤處理的最佳實務" | | `hybrid` | 一般搜尋、未知查詢類型 | 多數 Agent 使用情境 | ## Agent Tool 在 Workspace 上設定搜尋後,Agent 會取得搜尋內容及建立內容索引的 Tool。詳情請參閱 [Workspace 類別參考](https://mastra.zisheng.pro/zh-TW/reference/workspace/workspace-class)。 ## 相關資源 - [Workspace 概觀](https://mastra.zisheng.pro/zh-TW/docs/workspace/overview) - [RAG 概觀](https://mastra.zisheng.pro/zh-TW/guides/rag/overview) - [Workspace 類別參考](https://mastra.zisheng.pro/zh-TW/reference/workspace/workspace-class)