Vectorizing Long-Term Chat Memory So It Survives a Paraphrase
Most chat apps bolt on RAG and call it memory, but the real work is in the guardrails: which fields get indexed, which conversations trigger recall, and how the system degrades when the vector store is down. This implementation makes those boundaries explicit, offering a reference design for anyone adding semantic memory to a LangGraph agent without letting it become a single point of failure.
Keyword matching fails the moment a user rephrases a stored preference. AI Mind v0.4.6 adds a vector index to every active UserMemory, embedding `text` and `tags` via Doubao's embedding model into pgvector. On each eligible chat turn, the user's input is vectorized and run through an ANN search for the top-8 candidates, then squeezed through a six-layer filter chain that enforces a 0.32 cosine-similarity threshold, polarity conflict detection, and a hard budget of three memories totaling 900 characters.
The write path is deliberately narrow: only `active` memories get indexed, and only the `text` and `tags` fields are vectorized. The recall path is conservative by design, preferring to return nothing over injecting irrelevant context. A 1500ms timeout and two layers of try/catch ensure a failed embedding call or a dead pgvector query degrades to zero memories without blocking the chat stream.
The result is a retrieval system that finds "don't be too abstract" when the stored preference says "explain in plain language first," without a single LLM query-rewrite call.
The decision to skip LLM query rewriting is a deliberate trade-off: it saves a round-trip and avoids rewrite-induced semantic drift, betting that the embedding model's own generalization is good enough for the recall task.
Scoping vector indexing to explicit fields rather than the whole JSON document is a security and relevance boundary that many RAG pipelines overlook, and it prevents metadata leakage into semantic search results.
The six-layer filter chain is effectively a cost-control mechanism disguised as quality assurance — each layer removes candidates that would waste context-window tokens without improving the answer.
Polarity conflict detection treats the current user utterance as higher authority than stored memory, which is correct for a chat assistant but would be wrong for a system that must enforce persistent rules.
Hard-coding the embedding model ID and version into persisted document metadata creates a future-proofing hook: when the model changes, old vectors are automatically distrusted rather than silently producing degraded results.