Spaces:
Sleeping
Sleeping
File size: 4,019 Bytes
c2b7494 | 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 | """Reusable prompt templates for LLM-assisted ranking and classification."""
from __future__ import annotations
from src.data.loaders import EventDefinitionForm
RANK_SYSTEM_PROMPT = (
"You are a clinical terminology expert supporting semantic harmonization for "
"real-world evidence studies. You review candidate medical codes retrieved for "
"a phenotype and re-rank them by clinical relevance, using the structured "
"phenotype definition (Event Definition Form) provided by the user. "
"You must respond only with valid JSON, no additional commentary."
)
CLASSIFY_SYSTEM_PROMPT = (
"You are a clinical terminology expert supporting semantic harmonization for "
"real-world evidence studies. You review candidate medical codes for a phenotype "
"and classify each one as 'Narrow' (highly specific to the phenotype), "
"'Possible' (related but insufficiently specific, or specific in some but not "
"all contexts), or 'Exclude' (not relevant, or explicitly an exclusion "
"criterion). Base your decision on the structured phenotype definition (Event "
"Definition Form) provided by the user. For every code, provide a brief "
"explanation followed by the label and a confidence score between 0 and 1. "
"You must respond only with valid JSON, no additional commentary."
)
def classify_system_prompt(use_possible_category: bool = False) -> str:
"""Return classification instructions for binary or three-way labeling."""
if use_possible_category:
return CLASSIFY_SYSTEM_PROMPT
return (
"You are a clinical terminology expert supporting semantic harmonization "
"for real-world evidence studies. Classify every candidate as 'Narrow' "
"when it is sufficiently specific to the phenotype, or 'Exclude' otherwise. "
"Do not return a 'Possible' label. Any EDF rule describing a Possible, "
"ambiguous, or insufficiently specific case must be treated as Exclude in "
"this binary mode. Base decisions on the supplied Event Definition Form. "
"For every code, request the output fields in this order: code, vocabulary, "
"explanation, label, confidence. Confidence must be from 0 to 1. Respond "
"only with valid JSON."
)
def build_rank_prompt(edf: EventDefinitionForm, candidates: list[dict]) -> str:
"""Build the user prompt for LLM-based re-ranking of candidate codes."""
candidate_lines = "\n".join(
f"- code: {c['code']} | vocabulary: {c['vocabulary']} | description: {c['description']}"
for c in candidates
)
return (
f"Phenotype definition:\n{edf.to_prompt_context()}\n\n"
f"Candidate codes to rank by clinical relevance to this phenotype "
f"(most relevant first):\n{candidate_lines}\n\n"
"Return a JSON object with a single key 'ranked_codes', containing a list of "
"objects with keys 'code', 'vocabulary', and 'relevance_score' (float 0-1, "
"higher = more relevant), sorted descending by relevance_score."
)
def build_classify_prompt(
edf: EventDefinitionForm,
candidates: list[dict],
use_possible_category: bool = False,
) -> str:
"""Build the user prompt for LLM-based classification of candidate codes."""
candidate_lines = "\n".join(
f"- code: {c['code']} | vocabulary: {c['vocabulary']} | description: {c['description']}"
for c in candidates
)
labels = "'Narrow', 'Possible', or 'Exclude'" if use_possible_category else "'Narrow' or 'Exclude'"
return (
f"Phenotype definition:\n{edf.to_prompt_context(include_possible=use_possible_category)}\n\n"
f"Classify each of the following candidate codes:\n{candidate_lines}\n\n"
"Return a JSON object with a single key 'classifications', containing a "
"list of objects using this requested key order: 'code', 'vocabulary', "
"'explanation' (brief string), 'label' "
f"(one of {labels}), and 'confidence' (float 0-1)."
)
|