File size: 6,123 Bytes
1bc3f18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
from generation.ExamRagGenerator import ExamGenerationRequest, ExamResponse
import json

class ExamPromptBuilder:
    MAX_SCORE = 40

    def build_exam_generation_prompt(self,request: ExamGenerationRequest,context: str) -> str:
        distribution = {
            q_type.value: count
            for q_type, count in request.question_types_distribution.items()
        }

        return f"""
    You are an automated exam generation system.

    Your job is to produce a structured exam strictly following the schema below.

    ----------------------------------------------------
    CRITICAL OUTPUT RULES
    ----------------------------------------------------

    You MUST return ONLY a valid JSON object.

    Do NOT include:

    - explanations
    - markdown
    - comments
    - code blocks
    - text before or after the JSON

    The response MUST start with {{ and end with }}.

    If the output is not valid JSON the result will be rejected.

    ----------------------------------------------------
    ENUM VALUES (STRICT)
    ----------------------------------------------------

    difficulty must be exactly one of:

    easy
    medium
    hard

    question type must be exactly one of:

    mcq
    true_false
    short_answer
    essay
    code

    ----------------------------------------------------
    EXAM REQUIREMENTS
    ----------------------------------------------------

    course: {request.course}

    difficulty: {request.difficulty.value}

    total_questions: {request.total_questions}

    question_types_distribution:
    {json.dumps(distribution)}

    You MUST generate exactly:

    {json.dumps(distribution)}

    Example:

    {{
    "mcq": 3,
    "essay": 2
    }}

    means exactly:
    3 mcq questions
    2 essay questions

    ----------------------------------------------------
    CONTEXT
    ----------------------------------------------------

    Use ONLY the information from this context when creating questions.

    {context}

    ----------------------------------------------------
    QUESTION RULES
    ----------------------------------------------------

    MCQ QUESTIONS

    - must contain exactly 4 options
    - options must be plain text
    - correct_answer must match one option EXACTLY
    - do NOT use letters like A/B/C/D
    - do NOT include numbering inside options

    Example:

    {{
    "type": "mcq",
    "question": "What is 2 + 2?",
    "options": ["1","2","3","4"],
    "correct_answer": "4",
    "explanation": "2 + 2 equals 4"
    }}

    ----------------------------------------------------

    TRUE/FALSE QUESTIONS

    correct_answer must be boolean.

    Example:

    {{
    "type": "true_false",
    "question": "The Earth revolves around the Sun.",
    "correct_answer": true,
    "explanation": "Astronomy confirms this."
    }}

    ----------------------------------------------------

    SHORT ANSWER QUESTIONS

    Example:

    {{
    "type": "short_answer",
    "question": "Define photosynthesis.",
    "answer": "Process where plants convert light into chemical energy",
    "explanation": "Occurs in chloroplasts using sunlight"
    }}

    ----------------------------------------------------

    ESSAY QUESTIONS

    Example:

    {{
    "type": "essay",
    "question": "Explain Newton's First Law.",
    "answer": "Newton's First Law states that an object will remain at rest or continue moving in a straight line at constant velocity unless acted upon by an external force. This property is called inertia. For example, a book on a table stays at rest until someone pushes it, and a moving car continues moving until friction or braking stops it.",
    "answer_guidelines": "Describe inertia and provide examples"
    }}

    ----------------------------------------------------

    CODE QUESTIONS

    Rules:

    starter_code must be either a string OR null.
    Never output the string "None".

    Example:

    {{
    "type": "code",
    "question": "Write a Python function to compute factorial.",
    "language": "c",
    "starter_code": "def factorial(n):",
    "solution": "def factorial(n): return 1 if n<=1 else n*factorial(n-1)",
    "explanation": "Uses recursion"
    }}

    ----------------------------------------------------
    IMPORTANT RESTRICTIONS
    ----------------------------------------------------

    Do NOT output:

    LaTeX
    math formulas
    markdown
    additional fields

    Use plain text only.

    ----------------------------------------------------
    FINAL JSON STRUCTURE
    ----------------------------------------------------

    {{
    "exam_id": "{request.exam_id}",
    "difficulty": "{request.difficulty.value}",
    "total_questions": {request.total_questions},
    "expected_distribution": {json.dumps(distribution)},
    "questions": []
    }}

    Fill the questions array with the generated questions.

    ----------------------------------------------------

    Return ONLY the JSON object.
    """
    
    def build_exam_evaluation_prompt(self,request: ExamGenerationRequest,exam: ExamResponse) -> str:

        exam_json = exam.model_dump_json()

        return f"""
You are an exam quality evaluator.

--------------------------------
OUTPUT RULES
--------------------------------
1. Output MUST be valid JSON.
2. Do NOT include markdown.
3. Do NOT include reasoning outside JSON.
4. Output ONLY the JSON object.
5. JSON must start with {{ and end with }}.

--------------------------------
SCORING RANGE
--------------------------------
0 to {self.MAX_SCORE}

--------------------------------
EVALUATION CRITERIA
--------------------------------
1. Relevance of questions to the topics
2. Correct distribution of question types
3. Clarity and wording of questions
4. Difficulty consistency
5. Correctness of answers

--------------------------------
EXAM TO EVALUATE
--------------------------------
{exam_json}

--------------------------------
OUTPUT FORMAT
--------------------------------

{{
"overall_score": integer between 0 and {self.MAX_SCORE},
"feedback": "short explanation of issues if any"
}}

Return ONLY JSON.
"""