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
- anthropic-api
- fastapi
- python
- sqlalchemy
- sqlite
- twilio
Log in or sign up for Devpost to join the conversation.