跪拜 Guibai
← All articles
Java · Backend · Artificial Intelligence

A Production MultiAgent Memory System Splits Short-Term Context from Four-Layer Long-Term Recall

By 得物技术 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Most agent memory discussions stop at “stuff history into the prompt.” This architecture shows what a production-grade split actually looks like: parallel async loading, token budgets per scope, similarity dedup, conflict resolution, and a write-first persistence strategy that accepts eventual consistency because the memory store is an external service. Teams building multi-agent systems will hit the same boundary problems—session pollution from child agents, summary thresholds, and the impossibility of transactional writes across an HTTP API—and the design choices here are directly transferable.

Summary

The memory system treats short-term and long-term recall as two independent, parallel-loaded chains. Short-term memory uses a Redis-cached, MySQL-backed sliding window with token budget control and summary injection; long-term memory routes through MemOS semantic search across user_profile and agent-specific cubes, then allocates a fixed 4000-token budget with a 60% cap for user profile. After a session ends, an async process acquires a distributed Redis lock, marks new messages by MD5 hash for idempotency, runs LLM-based judgment to extract structured memories, performs local Jaccard/Levenshtein deduplication, resolves conflicts against existing memories, and persists new items before best-effort deletion of stale ones.

MemOS retrieval uses fast mode with MMR dedup, a 0.45 relativity threshold, and post-retrieval filtering at score < 0.3 with 1000-character truncation. The write path adopts a write-first, delete-later strategy because MemOS is an external HTTP service and cannot participate in a local transaction. Degradation paths exist throughout: Redis misses fall back to MySQL, LLM judgment failures fall back to rule-based extraction, and long-term memory query failures return empty results without blocking the main dialogue.

Takeaways
Short-term and long-term memory load in parallel via CompletableFuture on a dedicated thread pool, converging at join() before model invocation.
Short-term history uses a sliding token window with a reserved summary budget; when total tokens exceed the max window, a precomputed conversation summary is injected as a SystemMessage.
Redis serves as a hot cache for short-term memory with leftPush writes and rightPop eviction at 200 messages; MySQL is the persistence fallback.
Child Agent messages not of type ChatMessageDto are excluded from the main session write path to prevent virtual session pollution.
Session summary generation triggers only when unsummarized messages reach 20, with a ~2000-token budget and 1-hour Redis cache.
Long-term memory retrieval queries MemOS across user_profile and agent_{agentId} cubes simultaneously, with preference retrieval at prefTopK=6.
MemOS search uses fast mode, MMR dedup, a 0.45 relativity threshold, and post-retrieval filtering at score < 0.3 with 1000-character truncation per item.
Long-term memory injection uses a 4000-token budget; user_profile caps at 60%, with remaining tokens allocated to agent memory via line-by-line truncation.
Session-end processing acquires a 10-minute distributed Redis lock and uses MD5(role:content) hashes with 7-day TTL for idempotency.
LLM judgment marks new messages with [[NEW]] tags in the full context prompt; on LLM failure, it degrades to rule-based extraction from new messages only.
Local deduplication before persistence runs exact, contains, Jaccard (0.7), and Levenshtein (0.8) checks sequentially.
Conflict resolution against existing memories is called per-item; the batch method groups by cube but still invokes detection individually.
MemOS persistence uses a write-first, delete-later strategy: new memories are written via async/fine mode, then conflicting old IDs are deleted on a best-effort basis with warning-only logging on failure.
MemOS query failures do not auto-failover to MySQL; the provider logs a warning and returns empty results.
Conclusions

The four-layer model (Working, Session, User, Agent) and MemOS content types (text_mem, pref_mem, skill_mem, tool_mem) are explicitly two separate classification dimensions—a distinction most memory discussions conflate.

The platform deliberately does not inject short-term history into the long-term memory query; the two chains are parallel and independent, meaning long-term retrieval runs with an empty context on the first request of a session.

The write-first, delete-later strategy is an explicit acceptance of eventual consistency because MemOS is an external HTTP service that cannot join a local transaction—a constraint any team using a separate memory service will face.

The summary threshold of 20 unsummarized messages and the 2000-token budget are concrete operational numbers that emerged from production tuning, not arbitrary defaults.

The Redis list implementation ignores the lastN parameter for range boundaries, relying instead on application-layer token window trimming—a leaky abstraction that could surprise operators expecting Redis-side limits.

The [[NEW]] marking strategy feeds the full context to the LLM but tags only new messages, letting the model distinguish what needs extraction without losing the surrounding dialogue for disambiguation.

Concepts & terms
Four-Layer Memory Model
A lifecycle-based classification: Working Memory (single reasoning step), Session Memory (current dialogue history), User Memory (cross-agent preferences and stable facts), and Agent Memory (task experience and collaboration rules for a specific agent).
MemOS
An external memory service used as the primary long-term memory store. Organizes memory into cubes (e.g., user_profile, agent_{agentId}) and supports semantic search with MMR dedup, relevance thresholds, and preference retrieval.
Token Budget Allocation
A fixed token limit (4000) for long-term memory injection, with user_profile capped at 60%. Remaining tokens go to agent memory. Truncation is line-by-line to avoid splitting individual memory items mid-sentence.
MMR (Maximal Marginal Relevance) Dedup
A search result diversification algorithm used by MemOS to reduce redundancy in retrieved memories, balancing relevance against novelty.
Write-First, Delete-Later
A persistence strategy that writes new memories before attempting to delete conflicting old ones. Accepts eventual consistency because the memory store is an external HTTP service outside local transaction boundaries; delete failures are logged as warnings and left for later cleanup.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗