Architecture Overview

- Profile: Learning style, pace, strengths, goals
- Episodic Memory: Topic discussions, quiz results, explanations given
Setup: Initialize Tutor
Install the EverOS SDK:pip install everos
from everos import EverOS
import time
client = EverOS()
memories = client.v1.memories
class AITutor:
def __init__(self, subject: str):
self.subject = subject
def store_interaction(self, student_id: str, student_message: str, tutor_response: str):
"""Store a tutoring interaction."""
now = int(time.time() * 1000)
memories.add(
user_id=student_id,
messages=[
{"role": "user", "timestamp": now, "content": student_message},
{"role": "assistant", "timestamp": now + 1000, "content": tutor_response},
],
)
def store_student_message(self, student_id: str, content: str):
"""Store a student's message (e.g., learning goals)."""
memories.add(
user_id=student_id,
messages=[
{"role": "user", "timestamp": int(time.time() * 1000), "content": content},
],
)
def set_learning_goals(self, student_id: str, learning_goals: list):
"""Record a student's learning goals."""
goals_text = ", ".join(learning_goals)
self.store_student_message(
student_id=student_id,
content=f"My learning goals for {self.subject}: {goals_text}",
)
Track Learning Progress
Store quiz results and topic discussions to build a picture of student progress.def record_quiz_result(self, student_id: str, topic: str, score: int, max_score: int, missed_concepts: list = None):
"""Record a quiz or assessment result."""
percentage = (score / max_score) * 100
result_message = f"Quiz completed on {topic}. Score: {score}/{max_score} ({percentage:.0f}%)."
if missed_concepts:
result_message += f" Concepts to review: {', '.join(missed_concepts)}."
if percentage >= 90:
result_message += " Excellent understanding demonstrated."
elif percentage >= 70:
result_message += " Good progress, some areas need reinforcement."
else:
result_message += " This topic needs more practice."
self.store_interaction(student_id, f"I just finished the {topic} quiz.", result_message)
def record_explanation(self, student_id: str, topic: str, difficulty_level: str, understood: bool):
"""Record when a concept is explained."""
status = "understood" if understood else "needs more explanation"
message = f"Explained {topic} at {difficulty_level} level. Student {status}."
if not understood:
message += " Will revisit with different approach."
self.store_interaction(
student_id,
f"Can you explain {topic} at a {difficulty_level} level?",
message,
)
Identify Knowledge Gaps
Search memories to identify areas where the student struggles.def identify_knowledge_gaps(self, student_id: str) -> list:
"""Analyze memory to find topics needing review."""
resp = memories.search(
filters={"user_id": student_id},
query="needs review struggled difficult missed concepts not understood",
method="vector",
memory_types=["episodic_memory"],
top_k=20,
)
results = resp.get("results", [])
# Extract topics mentioned in struggling contexts
gaps = []
for mem in results:
content = mem.get("memory", "").lower()
if any(word in content for word in ["review", "struggled", "difficult", "missed", "not understood"]):
gaps.append(mem.get("memory"))
return gaps
def get_strong_topics(self, student_id: str) -> list:
"""Find topics the student has mastered."""
resp = memories.search(
filters={"user_id": student_id},
query="excellent mastered understood good progress correct",
method="vector",
memory_types=["episodic_memory"],
top_k=20,
)
results = resp.get("results", [])
strengths = [
mem.get("memory")
for mem in results
if any(word in mem.get("memory", "").lower()
for word in ["excellent", "mastered", "understood well", "90%", "100%"])
]
return strengths
Schedule Reviews with Episodic Memory
Store review reminders as part of the tutoring conversation. Search for them later to surface due reviews.def schedule_review(self, student_id: str, topic: str, review_date_str: str):
"""Schedule a topic review by storing it as an episodic memory."""
self.store_interaction(
student_id,
f"When should I review {topic}?",
f"You should review {topic} on {review_date_str}. This topic needs reinforcement based on recent quiz results.",
)
def get_due_reviews(self, student_id: str) -> list:
"""Search for stored review reminders."""
resp = memories.search(
filters={"user_id": student_id},
query="review remember study practice scheduled review",
method="vector",
memory_types=["episodic_memory"],
top_k=10,
)
return [mem.get("memory") for mem in resp.get("results", [])]
Personalized Question Generation
Use memory context to generate adaptive questions.def generate_adaptive_question(self, student_id: str, topic: str) -> dict:
"""Generate a question adapted to student's level."""
# Get student's profile and learning style
profile_resp = memories.search(
filters={"user_id": student_id},
query=f"learning style pace {topic}",
method="vector",
memory_types=["profile"],
top_k=5,
)
profile_memories = profile_resp.get("results", [])
# Get topic progress
progress_resp = memories.search(
filters={"user_id": student_id},
query=f"{topic} quiz score understanding",
method="vector",
memory_types=["episodic_memory"],
top_k=5,
)
progress_memories = progress_resp.get("results", [])
# Format for LLM
context = {
"profile": [m.get("memory") for m in profile_memories],
"progress": [m.get("memory") for m in progress_memories],
"topic": topic,
}
# Generate question with LLM (placeholder)
return {
"context": context,
"prompt": f"Generate a {topic} question appropriate for this student's level",
}
Complete AI Tutor Implementation
from everos import EverOS
import time
from datetime import datetime, timedelta
client = EverOS()
memories = client.v1.memories
class AITutor:
def __init__(self, subject: str):
self.subject = subject
def _store(self, student_id: str, student_msg: str, tutor_msg: str):
"""Store a tutoring exchange."""
now = int(time.time() * 1000)
memories.add(
user_id=student_id,
messages=[
{"role": "user", "timestamp": now, "content": student_msg},
{"role": "assistant", "timestamp": now + 1000, "content": tutor_msg},
],
)
def _search(self, student_id: str, query: str,
memory_types: list = None, top_k: int = 5) -> list:
"""Search student memories."""
resp = memories.search(
filters={"user_id": student_id},
query=query,
method="vector",
memory_types=memory_types or ["episodic_memory", "profile"],
top_k=top_k,
)
return resp.get("results", [])
def study_session(self, student_id: str, student_message: str) -> str:
"""Handle a study session interaction."""
# Get learning context
context = self._get_learning_context(student_id, student_message)
# Get due reminders
reminders = self._get_reminders(student_id)
# Generate personalized response (implement with your LLM)
response = self._generate_response(student_message, context, reminders)
# Store the full exchange
self._store(student_id, student_message, response)
return response
def record_assessment(self, student_id: str, topic: str, score: int, total: int, notes: str = ""):
"""Record quiz/assessment results."""
pct = (score / total) * 100
tutor_msg = f"Assessment on {topic}: {score}/{total} ({pct:.0f}%). {notes}"
self._store(student_id, f"I just completed the {topic} assessment.", tutor_msg)
# Schedule review if score is low
if pct < 80:
review_date = datetime.now() + timedelta(days=3)
self._store(
student_id,
f"When should I review {topic}?",
f"You should review {topic} by {review_date.strftime('%B %d')} - you scored {pct:.0f}%.",
)
def _get_learning_context(self, student_id: str, query: str) -> dict:
return {
"profile": self._search(student_id, query, memory_types=["profile"]),
"progress": self._search(student_id, query, memory_types=["episodic_memory"]),
"gaps": self._search(student_id, "struggled difficult needs review"),
}
def _get_reminders(self, student_id: str) -> list:
return self._search(
student_id,
"review remember practice scheduled",
memory_types=["episodic_memory"],
)
def _generate_response(self, message: str, context: dict, reminders: list) -> str:
# Implement with your LLM
return f"[Tutor response based on {len(context['progress'])} progress memories]"
# Usage Example
tutor = AITutor("Calculus")
# Set learning goals
memories.add(
user_id="student_emma",
messages=[
{"role": "user", "timestamp": int(time.time() * 1000), "content": "My learning goals for Calculus: pass the AP exam, understand derivatives and integrals"},
],
)
# Study session
response = tutor.study_session("student_emma",
"I'm having trouble understanding derivatives. Can you explain?")
print(f"Tutor: {response}")
# Record assessment
tutor.record_assessment("student_emma", "Basic Derivatives", 7, 10,
"Struggled with chain rule applications")
# Another session - tutor now knows about the struggle
response = tutor.study_session("student_emma",
"Can we practice more derivative problems?")
# Response will be informed by previous assessment results
Spaced Repetition with Episodic Memory
Implement spaced repetition by storing review schedules as episodic memories and searching for them when needed.def schedule_spaced_reviews(self, student_id: str, topic: str, mastery_level: int):
"""Schedule reviews using spaced repetition intervals."""
# Intervals based on mastery (1 = new, 5 = mastered)
intervals = {
1: [1, 3, 7], # New: review in 1, 3, 7 days
2: [3, 7, 14], # Learning: 3, 7, 14 days
3: [7, 14, 30], # Familiar: 7, 14, 30 days
4: [14, 30, 60], # Good: 14, 30, 60 days
5: [30, 90], # Mastered: 30, 90 days
}
review_days = intervals.get(mastery_level, [7, 14, 30])
for days in review_days:
review_date = datetime.now() + timedelta(days=days)
self._store(
student_id,
f"Schedule my next review for {topic}.",
f"Scheduled review: {topic} on {review_date.strftime('%B %d, %Y')}. "
f"Current mastery level: {mastery_level}/5.",
)
Best Practices
Learning Profile Construction
Learning Profile Construction
Build rich profiles over time. Store learning preferences as messages so EverOS extracts them into profile memories.
# Store learning preferences - EverOS extracts these into profile memories
preferences = [
"I learn better with visual examples",
"I prefer to practice problems before theory",
"I usually study in the evenings",
"My goal is to pass the AP Calculus exam",
]
for pref in preferences:
memories.add(
user_id="student_emma",
messages=[
{"role": "user", "timestamp": int(time.time() * 1000), "content": pref},
],
)
Progress Granularity
Progress Granularity
Record specific, actionable progress notes.
# Good: Specific and actionable
"Scored 85% on integration by parts. Struggled with choosing u and dv."
# Bad: Too vague
"Did okay on integration quiz."
Adaptive Difficulty
Adaptive Difficulty
Use memory to adjust question difficulty.
def get_difficulty_level(context: dict) -> str:
recent_scores = [m for m in context["progress"] if "%" in m.get("memory", "")]
if not recent_scores:
return "medium"
# Parse scores and adjust
# High scores -> harder questions
# Low scores -> easier questions, more scaffolding
Next Steps
Memory Types
Learn about MemCell and how profile and episodic memories work
Python Integration
Production patterns for tutoring applications