MemX × Kova × Lurus API
기억을 갖춘 AI 고객 지원 봇 만들기
목표: 30분 안에 사용자의 과거 질문을 기억하고, 충돌 시 자동 복구하며, 필요에 따라 지식을 증류하는 고객 지원 Agent를 완성합니다.
30분완성 목표
6단계의존성부터 기록까지
3개 서비스MemX · Kova · API
아키텍처 다이어그램
세 서비스가 각자의 역할을 맡습니다. MemX는 장기 기억의 회수와 증류를 담당하고, Lurus API는 LLM 호출을 담당하며, Kova WAL은 상태 영속화와 충돌 복구를 담당합니다.
graph LR
U[사용자] --> W[Web 프론트엔드]
W -->|HTTP| A[Agent App]
A -->|1. 회수| M[MemX]
A -->|2. LLM| L[Lurus API]
A -->|3. 상태| K[Kova WAL]
A -->|4. 기록| M
L --> A
M --> A6단계
의존성 준비
bashpip install lurus memx-client kova-py lumen-ai openai세 서비스 초기화
pythonfrom openai import OpenAI from memx import Memory from kova import KovaClient llm = OpenAI(base_url="https://hub.lurus.cn/v1", api_key="sk-...") mem = Memory(config={"ace_enabled": True}) kova = KovaClient("kova://localhost")Agent 상태 정의
pythonfrom typing import TypedDict, Annotated, Sequence class State(TypedDict): user_id: str messages: Annotated[Sequence, "chat history"] relevant_memory: list과거 기억 회수 — MemX에서 현재 질문과 관련된 기억을 가져옵니다
pythondef retrieve_memory(state: State) -> State: last = state["messages"][-1]["content"] hits = mem.search(last, user_id=state["user_id"], limit=5) return {**state, "relevant_memory": hits}LLM 호출 및 응답 반환 — 회수한 사실을 system prompt에 주입합니다
pythondef respond(state: State) -> State: context = "\n".join(h["text"] for h in state["relevant_memory"]) resp = llm.chat.completions.create( model="deepseek-chat", messages=[ {"role": "system", "content": f"已知事实:\n{context}"}, *state["messages"], ], ) reply = resp.choices[0].message.content return {**state, "messages": [*state["messages"], {"role": "assistant", "content": reply}]}증류 후 기록 — 새 대화를 MemX에 다시 기록하면 다음 회수 시 바로 사용할 수 있습니다
pythondef distill(state: State) -> State: mem.add( list(state["messages"][-2:]), user_id=state["user_id"], scope="support:general", ) return state
Kova 충돌 복구 추가
Kova를 LangGraph의 checkpointer로 연결하면, Agent가 충돌한 뒤 WAL에서 복구하며 LLM을 다시 호출하지 않습니다.
python
from kova.langgraph import KovaCheckpointer
graph = wf.compile(checkpointer=KovaCheckpointer(kova))왜 LLM을 다시 호출하지 않는가
Kova는 각 단계마다 사전 기록 로그(WAL)를 남깁니다. 프로세스가 충돌한 뒤 엔진은 중단 지점부터 실행 상태를 재생하며, 이미 완료된 LLM 호출은 다시 발생하지 않습니다. 덕분에 토큰을 절약하면서도 응답의 일관성을 보장합니다.
완성된 프로젝트 산출물
예제 저장소
https://github.com/hanmahong5-arch/lurus-examples/tree/main/memory-agent — 코드 완성본, docker-compose.yml(로컬에서 MemX + Kova 기동), 세 노드를 커버하는 Pytest, .env.example을 포함합니다.