glucoguide_ai / knowledge_base.py
stefanssunday's picture
Upload 4 files
59b983d verified
Raw
History Blame Contribute Delete
9.07 kB
"""Small, curated diabetes education knowledge base.
The application uses deterministic keyword retrieval so the language model receives
short summaries from reputable public-health sources. This is intentionally simple
and transparent for a course project; it is not a clinical retrieval system.
"""
from __future__ import annotations
from dataclasses import dataclass
import re
from typing import Iterable
@dataclass(frozen=True)
class Source:
source_id: str
title: str
organization: str
url: str
summary: str
keywords: tuple[str, ...]
SOURCES: tuple[Source, ...] = (
Source(
source_id="S1",
title="What Is Diabetes?",
organization="National Institute of Diabetes and Digestive and Kidney Diseases (NIDDK)",
url="https://www.niddk.nih.gov/health-information/diabetes/overview/what-is-diabetes",
summary=(
"Diabetes occurs when blood glucose is too high because the body does not make "
"enough insulin, makes no insulin, or does not use insulin properly. The main types "
"include type 1, type 2, and gestational diabetes."
),
keywords=(
"diabetes", "type 1", "type one", "type 2", "type two", "gestational",
"insulin", "blood sugar", "blood glucose", "glucose", "prediabetes",
"diabetes tipo", "azúcar en la sangre", "glucosa",
),
),
Source(
source_id="S2",
title="Diabetes Tests & Diagnosis",
organization="NIDDK",
url="https://www.niddk.nih.gov/health-information/diabetes/overview/tests-diagnosis",
summary=(
"Health professionals diagnose diabetes and prediabetes with blood tests. Home blood "
"glucose meters cannot diagnose diabetes, and abnormal results may need confirmation."
),
keywords=(
"a1c", "hba1c", "test", "diagnosis", "diagnose", "screen", "fasting",
"oral glucose", "lab", "laboratory", "prediabetes range", "prueba", "diagnóstico",
),
),
Source(
source_id="S3",
title="About Insulin Resistance and Type 2 Diabetes",
organization="Centers for Disease Control and Prevention (CDC)",
url="https://www.cdc.gov/diabetes/about/insulin-resistance-type-2-diabetes.html",
summary=(
"Insulin resistance means cells do not respond well to insulin. The pancreas may make "
"more insulin at first, but blood glucose can rise over time and lead to prediabetes "
"or type 2 diabetes."
),
keywords=(
"insulin resistance", "resistant", "prediabetes", "type 2", "metabolic",
"resistencia a la insulina", "prediabetes",
),
),
Source(
source_id="S4",
title="Diabetes Meal Planning",
organization="CDC",
url="https://www.cdc.gov/diabetes/healthy-eating/diabetes-meal-planning.html",
summary=(
"Meal planning can support nutrition and blood glucose management. Common educational "
"tools include carbohydrate awareness and the plate method. Individual plans should be "
"created with a qualified clinician or diabetes educator."
),
keywords=(
"food", "meal", "diet", "carb", "carbohydrate", "plate method", "portion",
"breakfast", "lunch", "dinner", "snack", "nutrition", "eat", "eating",
"comida", "alimentación", "carbohidrato", "plato", "nutrición",
),
),
Source(
source_id="S5",
title="Healthy Living with Diabetes",
organization="NIDDK",
url="https://www.niddk.nih.gov/health-information/diabetes/overview/healthy-living-with-diabetes",
summary=(
"Healthy living with diabetes may include balanced eating, physical activity, adequate "
"sleep, stress management, and collaboration with a health care team. Plans should be "
"adapted to the person's health status and treatment."
),
keywords=(
"exercise", "activity", "walking", "workout", "sleep", "stress", "lifestyle",
"weight", "healthy living", "physical activity", "ejercicio", "actividad", "sueño",
),
),
Source(
source_id="S6",
title="Low Blood Sugar (Hypoglycemia)",
organization="CDC",
url="https://www.cdc.gov/diabetes/about/low-blood-sugar-hypoglycemia.html",
summary=(
"Low blood glucose can be dangerous and requires prompt attention. People at risk should "
"know their care plan, recognize warning signs, and discuss prevention and treatment with "
"their health care team."
),
keywords=(
"low blood sugar", "low glucose", "hypoglycemia", "hypoglycaemia", "shaky",
"sweating", "confused", "glucagon", "azúcar baja", "hipoglucemia", "temblor",
),
),
Source(
source_id="S7",
title="Manage Blood Sugar",
organization="CDC",
url="https://www.cdc.gov/diabetes/treatment/index.html",
summary=(
"Blood glucose can become too high or too low for many reasons. Monitoring frequency and "
"target ranges should be determined with a health professional, especially for people "
"using insulin or medicines that can cause hypoglycemia."
),
keywords=(
"high blood sugar", "high glucose", "hyperglycemia", "ketone", "monitor", "meter",
"cgm", "continuous glucose", "target range", "azúcar alta", "hiperglucemia", "cetona",
),
),
Source(
source_id="S8",
title="Insulin, Medicines, & Other Diabetes Treatments",
organization="NIDDK",
url="https://www.niddk.nih.gov/health-information/diabetes/overview/insulin-medicines-treatments",
summary=(
"Diabetes treatment may involve lifestyle measures, oral medicines, injectable medicines, "
"or insulin. The appropriate treatment depends on diabetes type, other health conditions, "
"side effects, cost, access, and individual circumstances. Medication changes require a clinician."
),
keywords=(
"medicine", "medication", "drug", "insulin", "metformin", "glp-1", "glp1",
"side effect", "dose", "dosage", "injection", "medicina", "medicamento", "dosis",
),
),
Source(
source_id="S9",
title="Preventing Diabetes Problems",
organization="NIDDK",
url="https://www.niddk.nih.gov/health-information/diabetes/overview/preventing-problems",
summary=(
"Diabetes can affect the heart, blood vessels, kidneys, eyes, nerves, and feet. Routine "
"care and management of blood glucose, blood pressure, cholesterol, and smoking status "
"can help reduce complication risks."
),
keywords=(
"complication", "heart", "kidney", "eye", "vision", "nerve", "neuropathy", "foot",
"feet", "stroke", "cholesterol", "blood pressure", "complicación", "riñón", "pie",
),
),
)
def _tokenize(text: str) -> set[str]:
return set(re.findall(r"[a-záéíóúñ0-9-]+", text.lower()))
def retrieve_sources(query: str, limit: int = 3) -> list[Source]:
"""Return the most relevant curated sources for a user query.
Scores use exact phrase matches plus token overlap. A general diabetes source
is always available as a fallback.
"""
normalized = query.lower().strip()
query_tokens = _tokenize(normalized)
ranked: list[tuple[float, Source]] = []
for source in SOURCES:
score = 0.0
for keyword in source.keywords:
key = keyword.lower()
if key in normalized:
score += 4.0 if " " in key else 2.0
key_tokens = _tokenize(key)
score += 0.35 * len(query_tokens.intersection(key_tokens))
ranked.append((score, source))
ranked.sort(key=lambda item: item[0], reverse=True)
selected = [source for score, source in ranked if score > 0][:limit]
if not selected:
selected = [SOURCES[0], SOURCES[4]][:limit]
elif SOURCES[0] not in selected and len(selected) < limit:
selected.append(SOURCES[0])
return selected[:limit]
def format_context(sources: Iterable[Source]) -> str:
"""Format source summaries for inclusion in the model prompt."""
blocks = []
for source in sources:
blocks.append(
f"[{source.source_id}] {source.title}{source.organization}\n"
f"Summary: {source.summary}\n"
f"URL: {source.url}"
)
return "\n\n".join(blocks)
def format_reference_list(sources: Iterable[Source]) -> str:
"""Format deterministic Markdown references appended to each answer."""
items = [
f"- [{source.source_id}] [{source.title}]({source.url}) — {source.organization}"
for source in sources
]
return "\n".join(items)