Spaces:
Sleeping
Sleeping
| from typing import List | |
| from openai import OpenAI | |
| from models import BaseLearningObjective, LearningObjective, TEMPERATURE_UNAVAILABLE | |
| from prompts.incorrect_answers import INCORRECT_ANSWER_EXAMPLES_WITH_EXPLANATION | |
| def generate_incorrect_answer_options(client: OpenAI, model: str, temperature: float, file_contents: List[str], base_objectives: List[BaseLearningObjective], model_override: str = None) -> List[LearningObjective]: | |
| """ | |
| Generate incorrect answer options for each base learning objective. | |
| Args: | |
| file_contents: List of file contents with source tags | |
| base_objectives: List of base learning objectives to enhance | |
| Returns: | |
| List of learning objectives with incorrect answer suggestions | |
| """ | |
| print(f"Generating incorrect answer options for {len(base_objectives)} learning objectives") | |
| # Create combined content for context | |
| combined_content = "\n\n".join(file_contents) | |
| enhanced_objectives = [] | |
| for i, objective in enumerate(base_objectives): | |
| print(f"Processing objective {i+1}/{len(base_objectives)}: {objective.learning_objective[:50]}...") | |
| print(f"Learning objective: {objective.learning_objective}") | |
| print(f"Correct answer: {objective.correct_answer}") | |
| # # Create the prompt for generating incorrect answer options | |
| prompt = f""" | |
| Based on the learning objective and correct answer provided below. | |
| Learning Objective: {objective.learning_objective} | |
| Correct Answer: {objective.correct_answer} | |
| Generate 3 incorrect answer options. | |
| Use the examples with explanations below to guide you in generating incorrect answer options: | |
| <examples_with_explanation> | |
| {INCORRECT_ANSWER_EXAMPLES_WITH_EXPLANATION} | |
| </examples_with_explanation> | |
| Here's the course content that the student has been exposed to: | |
| <course_content> | |
| {combined_content} | |
| </course_content> | |
| Here's the learning objective that was identified: | |
| <learning_objective> | |
| "id": {objective.id}, | |
| "learning_objective": "{objective.learning_objective}", | |
| "source_reference": "{objective.source_reference}", | |
| "correct_answer": "{objective.correct_answer}" | |
| </learning_objective> | |
| When creating incorrect answers, refer to the correct answer <correct_answer>{objective.correct_answer}</correct_answer>. | |
| Make sure incorrect answers match the correct answer in terms of length, complexity, phrasing, style, and subject matter. | |
| Incorrect answers should be of approximate equal length to the correct answer, preferably one sentence and 20 words long. Pay attention to the | |
| example in <examples_with_explanation> about avoiding unnecessary length. | |
| """ | |
| try: | |
| model_to_use = model_override if model_override else model | |
| # Use OpenAI beta API for structured output | |
| system_prompt = "You are an expert in designing effective multiple-choice questions that assess higher-order thinking skills while following established educational best practices." | |
| params = { | |
| "model": model_to_use, | |
| "messages": [ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": prompt} | |
| ], | |
| "response_format": LearningObjective | |
| } | |
| if not TEMPERATURE_UNAVAILABLE.get(model_to_use, True): | |
| params["temperature"] = temperature # Use higher temperature for creative misconceptions | |
| print(f"DEBUG - Using model {model_to_use} for incorrect answer options with temperature {params.get('temperature', 'N/A')}") | |
| completion = client.beta.chat.completions.parse(**params) | |
| enhanced_obj = completion.choices[0].message.parsed | |
| # Simple debugging for incorrect answer suggestions | |
| if enhanced_obj.incorrect_answer_options: | |
| print(f" β Got {len(enhanced_obj.incorrect_answer_options)} incorrect answers") | |
| print(f" β First option: {enhanced_obj.incorrect_answer_options[0][:100]}..." if len(enhanced_obj.incorrect_answer_options[0]) > 100 else enhanced_obj.incorrect_answer_options[0]) | |
| else: | |
| print(" β No incorrect answer options received!") | |
| # Preserve grouping metadata from the original objective | |
| enhanced_obj.in_group = getattr(objective, 'in_group', None) | |
| enhanced_obj.group_members = getattr(objective, 'group_members', None) | |
| enhanced_obj.best_in_group = getattr(objective, 'best_in_group', None) | |
| enhanced_objectives.append(enhanced_obj) | |
| except Exception as e: | |
| print(f"Error generating incorrect answer options for objective {objective.id}: {e}") | |
| # If there's an error, create a learning objective without suggestions | |
| enhanced_obj = LearningObjective( | |
| id=objective.id, | |
| learning_objective=objective.learning_objective, | |
| source_reference=objective.source_reference, | |
| correct_answer=objective.correct_answer, | |
| incorrect_answer_options=None, | |
| in_group=getattr(objective, 'in_group', None), | |
| group_members=getattr(objective, 'group_members', None), | |
| best_in_group=getattr(objective, 'best_in_group', None) | |
| ) | |
| enhanced_objectives.append(enhanced_obj) | |
| print(f"Generated incorrect answer options for {len(enhanced_objectives)} learning objectives") | |
| return enhanced_objectives |