跳至主要內容

Workspace

新增於: @mastra/core@1.1.0

Mastra Workspace 為 Agent 提供持久環境,用於儲存檔案及執行命令。Agent 可使用 Workspace Tool 讀寫檔案、執行 Shell 命令,以及搜尋已建立索引的內容。

Workspace 支援下列功能:

  • 檔案系統:檔案儲存(讀取、寫入、列出、刪除、複製、移動、grep)
  • Sandbox:命令執行(Shell 命令)與背景處理程序
  • LSP 檢查:透過語言伺服器進行懸停、定義與實作查詢
  • 搜尋:在已建立索引的內容上進行 BM25、向量或混合搜尋
  • Skills:可供 Agent 重複使用的指示

適合使用 Workspace 的情境
「適合使用 Workspace 的情境」的直接連結

當 Agent 需要存取本機檔案系統、Shell 命令、語意程式碼檢查、索引搜尋或可重複使用的 Skill 指示時,請使用 Workspace。

運作方式
「運作方式」的直接連結

將 Workspace 指派給 Agent 後,Mastra 會把對應的 Tool 加入 Agent 的 Tool 集合。Agent 隨後可透過這些 Tool 操作檔案及執行命令。

你可以任意組合支援的功能來建立 Workspace。Agent 只會取得與設定內容相關的 Tool。

用法
「用法」的直接連結

建立 Workspace
「建立 Workspace」的直接連結

以所需功能建立 Workspace 執行個體:

src/mastra/workspaces.ts
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'

const workspace = new Workspace({
filesystem: new LocalFilesystem({
basePath: './workspace',
}),
sandbox: new LocalSandbox({
workingDirectory: './workspace',
}),
skills: ['skills'],
})

skills 陣列指定包含 Skill 定義的目錄路徑,請參閱 Skills

全域 Workspace
「全域 Workspace」的直接連結

在 Mastra 執行個體上設定 Workspace。除非 Agent 定義自己的 Workspace,否則所有 Agent 都會繼承此 Workspace:

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { Workspace, LocalFilesystem } from '@mastra/core/workspace'

const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './workspace' }),
})

const mastra = new Mastra({
workspace,
})

Agent 層級的 Workspace
「Agent 層級的 Workspace」的直接連結

直接將 Workspace 指派給 Agent,以覆寫全域 Workspace:

src/mastra/agents/my-agent.ts
import { Agent } from '@mastra/core/agent'
import { Workspace, LocalFilesystem } from '@mastra/core/workspace'

const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './agent-workspace' }),
})

export const myAgent = new Agent({
id: 'my-agent',
model: 'openai/gpt-5.6-sol',
workspace,
})

生命週期與清理
「生命週期與清理」的直接連結

Mastra 會註冊全域與 Agent Workspace,以便在執行階段列出及擷取。呼叫 mastra.shutdown() 時,Mastra 會銷毀其擁有的已註冊 Workspace,關閉語言伺服器、瀏覽器、Sandbox 處理程序及檔案系統 Provider Handle 等資源。

若要手動清理,請使用 mastra.removeWorkspace()。若 Workspace 應在從登錄中移除前銷毀,請傳入 { destroy: true }

靜態 Provider 由 Workspace 擁有。以解析器為基礎的 Provider 由應用程式擁有,因為 Workspace 會在請求時建立它們。解析器清理模型請參閱執行階段 Sandbox 生命週期擁有權

設定模式
「設定模式」的直接連結

Workspace 依 Agent 所需能力支援數種設定模式。主要元件是 filesystem(檔案 Tool)與 sandbox(命令執行),而 mounts 則用來將雲端儲存空間橋接至 Sandbox。

檔案系統 + Sandbox(本機)
「檔案系統 + Sandbox(本機)」的直接連結

進行本機開發時,請將 LocalFilesystemLocalSandbox 指向同一目錄。兩者都在本機運作,因此透過檔案系統寫入的檔案可立即供 Sandbox 命令使用:

const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './workspace' }),
sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
})

Agent 會同時取得檔案 Tool 與 execute_command。這是最簡單且功能完整的設定。

掛載 + Sandbox(雲端儲存空間)
「掛載 + Sandbox(雲端儲存空間)」的直接連結

需要在 Sandbox 中存取雲端儲存空間時,請使用 mounts。它會透過 FUSE 將雲端檔案系統掛載至 Sandbox,讓命令能在掛載路徑讀寫檔案:

const workspace = new Workspace({
mounts: {
'/data': new S3Filesystem({
bucket: 'my-bucket',
region: 'us-east-1',
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
}),
'/skills': new GCSFilesystem({
bucket: 'agent-skills',
}),
},
sandbox: new E2BSandbox({ id: 'dev-sandbox' }),
})

mounts 會在內部建立 CompositeFilesystem,依路徑前綴將檔案 Tool 操作路由至正確的 Provider。Sandbox 命令可直接存取掛載路徑(例如 ls /data)。

你可以將多個 Provider 掛載至不同路徑。各掛載路徑必須唯一且不可重疊。

備註

filesystemmounts 互斥,不能在同一個 Workspace 中併用。不含 Sandbox 的單一 Provider 請使用 filesystem;需要將雲端儲存空間與 Sandbox 結合時,則使用 mounts

僅檔案系統
「僅檔案系統」的直接連結

Agent 只需讀寫檔案時,請使用單一 filesystem。此模式無法執行命令。

const workspace = new Workspace({
filesystem: new S3Filesystem({
bucket: 'my-bucket',
region: 'us-east-1',
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
}),
})

Agent 會取得直接操作儲存空間 Provider 的檔案 Tool(read_filewrite_filelist_directorygrep 等)。

僅 Sandbox
「僅 Sandbox」的直接連結

Agent 只需執行命令時,請使用單一 sandbox。系統不會加入檔案 Tool。

const workspace = new Workspace({
sandbox: new E2BSandbox({ id: 'dev-sandbox' }),
})

Agent 會取得 execute_command Tool。

動態檔案系統(依請求)
「動態檔案系統(依請求)」的直接連結

將解析器函式傳給 filesystem,即可為每個請求傳回不同檔案系統。這適合多租戶應用程式或多角色 Agent,讓每個請求使用不同儲存根目錄或權限。

const workspace = new Workspace({
filesystem: ({ requestContext }) => {
const role = requestContext.get('agent-role') || 'guest'
return new LocalFilesystem({
basePath: `/workspaces/${role}`,
readOnly: role !== 'admin',
})
},
})

單一 Workspace 執行個體可處理所有請求。解析器會在 Tool 執行時運作,因此每個請求都有自己的檔案系統。詳情請參閱動態檔案系統

動態 Sandbox(依請求)
「動態 Sandbox(依請求)」的直接連結

將解析器函式傳給 sandbox,即可為每個請求傳回不同 Sandbox。這適合每位使用者或角色需要隔離工作目錄或不同執行權限的多租戶部署。

const workspace = new Workspace({
sandbox: ({ requestContext }) => {
const userId = requestContext.get('user-id') as string
return new LocalSandbox({
workingDirectory: `/workspaces/${userId}`,
})
},
})

解析器與 mountslsp: true 不相容,因為兩者在建構時都需要具體的 Sandbox 執行個體。詳情請參閱動態 Sandbox

應該使用哪種模式?
「應該使用哪種模式?」的直接連結

情境模式
使用檔案及命令進行本機開發filesystem + sandbox(兩者均為本機且使用相同目錄)
在雲端 Sandbox 中存取雲端儲存空間mounts + sandbox
在單一 Sandbox 中使用多個雲端 Providermounts + sandbox(每個 Provider 一個掛載點)
Agent 讀寫檔案,不需執行命令filesystem
Agent 執行命令,不需檔案 Toolsandbox
多角色或多租戶 Agent 使用依請求區分的儲存空間含解析器函式的 filesystem
多租戶 Agent 使用依請求區分的執行範圍含解析器函式的 sandbox

Tool 設定
「Tool 設定」的直接連結

透過 Workspace 的 tools 選項設定 Tool 行為,控制啟用哪些 Tool 及其運作方式。

src/mastra/workspaces.ts
import { Workspace, LocalFilesystem, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace'

const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './workspace' }),
sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
tools: {
// Global defaults
enabled: true,
requireApproval: false,

// Per-tool overrides
[WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]: {
requireApproval: true,
requireReadBeforeWrite: true,
},
[WORKSPACE_TOOLS.FILESYSTEM.DELETE]: {
enabled: false,
},
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
requireApproval: true,
},
},
})

Tool 選項
「Tool 選項」的直接連結

選項型別說明
enabledboolean | (context) => booleanTool 是否可用(預設:true)。若為函式,會在列出 Tool 時評估。
requireApprovalboolean | (context) => booleanTool 執行前是否需要使用者核准(預設:false)。若為函式,會在執行時評估並可存取 args
requireReadBeforeWriteboolean | (context) => boolean寫入 Tool 是否需先讀取檔案(預設:false)。若為函式,會在執行時評估並可存取 args
namestringTool 的自訂名稱,會取代預設的 mastra_workspace_* 名稱。
maxOutputTokensnumberTool 輸出的 Token 上限(預設:2000)。超出限制的輸出會使用 tiktoken 截斷。

動態 Tool 設定
「動態 Tool 設定」的直接連結

接受函式的 Tool 選項會接收情境物件並傳回布林值,讓 Tool 行為能依情境調整。

src/mastra/workspaces.ts
const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './workspace' }),
tools: {
// Dynamic enabled: disable command execution unless explicitly allowed
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
enabled: async ({ requestContext }) => {
return requestContext['allowExecution'] === 'true'
},
},

// Dynamic requireApproval: only require approval for protected paths
[WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]: {
requireApproval: async ({ args }) => {
return (args.path as string).startsWith('/protected')
},
requireReadBeforeWrite: true,
},
},
})

enabled 函式會收到 { requestContext, workspace }requireApprovalrequireReadBeforeWrite 函式因在呼叫 Tool 時評估,也會收到 args

Tool 名稱重新對應
「Tool 名稱重新對應」的直接連結

可重新命名 Workspace Tool,使其符合 Agent 預期的慣例。設定鍵仍為原始 WORKSPACE_TOOLS 常數,只有公開名稱會改變。

src/mastra/workspaces.ts
import { Workspace, LocalFilesystem, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace'

const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './workspace' }),
sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
lsp: true,
tools: {
[WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]: { name: 'view' },
[WORKSPACE_TOOLS.FILESYSTEM.GREP]: { name: 'search_content' },
[WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES]: { name: 'find_files' },
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: { name: 'execute_command' },
[WORKSPACE_TOOLS.LSP.LSP_INSPECT]: { name: 'lsp_inspect' },
},
})

Agent 看到的是 viewsearch_contentfind_filesexecute_commandlsp_inspect,而不是預設的 mastra_workspace_* 名稱。Tool 名稱必須唯一,重複名稱或與其他預設名稱衝突時會擲回錯誤。

Tool Hook
「Tool Hook」的直接連結

設定 tools.hooks,即可在每次啟用的 Workspace Tool 呼叫前後執行邏輯。Hook 在名稱重新對應後執行,因此情境同時包含公開的 toolName 與原始 workspaceToolName

src/mastra/workspaces.ts
import { Workspace, LocalFilesystem } from '@mastra/core/workspace'

const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './workspace' }),
tools: {
hooks: {
beforeToolCall: ({ toolName, workspaceToolName, input }) => {
console.log(`Running ${toolName} (${workspaceToolName})`, input)
},
afterToolCall: ({ toolName, output, error }) => {
console.log(`Finished ${toolName}`, { output, error })
},
},
},
})

beforeToolCall 傳回 { proceed: false, output },即可略過 Tool 呼叫,並以 output 作為結果。

若擁有此 Workspace 的 Agent 也定義了 Tool Hook,Workspace Hook 會在 Agent Hook 包裝器內執行。順序為 Agent beforeToolCall、Workspace beforeToolCall、Tool、Workspace afterToolCall、Agent afterToolCall

LSP 檢查
「LSP 檢查」的直接連結

在 Workspace 上啟用 lsp,即可透過語言伺服器加入語意程式碼檢查。預設會加入 mastra_workspace_lsp_inspect Tool,可傳回特定游標位置符號的懸停資訊、定義位置與實作。

設定、範例及 Tool 名稱重新對應請參閱 LSP 檢查

輸出截斷
「輸出截斷」的直接連結

Workspace Tool 會自動截斷大型輸出,避免超出 LLM 情境限制。截斷分為兩層:

  1. 依行保留尾端:命令輸出預設只保留最後 200 行(可透過每個命令的 tail 參數設定)
  2. Token 上限:Tool 輸出預設以 2000 個 Token 為上限

可為每個 Tool 設定 maxOutputTokens 以調整 Token 上限:

const workspace = new Workspace({
// ...
tools: {
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
maxOutputTokens: 5000,
},
},
})

命令輸出傳至模型前,會自動移除 ANSI Escape Code(顏色、游標序列)。

寫入前讀取
「寫入前讀取」的直接連結

在寫入 Tool 上啟用 requireReadBeforeWrite 後,Agent 必須先讀取檔案才能寫入,避免覆寫 Agent 尚未查看的檔案:

  • 新檔案:不必讀取即可寫入(因為尚不存在)
  • 現有檔案:必須先讀取
  • 外部修改的檔案:若檔案在 Agent 讀取後有變更,寫入會失敗

檔案寫入安全性會在兩層強制執行:

  1. Tool 層:寫入 Tool 執行前,讀取追蹤器會檢查檔案自上次讀取後是否修改。若有修改,Tool 會擲回 FileReadRequiredError
  2. 檔案系統層:寫入時,writeFile() 會將目前修改時間與預期值(透過寫入選項的 expectedMtime 傳入)比較。不相符時會擲回 StaleFileError,以攔截 Tool 層檢查與實際寫入之間發生的外部修改(例如編輯器儲存檔案)。

啟用 requireReadBeforeWrite 後,Workspace Tool 會自動傳遞記錄的修改時間。在 Tool 外呼叫 filesystem.writeFile() 時,也可以直接使用 expectedMtime

const stat = await filesystem.stat('/docs/file.md')
// ... later ...
await filesystem.writeFile('/docs/file.md', newContent, {
expectedMtime: stat.modifiedAt,
})

初始化
「初始化」的直接連結

多數情況不必呼叫 init(),部分 Provider 會在第一次操作時初始化。若在 Mastra 外使用 Workspace(獨立指令碼、測試),或需要在 Agent 第一次互動前預先佈建資源,請手動呼叫 init()

src/mastra/workspaces.ts
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'

const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './workspace' }),
sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
})

// Optional: pre-create directories and sandbox before first use
await workspace.init()

init() 的作用
「what-init-does」的直接連結

初始化會為每個已設定的 Provider 執行設定邏輯:

  • LocalFilesystem:若基底目錄不存在則建立
  • LocalSandbox:建立工作目錄
  • Search(若已設定):為 autoIndexPaths 中的檔案建立索引,請參閱搜尋與索引

外部 Provider 可能進行其他設定,例如建立連線或驗證身分。