본문으로 건너뛰기

작업공간

추가된 항목: @mastra/core@1.1.0

Mastra 작업 공간은 Agent에 파일 저장 및 명령 실행을 위한 지속적인 환경을 제공합니다. Agent는 작업 공간 Tool을 사용하여 파일을 읽고 쓰고 셸 명령을 실행하며 색인된 콘텐츠를 검색합니다.

작업공간은 다음 기능을 지원합니다.

  • 파일 시스템: 파일 저장(읽기, 쓰기, 나열, 삭제, 복사, 이동, grep)
  • 모래 상자: 명령 실행(셸 명령) 및 백그라운드 프로세스
  • LSP 검사: 언어 서버를 통한 호버, 정의, 구현 쿼리
  • 찾다: 색인화된 콘텐츠에 대한 BM25, 벡터 또는 하이브리드 검색
  • 기술: Agent를 위한 재사용 가능한 지침

작업공간을 사용해야 하는 경우
작업공간을 사용해야 하는 경우에 대한 직접 링크

Agent가 로컬 파일 시스템, 셸 명령, 의미 체계 코드 검사, 색인 검색 또는 재사용 가능한 기술 지침에 액세스해야 하는 경우 작업 영역을 사용하세요.

작동 원리
작동 원리에 대한 직접 링크

Agent에 작업 영역을 할당하면 Mastra는 Agent Tool 세트에 해당 Tool을 포함합니다. 그런 다음 Agent는 이러한 Tool을 사용하여 파일과 상호 작용하고 명령을 실행할 수 있습니다.

지원되는 기능을 원하는 대로 조합하여 작업 공간을 만들 수 있습니다. Agent는 구성된 것과 관련된 Tool만 ​​받습니다.

용법
용법에 대한 직접 링크

작업공간 만들기
작업공간 만들기에 대한 직접 링크

원하는 기능을 지정하여 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 정의가 포함된 디렉터리의 경로를 지정합니다. Skill을 참조하세요.

글로벌 작업공간
글로벌 작업공간에 대한 직접 링크

Mastra 인스턴스에 작업공간을 설정합니다. 모든 Agent은 자신이 직접 정의하지 않는 한 이 작업 영역을 상속받습니다.

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 수준 작업공간
Agent 수준 작업공간에 대한 직접 링크

전역 작업 영역을 재정의하려면 작업 영역을 Agent에 직접 할당하세요.

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는 런타임에 전역 Workspace와 Agent Workspace를 등록하여 나열하고 조회할 수 있도록 합니다. mastra.shutdown()을 호출하면 Mastra가 소유한 등록된 Workspace를 제거합니다. 이때 언어 서버, 브라우저, Sandbox 프로세스, 파일 시스템 Provider 핸들과 같은 Workspace 리소스가 닫힙니다. 수동으로 정리하려면 mastra.removeWorkspace()를 사용하세요. 레지스트리에서 제거하기 전에 Workspace를 제거해야 한다면 { destroy: true }를 전달하세요. 정적 Provider는 Workspace가 소유합니다. 리졸버 기반 Provider는 요청 시 Workspace가 생성하므로 애플리케이션이 소유합니다. 리졸버 정리 모델은 런타임 Sandbox 수명 주기 소유권을 참조하세요.

구성 패턴
구성 패턴에 대한 직접 링크

Workspace는 Agent에 필요한 기능에 따라 여러 구성 패턴을 지원합니다. 주요 구성 요소는 filesystem(파일 Tool)과 sandbox(명령 실행)이며, mounts를 사용해 클라우드 스토리지를 Sandbox에 연결할 수 있습니다.

파일 시스템 + 샌드박스(로컬)
파일 시스템 + 샌드박스(로컬)에 대한 직접 링크

로컬 개발에서는 LocalFilesystemLocalSandbox가 같은 디렉터리를 가리키도록 설정하세요. 둘 다 로컬 시스템에서 작동하므로 파일 시스템을 통해 작성한 파일을 Sandbox의 명령에서 즉시 사용할 수 있습니다.

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

Agent에는 파일 Tool과 execute_command가 제공됩니다. 모든 기능을 갖춘 가장 간단한 설정입니다.

마운트 + 샌드박스(클라우드 스토리지)
마운트 + 샌드박스(클라우드 스토리지)에 대한 직접 링크

Sandbox 내부에서 액세스할 수 있는 클라우드 스토리지가 필요하면 mounts를 사용하세요. 클라우드 파일 시스템이 Sandbox에 FUSE로 마운트되므로 명령에서 마운트 경로의 파일을 읽고 쓸 수 있습니다.

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는 경로 접두사를 기준으로 파일 Tool 작업을 올바른 Provider에 라우팅하는 CompositeFilesystem을 생성합니다. Sandbox의 명령은 마운트된 경로에 직접 액세스합니다(예: ls /data). 여러 경로에 여러 공급자를 탑재할 수 있습니다. 각 마운트 경로는 고유해야 하며 겹치지 않아야 합니다.

노트

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_file, write_file, list_directory, grep 등)이 제공됩니다.

샌드박스 전용
샌드박스 전용에 대한 직접 링크

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를 반환할 수 있습니다. 각 사용자나 역할에 격리된 작업 디렉터리 또는 서로 다른 실행 권한이 필요한 멀티테넌트 배포에 유용합니다.

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에서 여러 클라우드 Provider 사용mounts + sandbox(Provider마다 마운트 하나)
Agent가 파일을 읽고 쓰며 명령 실행은 필요하지 않음filesystem만 사용
Agent가 명령을 실행하며 파일 Tool은 필요하지 않음sandbox만 사용
요청별 스토리지를 사용하는 다중 역할 또는 멀티테넌트 Agent리졸버 함수와 함께 filesystem 사용
요청별 실행 범위를 사용하는 멀티테넌트 Agent리졸버 함수와 함께 sandbox 사용

Tool 구성
Tool 구성에 대한 직접 링크

Workspace의 tools 옵션을 통해 Tool 동작을 구성하세요. 이 옵션으로 활성화할 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 출력의 최대 토큰 수입니다(기본값: 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 이름 다시 매핑에 대한 직접 링크

Agent가 기대하는 규칙에 맞게 Workspace Tool의 이름을 변경할 수 있습니다. 구성 키는 원래 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에는 기본 mastra_workspace_* 이름 대신 view, search_content, find_files, execute_command, lsp_inspect가 표시됩니다. Tool 이름은 고유해야 하며, 이름이 중복되거나 다른 기본 이름과 충돌하면 오류가 발생합니다.

Tool 후크
Tool 후크에 대한 직접 링크

활성화된 모든 Workspace Tool 호출 전후에 로직을 실행하려면 tools.hooks를 설정하세요. Hook은 이름 재매핑 후에 실행되므로 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을 결과로 사용합니다. 이를 소유한 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 parameter)
  2. 토큰 기반 한도: Tool 출력은 기본적으로 2000개 토큰으로 제한됩니다.

Tool별로 maxOutputTokens를 설정하여 토큰 제한을 조정하세요.

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

ANSI 이스케이프 코드(색상, 커서 시퀀스)는 명령 출력이 Model에 도달하기 전에 자동으로 제거됩니다.

쓰기 전 읽기
쓰기 전 읽기에 대한 직접 링크

쓰기 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에 대한 직접 링크

초기화는 구성된 각 공급자에 대해 설정 논리를 실행합니다.

  • LocalFilesystem: 기본 디렉터리가 없으면 생성합니다.
  • LocalSandbox: 작업 디렉터리를 생성합니다.
  • Search(구성된 경우): autoIndexPaths에 있는 파일을 인덱싱합니다. 검색 및 인덱싱을 참조하세요. 외부 공급자는 연결 설정 또는 인증과 같은 추가 설정을 수행할 수 있습니다.