본문으로 건너뛰기

작업기억

하는 동안message history그리고의미적 회상Agent가 대화를 기억하도록 돕고, 작업 기억을 통해 상호 작용 전반에 걸쳐 사용자에 대한 지속적인 정보를 유지할 수 있습니다.

작업 Memory는 Agent의 활성 스크래치 패드입니다. 즉, 사용자나 작업에 대해 계속 사용할 수 있는 주요 정보입니다. 대화 중에 사람의 이름, 선호도 또는 기타 중요한 세부 정보를 유지할 수 있습니다.

이는 항상 관련성이 있고 Agent가 항상 사용할 수 있어야 하는 진행 중인 상태를 유지하는 데 유용합니다.

관찰 Memory를 사용한다면 observationalMemory.observation.manageWorkingMemory를 통해 OM이 Agent의 작업 Memory를 업데이트하도록 할 수 있습니다. :::tip[📹 보기]

Agent가 상호작용 전반에 걸쳐 지속적인 사용자 컨텍스트를 유지하는 방법을 알아보려면 Mastra 작업 Memory를 시청하세요. :::

작업 Memory는 두 가지 다른 범위에서 지속될 수 있습니다.

  • 리소스 범위(기본값): 동일한 사용자에 대한 모든 대화 스레드에서 Memory가 유지됩니다.
  • 스레드 범위: 대화 스레드마다 Memory가 격리됩니다.

요구 사항:범위 간 전환은 Agent가 다른 범위의 Memory를 볼 수 없음을 의미합니다. 스레드 범위 Memory는 리소스 범위 Memory와 완전히 분리됩니다.

빠른 시작
빠른 시작에 대한 직접 링크

다음은 작업 Memory가 있는 Agent를 설정하는 최소한의 예입니다.

import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'

// Create agent with working memory enabled
const agent = new Agent({
id: 'personal-assistant',
name: 'PersonalAssistant',
instructions: 'You are a helpful personal assistant.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
options: {
workingMemory: {
enabled: true,
},
},
}),
})

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

작업 Memory는 Agent가 지속적으로 관련 정보를 저장하기 위해 시간이 지남에 따라 업데이트할 수 있는 마크다운 텍스트 블록입니다.

Memory 지속성 범위
Memory 지속성 범위에 대한 직접 링크

작업 Memory는 두 가지 다른 범위에서 작동할 수 있으므로 대화 전반에 걸쳐 Memory가 지속되는 방식을 선택할 수 있습니다.

리소스 범위 Memory(기본값)
리소스 범위 Memory(기본값)에 대한 직접 링크

기본적으로 작업 Memory는 동일한 사용자(resourceId)에 대한 모든 대화 스레드에서 지속되므로 영구 사용자 Memory를 활성화합니다.

const memory = new Memory({
storage,
options: {
workingMemory: {
enabled: true,
scope: 'resource', // Memory persists across all user threads
template: `# User Profile
- **Name**:
- **Location**:
- **Interests**:
- **Preferences**:
- **Long-term Goals**:
`,
},
},
})

사용 사례:

  • 사용자 선호도를 기억하는 개인 비서
  • 고객 상황을 유지하는 고객 서비스 봇
  • 학생의 진도를 추적하는 교육용 애플리케이션

Agent와 함께 사용
Agent와 함께 사용에 대한 직접 링크

리소스 범위 Memory를 사용한다면 Memory 옵션에 resource 매개변수를 전달해야 합니다.

// Resource-scoped memory requires resource
const response = await agent.generate('Hello!', {
memory: {
thread: 'conversation-123',
resource: 'user-alice-456', // Same user across different threads
},
})

스레드 범위 Memory
스레드 범위 Memory에 대한 직접 링크

스레드 범위 Memory는 작업 Memory를 개별 대화 스레드로 격리합니다. 각 스레드는 자체적으로 격리된 Memory를 유지합니다.

const memory = new Memory({
storage,
options: {
workingMemory: {
enabled: true,
scope: 'thread', // Memory is isolated per thread
template: `# User Profile
- **Name**:
- **Interests**:
- **Current Goal**:
`,
},
},
})

사용 사례:

  • 별도의 주제에 대한 다양한 대화
  • 임시 또는 세션별 정보
  • 각 스레드에 작업 Memory가 필요하지만 스레드가 일시적이고 서로 관련되지 않는 Workflow

스토리지 어댑터 지원
스토리지 어댑터 지원에 대한 직접 링크

리소스 범위 작업 Memory에는 다음을 지원하는 특정 스토리지 어댑터가 필요합니다.mastra_resources table:

지원되는 스토리지 어댑터
지원되는 스토리지 어댑터에 대한 직접 링크

  • libSQL (@mastra/libsql)
  • 포스트그레SQL (@mastra/pg)
  • 오라클DB (@mastra/oracledb)
  • 업스태시 (@mastra/upstash)
  • 몽고DB (@mastra/mongodb)

맞춤 템플릿
맞춤 템플릿에 대한 직접 링크

템플릿은 Agent에게 작업 Memory에서 추적하고 업데이트할 정보를 안내합니다. Mastra는 사용자가 템플릿을 제공하지 않을 때 기본 템플릿을 사용합니다. 가장 관련성이 높은 정보를 기억할 수 있도록 Agent 사용 사례에 대한 사용자 지정 템플릿을 정의하세요. 여러 사용자가 공유하는 스레드에 대해서는 다음을 참조하세요.Multi-user threads.

다음은 맞춤 템플릿의 예입니다. 이 예에서 Agent는 사용자가 다음 정보가 포함된 메시지를 보내는 즉시 사용자 이름, 위치, 시간대 등을 저장합니다.

const memory = new Memory({
options: {
workingMemory: {
enabled: true,
template: `
# User Profile

## Personal info

- Name:
- Location:
- Timezone:

## Preferences

- Communication Style: [e.g., Formal, Casual]
- Project Goal:
- Key Deadlines:
- [Deadline 1]: [Date]
- [Deadline 2]: [Date]

## Session state

- Last Task Discussed:
- Open Questions:
- [Question 1]
- [Question 2]
`,
},
},
})

효과적인 템플릿 디자인
효과적인 템플릿 디자인에 대한 직접 링크

잘 구성된 템플릿은 Agent가 구문 분석하고 업데이트할 수 있도록 정보를 간단하게 유지합니다. 치료하다 보조자가 최신 상태로 유지하기를 원하는 짧은 형식의 템플릿입니다.

  • 짧고 명확한 레이블을 사용하세요. 단락이나 매우 긴 제목은 피하세요. 업데이트를 쉽게 읽을 수 있고 잘릴 가능성을 줄이려면 레이블을 간결하게 유지하세요(예: ## Personal Info 또는 - Name:).
  • 대소문자를 일관되게 사용하세요. 일관되지 않은 대소문자(Timezone:timezone:)는 업데이트를 어수선하게 만들 수 있습니다. 제목과 글머리표 레이블에 제목식 대문자 표기나 소문자 표기 중 하나를 일관되게 사용하세요.
  • 자리표시자 텍스트를 최소화하세요. LLM이 올바른 위치를 채울 수 있도록 [e.g., Formal]이나 [Date] 같은 힌트를 사용하세요.
  • 매우 긴 값은 축약하세요. 짧은 형식만 필요하다면 법적 효력이 있는 전체 텍스트 대신 - Name: [First name or nickname]이나 - Address (short): 같은 지침을 포함하세요.
  • instructions에 업데이트 규칙을 명시하세요. Agent의 instructions 필드에서 각 섹션을 언제, 어떻게 채우거나 지울지 직접 지시할 수 있습니다.

대체 템플릿 스타일
대체 템플릿 스타일에 대한 직접 링크

몇 가지 항목만 필요한 경우 더 짧은 단일 블록을 사용하십시오.

const basicMemory = new Memory({
options: {
workingMemory: {
enabled: true,
template: `User Facts:\n- Name:\n- Favorite Color:\n- Current Topic:`,
},
},
})

좀 더 서술적인 스타일을 선호한다면 주요 사실을 짧은 단락 형식으로 저장할 수도 있습니다.

const paragraphMemory = new Memory({
options: {
workingMemory: {
enabled: true,
template: `Important Details:\n\nKeep a short paragraph capturing the user's important facts (name, main goal, current task).`,
},
},
})

구조화된 작업 기억
구조화된 작업 기억에 대한 직접 링크

Markdown 템플릿 대신 구조화된 스키마로 작업 Memory를 정의할 수도 있습니다. 이를 통해 추적할 정확한 필드와 유형을 지정할 수 있습니다. Standard JSON Schema(Zod, Valibot, ArkType 등)를 사용할 수 있습니다. 스키마를 사용하면 Agent가 스키마와 일치하는 JSON 객체로 작업 Memory를 확인하고 업데이트합니다. 요구 사항: template 또는 schema 중 하나만 지정해야 하며 둘 다 지정할 수는 없습니다.

예: 스키마 기반 작업 Memory
예: 스키마 기반 작업 Memory에 대한 직접 링크

import { z } from 'zod'
import { Memory } from '@mastra/memory'

const userProfileSchema = z.object({
name: z.string().optional(),
location: z.string().optional(),
timezone: z.string().optional(),
preferences: z
.object({
communicationStyle: z.string().optional(),
projectGoal: z.string().optional(),
deadlines: z.array(z.string()).optional(),
})
.optional(),
})

const memory = new Memory({
options: {
workingMemory: {
enabled: true,
schema: userProfileSchema,
// template: ... (do not set)
},
},
})

스키마가 제공되면 Agent는 작업 Memory를 JSON 개체로 받습니다. 예를 들어:

{
"name": "Sam",
"location": "Berlin",
"timezone": "CET",
"preferences": {
"communicationStyle": "Formal",
"projectGoal": "Launch MVP",
"deadlines": ["2025-07-01"]
}
}

스키마 기반 Memory에 대한 의미 체계 병합
스키마 기반 Memory에 대한 의미 체계 병합에 대한 직접 링크

스키마 기반 작업 Memory는 병합 의미 체계를 사용합니다. 즉, Agent는 추가하거나 업데이트할 필드만 포함하면 됩니다. 기존 필드는 자동으로 보존됩니다.

  • 객체 필드는 깊이 병합됩니다. 제공된 필드만 업데이트되고 나머지는 변경되지 않은 채 유지됩니다.
  • 필드를 삭제하려면 null로 설정하세요. 이렇게 하면 Memory에서 해당 필드가 명시적으로 제거됩니다.
  • 배열은 완전히 교체됩니다. 배열 필드를 제공하면 기존 배열을 대체합니다. 배열은 요소별로 병합되지 않습니다.

템플릿과 스키마 중에서 선택
템플릿과 스키마 중에서 선택에 대한 직접 링크

  • Agent가 사용자 프로필이나 스크래치패드 같은 자유 형식의 텍스트 블록으로 Memory를 유지하게 하려면 template(Markdown)을 사용하세요. 템플릿은 교체 의미 체계를 사용하므로 Agent가 업데이트할 때마다 전체 Memory 콘텐츠를 제공해야 합니다.
  • JSON으로 검증하고 프로그래밍 방식으로 접근할 수 있는 구조화된 타입 안전 데이터가 필요하다면 schema를 사용하세요. workingMemory.schema 필드는 PublicSchema와 호환되는 모든 스키마(Zod v3, Zod v4, JSON Schema 또는 이미 표준화된 스키마 포함)를 허용합니다. 스키마는 병합 의미 체계를 사용하므로 Agent는 업데이트할 필드만 제공하고 기존 필드는 보존됩니다.
  • 한 번에 하나의 모드만 활성화할 수 있습니다. templateschema를 모두 설정하는 것은 지원되지 않습니다.

예: 다단계 보존
예: 다단계 보존에 대한 직접 링크

다음은 짧은 사용자 대화에서 User Profile 템플릿이 업데이트되는 방식을 간략히 보여 줍니다.

# User Profile

## Personal info

- Name:
- Location:
- Timezone:

--- After user says "My name is **Sam** and I'm from **Berlin**" ---

# User Profile
- Name: Sam
- Location: Berlin
- Timezone:

--- After user adds "By the way I'm normally in **CET**" ---

# User Profile
- Name: Sam
- Location: Berlin
- Timezone: CET

이제 Sam 또는 Berlin이 작업 Memory에 저장되었으므로 Agent는 나중에 다시 정보를 요청하지 않고 응답에서 이를 참조할 수 있습니다. Agent가 작업 Memory를 예상대로 업데이트하지 않는다면 Agent의 instructions 설정에 이 템플릿을 사용하는 방법사용할 시점에 관한 시스템 지침을 추가할 수 있습니다.

초기 작업 Memory 설정
초기 작업 Memory 설정에 대한 직접 링크

Agent는 일반적으로 updateWorkingMemory Tool을 통해 작업 Memory를 업데이트하지만, 스레드를 생성하거나 업데이트할 때 초기 작업 Memory를 프로그래밍 방식으로 설정할 수도 있습니다. 매 요청에 전달하지 않고도 Agent가 사용할 수 있도록 사용자 데이터(이름, 선호 사항 또는 기타 정보)를 주입할 때 유용합니다.

스레드 메타데이터를 통해 작업 Memory 설정
스레드 메타데이터를 통해 작업 Memory 설정에 대한 직접 링크

스레드 생성 시 메타데이터를 통해 초기 작업 Memory를 제공할 수 있습니다.workingMemory key:

src/app/medical-consultation.ts
// Create a thread with initial working memory
const thread = await memory.createThread({
threadId: 'thread-123',
resourceId: 'user-456',
title: 'Medical Consultation',
metadata: {
workingMemory: `# Patient Profile
- Name: John Doe
- Blood Type: O+
- Allergies: Penicillin
- Current Medications: None
- Medical History: Hypertension (controlled)
`,
},
})

// The agent will now have access to this information in all messages
await agent.generate("What's my blood type?", {
memory: {
thread: thread.id,
resource: 'user-456',
},
})
// Response: "Your blood type is O+."

프로그래밍 방식으로 작업 Memory 업데이트
프로그래밍 방식으로 작업 Memory 업데이트에 대한 직접 링크

기존 스레드의 작업 Memory를 업데이트할 수도 있습니다.

src/app/medical-consultation.ts
// Update thread metadata to add/modify working memory
await memory.updateThread({
id: 'thread-123',
title: thread.title,
metadata: {
...thread.metadata,
workingMemory: `# Patient Profile
- Name: John Doe
- Blood Type: O+
- Allergies: Penicillin, Ibuprofen // Updated
- Current Medications: Lisinopril 10mg daily // Added
- Medical History: Hypertension (controlled)
`,
},
})

직접 Memory 업데이트
직접 Memory 업데이트에 대한 직접 링크

또는updateWorkingMemory method directly:

src/app/medical-consultation.ts
await memory.updateWorkingMemory({
threadId: 'thread-123',
resourceId: 'user-456', // Required for resource-scoped memory
workingMemory: 'Updated memory content...',
})

읽기 전용 작업 Memory
읽기 전용 작업 Memory에 대한 직접 링크

일부 시나리오에서는 Agent가 작업 Memory 데이터를 수정하지 않고도 작업 Memory 데이터에 액세스할 수 있기를 원할 수 있습니다. 이는 다음과 같은 경우에 유용합니다.

  • 라우팅 Agent컨텍스트가 필요하지만 사용자 프로필을 업데이트해서는 안 됩니다.
  • 서브 AgentMemory를 참조해야 하지만 소유하지는 않는 다중 Agent 시스템에서

읽기 전용 모드를 활성화하려면 Memory 옵션에서 readOnly: true를 설정하세요.

const response = await agent.generate('What do you know about me?', {
memory: {
thread: 'conversation-123',
resource: 'user-alice-456',
options: {
readOnly: true, // Working memory is provided but cannot be updated
},
},
})

상태 신호 선택(실험적)
상태 신호 선택(실험적)에 대한 직접 링크

기본적으로 작업 Memory는 시스템 메시지의 일부로 Model에 전달됩니다. useStateSignals: true를 설정하면 대신 상태 신호로 제공할 수 있습니다.

const memory = new Memory({
storage: new LibSQLStore({ id: 'mastra-storage', url: 'file:./mastra.db' }),
options: {
workingMemory: {
enabled: true,
template: '# User\n- name:\n- location:',
useStateSignals: true, // experimental: deliver as state signal
},
},
})

변경사항:

  • 스토리지는 동일합니다. 동일한 리소스/스레드의 workingMemory 필드를 읽고 씁니다.
  • Tool은 형태가 같지만 새 이름으로 표시됩니다. 쓰기는 여전히 동일한 기본 Tool을 통해 이루어집니다. 이 경로에서는 updateWorkingMemory 대신 setWorkingMemory로 등록됩니다. 이름을 변경하면 기존 제거 필터가 Tool 호출 부분을 제거하지 않으므로 일반 감사 추적으로 유지되고 다음 Model 단계에서 새 값을 자동으로 선택합니다.
  • 전달 방식만 변경됩니다. 시스템 Prompt에 포함하는 대신 Memory가 현재 작업 Memory를 stateId: 'working-memory'state 신호로 내보내는 WorkingMemoryStateProcessor를 자동 연결합니다. 스레드 범위 추적 메타데이터, 동일한 스냅샷을 한 번만 내보내는 cacheKey 중복 제거, 오래된 스냅샷이 창 밖으로 밀려날 때 수행되는 contextWindow.hasSnapshot 재삽입 등 표준 상태 신호의 이점을 제공합니다. 기본값(useStateSignals: false)은 기존 시스템 메시지 동작을 변경하지 않고 유지합니다. 템플릿 작업 Memory version: 'vnext'에서는 useStateSignals가 지원되지 않습니다.

예에 대한 직접 링크