Inspiration

Every day, radiology reports flag findings that need a follow-up scan, a specialist referral, or a repeat in six months. And every day, a huge number of those follow-ups never happen. The patient leaves the imaging center, the recommendation sits in a PDF, and nobody closes the loop. These missed follow-ups are one of the most preventable failure points in healthcare, and they fall hardest on patients who don't speak English well or don't know how to navigate the system.

We wanted to build the thing that actually makes the follow-up happen proactively, without taking the doctor out of the decision.

What it does

Recall closes the loop on radiology follow-ups:

  1. An imaging center's radiology report comes in as a PDF.
  2. Claude parses the report and classifies the finding against published clinical guidelines (Fleischner, BI-RADS, and others) to decide whether a follow-up is needed and how urgent it is.
  3. It drafts a patient-facing call script, then routes the case to a radiologist for sign-off. No patient is ever contacted without explicit human approval.
  4. Once the radiologist approves, a multilingual voice agent calls the patient, explains the follow-up, and books the appointment, in the patient's preferred language.

The whole pipeline is decision-support, not autonomous diagnosis. The human sign-off gate is the floor: the system physically cannot dial a patient on an unapproved case.

How we built it

The backend is a FastAPI service that orchestrates the pipeline. Claude handles the report parsing, guideline classification, urgency triage, and script drafting. The voice agent is built on a Twilio + Deepgram bridge, with Claude as the reasoning layer driving the conversation, and it streams audio in real time over a websocket for the length of the call.

Radiologist sign-off happens by email or directly from the doctor dashboard; both paths converge on the same approval function, which flips the case to approved and triggers the outbound call. The frontend is a Next.js app on Vercel with a landing page, a patient portal, and a doctor dashboard. Case data, audit logs, and call outcomes live in Supabase.

The multilingual support is real: the voice agent swaps its speech and transcription models per language and localizes the greeting, so a French-speaking patient hears a fluent French call, not English with an accent.

Challenges we ran into

  • Holding a live phone call open. A patient call lasts minutes, and the websocket to the voice provider would silently drop during conversational pauses. We had to add a keepalive heartbeat to hold the connection open while the patient was thinking.
  • Multilingual speech recognition. Getting a non-English call to actually transcribe correctly meant pinning the recognition language explicitly, because the model would otherwise default to English and turn French replies into word-salad.
  • Keeping the safety gate airtight. We wanted the approval-to-call flow to be impossible to bypass, so the call function re-checks the approval status from the database at dial time rather than trusting the caller.
  • Integrating four people's work under a deadline. Voice, orchestrator, and frontend were built in parallel and had to converge cleanly.

What we learned

How much of a "working AI product" is actually the unglamorous plumbing, the keepalives, the language pinning, the idempotency, the human-in-the-loop gate. The Claude reasoning was the easy part; making it safe and reliable enough to put on a real phone call to a real person was the hard part.

What's next

Real clinical validation, proper patient consent flows, HIPAA-grade infrastructure, and retry cadences for patients who miss the first call. We deliberately scoped the human sign-off as mandatory and would keep it that way in production.

Built With

Share this project:

Updates