Skip to content

Commit cecbf6b

Browse files
Update ai_assistant.md
1 parent ff4a673 commit cecbf6b

File tree

1 file changed

+150
-104
lines changed

1 file changed

+150
-104
lines changed

src/uc/ai_assistant.md

Lines changed: 150 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,199 @@
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 learns user preferences and context over time.
1+
This tutorial demonstrates how to build an AI assistant's memory system with Redis as its memory core.
92

103
**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.
114

125
### Architecture Overview
13-
| Layer | Description |
14-
| ---------- | ---------- |
15-
| `Working Memory`| `Short-term chat context (ephemeral)` |
16-
| `Knowledge Base` | `Long-term memory: persistent facts and preferences` |
17-
| `Vector Search` | `Unified semantic recall across both layers` |
18-
19-
### Working Memory (Ephemeral)
20-
Stores recent user and assistant messages with per-message TTL. Uses:
21-
- `HSETEX` to add field-level expiration to hashes to store all temporary messages in a single key while managing TTLs per message, simplifying short-term memory management without needing multiple keys.
22-
- `ZADD` for message ordering (based on timestamp)
23-
24-
```redis:[run_confirmation=true] Recent conversations with TTL based on importance
25-
// Step 1: Add message with TTL (5 mins)
26-
HSETEX user:alice:session:001 EX 300 FIELDS 1 msg:001 "What's the weather?"
27-
// Step 2: Track order with timestamp (epoch seconds)
28-
ZADD user:alice:session:001:zorder 1717935001 msg:001
29-
// Another message (30 min TTL)
30-
HSETEX user:alice:session:001 EX 1800 FIELDS 1 msg:002 "I need a dentist appointment"
31-
ZADD user:alice:session:001:zorder 1717935030 msg:002
32-
// Assistant reply (2 hour TTL)
33-
HSETEX user:alice:session:001 EX 7200 FIELDS 1 msg:003 "Booked for Tuesday 2 PM"
34-
ZADD user:alice:session:001:zorder 1717935090 msg:003
6+
| Layer | Description | Data type |
7+
| ---------- | ---------- | ---------- |
8+
| `Session History`| `Recent conversation context` | List |
9+
| `Rate Limiting` | `Per-user request throttling` | Hash |
10+
| `Knowledge Base` | `Long-term facts and preferences` | Hash |
11+
12+
### Session History
13+
AI assistants need context from previous messages to provide coherent responses. Without conversation history, each interaction would be isolated and the AI couldn't reference what was discussed earlier. We can store conversation history using Redis lists - simple, ordered, and efficient for chat scenarios.
14+
15+
```redis:[run_confirmation=true] Store conversation history
16+
// Add user message to session
17+
LPUSH user:alice:history:session_001 '{"type": "human", "content": "What's the weather like?", "timestamp": 1717935001}'
18+
19+
// Add AI response
20+
LPUSH user:alice:history:session_001 '{"type": "ai", "content": "It's sunny with 75°F temperature.", "timestamp": 1717935002}'
21+
22+
// Add another user message
23+
LPUSH user:alice:history:session_001 '{"type": "human", "content": "Should I bring an umbrella?", "timestamp": 1717935003}'
24+
25+
// Add AI response
26+
LPUSH user:alice:history:session_001 '{"type": "ai", "content": "No umbrella needed today!", "timestamp": 1717935004}'
27+
```
28+
### Reading Conversation History
29+
Now we can retrieve conversation history to provide context to the AI.
30+
31+
```redis:[run_confirmation=true] Read conversation history
32+
// Get last 5 messages (most recent first)
33+
LRANGE user:alice:history:session_001 0 4
34+
35+
// Get all messages in session
36+
LRANGE user:alice:history:session_001 0 -1
37+
38+
// Get specific message by index
39+
LINDEX user:alice:history:session_001 0
40+
41+
// Check how many messages in session
42+
LLEN user:alice:history:session_001
3543
```
44+
### Session Expiration
45+
Without expiration, conversation history would accumulate indefinitely, consuming memory and potentially exposing sensitive information. TTL ensures privacy and efficient memory usage.
3646

37-
```redis:[run_confirmation=true] Reading the session in order
38-
ZRANGEBYSCORE user:alice:session:001:zorder -inf +inf
39-
// Then for each msg ID:
40-
HGET user:alice:session:001 msg:001
41-
HGET user:alice:session:001 msg:002
42-
HGET user:alice:session:001 msg:003
47+
```redis:[run_confirmation=true] Session expiration
48+
// Set session to expire in 24 hours
49+
EXPIRE user:alice:history:session_001 86400
50+
51+
// Set session to expire in 1 hour
52+
EXPIRE user:alice:history:session_001 3600
53+
54+
// Check remaining TTL
55+
TTL user:alice:history:session_001
56+
57+
// Remove expiration (make persistent)
58+
PERSIST user:alice:history:session_001
4359
```
4460

45-
```redis:[run_confirmation=true] ZSET cleanup (recommended in background):
46-
// For each msg:XXX in the ZSET, check if it still exists
47-
HEXISTS user:alice:session:001 msg:003
48-
// If not, clean up:
49-
ZREM user:alice:session:001:zorder msg:003
61+
### Rate Limiting
62+
Rate limiting prevents abuse and ensures fair resource usage. Without it, users could overwhelm the system with requests, degrading performance for everyone.
63+
64+
```redis:[run_confirmation=true] Initialize Rate Limiting
65+
// First request - set counter with 1-minute TTL
66+
HSETEX user:alice:rate_limit EX 60 FIELDS 1 requests_per_minute 1
67+
68+
// Check current request count
69+
HGET user:alice:rate_limit requests_per_minute
5070
```
5171

52-
### Knowledge Base (Persistent)
53-
Long-term memory: stores important facts, user preferences, and context across sessions. These never expire.
54-
`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.
55-
56-
```redis:[run_confirmation=true] Important user information that never expires
57-
// User preferences - need vector fields for search
58-
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"
59-
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"
60-
// Personal facts
61-
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"
62-
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"
63-
// Work context
64-
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"
65-
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"
72+
The `HINCR` command allows you to atomically increment the counter, preventing race conditions in high-concurrency scenarios.
73+
74+
```redis:[run_confirmation=true] Increment Requests
75+
// Increment request counter
76+
HINCR user:alice:rate_limit requests_per_minute
77+
78+
// Check if field exists and get count
79+
HEXISTS user:alice:rate_limit requests_per_minute
80+
HGET user:alice:rate_limit requests_per_minute
81+
82+
// Check TTL on the hash
83+
TTL user:alice:rate_limit
84+
```
85+
86+
Different time windows serve different purposes - per-minute prevents burst attacks, per-hour prevents sustained abuse, per-day enforces usage quotas.
87+
```redis:[run_confirmation=true] Rate Limiting with Different Time Windows
88+
// Set multiple rate limits with different TTLs
89+
HSETEX user:alice:rate_limit EX 60 FIELDS 2 requests_per_minute 1 requests_per_hour 1
90+
91+
// Daily rate limit (24 hours)
92+
HSETEX user:alice:rate_limit EX 86400 FIELDS 1 requests_per_day 1
93+
94+
// Check all rate limits
95+
HGETALL user:alice:rate_limit
96+
```
97+
98+
### Knowledge Base (Persistent Memory)
99+
AI assistants become more helpful when they remember user preferences, important facts, and context across sessions. This creates a personalized experience that improves over time.
100+
Remembering user preferences (meeting times, communication style) enables the AI to provide more relevant and personalized responses without asking the same questions repeatedly.
101+
102+
```redis:[run_confirmation=true] Store User Preferences
103+
// Always secure sensitive data using encryption at rest, access control (Redis ACLs), and comply with data protection laws (e.g., GDPR).
104+
// Store morning preference
105+
HSET user:alice:knowledge:pref:001 user_id "alice" content "prefers morning appointments 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"
106+
107+
// Storing communication preference
108+
HSET user:alice:knowledge:pref:002 user_id "alice" content "likes detailed explanations with examples" 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"
109+
110+
// Store work schedule preference
111+
HSET user:alice:knowledge:pref:003 user_id "alice" content "works remotely on Fridays" importance 7 timestamp 1717935000 embedding "\x40\x80\x00\x00\x3f\x00\x00\x00\x40\x40\x00\x00\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x60\x00\x00\x40\x00\x00\x00\x3f\x40\x00\x00"
112+
113+
// Store health information
114+
HSET user:alice:knowledge:personal:001 user_id "alice" content "allergic to shellfish and nuts" 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"
115+
116+
// Store pet information
117+
HSET user:alice:knowledge:personal:002 user_id "alice" content "has a golden retriever named Max, 3 years old" 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"
118+
119+
// Store family information
120+
HSET user:alice:knowledge:personal:003 user_id "alice" content "married to Bob, two kids Sarah (8) and Tom (5)" importance 9 timestamp 1717935000 embedding "\x40\x60\x00\x00\x40\x00\x00\x00\x3f\x40\x00\x00\x40\x80\x00\x00\x40\x20\x00\x00\x3f\x80\x00\x00\x40\x40\x00\x00\x3f\x00\x00\x00"
66121
```
67122

68123
### Vector Search: Semantic Memory Recall
124+
Traditional keyword search misses semantic meaning. When a user asks about "scheduling meetings," vector search can find relevant information about "prefers morning appointments" even though the keywords don't match exactly.
125+
69126
Indexing persistent memory (knowledge base) for semantically meaningful search.
70127

71-
```redis:[run_confirmation=true] Create a vector index
72-
FT.CREATE idx:kbmemory
128+
```redis:[run_confirmation=true] Create a Vector Index
129+
// Create index for semantic search
130+
FT.CREATE idx:knowledge
73131
ON HASH
74132
PREFIX 1 user:
75133
SCHEMA
76134
user_id TAG
77-
memory_type TAG
78135
content TEXT
79136
importance NUMERIC
80137
timestamp NUMERIC
81138
embedding VECTOR HNSW 6
82139
TYPE FLOAT32
83-
DIM 8 // DIM = embedding size; 8 used here for simplicity — in production, use 128 to 1536
84-
DISTANCE_METRIC COSINE // COSINE = measures semantic closeness
140+
DIM 8 // DIM = embedding size, DIM 8 is just for demo purposes. In real use, embeddings are usually 128–1536 dimensions.
141+
DISTANCE_METRIC COSINE
85142
```
86143

87144
### Search for most relevant memory entries
88-
Find the top 5 most semantically relevant knowledge memory entries for user "alice" by performing a vector similarity search on the embedding field.
89145

90-
```redis:[run_confirmation=false] Find top 5 related messages by meaning
91-
FT.SEARCH idx:kbmemory
146+
```redis:[run_confirmation=false] Find Top 5 Most Relevant Knowledge Items
147+
FT.SEARCH idx:knowledge
92148
"(@user_id:{alice}) => [KNN 5 @embedding $vec AS score]"
93149
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"
94-
RETURN 4 content memory_type importance score
150+
RETURN 4 content importance score timestamp
95151
SORTBY score ASC
96152
DIALECT 2
97153
```
98154

99-
### Search for High-Importance Knowledge Items Only
100-
This query finds the top 3 most relevant knowledge memories for user "alice" that have an importance score above 7.
101-
102-
```redis:[run_confirmation=false] Knowledge-only search
103-
FT.SEARCH idx:kbmemory
104-
"(@user_id:{alice} @memory_type:{knowledge} @importance:[7 +inf]) => [KNN 3 @embedding $vec AS score]"
105-
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"
106-
RETURN 4 content importance score timestamp
107-
SORTBY score ASC
108-
DIALECT 2
155+
```redis:[run_confirmation=false] Search High-Importance Items Only
156+
FT.SEARCH idx:knowledge
157+
"(@user_id:{alice} @importance:[8 +inf]) => [KNN 3 @embedding $vec AS score]"
158+
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"
159+
RETURN 4 content importance score timestamp
160+
SORTBY score ASC
161+
DIALECT 2
109162
```
110-
111-
### Search Working Memory Excluding Messages Older Than a Certain Timestamp
112-
Retrieve the most similar knowledge memories for user "alice" that were created after a given timestamp (e.g., 1717935000), ensuring you only get recent context:
113-
```redis:[run_confirmation=false] Session-only search
114-
FT.SEARCH idx:kbmemory
115-
"(@user_id:{alice} @memory_type:{knowledge} @timestamp:[1717935000 +inf]) => [KNN 5 @embedding $vec AS score]"
116-
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"
117-
RETURN 4 content timestamp memory_type score
118-
SORTBY score ASC
119-
DIALECT 2
163+
```redis:[run_confirmation=false] Search Recent Knowledge Only
164+
FT.SEARCH idx:knowledge
165+
"(@user_id:{alice} @timestamp:[1717935000 +inf]) => [KNN 5 @embedding $vec AS score]"
166+
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"
167+
RETURN 4 content timestamp score
168+
SORTBY score ASC
169+
DIALECT 2
120170
```
121171

122-
### Monitoring Memory State
123-
Use these queries to inspect what’s stored in memory.
172+
### Memory State Monitoring
173+
Understanding what's stored in memory helps debug issues, optimize performance, and ensure data quality. It's also essential for user privacy compliance.
174+
```redis:[run_confirmation=false] Monitor user sessions
175+
// Scan 10,000 keys to find user sessions
176+
SCAN 0 MATCH user:*:history:* COUNT 10000
124177
125-
```redis:[run_confirmation=false] Check memory state
126-
// Check active session memory
127-
HGETALL user:alice:knowledge:pref:001 // Example for one preference item
128-
129-
// View user knowledge
130-
HGETALL user:alice:knowledge:pref:001
131-
132-
// Search user's memories
133-
FT.SEARCH idx:kbmemory
134-
"@user_id:{alice}"
135-
RETURN 3 content memory_type importance
178+
// Get session statistics
179+
LLEN user:alice:history:session_001
180+
TTL user:alice:history:session_001
136181
```
137-
138182
### Data Cleanup
139-
140-
For privacy compliance, delete all user-related keys.
141-
142-
```redis:[run_confirmation=true] Complete user removal
183+
```redis:[run_confirmation=true] Delete user data
184+
// Remove all user data (GDPR compliance)
185+
DEL user:alice:history:session_001
186+
DEL user:alice:history:session_002
187+
DEL user:alice:rate_limit
143188
DEL user:alice:knowledge:pref:001
144189
DEL user:alice:knowledge:pref:002
190+
DEL user:alice:knowledge:pref:003
145191
DEL user:alice:knowledge:personal:001
146192
DEL user:alice:knowledge:personal:002
193+
DEL user:alice:knowledge:personal:003
147194
DEL user:alice:knowledge:work:001
148195
DEL user:alice:knowledge:work:002
149-
DEL vmemory:alice:001
150-
DEL vmemory:alice:kb:001
196+
DEL user:alice:knowledge:work:003
151197
```
152198

153199
### Next Steps

0 commit comments

Comments
 (0)