File size: 5,752 Bytes
25732fb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | """
Teaching Agent - Autonomous content generation and delivery
"""
import json
from .base_agent import BaseAgent
from llm_service import LLMService
from agent_knowledge.rules.teaching_rules import TeachingRuleEngine
from agent_communication.message_bus import AgentMessageBus
from agent_communication.protocols import MessageProtocols
from datetime import datetime
import random
class TeachingAgent(BaseAgent):
"""
Autonomous agent responsible for:
- Generating personalized lessons
- Adapting teaching style
- Selecting examples based on student performance
"""
def __init__(self):
super().__init__("TA-001", "TeachingAgent")
self.llm_service = LLMService()
self.rule_engine = TeachingRuleEngine()
self.message_bus = AgentMessageBus()
self.lessons_generated = 0
self.knowledge_level = 0.0
self.learning_style = "visual"
self.lesson_complexity = "beginner"
self.current_strategy = {}
def perceive(self, student_state):
self.update_state("perceiving")
self.log(f"Perceiving student state for user {student_state.user_id}")
# Update internal state based on student data
self.user_id = student_state.user_id
self.knowledge_level = student_state.knowledge_level
self.learning_style = student_state.learning_style or "visual"
# Determine lesson complexity based on knowledge level
if self.knowledge_level < 0.3:
self.lesson_complexity = "beginner"
elif self.knowledge_level < 0.7:
self.lesson_complexity = "intermediate"
else:
self.lesson_complexity = "advanced"
self.update_state("perceived")
return self.state
def decide(self):
self.update_state("deciding")
# Use rule engine to determine strategy
student_profile = {
"knowledge_level": self.knowledge_level,
"learning_style": self.learning_style,
# Mock recent performance for now, ideally comes from KnowledgeAgent
"recent_performance": 0.8
}
self.current_strategy = self.rule_engine.select_teaching_strategy(student_profile)
self.log(f"Selected teaching strategy: {self.current_strategy['name']}")
self.update_state("decided")
return self
def act(self, topic, prompt=None):
self.update_state("acting")
self.log(f"Generating lesson for topic: {topic.name} with strategy {self.current_strategy['name']}")
# 1. Request updated profile from KnowledgeAgent (Async/Simulated)
self.message_bus.send_message(
self.name,
"KnowledgeAgent",
MessageProtocols.KNOWLEDGE_REQUEST,
MessageProtocols.request_student_profile(self.user_id, topic.id)
)
try:
# 2. Generate Lesson Structure using Rule Engine (No LLM)
lesson_structure = self.rule_engine.generate_lesson_structure(topic, self.current_strategy)
# 3. Fill in content (Hybrid: Try Templates first, else Fallback to LLM for specific sections)
# For this MVP, we will use the structure to guide the LLM, reducing its "thinking" time
# In a full impl, we would pull pre-written content from ContentLibrary
structured_prompt = f"""
Create a lesson for topic '{topic.name}' ({topic.difficulty}) following this structure:
Strategy: {self.current_strategy['name']} ({self.current_strategy['description']})
Sections:
"""
for section in lesson_structure['sections']:
structured_prompt += f"\n- {section['title']}: {section['instruction_for_llm']}"
# Fallback to LLM for content generation but with strict structure
lesson_content = self.llm_service.generate_lesson_with_prompt(
topic.name,
topic.difficulty,
self.knowledge_level,
custom_prompt=structured_prompt
)
self.lessons_generated += 1
self.log(f"Lesson generated successfully using rule-guided structure. (Total: {self.lessons_generated})")
# Store in agent memory
self.memory.append({
"action": "lesson_generated",
"topic": topic.name,
"strategy": self.current_strategy['name'],
"complexity": self.lesson_complexity,
"user_id": self.user_id
})
self.update_state("completed")
return {
"content": lesson_content,
"metadata": {
"teaching_style": self.current_strategy.get('name', 'default'),
"complexity": self.lesson_complexity,
"example_count": self.current_strategy.get('example_count', 3),
"agent": self.name,
"generated_at": datetime.utcnow().isoformat()
}
}
except Exception as e:
self.log(f"Error generating lesson: {str(e)}", "error")
self.update_state("error")
return {"error": str(e)}
def get_statistics(self):
"""Return agent statistics"""
return {
"agent": self.name,
"lessons_generated": self.lessons_generated,
"current_style": self.current_style,
"state": self.state,
"memory_size": len(self.memory)
} |