> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ko/llms.txt # 관찰 기억 **추가된 항목:** `@mastra/memory@1.1.0` Observational Memory(OM)는 긴 컨텍스트의 Agent Memory를 위한 Mastra의 Memory 시스템입니다. **Observer**는 대화를 관찰하고 관찰 내용을 생성합니다. **Reflector**는 관련 항목을 결합하고 중요한 패턴을 압축하여 관찰 내용을 재구성합니다. 두 구성 요소는 함께 원시 메시지 기록이 늘어남에 따라 이를 대체하는 관찰 로그를 유지합니다. ## 용법 ```typescript import { Memory } from '@mastra/memory' import { Agent } from '@mastra/core/agent' export const agent = new Agent({ id: 'my-agent', name: 'my-agent', instructions: 'You are a helpful assistant.', model: 'openai/gpt-5-mini', memory: new Memory({ options: { observationalMemory: true, }, }), }) ``` ## 구성 `observationalMemory` 옵션은 `true`, 구성 객체 또는 `false`를 받습니다. `true`로 설정하면 `google/gemini-2.5-flash`를 기본 Model로 사용하여 OM을 활성화합니다. 구성 객체를 전달할 때는 최상위 수준의 `model`이나 `observation.model` 및/또는 `reflection.model`을 설정합니다. 모든 Model 필드를 생략하면 OM은 `google/gemini-2.5-flash`로 대체합니다. Observer 입력은 멀티모달을 인식합니다. OM은 Observer용으로 생성하는 대화 기록에 `[Image #1: screenshot.png]` 같은 텍스트 자리 표시자를 유지하며, 가능한 경우 기반 이미지 파트도 전송합니다. 이는 단일 스레드 관찰과 일괄 다중 스레드 관찰 모두에 적용됩니다. 이미지가 아닌 파일은 자리 표시자로만 나타납니다. OM은 임계값을 판단할 때 빠른 로컬 토큰 추정 방식을 사용합니다. 텍스트에는 `tokenx`를 사용하고, 이미지 계열 입력에는 Provider를 고려한 휴리스틱과 메타데이터가 불완전할 때의 결정론적 대체 방식을 사용합니다. **enabled** (`boolean`): Observational Memory를 활성화하거나 비활성화합니다. 구성 객체에서 생략하면 기본값은 true입니다. enabled: false만 명시적으로 비활성화합니다. (Default: `true`) **model** (`string | LanguageModel | DynamicModel | ModelByInputTokens | ModelWithRetries[]`): Observer 및 Reflector Agent 모두에 사용할 Model입니다. 두 Agent의 Model을 한 번에 설정합니다. observation.model 또는 reflection.model과 함께 사용할 수 없으며, 둘 다 설정하면 오류가 발생합니다. 이 항목과 observation.model/reflection.model을 모두 생략하면 OM은 google/gemini-2.5-flash를 사용합니다. 기본 Model(google/gemini-2.5-flash)을 명시적으로 사용하려면 "default"를 사용합니다. (Default: `'google/gemini-2.5-flash'`) **scope** (`'resource' | 'thread'`): 관찰 내용의 Memory 범위입니다. 'thread'는 스레드별로 관찰 내용을 유지합니다. 'resource'(실험적)는 한 리소스의 모든 스레드에서 관찰 내용을 공유하여 대화 간 Memory를 지원합니다. (Default: `'thread'`) **activateAfterIdle** (`number | string | false | "auto"`): 비활성 상태가 된 후 observation.messageTokens에 도달하기 전이라도 버퍼링된 관찰 내용을 강제로 활성화하기까지의 시간입니다. 300\_000과 같은 밀리초 숫자 값, "5m" 또는 "1hr" 같은 기간 문자열, Provider를 고려한 Prompt 캐시 TTL을 사용하는 "auto", 상속된 관찰 유휴 활성화를 비활성화하는 false를 받을 수 있습니다. 성찰은 이 설정을 상속하지 않습니다. 성찰에 유휴 활성화를 적용하려면 reflection.activateAfterIdle을 사용합니다. **activateOnProviderChange** (`boolean`): 행위자의 Provider 또는 Model이 변경될 때 버퍼링된 관찰 내용을 강제로 활성화합니다. 성찰은 이 설정을 상속하지 않습니다. 성찰에 Provider 변경 시 활성화를 적용하려면 reflection.activateOnProviderChange를 사용합니다. (Default: `false`) **shareTokenBudget** (`boolean`): 메시지와 관찰 내용이 토큰 예산을 공유합니다. 활성화하면 총예산은 observation.messageTokens + reflection.observationTokens입니다. 관찰 내용이 적을 때 메시지가 더 많은 공간을 사용할 수 있으며 그 반대도 가능합니다. 유연한 할당을 통해 컨텍스트 사용량을 극대화합니다. shareTokenBudget은 아직 비동기 버퍼링과 호환되지 않습니다. 이 옵션을 사용할 때는 observation: { bufferTokens: false }를 설정해야 합니다(일시적인 제한 사항). (Default: `false`) **temporalMarkers** (`boolean`): 스레드의 이전 메시지가 최소 10분 전에 작성된 경우 새 사용자 메시지 앞에 시간 간격 알림 마커를 삽입합니다. 마커는 Memory에 영구 저장되고, 클라이언트가 특별하게 렌더링할 수 있도록 인라인 알림 이벤트로 방출되며, Observer가 사건 발생 시점을 기준으로 관찰 내용을 연결할 수 있도록 표시됩니다. (Default: `false`) **retrieval** (`boolean | { vector?: boolean; scope?: 'thread' | 'resource'; instructions?: string }`): Agent가 관찰 내용의 기반이 되는 원시 메시지 기록을 조회할 수 있게 합니다. 관찰 그룹은 원본 메시지를 가리키는 영구 포인터를 유지하며, Agent가 이를 탐색할 수 있도록 recall Tool이 등록됩니다. true는 기본적으로 스레드 간 탐색을 활성화합니다. { vector: true }는 Memory의 벡터 저장소와 임베더를 사용하는 의미 체계 검색도 활성화합니다. { scope: 'thread' }는 recall Tool을 현재 스레드로만 제한합니다. 기본 범위는 'resource'입니다. { instructions: '...' }는 Mastra의 내장 검색 지침 뒤에 애플리케이션별 회상 지침을 추가합니다. (Default: `false`) **hooks** (`ObserveHooks`): 모든 관찰/성찰 주기에 실행되는 수명 주기 훅입니다. 여기에는 수동 observe()/reflect() API, 턴 기반 동기식 관찰, 실행 후 결과를 기다리지 않는 비동기 버퍼링이 포함됩니다. 콜백은 threadId/resourceId/trigger 호출 컨텍스트('manual' | 'turn-sync' | 'async-buffer')를 받으며, 종료 훅(onObservationEnd/onReflectionEnd)은 추가로 OM Model 호출의 토큰 usage와 providerMetadata(AI Gateway 같은 Provider가 호출별 비용을 보고하는 위치)를 받습니다. 따라서 앱은 Observer/Reflector Model을 미들웨어로 래핑하지 않고도 OM Model 비용을 계산할 수 있습니다. 실패한 비동기 버퍼링 주기는 예외를 발생시키지 않으며 종료 훅의 error 필드를 통해 보고됩니다. 이러한 훅에서 발생한 오류는 포착되어 기록되며 주기를 실패하게 하지 않습니다. **observation** (`ObservationalMemoryObservationConfig`): 관찰 단계의 구성입니다. Observer Agent가 실행되는 시점과 동작 방식을 제어합니다. **observation.model** (`string | LanguageModel | DynamicModel | ModelByInputTokens | ModelWithRetries[]`): Observer Agent에 사용할 Model입니다. 최상위 model도 제공된 경우에는 설정할 수 없습니다. 이 항목과 최상위 model을 모두 설정하지 않으면 reflection.model을 사용합니다. **observation.instruction** (`string`): Observer의 시스템 Prompt에 추가되는 사용자 정의 지침입니다. 도메인별 선호 사항이나 우선순위 등 Observer가 집중할 대상을 사용자 정의하는 데 사용합니다. **observation.threadTitle** (`boolean`): true이면 Observer가 짧은 스레드 제목을 제안하고 대화 주제가 의미 있게 변경될 때 스레드 제목을 업데이트합니다. 명시적으로 활성화해야 하며 기본적으로 비활성화되어 있습니다. **observation.extract** (`Extractor[]`): 관찰 후 추출할 사용자 정의 값입니다. 스키마가 없는 추출기는 Observer 출력에서 인라인으로 요청됩니다. 스키마 기반 추출기는 후속 구조화 출력 호출로 실행되며 스레드 OM 메타데이터에 저장됩니다. **observation.manageWorkingMemory** (`boolean`): Observer가 OM 추출을 통해 작업 Memory를 관리하도록 합니다. WorkingMemoryExtractor를 추가하고 workingMemory.agentManaged의 기본값을 false로, workingMemory.useStateSignals의 기본값을 true로 설정합니다. 작업 Memory 업데이트를 참조하세요. **observation.observeAttachments** (`'auto' | boolean | string[]`): 자리 표시자 텍스트 행과 함께 Observer Model로 전달할 이미지/파일 첨부 파일을 제어합니다. true(기본값)는 모든 첨부 파일을 전달합니다. false는 자리 표시자는 계속 표시하면서 모든 첨부 파일을 제외합니다. 'auto'는 Provider 기능 레지스트리를 사용하여 결정합니다. Observer Model이 멀티모달 입력을 지원하면 첨부 파일을 전달하고, 그렇지 않으면 제외하며, 해당 Model의 기능 데이터가 없으면 전달합니다. 배열은 대소문자를 구분하지 않는 mimeType 허용 목록으로, 정확한 일치('application/pdf'), 와일드카드 하위 유형('image/\*'), 모든 항목을 나타내는 단독 '\*'를 지원합니다. 기본 Agent는 멀티모달 Model을 사용하지만 Observer Model은 텍스트 전용인 경우(예: 일부 DeepSeek 엔드포인트)에 유용합니다. Tool 결과의 첨부 파일도 같은 규칙으로 필터링됩니다. **observation.messageTokens** (`number`): 관찰을 트리거하는 미관찰 메시지의 토큰 수입니다. 미관찰 메시지 토큰이 이 임계값을 초과하면 Observer Agent가 호출됩니다. 텍스트는 tokenx를 사용해 로컬에서 추정합니다. 가능한 경우 Model을 고려한 휴리스틱으로 이미지 파트를 포함하며, 이미지 메타데이터가 불완전하면 결정론적 대체 방식을 사용합니다. 업로드가 파일로 정규화된 경우 이미지 계열 file 파트도 같은 방식으로 계산됩니다. **observation.maxTokensPerBatch** (`number`): 리소스 범위에서 여러 스레드를 관찰할 때 배치당 최대 토큰 수입니다. 스레드는 이 크기의 배치로 나뉘어 병렬 처리됩니다. 값이 낮을수록 병렬 처리는 늘어나지만 API 호출 수도 증가합니다. **observation.modelSettings** (`ObservationalMemoryModelSettings`): Observer Agent의 Model 설정입니다. maxOutputTokens: 100\_000 기본값은 기본 Model 선택(Model 미설정, "default" 또는 ModelByInputTokens 선택기)에만 적용됩니다. 사용자 정의 Model에는 maxOutputTokens 기본값이 적용되지 않습니다. **observation.modelSettings.temperature** (`number`): 생성을 위한 temperature입니다. 값이 낮을수록 더 일관된 출력이 생성됩니다. **observation.modelSettings.maxOutputTokens** (`number`): 최대 출력 토큰 수입니다. 관찰 내용이 잘리는 것을 방지하려면 높은 값으로 설정합니다. 100000 기본값은 기본 Model 선택에만 적용되며, 사용자 정의 Model에는 기본값이 없습니다. **observation.providerOptions** (`ProviderOptions`): Google 사고 구성과 같이 Observer Agent에 전달되는 Provider별 옵션입니다. **observation.bufferTokens** (`number | false`): 백그라운드 관찰 버퍼링의 실행 빈도입니다. 0과 1 사이의 값은 messageTokens의 비율입니다. 0.25는 임계값의 25%마다 버퍼링합니다(기본값 30k에서 7.5k 토큰). 1 이상의 값은 절대 토큰 수입니다. 5000은 5k 토큰마다 버퍼링합니다. 버퍼링된 관찰 내용은 messageTokens 임계값에 도달할 때까지 저장되었다가 차단형 LLM 호출 없이 즉시 활성화됩니다. 결과 값은 messageTokens보다 작아야 합니다. 모든 비동기 버퍼링(관찰 및 성찰 모두)을 비활성화하려면 false로 설정합니다. **observation.bufferOnIdle** (`boolean`): Agent 턴이 종료되고 Agent가 유휴 상태가 될 때 백그라운드 관찰 버퍼링을 실행합니다. 이는 단계 실행 중 비동기 버퍼링을 제어하는 bufferTokens와 별개입니다. 다음 턴이나 messageTokens 임계값을 기다리지 않고 짧은 유휴 턴을 버퍼링하려면 true로 설정합니다. **observation.bufferActivation** (`number`): 버퍼링된 관찰 내용이 활성화될 때 메시지 창에서 제거할 양입니다. 0과 1 사이의 값은 제거할 messageTokens의 비율입니다. 0.8은 메시지 기록의 약 80%를 제거하고 약 20%를 유지합니다(기본값 30k에서 6k 토큰). 1000 이상의 값은 유지할 토큰 수입니다. 4000은 활성화 후 메시지 토큰 약 4k를 유지합니다. 방향이 반대라는 점에 유의하세요. 비율이 높을수록 기록을 더 많이 제거하지만, 토큰 수가 높을수록 더 많이 유지합니다. **observation.activateAfterIdle** (`number | string | false | "auto"`): 비활성 상태가 된 후 버퍼링된 관찰 내용을 강제로 활성화하기까지의 시간입니다. 밀리초, 기간 문자열, Provider를 고려한 Prompt 캐시 TTL을 사용하는 "auto" 또는 false를 받습니다. 설정하지 않으면 관찰에 최상위 activateAfterIdle 값이 사용됩니다. 관찰에서 최상위 유휴 설정을 비활성화하려면 false로 설정합니다. 현재 독립 실행형 ObservationalMemory 클래스를 사용할 때만 적용됩니다. new Memory(...)는 최상위 activateAfterIdle만 적용합니다. **observation.activateOnProviderChange** (`boolean`): 행위자의 Provider 또는 Model이 변경될 때 버퍼링된 관찰 내용을 강제로 활성화합니다. 설정하지 않으면 관찰에 최상위 activateOnProviderChange 값이 사용됩니다. 현재 독립 실행형 ObservationalMemory 클래스를 사용할 때만 적용됩니다. new Memory(...)는 최상위 activateOnProviderChange만 적용합니다. **observation.blockAfter** (`number`): 백그라운드 버퍼링이 처리 속도를 따라가지 못할 때 동기식(차단) 관찰을 강제하는 안전장치입니다. 1 이상 100 미만의 값은 messageTokens의 배수입니다. 1.2는 임계값의 120%에서 차단 관찰을 강제합니다(기본값 30k일 때 36k 토큰). 100 이상의 값은 절대 토큰 수이며 messageTokens보다 커야 합니다. messageTokens와 blockAfter 사이에서는 비동기 버퍼링과 활성화만 실행됩니다. 버퍼링된 항목을 활성화할 때도 최소 잔여 컨텍스트(1000토큰과 보존 하한 중 더 작은 값)가 유지됩니다. bufferTokens가 설정된 경우에만 관련됩니다. 비동기 버퍼링이 활성화되면 기본값은 1.2입니다. **observation.previousObserverTokens** (`number | false`): Observer의 이전 관찰 컨텍스트에 사용할 선택적 토큰 예산입니다. 숫자로 설정하면 Observer Agent에 전달되는 관찰의 뒷부분을 잘라 이 예산에 맞추되, 최신 관찰을 유지하고 가능한 경우 강조된 🔴 항목을 보존합니다. 버퍼링된 반영이 대기 중이면 자르기 전에 이미 반영된 관찰 줄이 반영 요약으로 자동 대체됩니다. 이전 관찰을 완전히 제외하려면 0으로 설정하고, 자르기를 명시적으로 비활성화하려면 false로 설정합니다. **reflection** (`ObservationalMemoryReflectionConfig`): 반영 단계의 구성입니다. Reflector Agent가 실행되는 시점과 동작 방식을 제어합니다. **reflection.model** (`string | LanguageModel | DynamicModel | ModelByInputTokens | ModelWithRetries[]`): Reflector Agent에 사용할 Model입니다. 최상위 model도 제공된 경우에는 설정할 수 없습니다. 이 항목과 최상위 model이 모두 설정되지 않으면 observation.model을 사용합니다. **reflection.instruction** (`string`): Reflector의 시스템 Prompt에 추가되는 사용자 지정 지침입니다. 특정 정보 유형의 우선순위를 지정하는 등 Reflector가 관찰을 통합하는 방식을 맞춤 설정할 때 사용합니다. **reflection.extract** (`Extractor[]`): 반영 후 추출할 사용자 지정 값입니다. 스키마가 없는 추출기는 Reflector 출력 내에서 요청됩니다. 스키마 기반 추출기는 후속 구조화 출력 호출로 실행되며 스레드 OM 메타데이터에 저장됩니다. **reflection.observationTokens** (`number`): 반영을 트리거하는 관찰의 토큰 수입니다. 관찰 토큰이 이 임계값을 초과하면 Reflector Agent를 호출해 관찰을 압축합니다. **reflection.modelSettings** (`ObservationalMemoryModelSettings`): Reflector Agent의 Model 설정입니다. maxOutputTokens: 100\_000 기본값은 기본 Model 선택(Model 미설정, "default" 또는 ModelByInputTokens 선택기)에만 적용됩니다. 사용자 지정 Model에는 maxOutputTokens 기본값이 적용되지 않습니다. **reflection.modelSettings.temperature** (`number`): 생성에 사용할 temperature입니다. 값이 낮을수록 더 일관된 출력이 생성됩니다. **reflection.modelSettings.maxOutputTokens** (`number`): 최대 출력 토큰 수입니다. 관찰이 잘리지 않도록 높은 값으로 설정하세요. 100000 기본값은 기본 Model 선택에만 적용되며, 사용자 지정 Model에는 기본값이 없습니다. **reflection.providerOptions** (`ProviderOptions`): Google 사고 구성과 같이 Reflector Agent에 전달되는 Provider별 옵션입니다. **reflection.bufferActivation** (`number`): 백그라운드 반영이 시작되는 시점을 observationTokens의 비율(0\~1)로 지정합니다. 0.5는 관찰이 임계값의 50%에 도달하면 백그라운드 반영을 시작합니다(기본값 40k일 때 20k 토큰). 전체 임계값에 도달하면 버퍼링된 반영이 해당 범위의 관찰을 대체하며, 그 범위 뒤에 추가된 새 관찰은 보존됩니다. **reflection.activateAfterIdle** (`number | string | false | "auto"`): 비활성 상태가 된 후 버퍼링된 반영을 강제로 활성화하기까지의 시간입니다. 밀리초, 기간 문자열, Provider를 인식하는 Prompt 캐시 TTL을 사용하는 "auto", 또는 false를 허용합니다. 반영은 최상위 activateAfterIdle을 상속하지 않습니다. 유휴 활성화에 반영을 포함하려면 이를 명시적으로 설정하세요. 현재 독립 실행형 ObservationalMemory 클래스를 사용할 때만 적용되며, new Memory(...)를 통해 사용할 때는 이 설정이 적용되지 않습니다. **reflection.activateOnProviderChange** (`boolean`): 행위자의 Provider 또는 Model이 변경될 때 버퍼링된 반영을 강제로 활성화합니다. 반영은 최상위 activateOnProviderChange를 상속하지 않습니다. Provider 변경 시 활성화에 반영을 포함하려면 이를 명시적으로 설정하세요. 현재 독립 실행형 ObservationalMemory 클래스를 사용할 때만 적용되며, new Memory(...)를 통해 사용할 때는 이 설정이 적용되지 않습니다. **reflection.blockAfter** (`number`): 백그라운드 반영이 처리 속도를 따라가지 못할 때 동기식(차단) 반영을 강제하는 안전장치입니다. 1 이상 100 미만의 값은 observationTokens의 배수입니다. 1.2는 임계값의 120%에서 차단 반영을 강제합니다(기본값 40k일 때 48k 토큰). 100 이상의 값은 절대 토큰 수이며 observationTokens보다 커야 합니다. observationTokens와 blockAfter 사이에서는 비동기 버퍼링과 활성화만 실행됩니다. bufferActivation이 설정된 경우에만 관련됩니다. 비동기 반영이 활성화되면 기본값은 1.2입니다. ### 토큰 추정 메타데이터 캐시 OM은 토큰 페이로드 추정을 유지하므로 반복 계산으로 이전 토큰 추정 작업을 재사용할 수 있습니다. - 파트 수준 캐시: `part.providerMetadata.mastra`. - 문자열 콘텐츠 대체 캐시: 파트가 없을 때의 메시지 수준 메타데이터입니다. - 캐시 버전 또는 토크나이저 소스가 일치하지 않으면 캐시 항목을 무시하고 다시 계산합니다. - 메시지별 및 대화별 오버헤드는 항상 런타임에 다시 계산되며 캐시되지 않습니다. - `data-*` 및 `reasoning` 파트는 건너뛰며 캐시 항목이 생성되지 않습니다. ## 추출기 API `Extractor`는 관찰 또는 반영 중에 OM이 추출해야 하는 값을 정의합니다. `current-task`, `suggested-response`, `thread-title` 같은 기본 제공 OM 값도 사용자 지정 값과 동일한 추출기 파이프라인을 사용합니다. ```typescript import { Memory, Extractor } from '@mastra/memory' import { z } from 'zod' const memory = new Memory({ options: { observationalMemory: { model: 'openai/gpt-5-mini', observation: { extract: [ new Extractor({ name: 'User profile', instructions: 'Extract stable user profile facts that should be remembered.', schema: z.object({ name: z.string().optional(), timezone: z.string().optional(), }), }), ], }, }, }, }) ``` **name** (`string`): 사람이 읽을 수 있는 추출기 이름입니다. OM은 이 값을 슬러그화하여 추출기 슬러그를 만듭니다. 슬러그 생성 후의 이름은 고유해야 합니다. **slug** (`string`): name에서 파생되는 읽기 전용 속성이며 생성자 옵션이 아닙니다. 영구 저장 값과 XML 태그에 사용되는 안정적인 식별자입니다. 슬러그에는 소문자, 숫자, 하이픈을 사용합니다. 사용자 지정 추출기에서는 기본 제공 슬러그와 예약된 XML 태그를 사용할 수 없습니다. **instructions** (`string | (context) => string`): 추출할 항목과 값을 업데이트할 시점에 관한 지침입니다. 런타임 컨텍스트에서 지침을 파생하려면 함수를 사용하세요. **schema** (`ZodType | (context) => ZodType | undefined`): 구조화 추출을 위한 선택적 Zod 스키마입니다. 제공하면 OM은 기본 OM 작업 후 후속 구조화 출력 호출을 실행합니다. 생략하면 추출기는 Observer 또는 Reflector 응답에서 출력되는 인라인 문자열 추출기가 됩니다. 런타임 컨텍스트에서 스키마를 파생하려면 함수를 사용하세요. **includePreviousExtraction** (`boolean`): 향후 OM 실행에서 이전 추출 결과를 추출기에 표시할지 제어합니다. 현재 OM 실행에서만 가져와야 하는 값에는 false로 설정하세요. (Default: `true`) **metadataKeyPath** (`string | false`): 추출된 값을 영구 저장하는 데 사용되는 점으로 구분된 OM 메타데이터 경로입니다. OM 메타데이터에 전혀 저장하지 않으려면 false로 설정하세요. (Default: `'extracted.'`) **onExtracted** (`(context) => T | void | Promise`): 사용자 지정 추출기가 값을 반환한 후, 메타데이터에 저장하기 전에 호출되는 선택적 훅입니다. 값을 반환하면 추출된 값이 대체됩니다. 예외를 발생시키면 추출 실패가 기록됩니다. ### 추출 동작 - 추출된 값은 스레드 OM 메타데이터의 `om.extracted`에 저장됩니다. - 기본 제공 추출기 값은 호환성 메타데이터 필드인 `currentTask`, `suggestedResponse`, `threadTitle`에도 미러링됩니다. - `thread-title`은 `observation.threadTitle`이 활성화된 경우에만 스레드 제목을 업데이트합니다. - `observation.extract`는 관찰 중에 실행됩니다. `reflection.extract`는 반영 중에 실행됩니다. - 스키마 기반 추출기는 후속 구조화 출력 요청을 추가합니다. - 스키마가 없는 추출기는 Observer 또는 Reflector 출력에서 직접 출력되는 인라인 문자열 추출기입니다. - 동적 추출기 함수는 사용 가능한 경우 `source`, `threadId`, `resourceId`, `mainAgent`, `memory`, `requestContext`를 포함한 런타임 컨텍스트를 받습니다. - `WorkingMemoryExtractor`는 활성 `Memory` 인스턴스를 통해 작업 Memory를 업데이트하는 데 일반 추출기 파이프라인을 사용합니다. 작업 Memory에 JSON 스키마가 있으면 구조화 추출을 사용하고 OM 메타데이터 저장을 건너뛰므로 작업 Memory 페이로드가 OM 추출 메타데이터 아래에 중복되지 않습니다. - `observationalMemory.observation.manageWorkingMemory`는 `WorkingMemoryExtractor`를 추가하고 `workingMemory.agentManaged`의 기본값을 `false`로 설정합니다. 작업 Memory가 활성화되면 `workingMemory.useStateSignals`의 기본값을 `true`로 설정합니다. - 추출 실패는 OM 마커 데이터에 보고되며 성공한 다른 추출 값은 삭제되지 않습니다. ## 예 ### 작업 기억 업데이트 OM이 작업 Memory를 업데이트해야 할 때는 `observationalMemory.observation.manageWorkingMemory`를 사용하세요. ```typescript import { Memory } from '@mastra/memory' const memory = new Memory({ options: { workingMemory: { enabled: true, }, observationalMemory: { enabled: true, observation: { manageWorkingMemory: true, }, }, }, }) ``` 기본 Agent가 작업 Memory Tool과 지침 삽입을 계속 받아야 한다면 `workingMemory.agentManaged: true`로 설정하세요. ### 사용자 정의 임계값이 있는 리소스 범위(실험적) ```typescript import { Memory } from '@mastra/memory' import { Agent } from '@mastra/core/agent' export const agent = new Agent({ id: 'my-agent', name: 'my-agent', instructions: 'You are a helpful assistant.', model: 'openai/gpt-5-mini', memory: new Memory({ options: { observationalMemory: { model: 'google/gemini-2.5-flash', scope: 'resource', observation: { messageTokens: 20_000, }, reflection: { observationTokens: 60_000, }, }, }, }), }) ``` ### 공유 토큰 예산 `shareTokenBudget`이 활성화되면 총예산은 `observation.messageTokens + reflection.observationTokens`입니다(이 예제에서는 100k). 관찰이 30k 토큰만 사용하면 메시지는 최대 70k까지 확장할 수 있습니다. 메시지가 짧으면 반영을 트리거하기 전까지 관찰에 더 많은 여유가 생깁니다. ```typescript import { Memory } from '@mastra/memory' import { Agent } from '@mastra/core/agent' export const agent = new Agent({ id: 'my-agent', name: 'my-agent', instructions: 'You are a helpful assistant.', model: 'openai/gpt-5-mini', memory: new Memory({ options: { observationalMemory: { shareTokenBudget: true, observation: { messageTokens: 20_000, bufferTokens: false, // required when using shareTokenBudget (temporary limitation) }, reflection: { observationTokens: 80_000, }, }, }, }), }) ``` ### 맞춤형 Model 구성에 `model`을 전달하면 Mastra의 Model 라우터에서 제공하는 모든 Model을 사용할 수 있습니다. ```typescript import { Memory } from '@mastra/memory' import { Agent } from '@mastra/core/agent' export const agent = new Agent({ id: 'my-agent', name: 'my-agent', instructions: 'You are a helpful assistant.', model: 'openai/gpt-5.6-sol', memory: new Memory({ options: { observationalMemory: { model: 'openai/gpt-5-mini', }, }, }), }) ``` ### Agent마다 다른 Model ```typescript import { Memory } from '@mastra/memory' import { Agent } from '@mastra/core/agent' export const agent = new Agent({ id: 'my-agent', name: 'my-agent', instructions: 'You are a helpful assistant.', model: 'openai/gpt-5.6-sol', memory: new Memory({ options: { observationalMemory: { observation: { model: 'google/gemini-2.5-flash', }, reflection: { model: 'openai/gpt-5-mini', }, }, }, }), }) ``` ### 맞춤 지침 사용자 지정 지침을 제공하여 Observer 및 Reflector가 중점을 두는 항목을 사용자 지정하세요. ```typescript import { Memory } from '@mastra/memory' import { Agent } from '@mastra/core/agent' export const agent = new Agent({ id: 'health-assistant', name: 'health-assistant', instructions: 'You are a health and wellness assistant.', model: 'openai/gpt-5.6-sol', memory: new Memory({ options: { observationalMemory: { model: 'google/gemini-2.5-flash', observation: { // Focus observations on health-related preferences and goals instruction: 'Prioritize capturing user health goals, dietary restrictions, exercise preferences, and medical considerations. Avoid capturing general chit-chat.', }, reflection: { // Guide reflection to consolidate health patterns instruction: 'When consolidating, group related health information together. Preserve specific metrics, dates, and medical details.', }, }, }, }), }) ``` ### 비동기 버퍼링 비동기 버퍼링은 **기본적으로 활성화됩니다**. 대화가 길어짐에 따라 백그라운드에서 관찰을 미리 계산합니다. `messageTokens` 임계값에 도달하면 차단 LLM 호출 없이 버퍼링된 관찰이 즉시 활성화됩니다. 수명 주기는 **버퍼링 → 활성화 → 메시지 제거 → 반복**입니다. 백그라운드 Observer 호출은 `bufferTokens` 간격으로 실행되며, 호출할 때마다 관찰 청크를 생성합니다. 임계값에 도달하면 청크가 활성화됩니다. 관찰은 로그로 이동하고 원시 메시지는 컨텍스트에서 제거됩니다. 버퍼링이 처리 속도를 따라가지 못하면 `blockAfter` 임계값이 동기식 대체 처리를 강제합니다. 기본 설정: - `observation.bufferTokens: 0.2`: `messageTokens`의 20%마다 버퍼링합니다(예: 임계값이 30k이면 약 6k 토큰마다). - `observation.bufferActivation: 0.8`: 활성화 시 임계값의 20%만 남도록 충분한 메시지를 제거합니다. - 버퍼링된 관찰에는 활성화 후에도 유지되어 대화의 연속성을 보존하는 연속성 힌트(`suggestedResponse`, `currentTask`)가 포함됩니다. - `reflection.bufferActivation: 0.5`: 관찰 임계값의 50%에서 백그라운드 반영을 시작합니다. 사용자 정의하려면: ```typescript import { Memory } from '@mastra/memory' import { Agent } from '@mastra/core/agent' export const agent = new Agent({ id: 'my-agent', name: 'my-agent', instructions: 'You are a helpful assistant.', model: 'openai/gpt-5-mini', memory: new Memory({ options: { observationalMemory: { model: 'google/gemini-2.5-flash', observation: { messageTokens: 30_000, // Buffer every 5k tokens (runs in background) bufferTokens: 5_000, // Activate to retain 30% of threshold bufferActivation: 0.7, // Force synchronous observation at 1.5x threshold blockAfter: 1.5, }, reflection: { observationTokens: 60_000, // Start background reflection at 50% of threshold bufferActivation: 0.5, // Force synchronous reflection at 1.2x threshold blockAfter: 1.2, }, }, }, }), }) ``` 비동기 버퍼링을 완전히 비활성화하려면: ```typescript observationalMemory: { model: "google/gemini-2.5-flash", observation: { bufferTokens: false, }, } ``` `bufferTokens: false`로 설정하면 관찰과 반영의 비동기 버퍼링이 모두 비활성화됩니다. 관찰과 반영은 각각의 임계값에 도달하면 동기식으로 실행됩니다. > **노트:** 비동기 버퍼링은 `scope: 'resource'`를 지원하지 않으며 리소스 범위에서는 자동으로 비활성화됩니다. ## 스트리밍 데이터 부분 관찰 Memory는 Agent 실행 중에 클라이언트가 실시간 UI 피드백에 사용할 수 있는 형식화된 데이터 부분을 내보냅니다. 이는 Agent의 응답과 함께 스트리밍됩니다. ### 추출기 결과 읽기 두 완료 이벤트 모두 `data` 페이로드에 추출기 출력을 전달합니다. 추출기 필드는 다음과 같습니다. ```typescript interface DataOmObservationEndPart { type: 'data-om-observation-end' data: { /** Whether the completed work was an observation or reflection */ operationType: 'observation' | 'reflection' /** Values extracted during this OM operation, keyed by extractor slug */ extractedValues?: Record /** Extractor failures from this OM operation. Successful extractor values are still included */ extractionFailures?: Array<{ slug: string; error: string }> // ...other fields documented in the tables below } } ``` 두 추출기 필드는 모두 선택 사항입니다. 완료 데이터에는 값, 실패, 둘 다 포함되거나 어느 쪽도 포함되지 않을 수 있습니다. `data-om-observation-end`는 동기식 완료를 보고합니다. `data-om-buffering-end`는 완료되었지만 버퍼링된 콘텐츠가 아직 활성화를 기다리는 백그라운드 작업을 보고합니다. 단, 추출기 메타데이터는 이미 저장된 상태입니다. `DataOmBufferingEndPart`는 동일한 추출기 필드를 포함하며 두 타입 모두 `@mastra/memory/processors`에서 내보냅니다. 소비자 예제는 [스트림에서 추출된 값 읽기](https://mastra.zisheng.pro/ko/docs/memory/observational-memory)를 참조하세요. ### `data-om-status` Model 생성 전에 Agent 루프 단계당 한 번 방출됩니다. 컨텍스트 창과 비동기 버퍼링된 콘텐츠의 상태에 대한 토큰 사용을 포함하여 현재 Memory 상태의 스냅샷을 제공합니다. ```typescript interface DataOmStatusPart { type: 'data-om-status' data: { windows: { active: { /** Unobserved message tokens and the threshold that triggers observation */ messages: { tokens: number; threshold: number } /** Observation tokens and the threshold that triggers reflection */ observations: { tokens: number; threshold: number } } buffered: { observations: { /** Number of buffered chunks staged for activation */ chunks: number /** Total message tokens across all buffered chunks */ messageTokens: number /** Projected message tokens that would be removed if activation happened now (based on bufferActivation ratio and chunk boundaries) */ projectedMessageRemoval: number /** Observation tokens that will be added on activation */ observationTokens: number /** idle: no buffering in progress. running: background observer is working. complete: chunks are ready for activation. */ status: 'idle' | 'running' | 'complete' } reflection: { /** Observation tokens that were fed into the reflector (pre-compression size) */ inputObservationTokens: number /** Observation tokens the reflection will produce on activation (post-compression size) */ observationTokens: number /** idle: no reflection buffered. running: background reflector is working. complete: reflection is ready for activation. */ status: 'idle' | 'running' | 'complete' } } } recordId: string threadId: string stepNumber: number /** Increments each time the Reflector creates a new generation */ generationCount: number } } ``` `buffered.reflection.inputObservationTokens`는 Reflector로 전송된 관찰의 크기입니다. `buffered.reflection.observationTokens`는 압축 결과, 즉 반영이 활성화될 때 해당 관찰을 대체할 콘텐츠의 크기입니다. 클라이언트는 이 두 값을 사용해 압축률을 표시할 수 있습니다. 클라이언트는 원시 값에서 백분율과 활성화 후 추정치를 도출할 수 있습니다. ```typescript // Message window usage % const msgPercent = status.windows.active.messages.tokens / status.windows.active.messages.threshold // Observation window usage % const obsPercent = status.windows.active.observations.tokens / status.windows.active.observations.threshold // Projected message tokens after buffered observations activate // Uses projectedMessageRemoval which accounts for bufferActivation ratio and chunk boundaries const postActivation = status.windows.active.messages.tokens - status.windows.buffered.observations.projectedMessageRemoval // Reflection compression ratio (when buffered reflection exists) const { inputObservationTokens, observationTokens } = status.windows.buffered.reflection if (inputObservationTokens > 0) { const compressionRatio = observationTokens / inputObservationTokens } ``` ### `data-om-observation-start` Observer 또는 Reflector Agent가 처리를 시작할 때 발생합니다. **cycleId** (`string`): 이 주기의 고유 ID입니다. 시작/종료/실패 마커에서 공유됩니다. **operationType** (`'observation' | 'reflection'`): 관찰 작업인지 반영 작업인지 나타냅니다. **startedAt** (`string`): ISO timestamp when processing started. **tokensToObserve** (`number`): Message tokens (input) being processed in this batch. **recordId** (`string`): The OM record ID. **threadId** (`string`): This thread's ID. **threadIds** (`string[]`): All thread IDs in this batch (for resource-scoped). **config** (`ObservationMarkerConfig`): 관찰 시점의 messageTokens, observationTokens, scope 스냅샷입니다. ### `data-om-observation-end` 관찰이나 반영이 성공적으로 완료되면 발생합니다. **cycleId** (`string`): Matches the corresponding start marker. **operationType** (`'observation' | 'reflection'`): Type of operation that completed. **completedAt** (`string`): ISO timestamp when processing completed. **durationMs** (`number`): Duration in milliseconds. **tokensObserved** (`number`): Message tokens (input) that were processed. **observationTokens** (`number`): Observer가 압축한 후 생성된 관찰 토큰(출력)입니다. **observations** (`string`): The generated observations text. **currentTask** (`string`): Current task extracted by the Observer. **suggestedResponse** (`string`): Observer가 추출한 추천 응답입니다. **extractedValues** (`Record`): 이 OM 작업 중 추출된 값으로, 추출기 슬러그를 키로 사용합니다. **extractionFailures** (`Array<{ slug: string; error: string }>`): 이 OM 작업에서 발생한 추출기 실패입니다. 성공한 추출기 값은 계속 포함됩니다. **recordId** (`string`): The OM record ID. **threadId** (`string`): This thread's ID. ### `data-om-observation-failed` 관찰이나 반영이 실패할 때 발생합니다. 시스템은 동기 처리로 대체됩니다. **cycleId** (`string`): Matches the corresponding start marker. **operationType** (`'observation' | 'reflection'`): Type of operation that failed. **failedAt** (`string`): ISO timestamp when the failure occurred. **durationMs** (`number`): Duration until failure in milliseconds. **tokensAttempted** (`number`): Message tokens (input) that were attempted. **error** (`string`): Error message. **observations** (`string`): 표시할 수 있는 부분 콘텐츠입니다. **recordId** (`string`): The OM record ID. **threadId** (`string`): This thread's ID. ### `data-om-buffering-start` 비동기 버퍼링이 백그라운드에서 시작될 때 발생합니다. 버퍼링은 기본 임계값에 도달하기 전에 관찰 또는 반사를 미리 계산합니다. **cycleId** (`string`): Unique ID for this buffering cycle. **operationType** (`'observation' | 'reflection'`): Type of operation being buffered. **startedAt** (`string`): ISO timestamp when buffering started. **tokensToBuffer** (`number`): Message tokens (input) being buffered in this cycle. **recordId** (`string`): The OM record ID. **threadId** (`string`): This thread's ID. **threadIds** (`string[]`): All thread IDs being buffered (for resource-scoped). **config** (`ObservationMarkerConfig`): Snapshot of config at buffering time. ### `data-om-buffering-end` 비동기 버퍼링이 완료되면 발생합니다. 콘텐츠가 저장되었지만 아직 기본 컨텍스트에서 활성화되지 않았습니다. **cycleId** (`string`): Matches the corresponding buffering-start marker. **operationType** (`'observation' | 'reflection'`): 버퍼링된 작업의 유형입니다. **completedAt** (`string`): ISO timestamp when buffering completed. **durationMs** (`number`): Duration in milliseconds. **tokensBuffered** (`number`): Message tokens (input) that were buffered. **bufferedTokens** (`number`): Observer가 압축한 후의 관찰 토큰(출력)입니다. **observations** (`string`): The buffered content. **extractedValues** (`Record`): 이 버퍼링된 OM 작업 중 추출된 값으로, 추출기 슬러그를 키로 사용합니다. **extractionFailures** (`Array<{ slug: string; error: string }>`): 이 버퍼링된 OM 작업에서 발생한 추출기 실패입니다. 성공한 추출기 값은 계속 포함됩니다. **recordId** (`string`): The OM record ID. **threadId** (`string`): This thread's ID. ### `data-om-buffering-failed` 비동기 버퍼링이 실패할 때 발생합니다. 임계값에 도달하면 시스템은 동기 처리로 대체됩니다. **cycleId** (`string`): Matches the corresponding buffering-start marker. **operationType** (`'observation' | 'reflection'`): Type of operation that failed. **failedAt** (`string`): ISO timestamp when the failure occurred. **durationMs** (`number`): Duration until failure in milliseconds. **tokensAttempted** (`number`): Message tokens (input) that were attempted to buffer. **error** (`string`): Error message. **observations** (`string`): Any partial content. **recordId** (`string`): The OM record ID. **threadId** (`string`): This thread's ID. ### `data-om-activation` 버퍼링된 관찰 또는 반사가 활성화될 때 발생합니다(활성 컨텍스트 창으로 이동). 이는 즉각적인 작업입니다. LLM 통화가 필요하지 않습니다. **cycleId** (`string`): Unique ID for this activation event. **operationType** (`'observation' | 'reflection'`): Type of content activated. **activatedAt** (`string`): ISO timestamp when activation occurred. **chunksActivated** (`number`): Number of buffered chunks activated. **tokensActivated** (`number`): 활성화된 청크의 메시지 토큰(입력)입니다. 관찰 활성화 시에는 메시지 창에서 제거됩니다. 반영 활성화 시에는 압축된 관찰 토큰입니다. **observationTokens** (`number`): Resulting observation tokens after activation. **messagesActivated** (`number`): Number of messages that were observed via activation. **generationCount** (`number`): Current reflection generation count. **observations** (`string`): The activated observations text. **triggeredBy** (`'threshold' | 'ttl' | 'provider_change'`): 임계값 초과, activateAfterIdle 만료 또는 Model/Provider 변경 중 무엇이 활성화를 트리거했는지 나타냅니다. **lastActivityAt** (`number`): TTL 검사에 사용된 마지막 어시스턴트 메시지 파트의 Unix 밀리초 타임스탬프입니다. **ttlExpiredMs** (`number`): 활성화가 실행된 시점에 activateAfterIdle을 초과한 시간입니다. **previousModel** (`string`): 활성화를 트리거한 이전 어시스턴트 Model 식별자입니다(예: openai/gpt-4o). **currentModel** (`string`): 활성화를 트리거한 현재 행위자 Model 식별자입니다. **recordId** (`string`): The OM record ID. **threadId** (`string`): This thread's ID. **config** (`ObservationMarkerConfig`): Snapshot of config at activation time. ### `data-om-thread-update` Observer가 스레드 제목을 업데이트할 때 발생합니다. `observation.threadTitle`이 활성화된 경우에만 방출됩니다. **cycleId** (`string`): 이 관찰 주기의 고유 ID로, 관찰 마커와 공유됩니다. **threadId** (`string`): The thread ID that was updated. **oldTitle** (`string`): 이전 스레드 제목입니다. 스레드에 제목이 없었다면 undefined입니다. **newTitle** (`string`): The new thread title. **timestamp** (`string`): When this update occurred. ## 독립형 사용 대부분의 사용자는 위의 `Memory` 클래스를 사용하면 됩니다. `ObservationalMemory`를 직접 사용하는 방식은 주로 벤치마킹, 실험 또는 다른 프로세서([가드레일](https://mastra.zisheng.pro/ko/docs/agents/guardrails) 등)와 함께 프로세서 순서를 제어해야 할 때 유용합니다. `ObservationalMemory` 클래스는 엔진입니다. 이를 Agent에 연결하려면 `ObservationalMemoryProcessor`로 래핑해야 하며, 메시지를 불러오고 영구 저장하기 위한 `Memory` 인스턴스가 필요합니다. 스토리지 어댑터에서 `stores.memory`는 선택 사항으로 타입이 지정되어 있으므로 non-null 단언(또는 런타임 검사)이 필요합니다. ```typescript import { ObservationalMemory, ObservationalMemoryProcessor } from '@mastra/memory/processors' import { Memory } from '@mastra/memory' import { Agent } from '@mastra/core/agent' import { LibSQLStore } from '@mastra/libsql' const storage = new LibSQLStore({ id: 'my-storage', url: 'file:./memory.db', }) const memory = new Memory({ storage }) const om = new ObservationalMemory({ storage: storage.stores.memory!, memory, model: 'google/gemini-2.5-flash', scope: 'resource', observation: { messageTokens: 20_000, }, reflection: { observationTokens: 60_000, }, }) const omProcessor = new ObservationalMemoryProcessor(om, memory) export const agent = new Agent({ id: 'my-agent', name: 'my-agent', instructions: 'You are a helpful assistant.', model: 'openai/gpt-5-mini', inputProcessors: [omProcessor], outputProcessors: [omProcessor], }) ``` ### 독립형 구성 독립 실행형 `ObservationalMemory` 클래스는 위 `observationalMemory` 구성 객체와 동일한 모든 옵션에 더해 다음 옵션을 허용합니다. **storage** (`MemoryStorage`): 관찰을 영구 저장하기 위한 스토리지 어댑터입니다. MemoryStorage 인스턴스(MastraStorage.stores.memory에서 가져옴)여야 합니다. **onDebugEvent** (`(event: ObservationDebugEvent) => void`): 관찰 이벤트를 위한 디버그 콜백입니다. 관찰 관련 이벤트가 발생할 때마다 호출됩니다. 관찰 흐름을 디버깅하고 이해하는 데 유용합니다. **obscureThreadIds** (`boolean`): 활성화하면 관찰 컨텍스트에 포함하기 전에 스레드 ID를 해시합니다. 이렇게 하면 LLM이 스레드 식별자의 패턴을 인식하지 못합니다. Memory 클래스를 통해 리소스 범위를 사용할 때 자동으로 활성화됩니다. (Default: `false`) ## 리콜 Tool `retrieval`이 설정되면(truthy 값), Agent가 관찰 그룹 범위 뒤에 있는 원시 메시지를 페이지 단위로 탐색할 수 있도록 `recall` Tool이 등록됩니다. 기본적으로(범위가 `'resource'`인 경우) 이 Tool은 스레드 목록 조회(`mode: "threads"`), 다른 스레드 탐색(`threadId`), 스레드 간 검색을 지원합니다. `retrieval: { vector: true }`를 사용하면 의미론적 검색(`mode: "search"`)을 사용할 수 있습니다. Tool을 현재 스레드로만 제한하려면 `scope: 'thread'`로 설정하세요. 이 Tool은 Agent의 Tool 목록에 자동으로 추가됩니다. Mastra는 범위를 인식하는 사용 지침도 Agent의 컨텍스트에 삽입합니다. 리소스 범위에서 `vector: true`인 경우 이 지침은 `search`, `threads`, `messages` 간의 라우팅을 다루며, 검색 결과가 적합하지 않을 때 스레드 탐색으로 대체하는 방법도 포함합니다. `vector: true`가 없으면 지침은 `threads`와 `messages` 탐색만 다루므로 구성되지 않은 검색 모드를 사용하도록 Agent를 유도하지 않습니다. 리소스 범위 지침은 관찰 그룹이 아직 하나도 없을 때도 삽입되므로 Agent는 첫 메시지부터 다른 스레드를 탐색할 수 있습니다. 기본 제공 지침 뒤에 애플리케이션별 안내를 추가하려면 `retrieval: { instructions: '...' }`를 사용하세요. ### 매개변수 **mode** (`'messages' | 'threads' | 'search'`): 검색할 항목입니다. "messages"(기본값)는 메시지 기록을 페이지 단위로 탐색합니다. "threads"는 현재 사용자의 모든 스레드를 나열합니다. "search"는 모든 스레드에서 의미적 유사성으로 메시지를 찾습니다(벡터 스토어와 임베더 필요). (Default: `'messages'`) **query** (`string`): mode: "search"에 사용할 검색어입니다. 현재 사용자의 모든 스레드에서 이 텍스트와 의미적으로 유사한 메시지를 찾습니다. **cursor** (`string`): recall 쿼리의 기준점으로 사용할 메시지 ID입니다. 관찰 그룹 범위에서 시작 또는 종료 ID를 추출하세요(예: \_range: \startId:endId\\\_에서 startId 또는 endId 사용). 범위 문자열을 직접 전달하면 Tool은 올바른 ID를 추출하는 방법을 설명하는 힌트를 반환합니다. mode: "messages"에서 cursor와 threadId를 모두 생략하면 Tool은 anchor로 설정한 위치부터 현재 스레드를 탐색합니다. **threadId** (`string`): ID로 다른 스레드를 탐색하거나 활성 스레드에는 "current"를 전달합니다. 먼저 mode: "threads"를 사용해 스레드 ID를 찾으세요. cursor 없이 제공하면 스레드의 처음부터 읽기 시작합니다. **anchor** (`'start' | 'end'`): cursor 없이 mode: "messages"를 사용할 때 스레드의 시작(오래된 항목부터) 또는 끝(최신 항목부터)에서 페이지 탐색을 시작합니다. (Default: `'start'`) **page** (`number`): 페이지네이션 오프셋입니다. 메시지의 경우 양수는 커서에서 앞으로, 음수는 뒤로 페이지를 이동합니다. 스레드의 경우 페이지 번호입니다(0부터 시작). 메시지에서는 0을 1로 처리합니다. (Default: `1`) **limit** (`number`): 페이지당 반환할 최대 항목 수입니다. (Default: `20`) **detail** (`'low' | 'high'`): 메시지 파트별로 표시할 콘텐츠의 양을 제어합니다. 'low'는 잘린 텍스트와 Tool 이름을 위치 인덱스(\[p0], \[p1])와 함께 표시합니다. 'high'는 Tool 인수와 결과를 포함한 전체 콘텐츠를 표시하되, 호출당 하나의 파트로 제한하고 계속 탐색할 수 있는 힌트를 제공합니다. (Default: `'low'`) **partType** (`'text' | 'tool-call' | 'tool-result' | 'reasoning' | 'image' | 'file'`): 결과를 필터링하여 이 유형의 메시지 파트만 포함합니다. mode: "messages"에만 적용됩니다. **toolName** (`string`): 결과를 필터링하여 이 Tool 이름과 일치하는 tool-call 및 tool-result 파트만 포함합니다. mode: "messages"에만 적용됩니다. **partIndex** (`number`): 위치 인덱스로 단일 메시지 파트를 전체 세부 정보로 가져옵니다. 낮은 세부 정보의 recall에서 \[p1]에 흥미로운 파트가 표시된 경우, 모든 파트를 불러오지 않고 전체 콘텐츠를 보려면 partIndex: 1로 다시 호출하세요. **before** (`string`): mode: "threads"에만 사용합니다. 이 날짜 이전에 생성된 스레드로 필터링합니다. ISO 8601 형식(예: "2026-03-15", "2026-03-10T00:00:00Z")을 허용합니다. **after** (`string`): mode: "threads"에만 사용합니다. 이 날짜 이후에 생성된 스레드로 필터링합니다. ISO 8601 형식(예: "2026-03-01", "2026-03-10T00:00:00Z")을 허용합니다. ### 반품(메시지 모드) **messages** (`string`): 형식이 지정된 메시지 콘텐츠입니다. 형식은 detail 수준에 따라 달라집니다. **count** (`number`): 이 페이지의 메시지 수입니다. **cursor** (`string`): 이 쿼리에 사용된 커서 메시지 ID입니다. **page** (`number`): 반환된 페이지 번호입니다. **limit** (`number`): 이 쿼리에 사용된 제한값입니다. **detail** (`'low' | 'high'`): 이 쿼리에 사용된 세부 정보 수준입니다. **hasNextPage** (`boolean`): 이 페이지 뒤에 메시지가 더 있는지 나타냅니다. **hasPrevPage** (`boolean`): 이 페이지 앞에 메시지가 더 있는지 나타냅니다. **truncated** (`boolean`): 토큰 예산으로 인해 출력이 제한되면 존재하며 값은 true입니다. Agent는 페이지네이션하거나 partIndex를 사용해 남은 콘텐츠에 접근할 수 있습니다. **tokenOffset** (`number`): truncated가 true일 때 잘려 나간 대략적인 토큰 수입니다. ### 반환(스레드 모드) **threads** (`string`): 형식이 지정된 스레드 목록입니다. 각 스레드에는 제목, ID, 날짜가 표시됩니다. 현재 스레드는 ← current로 표시됩니다. **count** (`number`): 반환된 스레드 수입니다. **page** (`number`): 반환된 페이지 번호입니다. **hasMore** (`boolean`): 다음 페이지에 스레드가 더 있는지 나타냅니다. ### 반품(검색 모드) **results** (`string`): 스레드별로 그룹화되고 형식이 지정된 검색 결과입니다. 각 결과에는 스레드 제목, 스레드 ID, 관련성 점수, 메시지 미리 보기, 해당 스레드를 탐색하기 위한 커서 ID가 표시됩니다. **count** (`number`): 찾은 일치 메시지 수입니다. ### ModelByInputTokens `ModelByInputTokens`입력 토큰 수를 기반으로 Model을 선택합니다. 실제 입력 크기를 포괄하는 가장 작은 임계값에 대한 Model을 선택합니다. #### 건설자 ```typescript new ModelByInputTokens(config) ``` 여기서 `config`는 토큰 임계값(숫자)을 대상 Model에 매핑하는 `upTo` 키를 가진 객체입니다. #### 예 ```typescript import { ModelByInputTokens } from '@mastra/memory' const selector = new ModelByInputTokens({ upTo: { 10_000: 'google/gemini-2.5-flash', // Fast for small inputs 40_000: 'openai/gpt-5-mini', // Stronger for medium inputs 1_000_000: 'openai/gpt-5.6-sol', // Most capable for large inputs }, }) ``` #### 행동 - 임계값은 내부적으로 정렬되므로 구성 객체의 순서는 중요하지 않습니다. - `inputTokens ≤ smallest threshold` → 해당 임계값의 Model을 사용합니다. - `inputTokens > largest threshold` → `resolve()`가 오류를 발생시킵니다. OM Observer 또는 Reflector 실행 중에 이 문제가 발생하면 OM이 TripWire를 통해 중단되므로, 호출자는 일반 어시스턴트 응답 대신 빈 `text` 결과 또는 스트리밍된 `tripwire`를 받습니다. - OM은 Observer 또는 Reflector 호출의 입력 토큰 수를 계산하고 일치하는 Model 계층을 직접 확인합니다. #### 행동 양식 **resolve** (`(inputTokens: number) => MastraModelConfig`): 주어진 입력 토큰 수에 사용할 Model을 반환합니다. inputTokens가 구성된 가장 큰 임계값을 초과하면 오류를 발생시킵니다. OM 실행 중 이 문제가 발생하면 호출자는 일반 어시스턴트 응답 대신 TripWire/빈 텍스트 결과를 받습니다. **getThresholds** (`() => number[]`): 구성된 임계값을 오름차순으로 반환합니다. 내부 상태를 검사할 때 유용합니다. ### 관련된 - [관찰 기억](https://mastra.zisheng.pro/ko/docs/memory/observational-memory) - [Memory 개요](https://mastra.zisheng.pro/ko/docs/memory/overview) - [Memory 클래스](https://mastra.zisheng.pro/ko/reference/memory/memory-class) - [Memory 프로세서](https://mastra.zisheng.pro/ko/docs/memory/memory-processors) - [프로세서](https://mastra.zisheng.pro/ko/docs/agents/processors)