Version1 / agents /bloom_assess.py
Prerit018's picture
Upload 26 files
6bc3db2 verified
Raw
History Blame Contribute Delete
10.2 kB
import os
from dotenv import load_dotenv
import openai
import json
from .base_agent import BaseAgent
load_dotenv()
class BloomsAssessmentAgent(BaseAgent):
def __init__(self):
super().__init__("BloomsAssessmentAgent")
api_key = os.getenv("OPENAI_API_KEY")
self.client = openai.OpenAI(api_key=api_key)
self.bloom_levels = [
"Remembering", "Understanding", "Applying",
"Analyzing", "Evaluating", "Creating"
]
def generate_bloom_question(self, chapter, bloom_level):
system_prompt = (
f"You are an expert educator creating a {bloom_level} level question according to Bloom's Taxonomy. "
f"Generate ONE question that tests the student's ability at the {bloom_level} level for the given chapter. "
"The question should be clear, concise, and appropriate for the chapter content. "
"Return ONLY the question text, no additional formatting or explanation."
)
user_prompt = (
f"Chapter: {chapter.name}\n"
f"Modules in this chapter: {[m.name for m in chapter.modules]}\n"
f"Bloom's Level: {bloom_level}\n"
f"Generate a {bloom_level} level question."
)
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
]
)
return response.choices[0].message.content.strip()
def evaluate_bloom_answer(self, question, user_answer, bloom_level, chapter):
system_prompt = (
f"You are an expert educator evaluating a student's answer for a {bloom_level} level question. "
"Evaluate the answer based on the specific cognitive skills required for this Bloom's level. "
"Be STRICT about answer quality - vague, incomplete, or overly brief answers should receive low scores.\n\n"
"**Evaluation Criteria:**\n"
"- **Precision:** Is the answer specific and detailed enough for the Bloom's level?\n"
"- **Relevance:** Does it directly address the question asked?\n"
"- **Depth:** Does it demonstrate the expected cognitive complexity?\n"
"- **Completeness:** Are all parts of the question addressed?\n\n"
"**Automatic Penalties:**\n"
"- Answers under 15 words: Maximum score of 3\n"
"- Vague responses (yes/no, maybe, I think): Maximum score of 2\n"
"- Off-topic or irrelevant answers: Score of 0-1\n\n"
"You must respond with a JSON object containing:\n"
"1. 'score': A number between 0 and 10\n"
"2. 'feedback': Detailed explanation of the score and what was missing\n"
"3. 'level_achieved': The Bloom's level the answer demonstrates\n"
"4. 'hint': A subtle hint to guide toward better understanding (if score < 7)"
)
user_prompt = (
f"Question (Bloom's Level: {bloom_level}): {question}\n"
f"Student's Answer: {user_answer}\n"
f"Chapter Context: {chapter.name}\n"
"Evaluate this answer and provide the JSON response."
)
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
]
)
return response.choices[0].message.content.strip()
def process(self, chapter):
print(f"\n{'='*60}")
print(f"BLOOM'S TAXONOMY ASSESSMENT")
print(f"Chapter: {chapter.name}")
print(f"{'='*60}")
print("You will be asked 2 questions for each of the 6 Bloom's levels.")
print("This comprehensive assessment will evaluate your mastery of the chapter.")
results = {}
total_score = 0
questions_asked = 0
for bloom_level in self.bloom_levels:
level_scores = []
print(f"\n--- {bloom_level.upper()} LEVEL (2 Questions) ---")
for question_num in range(1, 3): # 2 questions per level
print(f"\n[Question {question_num}/2 for {bloom_level}]")
question = self.generate_bloom_question(chapter, bloom_level)
print(f"Question: {question}")
user_answer = input("Your answer: ")
evaluation_json = self.evaluate_bloom_answer(question, user_answer, bloom_level, chapter)
try:
evaluation = json.loads(evaluation_json)
score = evaluation.get('score', 0)
feedback = evaluation.get('feedback', 'No feedback provided')
level_achieved = evaluation.get('level_achieved', bloom_level)
hint = evaluation.get('hint', '')
print(f"Score: {score}/10")
print(f"Feedback: {feedback}")
print(f"Level Demonstrated: {level_achieved}")
# If score is low, provide hint and offer retry
if score < 7 and hint:
print(f"💡 Hint: {hint}")
retry = input("\nYour answer needs improvement. Would you like to try again? (y/n): ").lower().strip()
if retry == 'y':
print("\n🔄 Please provide a more detailed and specific answer.")
retry_answer = input("Your revised answer: ")
# Re-evaluate the retry answer
retry_evaluation_json = self.evaluate_bloom_answer(question, retry_answer, bloom_level, chapter)
try:
retry_evaluation = json.loads(retry_evaluation_json)
retry_score = retry_evaluation.get('score', 0)
retry_feedback = retry_evaluation.get('feedback', 'No feedback provided')
retry_level = retry_evaluation.get('level_achieved', bloom_level)
print(f"\nRetry Score: {retry_score}/10")
print(f"Retry Feedback: {retry_feedback}")
print(f"Retry Level Demonstrated: {retry_level}")
# Use the better of the two scores
final_score = max(score, retry_score)
level_scores.append(final_score)
total_score += final_score
questions_asked += 1
except json.JSONDecodeError:
print("Error evaluating retry answer. Using original score.")
level_scores.append(score)
total_score += score
questions_asked += 1
else:
level_scores.append(score)
total_score += score
questions_asked += 1
else:
level_scores.append(score)
total_score += score
questions_asked += 1
except json.JSONDecodeError:
print("Error evaluating answer. Defaulting to score 5.")
level_scores.append(5)
total_score += 5
questions_asked += 1
# Store results for this Bloom's level
results[bloom_level] = {
'scores': level_scores,
'average_score': sum(level_scores) / len(level_scores),
'total_score': sum(level_scores)
}
# Calculate overall results
max_possible = questions_asked * 10
average_score = total_score / questions_asked
percentage = (total_score / max_possible) * 100
print(f"\n{'='*60}")
print("COMPREHENSIVE ASSESSMENT RESULTS")
print(f"{'='*60}")
print(f"Total Score: {total_score}/{max_possible}")
print(f"Average Score: {average_score:.1f}/10")
print(f"Percentage: {percentage:.1f}%")
# Enhanced mastery determination
if percentage >= 85:
mastery = "Excellent Mastery"
recommendation = "Ready to advance to next level"
elif percentage >= 70:
mastery = "Good Understanding"
recommendation = "Ready to advance with some review"
elif percentage >= 55:
mastery = "Basic Understanding"
recommendation = "Review weak areas before advancing"
else:
mastery = "Needs Significant Review"
recommendation = "Revisit chapter content and retake assessment"
print(f"Mastery Level: {mastery}")
print(f"Recommendation: {recommendation}")
print(f"\nDetailed Breakdown by Bloom's Level:")
for level, result in results.items():
avg = result['average_score']
print(f" {level}: {avg:.1f}/10 (Scores: {result['scores']})")
# Determine if student should advance or review
should_advance = percentage >= 70
return {
'chapter': chapter.name,
'total_score': total_score,
'max_possible': max_possible,
'average_score': average_score,
'percentage': percentage,
'mastery_level': mastery,
'recommendation': recommendation,
'should_advance': should_advance,
'detailed_results': results
}