본문으로 건너뛰기

어댑터

모든 어댑터는 동일한 recall/save 계약을 구현하므로 memoryMiddleware에서 서로 교체해 사용할 수 있습니다. 이 페이지는 각 어댑터의 옵션과 예시를 포함한 전체 옵션 참조입니다.

공통 옵션

inMemory()redis()는 모두 동일한 파이프라인을 기반으로 하는 클라이언트 측 랭커이므로 다음 옵션을 공유합니다.

옵션타입기본값용도
topKnumber6recall이 반환하는 최대 결과 수입니다.
minScorenumber0.15이 값보다 낮은 점수의 결과를 제외합니다.
kindsArray<MemoryKind>all다음 레코드 종류로 recall을 제한합니다 ('message', 'summary', 'fact', 'preference').
embedder{ embed(text): Promise<number[]> }none의미 기반 점수를 활성화합니다 (recallsave 모두에서 임베딩).
extract(turn, scope) => ExtractedFact[]none원시 턴과 함께 파생 사실을 save에서 영속화합니다.
render(hits) => string기본 제공프롬프트 렌더러를 대체합니다.

한 어댑터에 모든 옵션을 적용한 예시입니다.

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

// `embedText` stands in for your embedding client (OpenAI, Cohere, a local model).
declare function embedText(text: string): Promise<Array<number>>

const memory = inMemory({
topK: 8, // return up to 8 hits
minScore: 0.2, // ignore weak matches
kinds: ['message', 'fact', 'preference'], // skip summaries
embedder: { embed: embedText }, // semantic + lexical scoring
extract: (turn) => [
// store a derived fact in addition to the raw turn
{ text: `User said: ${turn.user}`, kind: 'fact', importance: 0.8 },
],
render: (hits) =>
// custom prompt block instead of the default renderer
`What I remember:\n${hits.map((h) => `- ${h.record.text}`).join('\n')}`,
})

**extract**는 ExtractedFact[]({ text, kind?, importance?, metadata? })를 반환합니다. 아무 작업도 하지 않을 때는 undefined를 반환합니다. 어댑터가 특정 모델에 직접 의존하지 않고 LLM 기반 사실 추출기를 연결하는 지점입니다.

**embedder**는 recall 경로에서 쿼리를 임베딩하기 위해 호출되고, 저장된 텍스트를 임베딩하기 위해 save에서 다시 호출됩니다. 이것이 없으면 점수는 어휘 및 최신성만 사용합니다.

inMemory()

의존성이 없고 Map을 기반으로 합니다. 위의 공통 옵션만 받습니다. 재시작하면 레코드가 사라지므로 개발, 테스트 및 단일 프로세스 데모에 사용합니다.

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

const memory = inMemory() // all options are optional

redis()

일반 Redis 어댑터입니다. 공통 옵션에 두 옵션을 추가하며 클라이언트가 필요합니다.

옵션타입기본값용도
redisRedisLike(필수)사용할 Redis 클라이언트입니다 (ioredis 또는 fromNodeRedis를 통한 node-redis).
prefixstring'tanstack-ai:memory'키 네임스페이스입니다.
import Redis from 'ioredis'
import { redis } from '@tanstack/ai-memory/redis'

const memory = redis({
redis: new Redis(process.env.REDIS_URL ?? 'redis://localhost:6379'), // required
prefix: 'myapp:memory', // key namespace
topK: 8, // common options apply here too
minScore: 0.2,
})

ioredis 대신 node-redis(redis 패키지)를 사용하나요? camelCase API가 RedisLike와 일치하지 않으므로 fromNodeRedis로 감싸야 합니다.

import { createClient } from 'redis'
import { redis, fromNodeRedis } from '@tanstack/ai-memory/redis'

const client = createClient({ url: process.env.REDIS_URL })
await client.connect()

const memory = redis({ redis: fromNodeRedis(client) })

ioredisredis는 모두 선택적 peer dependency입니다. 사용하는 패키지를 설치합니다.

Scope 필드: 인덱스 키는 {prefix}:index:{tenantId|_}:{userId|_}:{threadId}입니다 (각 세그먼트를 이스케이프하므로 값의 :, \, _가 충돌하지 않습니다). 선택적 차원이 없으면 _가 되므로 tenantId를 포함해 쓰고 이를 제외해 읽으면 서로 다른 키에 접근합니다 — 항상 기록할 때 사용한 것과 동일한 차원을 전달합니다. 이전 레이아웃을 함께 읽지 않으므로 이전에 다른 인덱스 형태로 기록했다면 다시 인덱싱하거나 삭제합니다.

각 어댑터가 처리하는 Scope 필드

어댑터threadIduserIdtenantIdnamespace
inMemory()예 (정확히 일치)예 (정확히 일치)예 (정확히 일치)무시
redis()예 (키 세그먼트)예 (키 세그먼트)예 (키 세그먼트)무시
hindsight()예 (bank ID)예 (bank ID / user 옵션)예 (bank 접두사; 미설정 시 → _)무시
mem0()예 (run_id)예 (user_id / user 옵션)아니요무시
honcho()예 (세션 키)예 (peer ID / user 옵션)예 (세션/peer 접두사)무시

선택적 차원은 정확히 일치해야 합니다(생략 ≠ 모두 일치). mem0은 테넌트를 모델링하지 않으므로 필요하면 멀티테넌트 격리를 user에 인코딩합니다.

hindsight()

Hindsight를 기반으로 하는 호스팅 어댑터입니다. 추출 및 랭킹을 서버에서 처리하며 recall을 통해 retain/recall/reflect LLM 도구를 노출합니다. @vectorize-io/hindsight-client는 선택적 peer이며 지연 로드됩니다.

옵션타입기본값용도
userstringscope.userIdbank 키에 사용하는 영속 사용자 ID입니다 ({tenant|_}__{user}__{threadId}).
baseUrlstringHINDSIGHT_URL / http://localhost:8888서버 URL.
budget'low' | 'mid' | 'high''mid'리콜 예산.
onToolRetain(receipt) => void없음hindsight_retain 호출될 때 발생.
onToolRecall(query, result) => void없음hindsight_recall 호출될 때 발생.
import { hindsight } from '@tanstack/ai-memory/hindsight'

const memory = hindsight({
user: 'alice', // bank = {_}__alice__{threadId} (or tenant__alice__{threadId})
baseUrl: 'https://hindsight.internal', // default: HINDSIGHT_URL
budget: 'high', // deeper recall
onToolRetain: (receipt) => console.log('model retained', receipt.ok),
onToolRecall: (query, result) =>
console.log('model recalled', query, result.fragments?.length),
})

Bank ID는 {tenantId|_}__{user}__{threadId}입니다.

mem0()

일반 HTTP를 통해 mem0 서버를 기반으로 동작하는 호스팅 어댑터입니다(SDK peer 없음). 실행 중인 mem0 서버가 필요합니다.

옵션타입기본값용도
userstringscope.userId / 'demo-user'mem0 user_id.
baseUrlstringMEM0_URL / http://localhost:8000서버 URL.
apiKeystringMEM0_ADMIN_API_KEYBearer 토큰.
rerankbooleantruemem0에게 검색 결과를 다시 순위 매기도록 요청합니다.
thresholdnumber0.1최소 검색 점수.
import { mem0 } from '@tanstack/ai-memory/mem0'

const memory = mem0({
user: 'alice', // mem0 user_id
baseUrl: 'https://mem0.internal', // default: MEM0_URL
apiKey: process.env.MEM0_ADMIN_API_KEY, // bearer token
rerank: true, // rerank results
threshold: 0.2, // stricter score floor
})

mem0 요청은 user_idrun_id (threadId) 를 보냅니다. tenantId 은 보내지지 않습니다.

honcho()

Honcho를 기반으로 동작하는 호스팅 어댑터입니다. recall은 사용자의 표현을 바탕으로 종합한 변증법적 답변을 반환합니다(개별 조각 없음). @honcho-ai/sdk는 선택적 peer이며 지연 로드됩니다.

옵션타입기본값용도
userstringscope.userId / 'demo-user'사용자 피어 ID.
baseURLstringHONCHO_URL / http://localhost:8001서버 URL.
workspaceIdstringHONCHO_APP_NAME / 'ai-memory'워크스페이스 ID.
apiKeystringHONCHO_API_KEY / 'dev-no-auth'API 키.
assistantIdstring'assistant'어시스턴트 피어 ID.
import { honcho } from '@tanstack/ai-memory/honcho'

const memory = honcho({
user: 'alice', // user peer
baseURL: 'https://honcho.internal', // default: HONCHO_URL
workspaceId: 'my-app', // default: HONCHO_APP_NAME
apiKey: process.env.HONCHO_API_KEY, // default: 'dev-no-auth'
assistantId: 'support-bot', // default: 'assistant'
})

Honcho 세션 키는 {tenantId|_}__{threadId}입니다. tenantId가 설정되면 peer는 {tenantId}__{user}이고, 그렇지 않으면 사용자 ID만 사용합니다.

다음 단계

  • Overview: recall/save 계약과 턴의 흐름
  • Quickstart: 실제 chat() 호출에 어댑터 연결
  • Operating memory: 옵션, 텔레메트리, devtools 이벤트 및 오류
  • Custom Adapter: 제공되지 않는 백엔드에 recall/save 구현