LLM classifier for domain mapping
The router answered "are they trying to book?" Now we need a different classifier: given their described issue, which specialty should we match them to? Users say things like "my chest feels tight when I climb stairs". Your downstream database speaks in labels like cardiology, dermatology, pediatrics. The classifier node bridges the two.
SUPPORTED_SPECIALTIES = [
"general_medicine",
"cardiology",
"dermatology",
"pediatrics",
"orthopedics",
]The closed vocabulary lives as a constant. Every valid output of the classifier must be in this list. The vocabulary is part of the system contract and is passed into the prompt explicitly.
async def match_specialty(state: BookingState) -> BookingState:
system = (
"You map a chief complaint to one medical specialty from this list: "
+ ", ".join(SUPPORTED_SPECIALTIES)
+ ". Return JSON: {\"specialty\": one of the list}."
)
prompt = (
"Complaint: "
+ (state.get("symptom") or state.get("user_message", ""))
+ "\nPick the single best specialty."
)
data = await _llm_json(prompt, system)
specialty = data.get("specialty")
if specialty not in SUPPORTED_SPECIALTIES:
specialty = "general_medicine"
state["specialty"] = specialty
_record_event(state, "match_specialty", {"specialty": specialty})
return stateThe prompt ships the allowed list to the model. The response is parsed as JSON. The output is validated against the list. If the model invents a specialty, the fallback kicks in and the user still gets helped by general medicine.
AI prompt: Try the classifier prompt
Loading practice…
Because the off-list case is usually a model quirk, not a user problem. The user said something real and the model responded with "cardiovascular" instead of "cardiology". Bouncing back to the user with "sorry, please re-describe your symptom" is a terrible UX for a model mistake. Defaulting to general medicine is a safe, universally useful specialty that lets the flow continue. You log the miss so you can tune the prompt later.
Quiz: Quiz
Loading practice…