from fenominal import Fenominal
import os
from langchain_ollama import ChatOllama
from langchain_core.messages import SystemMessage, HumanMessage
import jsonToy SPIRES
This notebook presents a much reduced (“toy”) version of the functionality of the Structured Prompt Interrogation and Recursive Extraction of Semantics (SPIRES) application Caufield et al., 2024, Bioinformatics 40:btae104.
Example sentences
We want to extract triples from these sentences First ten: MAXO TREATS HPO; second ten MAXO DIAGNOSES HPO
EXAMPLE_MAXO_HPO= [
"Continuous positive airway pressure therapy is used to treat obstructive sleep apnea.",
"Levodopa administration is used to treat bradykinesia.",
"Cochlear implantation is used to treat sensorineural hearing loss.",
"Anticonvulsant therapy is used to treat generalized tonic-clonic seizures.",
"Gastrostomy tube placement is used to treat failure to thrive.",
"Enzyme replacement therapy is used to treat hepatosplenomegaly in patients with lysosomal storage disease.",
"Physical therapy is used to treat muscle weakness and improve motor function.",
"Orthopedic bracing is used to treat scoliosis in affected individuals.",
"Insulin therapy is used to treat hyperglycemia in patients with diabetes mellitus.",
"Speech-language therapy is used to treat dysarthria in children with developmental delay.",
"Electroencephalography is used to diagnose epileptiform activity.",
"Brain magnetic resonance imaging is used to diagnose cerebellar atrophy.",
"Echocardiography is used to diagnose ventricular septal defect.",
"Slit-lamp examination is used to diagnose corneal clouding.",
"Pure tone audiometry is used to diagnose sensorineural hearing loss.",
"Nerve conduction study is used to diagnose peripheral neuropathy.",
"Skeletal survey is used to diagnose platyspondyly.",
"Polysomnography is used to diagnose obstructive sleep apnea.",
"Muscle biopsy is used to diagnose ragged-red fibers.",
"Abdominal ultrasonography is used to diagnose hepatomegaly.",
]Load fenominal
We use fenominal to ground the ontology labels Adjust the path to a directory that contains hp.json and maxo.json
hpo_dir = "../../../data/hpo/"
maxo_dir = "../../../data/maxo/"
hp_json= os.path.join(hpo_dir, "hp.json")
maxo_json = os.path.join(maxo_dir, "maxo.json")
maxo_fenominal = Fenominal(maxo_json, "maxo")
hpo_fenominal = Fenominal(hp_json)Load the LLM
We use a relatively small but surprisingly powerly local LLM derived from a Gemini model via the Ollama interface.
llm_client = ChatOllama(model="gemma3:12b", temperature=0)System prompt
Here, we tell the LLM via the system prompt that we want it to extract the labels of Medical Action Ontology (MAxO) and Human Phenotype Ontology (HPO) terms and to determine if they are associated by treats or diagnoses relations.
SYSTEM_MESSAGE = """
You are a highly specialized clinical information extraction system. Your task is to identify all Human Phenotype Ontology terms and all Medical Action Ontology terms in a document
and determine whether they are related by a "treats" or "diagnoses" relation.
Instructions:
Scan Every Sentence: Extract every phrase that describes a phenotype (HPO term)—signs, symptoms, abnormal findings, test results, anatomical observations.
Extract every phrase that describes a medical action (treatment, diagnostic modality).
Determine if the Maxo term "treats" the HPO term such as "Aspirin therapy (MAXO:0000903) **treats** Headache (HP:0002315).
Alternatively, determine if the MAxO term **diagnoses** the HPO term, such as chest radiograph procedure (MAXO:0010356) **diagnoses** Pulmonary opacity (HP:0031457). If neither of these relations is correct, output "other" as the relation.
Output only the labels of the HPO and MAxO terms. Do not attempt to identify the ontology identifiers (term ids)
Output JSON Only: Return { "triples": [ { "maxo_term": ..., "relation": ..., "hpo_term": ... }, ... ] }
Post-processing: Immediately drop sentences that do not contain both a MAxO and an HPO term."""The prompt
Here we create one prompt for each of the above sentences and send it to the gemma LLM model. The full SPIRES (ontoGPT) application would create the prompt automatically from a YAML configuration file, interact with one of a number of more powerful, online LLMs, and ground the results (associated ontology term identifiers and labels to the free-text results), resulting in a knoweldge graph for each parsed document.
for sentence in EXAMPLE_MAXO_HPO:
messages = [
SystemMessage(content=SYSTEM_MESSAGE),
HumanMessage(content=sentence),
]
response = llm_client.invoke(messages)
clean_content = (
response.content.strip()
.removeprefix("```json")
.removeprefix("```")
.removesuffix("```")
.strip()
)
data = json.loads(clean_content)
triples = data.get("triples", [])
for triple in triples:
maxo_term = triple.get("maxo_term")
hpo_term = triple.get("hpo_term")
relation = triple.get("relation")
print(f'{maxo_term} - {relation} - {hpo_term}.')Continuous positive airway pressure therapy - treats - Obstructive sleep apnea.
Levodopa administration - treats - bradykinesia.
cochlear implantation - treats - sensorineural hearing loss.
Anticonvulsant therapy - treats - generalized tonic-clonic seizures.
Gastrostomy tube placement - treats - Failure to thrive.
Enzyme replacement therapy - treats - hepatosplenomegaly.
Physical therapy - treats - Muscle weakness.
Physical therapy - treats - Motor function.
Orthopedic bracing - treats - scoliosis.
Insulin therapy - treats - hyperglycemia.
Speech-language therapy - treats - dysarthria.
electroencephalography - diagnoses - epileptiform activity.
Brain magnetic resonance imaging - diagnoses - Cerebellar atrophy.
echocardiography - diagnoses - ventricular septal defect.
Slit-lamp examination - diagnoses - Corneal clouding.
pure tone audiometry - diagnoses - sensorineural hearing loss.
nerve conduction study - diagnoses - peripheral neuropathy.
Skeletal survey - diagnoses - Platyspondyly.
Polysomnography - diagnoses - obstructive sleep apnea.
Muscle biopsy - diagnoses - ragged-red fibers.
Abdominal ultrasonography - diagnoses - Hepatomegaly.