|
| 1 | +This intelligent AI assistant is designed to support real-world, multi-session use with Redis as its memory core. |
| 2 | + |
| 3 | +What you get: |
| 4 | + - **Smart Memory**: Ephemeral context that expires automatically, long-term facts retained forever |
| 5 | + - **Semantic Search**: Recall relevant info by meaning using vector search |
| 6 | + - **Zero Maintenance**: Auto-expiring short-term memory without a need to track timestamps manually |
| 7 | + - **Multi-User**: Isolated memory per user |
| 8 | + - **Learning**: Assistant can "understand" each user better the more it's used |
| 9 | + |
| 10 | +**Note**: Requires [Redis 8](https://hub.docker.com/_/redis/tags) for `HSETEX`, which adds per-field TTL for hashes, which is ideal for managing short-term memory with precision. |
| 11 | + |
| 12 | +### Architecture overview |
| 13 | +| Layer | Description | |
| 14 | +| ---------- | ---------- | |
| 15 | +| `Working Memory`| `Short-term chat context (ephemeral)` | |
| 16 | +| `Knowledge Base` | `Persistent facts, user preferences` | |
| 17 | +| `Vector Search` | `Unified semantic recall across both layers` | |
| 18 | + |
| 19 | +### Working memory (ephemeral) |
| 20 | +Stores recent user messages with TTL based on importance. Automatically expires to prevent bloat. |
| 21 | +This uses `HSETEX`, a Redis 8 command that adds field-level expiration to hashes. It allows storing all temporary messages in a single key while managing TTLs per message, simplifying short-term memory management without needing multiple keys. |
| 22 | + |
| 23 | +```redis:[run_confirmation=true] Recent Conversations with TTL Based on Importance. |
| 24 | +// Quick exchanges (5 min) |
| 25 | +HSETEX user:alice:session:001 EX 300 FIELDS 1 msg:001 "What's the weather?" |
| 26 | +// Session context (30 min) |
| 27 | +HSETEX user:alice:session:001 EX 1800 FIELDS 1 msg:002 "I need a dentist appointment" |
| 28 | +// Important decisions (2 hours) |
| 29 | +HSETEX user:alice:session:001 EX 7200 FIELDS 1 msg:003 "Book it for Tuesday 2 PM" |
| 30 | +``` |
| 31 | + |
| 32 | +### Knowledge base (persistent) |
| 33 | +Long-term memory: stores important facts, user preferences, and context across sessions. These never expire. |
| 34 | +`embedding` is a binary-encoded `FLOAT32[]` used for vector similarity that can be generated using sentence-transformers or similar libraries. Demo uses 8-dim vectors; production models typically use 128–1536 dimensions. |
| 35 | + |
| 36 | +```redis:[run_confirmation=true] Important User Information That Never Expires. |
| 37 | +// User preferences - need vector fields for search |
| 38 | +HSET user:alice:knowledge:pref:001 user_id "alice" memory_type "knowledge" content "prefers mornings before 10 AM" importance 9 timestamp 1717935000 embedding "\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x40\x00\x00\x3f\x40\x00\x00\x40\x60\x00\x00\x40\x00\x00\x00\x3f\x00\x00\x00\x40\x80\x00\x00" |
| 39 | +HSET user:alice:knowledge:pref:002 user_id "alice" memory_type "knowledge" content "likes detailed explanations" importance 8 timestamp 1717935000 embedding "\x3f\x40\x00\x00\x40\x60\x00\x00\x40\x00\x00\x00\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x40\x00\x00\x40\x80\x00\x00\x3f\x00\x00\x00" |
| 40 | +// Personal facts |
| 41 | +HSET user:alice:knowledge:personal:001 user_id "alice" memory_type "knowledge" content "allergic to shellfish" importance 10 timestamp 1717935000 embedding "\x40\x00\x00\x00\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x40\x00\x00\x40\x60\x00\x00\x3f\x40\x00\x00\x40\x80\x00\x00\x3f\x00\x00\x00" |
| 42 | +HSET user:alice:knowledge:personal:002 user_id "alice" memory_type "knowledge" content "golden retriever named Max" importance 7 timestamp 1717935000 embedding "\x3f\x80\x00\x00\x40\x40\x00\x00\x40\x00\x00\x00\x3f\x40\x00\x00\x40\x80\x00\x00\x40\x20\x00\x00\x3f\x00\x00\x00\x40\x60\x00\x00" |
| 43 | +// Work context |
| 44 | +HSET user:alice:knowledge:work:001 user_id "alice" memory_type "knowledge" content "Senior PM at TechCorp" importance 8 timestamp 1717935000 embedding "\x40\x40\x00\x00\x3f\x00\x00\x00\x40\x80\x00\x00\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x60\x00\x00\x40\x00\x00\x00\x3f\x40\x00\x00" |
| 45 | +HSET user:alice:knowledge:work:002 user_id "alice" memory_type "knowledge" content "leading Project Apollo" importance 9 timestamp 1717935000 embedding "\x40\x60\x00\x00\x40\x80\x00\x00\x3f\x40\x00\x00\x40\x00\x00\x00\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x40\x00\x00\x3f\x00\x00\x00" |
| 46 | +``` |
| 47 | + |
| 48 | +### Vector search: semantic memory recall |
| 49 | +Unify working + knowledge memory into a vector index for semantically meaningful search. |
| 50 | + |
| 51 | +```redis:[run_confirmation=true] Create a Vector Index |
| 52 | +FT.CREATE idx:memory |
| 53 | + ON HASH |
| 54 | + PREFIX 2 vmemory: user: |
| 55 | + SCHEMA |
| 56 | + user_id TAG |
| 57 | + memory_type TAG |
| 58 | + content TEXT |
| 59 | + importance NUMERIC |
| 60 | + timestamp NUMERIC |
| 61 | + embedding VECTOR HNSW 6 |
| 62 | + TYPE FLOAT32 |
| 63 | + DIM 8 // DIM = embedding size; 8 used here for simplicity — in production, use 128 to 1536 |
| 64 | + DISTANCE_METRIC COSINE // COSINE = measures semantic closeness |
| 65 | +``` |
| 66 | + |
| 67 | +### Add indexed memory |
| 68 | +Populate the vector index with memory items from both ephemeral and persistent layers. |
| 69 | + |
| 70 | +```redis:[run_confirmation=true] Add entries for the chatbot |
| 71 | +// Working memory (expires from Redis, stays in search until rebuild) |
| 72 | +HSET vmemory:alice:001 user_id "alice" memory_type "working" content "Book dentist for Tuesday 2 PM" importance 8 timestamp 1717935310 embedding "\x3f\x80\x00\x00\x40\x00\x00\x00\x40\x40\x00\x00\x40\x80\x00\x00\x3f\x00\x00\x00\x40\x20\x00\x00\x40\x60\x00\x00\x3f\x40\x00\x00" |
| 73 | +
|
| 74 | +// Knowledge base (persistent) |
| 75 | +HSET vmemory:alice:kb:001 user_id "alice" memory_type "knowledge" content "allergic to shellfish" importance 10 timestamp 1717935000 embedding "\x40\x00\x00\x00\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x40\x00\x00\x40\x60\x00\x00\x3f\x40\x00\x00\x40\x80\x00\x00\x3f\x00\x00\x00" |
| 76 | +``` |
| 77 | + |
| 78 | +### Full memory search |
| 79 | +Search across all memories to recall relevant data. |
| 80 | + |
| 81 | +```redis:[run_confirmation=false] Find Top 5 Related Messages By Meaning |
| 82 | +FT.SEARCH idx:memory |
| 83 | + "(@user_id:{alice}) => [KNN 5 @embedding $vec AS score]" |
| 84 | + PARAMS 2 vec "\x40\x00\x00\x00\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x40\x00\x00\x40\x60\x00\x00\x3f\x40\x00\x00\x40\x80\x00\x00\x3f\x00\x00\x00" |
| 85 | + RETURN 4 content memory_type importance score |
| 86 | + SORTBY score ASC |
| 87 | + DIALECT 2 |
| 88 | +``` |
| 89 | + |
| 90 | +### Session-only search |
| 91 | +Limit results to current conversation context (ephemeral memory). |
| 92 | + |
| 93 | +```redis:[run_confirmation=false] Session-Only Search |
| 94 | +FT.SEARCH idx:memory |
| 95 | + "(@user_id:{alice} @memory_type:{working}) => [KNN 5 @embedding $vec AS score]" |
| 96 | + PARAMS 2 vec "\x3f\x80\x00\x00\x40\x40\x00\x00\x40\x00\x00\x00\x3f\x40\x00\x00\x40\x80\x00\x00\x40\x20\x00\x00\x3f\x00\x00\x00\x40\x60\x00\x00" |
| 97 | + RETURN 4 content score timestamp memory_type |
| 98 | + SORTBY score ASC |
| 99 | + DIALECT 2 |
| 100 | +``` |
| 101 | + |
| 102 | +### Knowledge-only search |
| 103 | +Focus only on persistent memory: facts, preferences, decisions. |
| 104 | + |
| 105 | +```redis:[run_confirmation=false] Knowledge-Only Search |
| 106 | +FT.SEARCH idx:memory |
| 107 | + "(@user_id:{alice} @memory_type:{knowledge}) => [KNN 8 @embedding $vec AS score]" |
| 108 | + PARAMS 2 vec "\x40\x40\x00\x00\x3f\x00\x00\x00\x40\x80\x00\x00\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x60\x00\x00\x40\x00\x00\x00\x3f\x40\x00\x00" |
| 109 | + RETURN 4 content importance score timestamp |
| 110 | + SORTBY score ASC |
| 111 | + DIALECT 2 |
| 112 | +``` |
| 113 | + |
| 114 | +### Monitoring memory state |
| 115 | +Use these queries to inspect what’s stored in memory. |
| 116 | + |
| 117 | +```redis:[run_confirmation=false] Check Memory State |
| 118 | +// Check active session memory |
| 119 | +HGETALL user:alice:knowledge:pref:001 // Example for one preference item |
| 120 | +
|
| 121 | +// View user knowledge |
| 122 | +HGETALL user:alice:knowledge:pref:001 |
| 123 | +
|
| 124 | +// Search user's memories |
| 125 | +FT.SEARCH idx:memory |
| 126 | + "@user_id:{alice}" |
| 127 | + RETURN 3 content memory_type importance |
| 128 | +``` |
| 129 | + |
| 130 | +### Data cleanup |
| 131 | + |
| 132 | +For privacy compliance, delete all user-related keys. |
| 133 | + |
| 134 | +```redis:[run_confirmation=true] Complete user removal |
| 135 | +DEL user:alice:knowledge:pref:001 |
| 136 | +DEL user:alice:knowledge:pref:002 |
| 137 | +DEL user:alice:knowledge:personal:001 |
| 138 | +DEL user:alice:knowledge:personal:002 |
| 139 | +DEL user:alice:knowledge:work:001 |
| 140 | +DEL user:alice:knowledge:work:002 |
| 141 | +DEL vmemory:alice:001 |
| 142 | +DEL vmemory:alice:kb:001 |
| 143 | +``` |
| 144 | + |
| 145 | +### Next steps |
| 146 | +Now that your assistant has memory and meaning, you can: |
| 147 | + - Combine with RAG Pipelines |
| 148 | + - Use sentence-transformers to generate high-dimensional vectors |
| 149 | + - Add [Redis Flex](https://redis.io/solutions/flex/?utm_source=redisinsight&utm_medium=app&utm_campaign=tutorials) for fallback persistence |
| 150 | + - Use Redis ACLs to isolate users, enforce quotas, and monitor usage |
0 commit comments