Files
group_xinghuo_jinrong/app/service/memory_service.py
T

61 lines
2.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""记忆服务(T-06 最小闭环):Redis 会话窗口 + MySQL 权威落盘。
口径(redis-keys §2.1):`sess:{agent}:{session_id}:msgs` List,TTL 2h,
最近 N≤20 条 JSON;Redis 只保窗口、丢失可重建(miss/异常回源 MySQL,
MySQL 为权威)。L1/L2/L3 画像读写归后续任务(画像不得覆盖 L0 正式测评)。
落盘策略:「每条消息同步或 5s 内异步写 MySQL」——最小闭环同步写(api/chat
双条落库),异步化归后续优化。
"""
from __future__ import annotations
import json
import logging
from app.config.settings import settings
from app.repository.session_repository import SessionRepository
from app.service.risk.redis_gateway import get_gateway
logger = logging.getLogger(__name__)
SESSION_TTL_SECONDS = 2 * 3600
WINDOW_SIZE = 20
def window_key(agent_type: str, session_id: str) -> str:
"""redis-keys §2.1:sess:{agent}:{session_id}:msgs。"""
return f"sess:{agent_type}:{session_id}:msgs"
def _session_repo() -> SessionRepository:
"""回源仓储入口(测试 monkeypatch 点,与 api 模式一致)。"""
return SessionRepository()
def get_recent(agent_type: str, session_id: str, limit: int = WINDOW_SIZE) -> list[dict]:
"""最近 N 轮消息([{role, content}]);Redis miss/异常回源 MySQL。"""
try:
raw = get_gateway().lrange(window_key(agent_type, session_id), -limit, -1)
if raw:
return [json.loads(item) for item in raw]
except Exception:
logger.warning("session window read failed, fallback to MySQL: %s", session_id, exc_info=True)
return _session_repo().list_messages(session_id, limit=limit)
def append_window(
agent_type: str,
session_id: str,
messages: list[dict],
) -> None:
"""追加窗口(RPUSH + LTRIM 保留最近 N 条 + TTL 续期);失败降级不阻塞。"""
try:
key = window_key(agent_type, session_id)
client = get_gateway()
client.rpush(key, *[json.dumps(m, ensure_ascii=False) for m in messages])
client.ltrim(key, -WINDOW_SIZE, -1)
client.expire(key, SESSION_TTL_SECONDS)
except Exception:
# 窗口丢失可重建(下次读回源 MySQL),不阻塞对话主链路
logger.warning("session window append failed (degrade): %s", session_id, exc_info=True)