PharmaPilot

About the project

Inspiration

We wanted a medication helper that fits into a real routine: people already live in messaging apps, but adherence tools often require yet another app, login, and push-notification setup. PharmaPilot started as a way to reduce two common failure modes: missing doses and running out of meds, while still being respectful about safety (no guessing, no overconfident medical claims).

What it does

PharmaPilot is a WhatsApp-based assistant that can:

  • Register medications and reminder times via natural language.
  • Send scheduled reminders and let users quickly confirm “Taken …”, snooze, or skip.
  • Track inventory and proactively suggest refills when supply is low.
  • Give “missed dose” guidance using a simplified pharmacokinetic (PK) model.
  • (Optional) Accept a photo of a prescription/bottle label, extract structured fields, and ask for confirmation before saving anything.

How we built it

  • FastAPI webhook: Twilio sends inbound WhatsApp messages to a FastAPI endpoint, which normalizes button payloads vs free-text and routes the request to either a deterministic handler (refill confirmation, reminder actions, photo confirmation) or the LLM orchestrator.
  • LLM tool-use loop: The AI layer is built around Anthropic’s tool use. The model proposes actions like “add_medication” or “record_dose_taken”, and the server executes those actions against the database, then returns a user-facing response.
  • Scheduling + automation: APScheduler runs recurring reminder jobs and a daily low-inventory check, sending WhatsApp messages (or template quick-replies when configured).
  • Data model + persistence: SQLAlchemy models store users, medications, schedules, dose logs, and refill requests in SQLite.
  • Ephemeral chat context: A small in-process short-term memory keeps just enough context for multi-turn flows (like confirming photo extraction) without permanently storing full chat logs.
  • Dashboard: A Streamlit dashboard reads from the same SQLite DB and visualizes inventory levels and adherence metrics.

The math (PK, simplified)

For missed-dose reasoning, PharmaPilot uses a simple first-order decay approximation based on half-life: $$ C(t) = C_0 \left(\frac{1}{2}\right)^{t/t_{1/2}} $$ This isn’t a clinical-grade model, but it provides a consistent, explainable heuristic for “take now vs skip” guidance, while still encouraging users to consult official instructions when ambiguous.

What we learned

  • How to design LLM “tool boundaries” so the model can be helpful without directly mutating state (the server executes tools, not the model).
  • Webhook realities: payloads are messy (form fields, button payloads, media URLs) and need careful normalization and guardrails.
  • Scheduling in an async app requires thoughtful separation between request/response latency and background work.
  • Vision extraction is much more reliable when you force a strict JSON schema and explicitly instruct “don’t guess.”

Challenges we faced

  • Multi-path conversation routing: a single inbound message might be a reminder action, a refill confirmation, a normal chat prompt, or a photo confirmation—getting the precedence right matters.
  • Safety vs usefulness: making missed-dose advice helpful without sounding like definitive medical instruction.
  • Media handling: downloading Twilio-hosted media securely, enforcing allowed content types, and limiting maximum bytes to prevent surprises.
  • State coordination: keeping DB state (meds/schedules/refills) consistent with scheduler jobs and short-term “pending” flows.

Built With

Share this project:

Updates