Personal Assistant
intermediateBuild an AI assistant that learns user preferences, routines, and habits over time — and gets smarter with each interaction.
What you'll build
An AI assistant that learns your preferences, remembers your routines, and adapts its behavior over time — without explicit configuration or re-training.
Prerequisites
| Requirement | Details |
|---|---|
| Account | Free tier or above |
| API key | From your dashboard |
| SDK | Python or JavaScript |
| Time | ~20 minutes |
The difference from a chatbot
A chatbot stores and recalls conversations. A personal assistant goes further:
| Feature | Chatbot | Personal Assistant |
|---|---|---|
| Remembers what was said | Yes | Yes |
| Learns preferences | Basic | Adaptive |
| Detects patterns | No | Yes (via consolidation) |
| Predicts needs | No | Yes (via causal links) |
| Improves over time | Static | Self-organizes |
Steps
1
Store observations
Every time you learn something about the user, store it as a typed memory with appropriate metadata.
2
Categorize knowledge
Use metadata types like 'preference', 'routine', 'fact', and 'feedback' to organize what you learn.
3
Retrieve with context
When the user asks something, retrieve relevant preferences and facts to personalize the response.
4
Track feedback
When the user corrects the assistant or confirms a suggestion, store that feedback to improve future behavior.
5
Let consolidation work
Over time, consolidation strengthens confirmed preferences and prunes contradicted ones automatically.
Complete code
import os
from engramma_cloud import EngrammaClient
client = EngrammaClient(api_key=os.environ["ENGRAMMA_API_KEY"])
class PersonalAssistant:
def __init__(self, user_id: str):
self.user_id = user_id
def learn(self, observation: str, category: str = "preference"):
"""Store something learned about the user."""
client.store(
observation,
metadata={
"user_id": self.user_id,
"category": category,
"protected": category == "preference"
}
)
def recall(self, context: str, top_k: int = 5):
"""Recall relevant knowledge about the user."""
results = client.retrieve(
context,
top_k=top_k,
metadata_filter={"user_id": self.user_id}
)
return [
{"text": r.text, "confidence": r.confidence, "category": r.metadata.get("category")}
for r in results
if r.confidence > 0.5
]
def record_feedback(self, original: str, correction: str):
"""Store user feedback to update preferences."""
client.store(
f"Correction: User said '{correction}' when assistant suggested '{original}'",
metadata={
"user_id": self.user_id,
"category": "feedback",
"protected": True
}
)
def get_profile(self):
"""Retrieve the user's known preferences."""
results = client.retrieve(
"user preferences and habits",
top_k=10,
metadata_filter={
"user_id": self.user_id,
"category": "preference"
}
)
return [r.text for r in results if r.confidence > 0.6]
# Usage
assistant = PersonalAssistant("user_456")
# The assistant learns over multiple interactions
assistant.learn("User wakes up at 6:30am on weekdays", "routine")
assistant.learn("User prefers Python over JavaScript", "preference")
assistant.learn("User drinks oat milk lattes", "preference")
assistant.learn("User has standup at 9am every Monday", "routine")
# Later — assistant recalls relevant context
context = assistant.recall("morning schedule")
print(context)
# [{'text': 'User wakes up at 6:30am on weekdays', 'confidence': 0.89, 'category': 'routine'},
# {'text': 'User has standup at 9am every Monday', 'confidence': 0.82, 'category': 'routine'}]
# User corrects the assistant
assistant.record_feedback(
original="You usually have coffee at 7am",
correction="I actually switched to tea last month"
)
assistant.learn("User drinks tea in the morning (switched from coffee)", "preference")How preferences evolve
Engramma's consolidation cycle makes your assistant smarter over time:
| Time | What happens |
|---|---|
| Day 1 | Store raw observations: "User likes dark mode" |
| Day 7 | Consolidation merges similar memories: multiple "dark mode" mentions combine into one strong memory |
| Day 14 | Causal links form: "User prefers dark mode" → "User works late at night" |
| Day 30 | Contradicted facts weaken: old coffee preference fades after tea correction |
Organizing knowledge categories
Use metadata categories to structure what the assistant knows:
| Category | Examples | Protected? |
|---|---|---|
preference | "Prefers Python", "Likes dark mode" | Yes |
routine | "Standup at 9am Monday", "Gym on Wednesdays" | No |
fact | "Works at Acme Corp", "Team size is 5" | Yes |
feedback | "Correction: tea not coffee" | Yes |
observation | "Seemed stressed today", "Asked about vacations" | No |
Tip
Protect preferences and facts — they represent core knowledge. Leave routines and observations unprotected so consolidation can prune outdated ones naturally.
Predicting user needs
Once enough causal links form, you can predict what the user might need:
# After many interactions, causal links emerge
results = client.retrieve(
"What does the user need on Monday morning?",
causal=True,
metadata_filter={"user_id": "user_456"}
)
# The engine connects:
# Monday → standup at 9am → needs agenda prepared
# Monday morning → wakes at 6:30 → drinks tea → commute by 8am
for r in results:
print(f"{r.text} (confidence: {r.confidence})")
if r.causal_chain:
print(f" Because: {' → '.join(r.causal_chain)}")Next steps
- Knowledge Base — Build a self-organizing knowledge system
- Causal Queries — Master intervention and counterfactual reasoning
- Consolidation — How memories strengthen and prune over time