Workspace
加入版本: @mastra/core@1.1.0
Mastra Workspace 为 Agent 提供用于存储文件和执行命令的持久环境。Agent 使用 Workspace Tool 读写文件、运行 shell 命令,并搜索已建立索引的内容。
Workspace 支持以下功能:
- 文件系统:文件 Storage(读取、写入、列出、删除、复制、移动、grep)
- Sandbox:命令执行(shell 命令)和后台进程
- LSP 检查:通过 Language Server 执行 hover、定义和实现查询
- 搜索:对已建立索引的内容进行 BM25、向量或混合搜索
- Skill:供 Agent 使用的可复用指令
何时使用 Workspace何时使用 Workspace的直接链接
当 Agent 需要访问本地文件系统、运行 shell 命令、执行语义代码检查、搜索索引内容或使用可复用 Skill 指令时,请使用 Workspace。
工作原理工作原理的直接链接
将 Workspace 分配给 Agent 时,Mastra 会将相应 Tool 添加到 Agent 的 Toolset。随后,Agent 可以使用这些 Tool 与文件交互并执行命令。
可以使用任意组合的支持功能创建 Workspace。Agent 只会收到与已配置功能相关的 Tool。
用法用法的直接链接
创建 Workspace创建 Workspace的直接链接
使用所需功能实例化 Workspace 类:
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 定义的目录路径。请参阅 Skill。
全局 Workspace全局 Workspace的直接链接
在 Mastra 实例上设置 Workspace。除非定义了自己的 Workspace,否则所有 Agent 都会继承它:
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 级 WorkspaceAgent 级 Workspace的直接链接
将 Workspace 直接分配给 Agent,以覆盖全局 Workspace:
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。这会关闭 Language Server、浏览器、Sandbox 进程和文件系统 Provider handle 等 Workspace 资源。
如需手动清理,请使用 mastra.removeWorkspace()。如果在从 Registry 中移除前应销毁 Workspace,请传入 { destroy: true }。
静态 Provider 由 Workspace 所有。基于 resolver 的 Provider 由应用所有,因为 Workspace 会在请求时创建它们。有关 resolver 清理模型,请参阅运行时 Sandbox 生命周期所有权。
配置模式配置模式的直接链接
Workspace 根据 Agent 需要的能力支持多种配置模式。主要构建块是 filesystem(文件 Tool)和 sandbox(命令执行),mounts 则用于将云 Storage 连接到 Sandbox。
文件系统 + Sandbox(本地)文件系统 + Sandbox(本地)的直接链接
本地开发时,将 LocalFilesystem 和 LocalSandbox 指向同一目录。由于二者都在本地计算机上运行,通过文件系统写入的文件会立即供 Sandbox 中的命令使用:
const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './workspace' }),
sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
})
Agent 会同时获得文件 Tool 和 execute_command。这是最简单的全功能设置。
Mount + Sandbox(云 Storage)Mount + Sandbox(云 Storage)的直接链接
当需要在 Sandbox 内访问云 Storage 时,请使用 mounts。这会通过 FUSE 将云文件系统 mount 到 Sandbox,使命令能够在 mount 路径读写文件:
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 中的命令直接访问 mount 路径(例如 ls /data)。
可以将多个 Provider mount 到不同路径。每个 mount 路径必须唯一且不能重叠。
filesystem 与 mounts 互斥,不能在同一个 Workspace 中同时使用。对于不含 Sandbox 的单个 Provider,请使用 filesystem;需要将云 Storage 与 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 会获得直接操作 Storage Provider 的文件 Tool(read_file、write_file、list_directory、grep 等)。
仅 Sandbox仅 Sandbox的直接链接
如果 Agent 只需要执行命令,请仅使用 sandbox。此时不会添加文件 Tool。
const workspace = new Workspace({
sandbox: new E2BSandbox({ id: 'dev-sandbox' }),
})
Agent 会获得 execute_command Tool。
动态文件系统(按请求)动态文件系统(按请求)的直接链接
向 filesystem 传入 resolver 函数,为每个请求返回不同的文件系统。它适用于多租户应用或多角色 Agent,其中每个请求需要不同的 Storage 根目录或权限。
const workspace = new Workspace({
filesystem: ({ requestContext }) => {
const role = requestContext.get('agent-role') || 'guest'
return new LocalFilesystem({
basePath: `/workspaces/${role}`,
readOnly: role !== 'admin',
})
},
})
一个 Workspace 实例即可服务所有请求。Resolver 在 Tool 执行时运行,因此每个请求都会获得自己的文件系统。有关详情,请参阅动态文件系统。
动态 Sandbox(按请求)动态 Sandbox(按请求)的直接链接
向 sandbox 传入 resolver 函数,为每个请求返回不同的 Sandbox。它适用于多租户部署,其中每位用户或每种角色都需要隔离的工作目录或不同的执行权限。
const workspace = new Workspace({
sandbox: ({ requestContext }) => {
const userId = requestContext.get('user-id') as string
return new LocalSandbox({
workingDirectory: `/workspaces/${userId}`,
})
},
})
Resolver 与 mounts 和 lsp: true 不兼容,因为二者都要求在构造时提供具体的 Sandbox 实例。有关详情,请参阅动态 Sandbox。
应使用哪种模式?应使用哪种模式?的直接链接
| 场景 | 模式 |
|---|---|
| 使用文件和命令进行本地开发 | filesystem + sandbox(二者均为本地,指向同一目录) |
| 在云 Sandbox 内访问云 Storage | mounts + sandbox |
| 在一个 Sandbox 中使用多个云 Provider | mounts + sandbox(每个 Provider 使用一个 mount) |
| Agent 读写文件,无需执行命令 | 仅 filesystem |
| Agent 运行命令,无需文件 Tool | 仅 sandbox |
| 多角色或多租户 Agent,每个请求使用不同 Storage | 带 resolver 函数的 filesystem |
| 多租户 Agent,每个请求具有不同执行 scope | 带 resolver 函数的 sandbox |
Tool 配置Tool 配置的直接链接
通过 Workspace 上的 tools 选项配置 Tool 行为。它控制启用哪些 Tool 及其行为。
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 选项的直接链接
| 选项 | 类型 | 说明 |
|---|---|---|
enabled | boolean | (context) => boolean | Tool 是否可用(默认值:true)。如果为函数,会在列出 Tool 时求值。 |
requireApproval | boolean | (context) => boolean | Tool 在执行前是否需要用户批准(默认值:false)。如果为函数,会在执行时求值,并可访问 args。 |
requireReadBeforeWrite | boolean | (context) => boolean | 对于写入 Tool,是否要求先读取文件(默认值:false)。如果为函数,会在执行时求值,并可访问 args。 |
name | string | Tool 的自定义名称,替换默认的 mastra_workspace_* 名称。 |
maxOutputTokens | number | Tool 输出的最大 token 数(默认值:2000)。超出此限制的输出会使用 tiktoken 截断。 |
动态 Tool 配置动态 Tool 配置的直接链接
接受函数的 Tool 选项会接收上下文对象并返回 boolean,从而实现感知上下文的 Tool 行为。
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 }。requireApproval 和 requireReadBeforeWrite 的函数还会接收 args,因为它们会在调用 Tool 时求值。
重映射 Tool 名称重映射 Tool 名称的直接链接
重命名 Workspace Tool,使其符合 Agent 预期的约定。配置键仍为原始 WORKSPACE_TOOLS 常量,只有暴露的名称会更改。
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 会看到 view、search_content、find_files、execute_command 和 lsp_inspect,而不是默认的 mastra_workspace_* 名称。Tool 名称必须唯一;名称重复或与其他默认名称冲突时会抛出错误。
Tool hookTool hook的直接链接
设置 tools.hooks,在每次已启用 Workspace Tool 调用前后运行逻辑。Hook 在名称重映射后运行,因此 hook 上下文同时包含暴露的 toolName 和原始 workspaceToolName:
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 用作结果。
如果所属 Agent 也定义了 Tool hook,Workspace hook 会在 Agent hook wrapper 内运行。顺序为:Agent beforeToolCall、Workspace beforeToolCall、Tool、Workspace afterToolCall、Agent afterToolCall。
LSP 检查LSP 检查的直接链接
在 Workspace 上启用 lsp,可通过 Language Server 添加语义代码检查。默认会添加 mastra_workspace_lsp_inspect Tool,它可以返回 hover 信息和定义位置,以及特定光标位置符号的实现。
有关配置、示例和 Tool 名称重映射,请参阅 LSP 检查。
输出截断输出截断的直接链接
Workspace Tool 会自动截断较大的输出,避免超过 LLM 上下文限制。以下截断层会依次应用:
- 按行保留末尾:默认将命令输出限制为最后 200 行(可通过每条命令的
tail参数配置) - 按 token 限制:Tool 输出默认限制为 2000 个 token
为每个 Tool 设置 maxOutputTokens 可调整 token 限制:
const workspace = new Workspace({
// ...
tools: {
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
maxOutputTokens: 5000,
},
},
})
命令输出到达模型前,会自动移除 ANSI 转义码(颜色、光标序列)。
写入前读取写入前读取的直接链接
为写入 Tool 启用 requireReadBeforeWrite 后,Agent 必须先读取文件才能写入,防止覆盖 Agent 尚未查看的文件:
- 新文件:无需读取即可写入(文件尚不存在)
- 现有文件:必须先读取
- 被外部修改的文件:如果文件在 Agent 读取后发生变化,写入会失败
文件写入安全性通过两层强制执行:
- Tool 层:写入 Tool 运行前,读取 tracker 会检查文件自上次读取后是否发生修改。如果发生修改,Tool 会抛出
FileReadRequiredError。 - 文件系统层:写入时,
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()。
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 可能执行其他设置,例如建立连接或进行身份验证。