Store : 장기기억 저장소
Store 기본 구조
namespace : 기억을 모아두는 공간
key : namespace 안에서 기억을 구분하는 이름
value : 실제 저장할 내용 {딕셔너리}
put : 저장
store.put(namespace, key, value)get : key로 정확히 불러오기
item = store.get(namespace, key)delete : 삭제
store.delete(namespace, key)search(query=) : 의미 검색
store.search(namespace, query=의미검색, filter=메타데이터 조건, limit=가져올개수)Node에서 Store 사용
@dataclass
class UserContext:
user_id: str # 실행 코드가 전달하는 사용자 ID. 기억의 조회 범위를 결정
from langgraph.runtime import Runtime
def recall_memories(state: CounselingState, runtime: Runtime[UserContext]):
# runtime : 노드가 실행될 때 필요한 사용자 정보 및 저장소 같은 자원에 접근하기 위한 변수
# runtime.context : langchain 정해진 부분
# user_id : 우리가 정의한 정보
user_id = runtime.context.user_id
profile_namespace = ("counseling", user_id, "profile")
episode_namespace = ("counseling", user_id, "episodes")
memories = []
# key로 정확히 조회
for key in ["work_context", "counseling_goal", "support_preference"]:
item = runtime.store.get(profile_namespace, key)
if item:
memories.append(item.value["text"])
# 현재 질문과 관련된 기억 검색
hits = runtime.store.search(
episode_namespace,
query=state["messages"][-1].text,
filter={"speaker": "user"},
limit=2,
)
memories += [item.value["text"] for item in hits]
return {"recalled_memories": memories}
runtime.context : 실행할 때 전달한 사용자 정보runtime.context.user_id : 사용자별 기억 구분runtime.store : Store 접근get() : 정확한 기억 조회search() : 관련 기억 검색Mem0 : 대화에서 장기기억을 LLM으로 추출 → 저장 → 검색하는 라이브러리
memory = Memory.from_config(mem0_config)
memory.add(message, user_id=user_id, prompt=profile_policy, metadata={"memory_space": "profile"})
memory.get_all(filters={"user_id": user_id, "memory_space": "profile"}, top_k=50)memory.search(question, filters={"user_id": user_id, "memory_space": "episodes"}, top_k=3)get_all() → 조건에 맞는 기억 전체 조회search() → 질문과 의미적으로 관련된 기억 검색filters → 사용자와 기억 공간 제한profile = memory.get_all(...) # 항상 필요한 정보 found = memory.search(...) # 관련 과거 경험get_all() / search() → 여러 기억 조회·검색memory.get(memory_id) → ID로 정확히 하나 조회memory.update(memory_id=memory_id, text="수정된 기억") → 기존 기억 수정memory.delete(memory_id) → 기존 기억 삭제memory.history(memory_id) → 변경 이력 확인infer=False→ LLM 추출 없이 이미 확정한 문장을 그대로 저장할 수 있다.
| LangGraph Store | Mem0 |
|---|---|
| 기억을 직접 정리해서 저장 | LLM이 대화에서 기억 추출 |
put() | add() |
| namespace / key / value 직접 지정 | user_id / metadata / id 사용 |
get() 정확 조회 | get(), get_all() 조회 |
search() 의미 검색 | search() 의미 검색 |
| 갱신 로직 직접 설계 | update/delete 제공 |
Context : LLM에게 넣어주는 정보
→ 시스템 프롬프트 + 대화내역 + 장기기억 + Tool 정보 + 출력 스키마 등
Context Engineering
: LLM에게 무엇을, 얼마나 넣을지 설계해서 답변 품질을 높이는 것
get()search()trim_messagesstrategy="last" → 최근 대화 우선전체 입력 예산 - 지시/기억/요약 = 최근 대화에 쓸 예산count_tokens_approximately() → 근사 토큰 계산전체 흐름:
사용자 질문 → 필요한 장기기억 조회 → 대화가 길면 오래된 내용 요약 → 입력 예산 계산 → 최근 대화 trim → 지시 + 기억 + 요약 + 최근 대화 → LLM 답변