Using Pydantic with TheDrummer: Cydonia 24B V4.1 on OpenRouter
This tutorial explains how to use a Pydantic schema to extract structured data using TheDrummer: Cydonia 24B V4.1.
Please read this tutorial first to understand the basic setup
Code:
import json
import os
import time
import requests
from dotenv import load_dotenv
from inputs import get_input_text
from schema import VAERSReport
from system import system_instruction_1 as system_instruction
load_dotenv()
model_name = 'thedrummer/cydonia-24b-v4.1'
api_key = os.getenv("OPENROUTER_API_KEY")
json_schema_text = json.dumps(VAERSReport.model_json_schema(), indent=2)
input_text, sentence_map = get_input_text()
prompt = f"""
Report: {input_text}
JSON Schema:
{json_schema_text}
"""
url = "https://openrouter.ai/api/v1/chat/completions"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"HTTP-Referer": "https://botflo.com/", # Optional. Site URL for rankings on openrouter.ai.
"X-Title": "LLM Accuracy Comparisons for Structured Outputs", # Optional
}
payload = {
"model": model_name,
"messages": [
{"role": "system", "content": f'{system_instruction}'},
{"role": "user", "content": f'{prompt}'}
],
"reasoning": {
"effort": "high"
}
}
before = time.time()
response_full = requests.post(url, headers=headers, data=json.dumps(payload))
elapsed = time.time() - before
response = response_full.json()
metadata = {
"metrics": {
"elapsed": elapsed,
"usage": response['usage']
},
"text": {
"system_instruction": system_instruction,
"sentence_map": sentence_map,
"json_schema_text": json_schema_text
}
}
response["metadata"] = metadata
response_file_name = f"responses/response_{model_name.replace('/', '-')}.json"
with open(response_file_name, 'w+') as f:
json.dump(response, f, indent=2)
output_text = response.get('choices')[0].get('message').get('content')
print(output_text)
input_file_name = f"inputs/input_{model_name.replace('/', '-')}.txt"
with open(input_file_name, 'w+') as f:
f.write(input_text)
output_file_name = f"outputs/output_{model_name.replace('/', '-')}.txt"
with open(output_file_name, 'w+') as f:
f.write(output_text)
LLM Response:
```json
{
"timeline": {
"date_of_vaccination": {
"year": 1999,
"month": 6,
"citations": [4],
"explanation": "Vaccination date mentioned in the report"
},
"regression_onset_date": null,
"diagnosis_date": null,
"age_at_vaccination_months": {
"value": 1.33,
"citations": [3],
"explanation": "Age of child at vaccination mentioned in the report"
},
"age_at_diagnosis_months": null
},
"developmental_milestones": [
{
"milestone_name": {
"value": "single_words",
"citations": [41]
},
"milestone_type": "language",
"milestone_age_in_months": {
"value": 17,
"citations": [41]
},
"milestone_has_regressed": {
"value": false,
"citations": [],
"explanation": "No regression mentioned for this milestone"
},
"regression_start_date_in_months": {
"value": null,
"explanation": "No regression date mentioned for this milestone"
},
"progressed_after_regression": {
"value": null,
"explanation": "No regression mentioned for this milestone"
}
},
{
"milestone_name": {
"value": "walking",
"citations": [41]
},
"milestone_type": "adaptive_behavior",
"milestone_age_in_months": {
"value": 12,
"citations": [41]
},
"milestone_has_regressed": {
"value": false,
"citations": [],
"explanation": "No regression mentioned for this milestone"
},
"regression_start_date_in_months": {
"value": null,
"explanation": "No regression date mentioned for this milestone"
},
"progressed_after_regression": {
"value": null,
"explanation": "No regression mentioned for this milestone"
}
},
{
"milestone_name": {
"value": "sitting_without_support",
"citations": [41]
},
"milestone_type": "adaptive_behavior",
"milestone_age_in_months": {
"value": 8,
"citations": [41]
},
"milestone_has_regressed": {
"value": false,
"citations": [],
"explanation": "No regression mentioned for this milestone"
},
"regression_start_date_in_months": {
"value": null,
"explanation": "No regression date mentioned for this milestone"
},
"progressed_after_regression": {
"value": null,
"explanation": "No regression mentioned for this milestone"
}
}
],
"regression_record": {
"pre_regression_language_level": {
"value": "no_speech",
"citations": [44],
"explanation": "Language development before regression mentioned as delayed"
},
"pre_regression_social_communication_level": {
"value": "basic_engagement",
"citations": [12],
"explanation": "Social engagement mentioned in symptoms before regression"
},
"pre_regression_adaptive_behavior_level": {
"value": "basic_self_help",
"citations": [42],
"explanation": "Development mentioned as 'not within normal limits'"
},
"post_regression_language_level": {
"value": "no_speech",
"citations": [19, 61],
"explanation": "Speech therapist's report and description of regression"
},
"post_regression_social_communication_level": {
"value": "no_engagement",
"citations": [100, 119],
"explanation": "Psychologist's reports of social engagement and communication difficulties"
},
"post_regression_adaptive_behavior_level": {
"value": "basic_self_help",
"citations": [119, 128],
"explanation": "Adaptive behavior level mentioned as 'Borderline Impaired'"
},
"has_language_loss": {
"value": true,
"citations": [12],
"explanation": "Speech loss mentioned as a symptom"
},
"has_social_loss": {
"value": true,
"citations": [12, 100, 108, 111],
"explanation": "Social withdrawal and reduced social engagement mentioned in multiple sections"
},
"has_adaptive_loss": {
"value": true,
"citations": [43],
"explanation": "Report of developmental regression and impact on adaptive behaviors"
},
"has_repetitive_behaviors": {
"value": true,
"citations": [126, 147],
"explanation": "Report of lining up toys and repetitive behaviors"
}
},
"early_vaccination_symptoms": null,
"diagnosis_record": {
"asd_severity": {
"value": 2,
"citations": [22, 45],
"explanation": "Report describes autism and moderate developmental delays"
},
"diagnosis_name": [
{
"value": "Autism",
"citations": [22, 45, 57]
},
{
"value": "Mixed Expressive Receptive Language Disorder",
"citations": [96, 130]
},
{
"value": "Pervasive Developmental Disorder (could not be ruled out)",
"citations": [130]
}
],
"diagnosing_professional": [
{
"value": "Psychologist",
"citations": [96, 130]
}
]
},
"intervention_record": {
"interventions": [
{
"value": "speech_therapy",
"citations": [86, 113]
},
{
"value": "occupational_therapy",
"citations": [143]
},
{
"value": "aba",
"citations": [154]
},
{
"value": "other",
"citations": [154],
"explanation": "Other interventions mentioned include special instruction and parent training"
}
],
"is_intervention_ongoing": {
"value": true,
"citations": [143, 154],
"explanation": "Multiple interventions described as ongoing in the report"
},
"has_recovery": {
"value": false,
"citations": [11, 66],
"explanation": "Report states 'no recovery' and autism continues"
}
},
"birth_record": {
"was_normal_pre_vaccination": {
"value": false,
"citations": [34, 43, 44],
"explanation": "Report describes various health issues from birth"
},
"apgar_score": [
{
"value": "8 at one minute, 9 at five minutes",
"citations": [29]
}
]
},
"behavior_record": {
"repetitive_behaviors": [
{
"value": "Lining up toys and objects (e.g., blocks, chairs)",
"citations": [126, 147]
}
]
},
"heavy_metal_tests": [
{
"metal_type": "lead",
"value": 16,
"unit": "ug/L",
"is_elevated": true,
"citations": [20]
},
{
"metal_type": "arsenic",
"value": 60,
"unit": "ug/L",
"is_elevated": true,
"citations": [20]
},
{
"metal_type": "mercury",
"value": 10,
"unit": "ug/L",
"is_elevated": false,
"citations": [20]
}
],
"comorbidities": [
{
"value": "eczema",
"citations": [6]
}
],
"environmental_exposures": [],
"legal_matter": {
"value": true,
"citations": [22],
"explanation": "Report states this was received as part of litigation proceedings"
},
"diagnosis_reporting_delay_reason": null
}
```
Metrics
{
"elapsed": 25.716096878051758,
"usage": {
"prompt_tokens": 14216,
"completion_tokens": 1989,
"total_tokens": 16205,
"prompt_tokens_details": {
"cached_tokens": 14208
}
}
}