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 调用不会再次发出——既省 Token,又保证回答一致。
完整项目产物
示例仓库
https://github.com/hanmahong5-arch/lurus-examples/tree/main/memory-agent — 含代码完整版、docker-compose.yml(本地起 MemX + Kova)、Pytest 覆盖三节点、.env.example。