intermediate
Build a Personal AI Tutor
Create an AI tutor that remembers what you've learned, tracks your progress, and adapts to your learning style using Memoid memory.
Prerequisites
- Python 3.8+
- Memoid account with API key
- OpenAI API key (for chat responses)
What You’ll Build
A personalized AI tutor that:
- Remembers topics you’ve studied
- Tracks areas where you struggle
- Adapts explanations to your learning style
- Provides spaced repetition reminders
Prerequisites
- Python 3.8+
- Memoid API key (sign up free, get key from dashboard)
- OpenAI API key (for generating tutor responses)
Note: Memoid handles all memory storage and search server-side. Your OpenAI key is only used for generating the tutor’s responses.
Setup
pip install openai requests Full Implementation
import os
import requests
from openai import OpenAI
MEMOID_API_KEY = os.environ["MEMOID_API_KEY"]
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
MEMOID_BASE_URL = "https://api.memoid.dev/v1"
class PersonalAITutor:
def __init__(self):
self.openai = OpenAI(api_key=OPENAI_API_KEY)
self.headers = {
"Authorization": f"Bearer {MEMOID_API_KEY}",
"Content-Type": "application/json"
}
def get_learning_context(self, student_id: str, topic: str) -> dict:
"""Get student's history with this topic from Memoid."""
response = requests.post(
f"{MEMOID_BASE_URL}/search",
headers=self.headers,
json={
"query": f"studying {topic}",
"user_id": student_id,
"limit": 10
}
)
context = {"previous_topics": [], "struggles": [], "strengths": []}
if response.status_code == 200:
memories = response.json().get("results", [])
for m in memories:
memory = m.get("memory", "")
if "struggled" in memory.lower() or "confused" in memory.lower():
context["struggles"].append(memory)
elif "understood" in memory.lower() or "learned" in memory.lower():
context["strengths"].append(memory)
else:
context["previous_topics"].append(memory)
return context
def store_learning(self, student_id: str, topic: str, interaction: str, understood: bool):
"""Store learning interaction in Memoid."""
status = "understood" if understood else "needs_review"
requests.post(
f"{MEMOID_BASE_URL}/memories",
headers=self.headers,
json={
"messages": [{"role": "user", "content": interaction}],
"user_id": student_id,
"metadata": {"type": "learning", "topic": topic, "status": status}
}
)
def ask(self, student_id: str, topic: str, question: str) -> str:
"""Handle a learning question."""
context = self.get_learning_context(student_id, topic)
system_prompt = f"""You are a patient, encouraging AI tutor.
Your student's learning profile:
- Previous topics: {', '.join(context['previous_topics'][:3]) or 'New student'}
- Areas of struggle: {', '.join(context['struggles'][:3]) or 'None identified yet'}
- Strengths: {', '.join(context['strengths'][:3]) or 'Building foundation'}
Teaching guidelines:
1. Build on what the student already knows
2. Use analogies and examples
3. If they've struggled with related concepts, provide extra clarity
4. Be encouraging and celebrate progress"""
response = self.openai.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"Topic: {topic}\n\nQuestion: {question}"}
]
)
answer = response.choices[0].message.content
interaction = f"Studying {topic}: Asked about '{question}'. Tutor explained the concept."
self.store_learning(student_id, topic, interaction, understood=True)
return answer
def mark_confusion(self, student_id: str, topic: str, concept: str):
"""Mark a concept as confusing for review."""
interaction = f"Student struggled with {concept} while studying {topic}"
self.store_learning(student_id, topic, interaction, understood=False)
def get_review_suggestions(self, student_id: str) -> list:
"""Get topics that need review."""
response = requests.get(
f"{MEMOID_BASE_URL}/memories",
headers=self.headers,
params={"user_id": student_id, "limit": 50}
)
review_topics = []
if response.status_code == 200:
memories = response.json().get("results", [])
for m in memories:
metadata = m.get("metadata", {})
if metadata.get("status") == "needs_review":
review_topics.append({
"topic": metadata.get("topic", "Unknown"),
"memory": m.get("memory", "")
})
return review_topics[:5]
def main():
tutor = PersonalAITutor()
student_id = "student_alex"
print("Personal AI Tutor")
print("=" * 40)
print("Commands: 'quit', 'confused', 'review'\n")
current_topic = None
while True:
user_input = input("You: ").strip()
if not user_input:
continue
if user_input.lower() == "quit":
break
if user_input.lower() == "confused":
if current_topic:
concept = input("What concept is confusing? ")
tutor.mark_confusion(student_id, current_topic, concept)
print("Noted! I'll explain this differently next time.\n")
continue
if user_input.lower() == "review":
topics = tutor.get_review_suggestions(student_id)
if topics:
print("\nTopics to review:")
for t in topics:
print(f" - {t['topic']}: {t['memory']}")
else:
print("\nNo topics need review right now!")
print()
continue
if ":" in user_input:
topic, question = user_input.split(":", 1)
current_topic = topic.strip()
question = question.strip()
else:
question = user_input
if not current_topic:
current_topic = input("What topic are you studying? ")
response = tutor.ask(student_id, current_topic, question)
print(f"\nTutor: {response}\n")
if __name__ == "__main__":
main() Running
export MEMOID_API_KEY="your-memoid-key"
export OPENAI_API_KEY="your-openai-key"
python tutor.py Example Session
Personal AI Tutor
========================================
Commands: 'quit', 'confused', 'review'
You: Python: What is a list comprehension?
Tutor: A list comprehension is a concise way to create lists in Python.
Instead of:
squares = []
for x in range(10):
squares.append(x ** 2)
You can write:
squares = [x ** 2 for x in range(10)]
You: confused
What concept is confusing? the syntax order
Noted! I'll explain this differently next time.
You: Can you explain the syntax again?
Tutor: I noticed you found the syntax order confusing, so let me
break it down differently... Key Features
- Adaptive Teaching: Memoid tracks struggles and the tutor adjusts explanations
- Spaced Repetition: Mark topics for review with metadata
- Knowledge Building: References previous learning when explaining new concepts