跳至主要內容

檔案系統

新增於: @mastra/core@1.1.0

檔案系統 Provider 讓 Agent 能夠讀取、寫入及管理檔案。在 Workspace 設定檔案系統後,Agent 便會獲得執行檔案操作的 Tool。

檔案系統 Provider 會處理 Workspace 的所有檔案操作:

  • 讀取 - 讀取檔案內容
  • 寫入 - 建立及更新檔案
  • 列出 - 瀏覽目錄,並可選擇使用 glob 模式篩選
  • 刪除 - 移除檔案及目錄
  • Stat - 取得檔案 metadata
  • 複製/移動 - 在不同位置之間複製或移動檔案
  • Grep - 使用正則表達式模式搜尋檔案內容

支援的 Provider
支援的 Provider 的直接連結

可用的 Provider:

提示

LocalFilesystem 不需要任何外部服務,是最簡單的入門方式。如需雲端儲存空間,請使用 S3FilesystemGCSFilesystemAzureBlobFilesystem。如需設有版本控制的儲存空間,請使用 MesaFilesystem。如需無須外部服務、以資料庫為基礎的儲存空間,請使用 AgentFSFilesystem

基本用法
基本用法 的直接連結

建立附有檔案系統的 Workspace,並將它指派給 Agent。Agent 隨後便可在執行任務期間讀取、寫入及管理檔案:

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

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

const agent = new Agent({
id: 'file-agent',
model: 'openai/gpt-5.6-sol',
instructions: 'You are a helpful file management assistant.',
workspace,
})

// The agent now has filesystem tools available
const response = await agent.generate('List all files in the workspace')

範圍限制
範圍限制 的直接連結

LocalFilesystem 預設以範圍限制模式運行,所有檔案操作都只能在 basePath 內進行。這可防止路徑遍歷攻擊及透過符號連結逸出限制範圍。

在範圍限制模式下:

  • 相對路徑(例如 src/index.ts)會以 basePath 為基準解析
  • 絕對路徑(例如 /home/user/.config/file.txt)會視為實際檔案系統路徑:如路徑位於 basePath 及所有 allowedPaths 之外,系統便會拋出 PermissionError
  • 波浪號路徑(例如 ~/Documents)會展開為主目錄,並遵循相同的範圍限制規則

如 Agent 需要存取 basePath 以外的特定路徑,可使用 allowedPaths 授予存取權,而無須完全停用範圍限制。相對路徑會以 basePath 為基準解析,而絕對路徑則會原樣使用:

const workspace = new Workspace({
filesystem: new LocalFilesystem({
basePath: './workspace',
allowedPaths: ['~/.claude/skills', '../shared-data'],
}),
})

你可以使用 setAllowedPaths() 方法,在運行時更新獲准存取的路徑:

// Add a path dynamically
workspace.filesystem.setAllowedPaths(prev => [...prev, '/home/user/documents'])

建議採用這種方式實施最小權限存取,Agent 只能存取你明確允許的目錄。

如 Agent 需要不受限制地存取整個檔案系統,請停用範圍限制:

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

containedfalse 時,絕對路徑會視為實際檔案系統路徑,不受任何限制。

動態檔案系統
動態檔案系統 的直接連結

filesystem 選項除了接受靜態實例,也接受 resolver 函數。resolver 會接收 requestContext,並為每個請求傳回一個檔案系統,讓單一 Workspace 可根據呼叫者的身分、角色或 tenant 使用不同的檔案系統。

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

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

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

每個請求都會為 Workspace Tool 及 Workspace instructions 解析其專屬的檔案系統:

import { RequestContext } from '@mastra/core/request-context'

// Admin request — reads and writes from /workspaces/admin/
const adminCtx = new RequestContext([['agent-role', 'admin']])
await agent.generate('Write report.txt with Q4 results', { requestContext: adminCtx })

// Viewer request — reads from /workspaces/viewer/, writes are blocked
const viewerCtx = new RequestContext([['agent-role', 'viewer']])
await agent.generate('Read info.txt', { requestContext: viewerCtx })

Workspace instructions 會使用相同的 requestContext,因此 Agent 可看到已解析 Provider 的檔案系統 context。

resolver 亦可以是非同步函數,例如從資料庫查詢設定:

const workspace = new Workspace({
filesystem: async ({ requestContext }) => {
const tenantConfig = await db.getTenant(requestContext.get('tenant-id'))
return new LocalFilesystem({ basePath: tenantConfig.storagePath })
},
})
備註

filesystemmounts 互相排斥,不能在同一個 Workspace 中同時使用 resolver 函數及 mounts

唯讀模式
唯讀模式 的直接連結

如要防止 Agent 修改檔案,請啟用唯讀模式:

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

使用靜態檔案系統時,寫入 Tool(write_fileedit_filedeletemkdir)會完全排除在 Agent 的 Tool 集合之外。Agent 仍可讀取及列出檔案。

使用動態檔案系統時,由於 resolver 運行前無法得知 readOnly,因此寫入 Tool 一律會包含在內。系統會改為在運行時阻擋寫入操作;如解析所得的檔案系統為唯讀,Tool 便會傳回錯誤。

Mount 與 CompositeFilesystem
mounts-and-compositefilesystem 的直接連結

在 Workspace 使用 mounts 選項時,Mastra 會建立 CompositeFilesystem,根據路徑前綴將檔案操作路由至正確的 Provider。

import { Workspace } from '@mastra/core/workspace'
import { S3Filesystem } from '@mastra/s3'
import { GCSFilesystem } from '@mastra/gcs'
import { E2BSandbox } from '@mastra/e2b'

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' }),
})

採用此設定後:

  • read_file('/data/input.csv') 會從 S3 bucket 讀取資料
  • write_file('/skills/guide.md', content) 會將資料寫入 GCS bucket
  • list_directory('/') 會傳回 /data/skills 的虛擬項目
  • Sandbox 中的命令可透過 FUSE mount 存取 /data/skills 的檔案

路徑路由
路徑路由 的直接連結

所有檔案路徑都必須以 mount 前綴開頭,因為當操作的路徑不符合任何 mount 時,操作便會失敗。列出根目錄(/)會傳回每個 mount point 的虛擬目錄項目。

mount 路徑不能互相嵌套,例如不能同時 mount 至 /data/data/sub

filesystemmounts 的比較
filesystem-vs-mounts 的直接連結

filesystemmounts 是 Workspace 中互相排斥的選項:

  • 如只有單一儲存空間 Provider,而且無須將其 mount 至 Sandbox,請使用 filesystem。Agent 會獲得直接對該 Provider 操作的檔案 Tool。
  • 如需在 Sandbox 內存取雲端儲存空間,或希望組合多個 Provider,請使用 mounts。Workspace 會為檔案 Tool 建立 CompositeFilesystem,並透過 FUSE 將儲存空間 mount 至 Sandbox。

進行本機開發時,通常無須使用 mounts;只要讓 LocalFilesystemLocalSandbox 指向同一目錄,便可同時使用檔案 Tool,並對相同檔案執行命令。詳情請參閱設定模式

Agent Tool
Agent Tool 的直接連結

在 Workspace 設定檔案系統後,Agent 便會獲得用於讀取、寫入、列出及刪除檔案的 Tool。詳情請參閱 Workspace class 參考資料