본문으로 건너뛰기

개요

세션이 끝나는 순간 어시스턴트가 모든 것을 잊어버립니다. 사용자가 이번 주에 자신의 이름을 알려줘도 다음 주에는 다시 묻습니다. memoryMiddleware가 이를 해결합니다. chat() 실행에 턴과 세션을 넘어 유지되는 메모리를 제공합니다.

두 단계로 작동합니다. 모델이 실행되기 전에 플러그형 어댑터에서 관련 메모리를 불러와 시스템 프롬프트에 추가합니다. 실행이 끝나면 해당 턴을 저장합니다. 저장은 지연되어 처리되므로 스트리밍을 차단하지 않습니다.

턴이나 세션을 넘어 내용을 불러와야 할 때 사용합니다. 동일한 요청에서 마지막 몇 개의 메시지만 유지하려면 messages에 전달하면 됩니다. 이 경우 메모리는 과합니다.

모든 기능은 @tanstack/ai-memory에 포함되어 있습니다. 미들웨어, 어댑터 계약, 내장 어댑터와 벤더 어댑터가 여기에 있습니다.

복사해 붙여 넣을 수 있는 설정이 필요하신가요? 빠른 시작을 참고하세요. 제공되지 않는 백엔드용 어댑터를 만들고 있나요? 사용자 지정 어댑터 가이드를 참고하세요.

언제 사용해야 하나요

필요한 기능사용할 항목
"지난주에 사용자가 알려준 내용을 기억합니다"영속 어댑터를 사용하는 메모리 미들웨어
"사용자마다 각자의 컨텍스트를 가집니다"범위가 지정된 어댑터를 사용하는 메모리 미들웨어
"호스팅된 메모리 서비스(mem0, Honcho, Hindsight)를 사용합니다"해당 벤더 어댑터
동일한 요청에서 마지막 몇 개의 턴을 유지합니다messages에 전달하고 메모리는 건너뜁니다

계약: 불러오기와 저장

메모리 어댑터에는 하나의 식별자와 두 개의 동작이 있습니다. 추출, 순위 지정, 렌더링, 저장은 모두 어댑터의 역할입니다. 미들웨어는 레코드 내부를 확인하지 않습니다.

멤버용도
id로그와 devtools에서 사용하는 안정적인 식별자입니다.
recall(scope, query)scope 내에서 query와 관련된 내용을 반환합니다. 렌더링된 systemPrompt, 선택적 fragments, 선택적 LLM toolstoolGuidance가 포함됩니다.
save(scope, turn)완료된 { user, assistant } 턴을 영속화합니다. 추출은 여기서 수행됩니다. 쓰기마다 하나의 SaveReceipt를 반환합니다.
inspect(scope)?선택 사항입니다. devtools 패널용 전체 스냅샷입니다.
listFacts(scope)?선택 사항입니다. devtools 패널용 평면 사실 목록입니다.
// The MemoryAdapter contract, from `@tanstack/ai-memory`:
import type { MemoryAdapter } from '@tanstack/ai-memory'

내장 어댑터는 각각 트리 셰이킹 가능한 서브 경로를 제공합니다.

import { inMemory } from '@tanstack/ai-memory/in-memory'
import { redis } from '@tanstack/ai-memory/redis'

벤더 어댑터입니다.

import { hindsight } from '@tanstack/ai-memory/hindsight'
import { mem0 } from '@tanstack/ai-memory/mem0'
import { honcho } from '@tanstack/ai-memory/honcho'

모든 어댑터와 옵션은 어댑터를 참고하세요.

턴의 흐름

  1. 불러오기는 모델보다 먼저, 실행의 init 단계에서 수행됩니다. adapter.recall(scope, userText)가 메모리를 반환하면 미들웨어가 systemPrompt, toolGuidance, 모든 tools를 실행에 추가합니다.
  2. 저장은 스트림이 끝난 후 ctx.defer를 통해 지연되어 수행되므로 응답을 차단하지 않습니다. 미들웨어는 { user, assistant } 턴을 adapter.save(scope, turn)에 전달합니다.

텔레메트리를 추가하거나, devtools에서 메모리를 확인하거나, 불러오지 않고 영속화하거나, 실패를 처리하려면 메모리 운영을 참고하세요.

범위와 보안

MemoryScope는 격리 경계입니다. @tanstack/ai의 공유 Scope 식별자 타입에 대한 별칭이며, 영속성에서 사용하는 것과 동일한 용어이므로 메모리와 채팅이 하나의 대화 키를 중심으로 작동합니다.

// MemoryScope is an alias of Scope from `@tanstack/ai`, exported by `@tanstack/ai-memory`:
type MemoryScope = {
threadId: string // required — same as ChatMiddlewareContext.threadId
userId?: string
tenantId?: string
namespace?: string // reserved — no adapter keys on it yet
}

서버에서는 신뢰할 수 있는 세션/인증 상태를 바탕으로 항상 범위를 확인해야 합니다. 클라이언트에서 시작된 threadId는 세션 사용자에게 속하는지 검증한 후에만 사용할 수 있으며, 요청 본문만으로 userId/tenantId를 절대 수락해서는 안 됩니다. scope의 함수 형식은 요청마다 실행되며 서버가 채팅 컨텍스트에 연결한 내용만 확인할 수 있습니다.

import { memoryMiddleware } from '@tanstack/ai-memory'
import type { MemoryAdapter } from '@tanstack/ai-memory'

declare const adapter: MemoryAdapter
declare function getSession(ctx: unknown): { threadId: string; userId: string }

memoryMiddleware({
adapter,
scope: (ctx) => {
const session = getSession(ctx) // your server-validated session
return { threadId: session.threadId, userId: session.userId }
},
})

다음 단계