docs/platform/features/advanced-retrieval.mdx
Advanced Retrieval gives you precise control over how memories are found and ranked. While basic search uses semantic similarity, these advanced options help you find exactly what you need, when you need it.
Reorders results using deep semantic understanding to put the most relevant memories first.
<Tabs> <Tab title="When to Use"> - Need the most relevant result at the top - Result order is critical for your application - Want consistent quality across different queries - Building user-facing features where accuracy matters </Tab> <Tab title="How it Works"> ```python Python # Get the most relevant travel plans first results = client.search( query="What are my upcoming travel plans?", rerank=True, filters={"user_id": "user123"}, )</Tab>
<Tab title="Performance">
- **Latency**: 150-200ms additional
- **Accuracy**: Significantly improved
- **Ordering**: Much more relevant
- **Best for**: Top-N precision, user-facing results
</Tab>
</Tabs>
## Real-World Use Cases
<Tabs>
<Tab title="Personal AI Assistant">
```python Python
# Smart home assistant finding device preferences
results = client.search(
query="How do I like my bedroom temperature?",
rerank=True, # Closest-matching preferences first
filters={"user_id": "user123"},
)
# Finds: "Keep bedroom at 68°F", "Too cold last night at 65°F", etc.
</Tab>
<Tab title="Healthcare AI">
```python Python
# Critical medical information needs perfect accuracy
results = client.search(
query="Patient allergies and contraindications",
rerank=True, # Most important info first
filters={"user_id": "patient789"},
)
# Ensures critical allergy info appears first
</Tab>
</Tabs>
## Choosing the Right Configuration
### Recommended Configurations
`rerank` is the only lever here that changes result *order*. `filters`, `top_k`, and `threshold` change *which* memories come back, not how they're ordered. The two functions below send the same query and filters; the only difference is the `rerank` flag.
<CodeGroup>
```python Python
# Fast path - use for exploratory search, or anywhere the user scans a list
# of results instead of trusting result #1 (dashboards, "show me everything
# about X" style queries). No reranking overhead.
def quick_search(query, user_id):
return client.search(
query=query,
filters={"user_id": user_id},
)
# Precision path - use when only the top result reaches the user, e.g. an
# agent that injects a single fact into a prompt. Reranking (see above)
# re-scores every match and moves the closest one to position 1, at the
# cost of ~150-200ms added latency.
def standard_search(query, user_id):
return client.search(
query=query,
rerank=True,
filters={"user_id": user_id},
)
// Fast path - use for exploratory search, or anywhere the user scans a list
// of results instead of trusting result #1 (dashboards, "show me everything
// about X" style queries). No reranking overhead.
function quickSearch(query, userId) {
return client.search(query, {
filters: { user_id: userId },
});
}
// Precision path - use when only the top result reaches the user, e.g. an
// agent that injects a single fact into a prompt. Reranking (see above)
// re-scores every match and moves the closest one to position 1, at the
// cost of ~150-200ms added latency.
function standardSearch(query, userId) {
return client.search(query, {
filters: { user_id: userId },
rerank: true,
});
}
What changes in the response: both calls return the same fields on each memory (see the Search Memories API reference for the full response shape). The only difference is the order of the results array, the same effect shown in the Reranking example above: quick_search returns results ranked by raw similarity, standard_search returns the reranked order.
# Performance monitoring example
import time
start_time = time.time()
results = client.search(
query="user preferences",
rerank=True, # +150ms
filters={"user_id": "user123"},
)
latency = time.time() - start_time
print(f"Search completed in {latency:.2f}s")
run_id to reduce search space