> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ko/llms.txt # 작업공간 **추가된 항목:** `@mastra/core@1.1.0` Mastra 작업 공간은 Agent에 파일 저장 및 명령 실행을 위한 지속적인 환경을 제공합니다. Agent는 작업 공간 Tool을 사용하여 파일을 읽고 쓰고 셸 명령을 실행하며 색인된 콘텐츠를 검색합니다. 작업공간은 다음 기능을 지원합니다. - **[파일 시스템](https://mastra.zisheng.pro/ko/docs/workspace/filesystem)**: 파일 저장(읽기, 쓰기, 나열, 삭제, 복사, 이동, grep) - **[모래 상자](https://mastra.zisheng.pro/ko/docs/workspace/sandbox)**: 명령 실행(셸 명령) 및 백그라운드 프로세스 - **[LSP 검사](https://mastra.zisheng.pro/ko/docs/workspace/lsp)**: 언어 서버를 통한 호버, 정의, 구현 쿼리 - **[찾다](https://mastra.zisheng.pro/ko/docs/workspace/search)**: 색인화된 콘텐츠에 대한 BM25, 벡터 또는 하이브리드 검색 - **[기술](https://mastra.zisheng.pro/ko/docs/workspace/skills)**: Agent를 위한 재사용 가능한 지침 ## 작업공간을 사용해야 하는 경우 Agent가 로컬 파일 시스템, 셸 명령, 의미 체계 코드 검사, 색인 검색 또는 재사용 가능한 기술 지침에 액세스해야 하는 경우 작업 영역을 사용하세요. ## 작동 원리 Agent에 작업 영역을 할당하면 Mastra는 Agent Tool 세트에 해당 Tool을 포함합니다. 그런 다음 Agent는 이러한 Tool을 사용하여 파일과 상호 작용하고 명령을 실행할 수 있습니다. 지원되는 기능을 원하는 대로 조합하여 작업 공간을 만들 수 있습니다. Agent는 구성된 것과 관련된 Tool만 ​​받습니다. ## 용법 ### 작업공간 만들기 원하는 기능을 지정하여 `Workspace` 클래스를 인스턴스화하면 Workspace를 만들 수 있습니다. ```typescript 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](https://mastra.zisheng.pro/ko/docs/workspace/skills)을 참조하세요. ### 글로벌 작업공간 Mastra 인스턴스에 작업공간을 설정합니다. 모든 Agent은 자신이 직접 정의하지 않는 한 이 작업 영역을 상속받습니다. ```typescript 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에 직접 할당하세요. ```typescript 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()`](https://mastra.zisheng.pro/ko/reference/core/removeWorkspace)를 사용하세요. 레지스트리에서 제거하기 전에 Workspace를 제거해야 한다면 `{ destroy: true }`를 전달하세요. 정적 Provider는 Workspace가 소유합니다. 리졸버 기반 Provider는 요청 시 Workspace가 생성하므로 애플리케이션이 소유합니다. 리졸버 정리 모델은 [런타임 Sandbox 수명 주기 소유권](https://mastra.zisheng.pro/ko/docs/workspace/sandbox)을 참조하세요. ## 구성 패턴 Workspace는 Agent에 필요한 기능에 따라 여러 구성 패턴을 지원합니다. 주요 구성 요소는 `filesystem`(파일 Tool)과 `sandbox`(명령 실행)이며, `mounts`를 사용해 클라우드 스토리지를 Sandbox에 연결할 수 있습니다. ### 파일 시스템 + 샌드박스(로컬) 로컬 개발에서는 `LocalFilesystem`과 `LocalSandbox`가 같은 디렉터리를 가리키도록 설정하세요. 둘 다 로컬 시스템에서 작동하므로 파일 시스템을 통해 작성한 파일을 Sandbox의 명령에서 즉시 사용할 수 있습니다. ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), sandbox: new LocalSandbox({ workingDirectory: './workspace' }), }) ``` Agent에는 파일 Tool과 `execute_command`가 제공됩니다. 모든 기능을 갖춘 가장 간단한 설정입니다. ### 마운트 + 샌드박스(클라우드 스토리지) Sandbox 내부에서 액세스할 수 있는 클라우드 스토리지가 필요하면 `mounts`를 사용하세요. 클라우드 파일 시스템이 Sandbox에 FUSE로 마운트되므로 명령에서 마운트 경로의 파일을 읽고 쓸 수 있습니다. ```typescript 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](https://mastra.zisheng.pro/ko/docs/workspace/filesystem)을 생성합니다. Sandbox의 명령은 마운트된 경로에 직접 액세스합니다(예: `ls /data`). 여러 경로에 여러 공급자를 탑재할 수 있습니다. 각 마운트 경로는 고유해야 하며 겹치지 않아야 합니다. > **노트:** `filesystem`과 `mounts`는 함께 사용할 수 없으므로 같은 Workspace에 둘 다 지정할 수 없습니다. Sandbox 없이 단일 Provider를 사용하려면 `filesystem`을 사용하고, 클라우드 스토리지와 Sandbox를 결합해야 한다면 `mounts`를 사용하세요. ### 파일 시스템만 Agent가 파일을 읽고 쓰기만 하면 되는 경우 단일 `filesystem`을 사용하세요. 명령 실행 기능은 제공되지 않습니다. ```typescript 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은 추가되지 않습니다. ```typescript const workspace = new Workspace({ sandbox: new E2BSandbox({ id: 'dev-sandbox' }), }) ``` Agent는`execute_command` tool. ### 동적 파일 시스템(요청별) `filesystem`에 리졸버 함수를 전달하면 요청마다 서로 다른 파일 시스템을 반환할 수 있습니다. 각 요청에 서로 다른 스토리지 루트나 권한이 필요한 멀티테넌트 애플리케이션 또는 다중 역할 Agent에 유용합니다. ```typescript const workspace = new Workspace({ filesystem: ({ requestContext }) => { const role = requestContext.get('agent-role') || 'guest' return new LocalFilesystem({ basePath: `/workspaces/${role}`, readOnly: role !== 'admin', }) }, }) ``` 하나의 Workspace 인스턴스가 모든 요청을 처리합니다. 리졸버는 Tool 실행 시점에 실행되므로 각 요청에 자체 파일 시스템이 제공됩니다. 자세한 내용은 [동적 파일 시스템](https://mastra.zisheng.pro/ko/docs/workspace/filesystem)을 참조하세요. ### 동적 샌드박스(요청별) `sandbox`에 리졸버 함수를 전달하면 요청마다 서로 다른 Sandbox를 반환할 수 있습니다. 각 사용자나 역할에 격리된 작업 디렉터리 또는 서로 다른 실행 권한이 필요한 멀티테넌트 배포에 유용합니다. ```typescript const workspace = new Workspace({ sandbox: ({ requestContext }) => { const userId = requestContext.get('user-id') as string return new LocalSandbox({ workingDirectory: `/workspaces/${userId}`, }) }, }) ``` 리졸버는 `mounts` 및 `lsp: true`와 호환되지 않습니다. 둘 다 생성 시점에 구체적인 Sandbox 인스턴스가 필요하기 때문입니다. 자세한 내용은 [동적 Sandbox](https://mastra.zisheng.pro/ko/docs/workspace/sandbox)를 참조하세요. ### 어떤 패턴을 사용해야 하나요? | 시나리오 | 패턴 | | ------------------------------------- | ---------------------------------------------- | | 파일 및 명령을 사용하는 로컬 개발 | `filesystem` + `sandbox`(둘 다 로컬이며 동일한 디렉터리 사용) | | 클라우드 Sandbox 내부에서 액세스할 수 있는 클라우드 스토리지 | `mounts` + `sandbox` | | 하나의 Sandbox에서 여러 클라우드 Provider 사용 | `mounts` + `sandbox`(Provider마다 마운트 하나) | | Agent가 파일을 읽고 쓰며 명령 실행은 필요하지 않음 | `filesystem`만 사용 | | Agent가 명령을 실행하며 파일 Tool은 필요하지 않음 | `sandbox`만 사용 | | 요청별 스토리지를 사용하는 다중 역할 또는 멀티테넌트 Agent | 리졸버 함수와 함께 `filesystem` 사용 | | 요청별 실행 범위를 사용하는 멀티테넌트 Agent | 리졸버 함수와 함께 `sandbox` 사용 | ## Tool 구성 Workspace의 `tools` 옵션을 통해 Tool 동작을 구성하세요. 이 옵션으로 활성화할 Tool과 각 Tool의 동작 방식을 제어할 수 있습니다. ```typescript 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 옵션 | 옵션 | 유형 | 설명 | | ------------------------ | --------------------------------- | ------------------------------------------------------------------------------------- | | `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 출력의 최대 토큰 수입니다(기본값: `2000`). 이 제한을 초과한 출력은 tiktoken을 사용해 잘립니다. | ### 동적 Tool 구성 함수를 허용하는 Tool 옵션은 컨텍스트 개체를 수신하고 부울을 반환합니다. 상황 인식 Tool 동작을 가능하게 합니다. ```typescript 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` 함수는 Tool 호출 시 평가되므로 `args`도 받습니다. ### Tool 이름 다시 매핑 Agent가 기대하는 규칙에 맞게 Workspace Tool의 이름을 변경할 수 있습니다. 구성 키는 원래 `WORKSPACE_TOOLS` 상수로 유지되며 외부에 노출되는 이름만 변경됩니다. ```typescript 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 후크 활성화된 모든 Workspace Tool 호출 전후에 로직을 실행하려면 `tools.hooks`를 설정하세요. Hook은 이름 재매핑 후에 실행되므로 Hook 컨텍스트에 외부에 노출되는 `toolName`과 원래의 `workspaceToolName`이 모두 포함됩니다. ```typescript 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](https://mastra.zisheng.pro/ko/docs/agents/using-tools)이 정의되어 있다면 Workspace Hook은 Agent Hook 래퍼 내부에서 실행됩니다. 실행 순서는 Agent `beforeToolCall`, Workspace `beforeToolCall`, Tool, Workspace `afterToolCall`, Agent `afterToolCall`입니다. ## LSP 검사 Workspace에서 `lsp`를 활성화하면 언어 서버를 통한 의미론적 코드 검사를 추가할 수 있습니다. 기본적으로 `mastra_workspace_lsp_inspect` Tool이 추가되며, 특정 커서 위치의 기호에 대한 호버 정보, 정의 위치 및 구현을 반환할 수 있습니다. 구성, 예제 및 Tool 이름 재매핑에 관한 내용은 [LSP 검사](https://mastra.zisheng.pro/ko/docs/workspace/lsp)를 참조하세요. ### 출력 잘림 Workspace Tool은 LLM 컨텍스트 제한을 초과하지 않도록 큰 출력을 자동으로 자릅니다. 다음과 같은 잘림 레이어가 적용됩니다. 1. **라인 기반 꼬리**: 명령 출력은 기본적으로 마지막 200줄로 제한됩니다(다음을 통해 명령별로 구성 가능).`tail` parameter) 2. **토큰 기반 한도**: Tool 출력은 기본적으로 2000개 토큰으로 제한됩니다. Tool별로 `maxOutputTokens`를 설정하여 토큰 제한을 조정하세요. ```typescript 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`을 직접 사용할 수도 있습니다. ```typescript 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()`을 직접 호출하세요. ```typescript 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()`의 역할 초기화는 구성된 각 공급자에 대해 설정 논리를 실행합니다. - `LocalFilesystem`: 기본 디렉터리가 없으면 생성합니다. - `LocalSandbox`: 작업 디렉터리를 생성합니다. - `Search`(구성된 경우): `autoIndexPaths`에 있는 파일을 인덱싱합니다. [검색 및 인덱싱](https://mastra.zisheng.pro/ko/docs/workspace/search)을 참조하세요. 외부 공급자는 연결 설정 또는 인증과 같은 추가 설정을 수행할 수 있습니다. ## 관련된 - [파일 시스템](https://mastra.zisheng.pro/ko/docs/workspace/filesystem) - [Sandbox](https://mastra.zisheng.pro/ko/docs/workspace/sandbox) - [LSP 검사](https://mastra.zisheng.pro/ko/docs/workspace/lsp) - [Skill](https://mastra.zisheng.pro/ko/docs/workspace/skills) - [검색 및 인덱싱](https://mastra.zisheng.pro/ko/docs/workspace/search) - [Workspace 클래스 레퍼런스](https://mastra.zisheng.pro/ko/reference/workspace/workspace-class) - 📹 [Mastra Workspace 소개 워크숍](https://www.youtube.com/watch?v=QcQLiYlJuNQ)