Restore original verbatim extraction prompt; switch to Claude Opus 4.6

Extraction prompt:
- Restored full original prompt with strict verbatim instructions
- Explanation field: must include full explanation paragraph + Critique
  verbatim + Content Specifications verbatim (no summarization)
- Correct answer: explicit step-by-step with example showing letter→full text
- Options: extract full text only, no letter prefix
- All 5 rules numbered and explicit

Model switch:
- Default extraction model changed from Claude Haiku 4.5 → Claude Opus 4.6
- Haiku tends to compress/summarize long explanation text
- Opus 4.6 follows verbatim instructions reliably and handles
  the structured PREP format (explanation + Critique + Content Specs)
  without losing content
- Haiku 4.5 still available in the Extraction Model dropdown for
  cost-sensitive use cases

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel 2026-04-01 12:57:28 +02:00
parent b859d441eb
commit 77da7aea6c

View file

@ -16,34 +16,45 @@ def _proxy_model(model_id: str) -> str:
EXTRACTION_PROMPT = """You are extracting questions from a PREP (Pediatric Review and Education Program) exam PDF. EXTRACTION_PROMPT = """You are extracting questions from a PREP (Pediatric Review and Education Program) exam PDF.
These PDFs have questions with a clinical vignette, followed by five answer options A-E. These PDFs follow a strict format:
Some PDFs include "Correct Answer: X" or "Preferred Response: X" right after the options. 1. A numbered question with a clinical vignette (patient scenario)
Some PDFs have the correct answers only at the END of the document in that case correct_answer will be null. 2. Five answer options labeled A, B, C, D, E
3. A line "Correct Answer: X" or "Preferred Response: X" where X is the letter of the correct option
4. An explanation paragraph
5. A "Critique:" section with detailed reasoning
6. A "Content Specifications:" section listing the learning objectives
Return ONLY a JSON object: Your task: extract every question and return ONLY a JSON object in this exact format:
{{"questions": [ {{"questions": [
{{ {{
"item_number": "<item number like '193' or '21' — digits only, null if not found>", "item_number": "<item number digits only, e.g. '193' null if not found>",
"question_text": "<full question stem including the clinical vignette>", "question_text": "<full question stem including any patient vignette>",
"question_type": "mcq", "question_type": "mcq",
"options": ["<option A text>", "<option B text>", "<option C text>", "<option D text>", "<option E text>"], "options": ["<option A text>", "<option B text>", "<option C text>", "<option D text>", "<option E text>"],
"correct_answer": "<full text of the correct option, NOT the letter — or null if not found>", "correct_answer": "<full text of the correct option, NOT the letter>",
"explanation": "<explanation/critique/content specs if present, else empty string>", "explanation": "<explanation paragraph>\\n\\nCritique: <critique section verbatim>\\n\\nContent Specifications: <content spec section verbatim>",
"page_reference": {page_ref} "page_reference": {page_ref}
}} }}
]}} ]}}
RULES: CRITICAL RULES follow exactly:
- A new question starts when you see "Item NNN" or "ltem NNN" (OCR artifact for Item). 1. CORRECT ANSWER: Find "Correct Answer: X" or "Preferred Response: X" after each question.
- Extract question_text as the full vignette + the "Of the following..." or "Which of the following..." stem. X is a letter (AE). Look up the full text of that option and store it as correct_answer.
- Options are labeled A. B. C. D. E. extract just the text, not the letter. NEVER store just the letter. NEVER guess. If not found, set correct_answer to null.
- If "Correct Answer: X" or "Preferred Response: X" appears after the options, resolve it to full option text. Example: options=["alpha","beta","gamma","delta","epsilon"] and "Correct Answer: C" correct_answer="gamma"
- CRITICAL: Content immediately after an image reference (e.g. "Item C123A", "Item C123B", figure captions,
table data) is NOT a new question. Skip it and wait for the next "Item NNN" number. 2. EXPLANATION: Copy the explanation paragraph, then the Critique section, then Content Specifications
- If no correct answer line is found for a question, set correct_answer to null do NOT guess. ALL VERBATIM do NOT summarize, shorten, or paraphrase anything.
- Do NOT omit questions extract all questions found in the content, even if partial. Format: "<explanation>\\n\\nCritique: <critique verbatim>\\n\\nContent Specifications: <specs verbatim>"
- Return ONLY the JSON no markdown, no preamble.
3. QUESTIONS: Extract ALL questions, even if partially cut off.
A new question starts with "Item NNN" or "ltem NNN" (OCR artifact lowercase l instead of I).
Content after an image reference (e.g. "Item C123A", figure captions) is NOT a new question.
4. OPTIONS: Extract just the text for each option, without the letter prefix (A. B. C. D. E.).
5. Return ONLY the JSON no markdown fences, no explanation, no preamble.
Content from page(s) {page_info}: Content from page(s) {page_info}:
{content}""" {content}"""