Skip to content

Commit 38051e4

Browse files
feat: Integrate Valkey with LangGraph store to enable semantic search scenarios (#735)
Enables Valkey use to store long term memories with documents along with semantic search support. --------- Co-authored-by: Michael Chin <[email protected]>
1 parent 72f509f commit 38051e4

37 files changed

+15809
-146
lines changed

libs/langgraph-checkpoint-aws/README.md

Lines changed: 257 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ This package provides multiple persistence solutions for LangGraph agents:
1717

1818
### Valkey Storage Solutions
1919
1. **Checkpoint storage** with Valkey (Redis-compatible)
20+
2. **Intelligent caching** for LLM responses and computation results
21+
3. **Document storage** with vector search capabilities
2022

2123
## Installation
2224

@@ -26,19 +28,21 @@ You can install the package using pip:
2628
# Base package (includes Bedrock AgentCore Memory components)
2729
pip install langgraph-checkpoint-aws
2830

29-
# With Valkey support
31+
# Optional Valkey support
3032
pip install 'langgraph-checkpoint-aws[valkey]'
3133

3234
```
3335

3436
## Components
3537

36-
This package provides four main components:
38+
This package provides following main components:
3739

3840
1. **AgentCoreMemorySaver** - AWS Bedrock-based checkpoint storage
39-
2. **DynamoDBSaver** - DynamoDB-based checkpoint storage with S3 offloading
40-
3. **ValkeySaver** - Valkey checkpoint storage
41-
4. **AgentCoreMemoryStore** - AWS Bedrock-based document store
41+
2. **AgentCoreMemoryStore** - AWS Bedrock-based document store
42+
3. **ValkeyCache** - Valkey LLM response cache
43+
4. **ValkeySaver** - Valkey checkpoint storage
44+
5. **ValkeyStore** - Valkey document store
45+
6. **DynamoDBSaver** - DynamoDB-based checkpoint storage with S3 offloading
4246

4347

4448
## Usage
@@ -153,8 +157,36 @@ response = graph.invoke(
153157
config=config
154158
)
155159
```
160+
### 3. Valkey Cache - LLM Response caching
161+
Intelligent caching to improve performance and reduce costs:
156162

157-
### 3. DynamoDB Checkpoint Storage
163+
```python
164+
from langgraph_checkpoint_aws import ValkeyCache
165+
from langchain_aws import ChatBedrockConverse
166+
167+
# Initialize cache
168+
with ValkeyCache.from_conn_string(
169+
"valkey://localhost:6379",
170+
ttl_seconds=3600, # 1 hour TTL
171+
pool_size=10
172+
) as cache:
173+
174+
# Use cache with your LLM calls
175+
model = ChatBedrockConverse(
176+
model="us.anthropic.claude-sonnet-4-5-20250929-v1:0"
177+
)
178+
179+
# Cache expensive prompts/computations
180+
cache_key = "expensive_computation_key"
181+
result = cache.get([cache_key])
182+
183+
if not result:
184+
# Compute and cache result
185+
prompt: str = "Your expensive prompt"
186+
response = model.invoke([HumanMessage(content=prompt)])
187+
cache.set({cache_key: (response.content, 3600)}) # Cache for 1 hour
188+
```
189+
### 4. DynamoDB Checkpoint Storage
158190

159191
```python
160192
from langgraph.graph import StateGraph
@@ -193,7 +225,7 @@ config = {"configurable": {"thread_id": "session-1"}}
193225
result = graph.invoke(1, config)
194226
```
195227

196-
### 4. Valkey Checkpoint Storage
228+
### 5. Valkey Checkpoint Storage
197229

198230
```python
199231
from langgraph.graph import StateGraph
@@ -216,13 +248,94 @@ with ValkeySaver.from_conn_string(
216248
result = graph.invoke(1, config)
217249
```
218250

251+
### 6. Valkey Store for Document Storage
252+
253+
Document storage with vector search capabilities using ValkeyIndexConfig:
254+
255+
```python
256+
from langchain_aws import BedrockEmbeddings
257+
from langgraph_checkpoint_aws import ValkeyStore
258+
# Initialize Bedrock embeddings
259+
embeddings = BedrockEmbeddings(
260+
model_id="amazon.titan-embed-text-v1",
261+
region_name=AWS_REGION
262+
)
263+
# Basic usage with ValkeyIndexConfig
264+
with ValkeyStore.from_conn_string(
265+
"valkey://localhost:6379",
266+
index={
267+
"collection_name": "my_documents",
268+
"dims": 1536,
269+
"embed": embeddings,
270+
"fields": ["text", "author"],
271+
"timezone": "UTC",
272+
"index_type": "hnsw"
273+
},
274+
ttl={"default_ttl": 60.0} # 1 hour TTL
275+
) as store:
276+
277+
# Setup vector search index
278+
store.setup()
279+
280+
# Store documents
281+
store.put(
282+
("documents", "user123"),
283+
"report_1",
284+
{
285+
"text": "Machine learning report on customer behavior analysis...",
286+
"tags": ["ml", "analytics", "report"],
287+
"author": "data_scientist"
288+
}
289+
)
290+
291+
# Search documents
292+
results = store.search(
293+
("documents",),
294+
query="machine learning customer analysis",
295+
filter={"author": "data_scientist"},
296+
limit=10
297+
)
298+
299+
# Advanced HNSW configuration for performance tuning
300+
with ValkeyStore.from_conn_string(
301+
"valkey://localhost:6379",
302+
index={
303+
"collection_name": "high_performance_docs",
304+
"dims": 768,
305+
"embed": embeddings,
306+
"fields": ["text", "title", "summary"],
307+
"timezone": "America/New_York",
308+
"index_type": "hnsw",
309+
"hnsw_m": 32, # More connections for better recall
310+
"hnsw_ef_construction": 400, # Higher construction quality
311+
"hnsw_ef_runtime": 20, # Better search accuracy
312+
}
313+
) as store:
314+
# Optimized for high-accuracy vector search
315+
pass
316+
317+
# FLAT index for exact search (smaller datasets)
318+
with ValkeyStore.from_conn_string(
319+
"valkey://localhost:6379",
320+
index={
321+
"collection_name": "exact_search_docs",
322+
"dims": 384,
323+
"embed": embeddings,
324+
"fields": ["text"],
325+
"index_type": "flat" # Exact search, no approximation
326+
}
327+
) as store:
328+
# Exact vector search for smaller datasets
329+
pass
330+
```
331+
219332
## Async Usage
220333

221334
All components support async operations:
222335

223336
```python
224337
from langgraph_checkpoint_aws.async_saver import AsyncBedrockSessionSaver
225-
from langgraph_checkpoint_aws.checkpoint.valkey import AsyncValkeySaver
338+
from langgraph_checkpoint_aws import AsyncValkeySaver
226339
from langgraph_checkpoint_aws.checkpoint.dynamodb import DynamoDBSaver
227340

228341
# Async Bedrock usage
@@ -233,10 +346,23 @@ session_id = (await session_saver.session_client.create_session()).session_id
233346
checkpointer = DynamoDBSaver(table_name="my-checkpoints", region_name="us-west-2")
234347
result = await graph.ainvoke(1, {"configurable": {"thread_id": "session-1"}})
235348

236-
# Async Valkey usage
349+
# Async ValkeySaver usage
237350
async with AsyncValkeySaver.from_conn_string("valkey://localhost:6379") as checkpointer:
238351
graph = builder.compile(checkpointer=checkpointer)
239352
result = await graph.ainvoke(1, {"configurable": {"thread_id": "session-1"}})
353+
354+
# Async ValkeyStore usage
355+
async with AsyncValkeyStore.from_conn_string("valkey://localhost:6379") as store:
356+
namespace = ("example",)
357+
key = "key"
358+
data = {
359+
"message": "Sample message",
360+
"timestamp": datetime.now().isoformat(),
361+
"status": "success"
362+
}
363+
await store.setup()
364+
await store.aput(namespace, key, data)
365+
result = await store.aget(namespace, key)
240366
```
241367

242368
## Configuration Options
@@ -305,6 +431,16 @@ Valkey components support these common configuration options:
305431
- **Batch Operations**: Efficient bulk operations for better throughput
306432
- **Async Support**: Non-blocking operations for high concurrency
307433

434+
#### ValkeyCache Options
435+
```python
436+
ValkeyCache(
437+
client: Valkey,
438+
prefix: str = "langgraph:cache:", # Key prefix
439+
ttl: float | None = None, # Default TTL in seconds
440+
serde: SerializerProtocol | None = None
441+
)
442+
```
443+
308444
#### ValkeySaver Options
309445
```python
310446
valkey_client = Valkey.from_url("valkey://localhost:6379")
@@ -314,6 +450,107 @@ ValkeySaver(
314450
serde: SerializerProtocol | None = None # Custom serialization
315451
)
316452
```
453+
#### ValkeyStore Options
454+
```python
455+
ValkeyStore(
456+
client: Valkey,
457+
index: ValkeyIndexConfig | None = None, # Valkey-specific vector search configuration
458+
ttl: TTLConfig | None = None # TTL configuration
459+
)
460+
461+
# ValkeyIndexConfig - Enhanced vector search configuration
462+
from langgraph_checkpoint_aws.store.valkey import ValkeyIndexConfig
463+
464+
index_config = {
465+
# Basic configuration
466+
"collection_name": "my_documents", # Index collection name
467+
"dims": 1536, # Vector dimensions
468+
"embed": embeddings, # Embedding model
469+
"fields": ["text", "content"], # Fields to index
470+
471+
# Valkey-specific configuration
472+
"timezone": "UTC", # Timezone for operations (default: "UTC")
473+
"index_type": "hnsw", # Algorithm: "hnsw" or "flat" (default: "hnsw")
474+
475+
# HNSW performance tuning parameters
476+
"hnsw_m": 16, # Connections per layer (default: 16)
477+
"hnsw_ef_construction": 200, # Construction search width (default: 200)
478+
"hnsw_ef_runtime": 10, # Runtime search width (default: 10)
479+
}
480+
481+
# TTL Configuration
482+
ttl_config = {
483+
"default_ttl": 60.0 # Default TTL in minutes
484+
}
485+
```
486+
##### Algorithm Selection Guide
487+
488+
**HNSW (Hierarchical Navigable Small World)**
489+
- **Best for**: Large datasets (>10K vectors), fast approximate search
490+
- **Trade-off**: Speed vs accuracy - configurable via parameters
491+
- **Use cases**: Real-time search, large document collections, production systems
492+
493+
**FLAT (Brute Force)**
494+
- **Best for**: Small datasets (<10K vectors), exact search requirements
495+
- **Trade-off**: Perfect accuracy but slower on large datasets
496+
- **Use cases**: High-precision requirements, smaller collections, research
497+
498+
#### Performance Tuning Parameters
499+
500+
**hnsw_m (Connections per layer)**
501+
- **Range**: 4-64 (default: 16)
502+
- **Higher values**: Better recall, more memory usage
503+
- **Lower values**: Faster search, less memory, lower recall
504+
- **Recommendation**: 16-32 for most use cases
505+
506+
**hnsw_ef_construction (Construction search width)**
507+
- **Range**: 100-800 (default: 200)
508+
- **Higher values**: Better index quality, slower construction
509+
- **Lower values**: Faster construction, potentially lower quality
510+
- **Recommendation**: 200-400 for production systems
511+
512+
**hnsw_ef_runtime (Query search width)**
513+
- **Range**: 10-500 (default: 10)
514+
- **Higher values**: Better recall, slower queries
515+
- **Lower values**: Faster queries, potentially lower recall
516+
- **Recommendation**: 10-50 depending on speed/accuracy requirements
517+
518+
##### Configuration Examples
519+
520+
```python
521+
# High-speed configuration (prioritize speed)
522+
speed_config = {
523+
"collection_name": "fast_search",
524+
"index_type": "hnsw",
525+
"hnsw_m": 8, # Fewer connections
526+
"hnsw_ef_construction": 100, # Faster construction
527+
"hnsw_ef_runtime": 10, # Fast queries
528+
}
529+
530+
# High-accuracy configuration (prioritize recall)
531+
accuracy_config = {
532+
"collection_name": "precise_search",
533+
"index_type": "hnsw",
534+
"hnsw_m": 32, # More connections
535+
"hnsw_ef_construction": 400, # Better construction
536+
"hnsw_ef_runtime": 50, # More thorough search
537+
}
538+
539+
# Balanced configuration (good speed/accuracy trade-off)
540+
balanced_config = {
541+
"collection_name": "balanced_search",
542+
"index_type": "hnsw",
543+
"hnsw_m": 16, # Default connections
544+
"hnsw_ef_construction": 200, # Default construction
545+
"hnsw_ef_runtime": 20, # Moderate search width
546+
}
547+
548+
# Exact search configuration (perfect accuracy)
549+
exact_config = {
550+
"collection_name": "exact_search",
551+
"index_type": "flat", # No HNSW parameters needed
552+
}
553+
```
317554

318555
## Development
319556

@@ -650,6 +887,17 @@ with ValkeySaver.from_conn_string(
650887
) as checkpointer:
651888
pass
652889
```
890+
#### Batch Operations
891+
```python
892+
# Use batch operations for better throughput
893+
cache.set({
894+
"key1": (value1, 3600),
895+
"key2": (value2, 1800),
896+
"key3": (value3, 7200)
897+
})
898+
899+
results = cache.get(["key1", "key2", "key3"])
900+
```
653901

654902
## Security Considerations
655903

0 commit comments

Comments
 (0)