DEV Community

Cover image for How I built an Autonomous Voice Healthcare Agent on FalkorDB that actually saves lives
Roshni Mishra
Roshni Mishra

Posted on

How I built an Autonomous Voice Healthcare Agent on FalkorDB that actually saves lives

Late last month, I was talking to a doctor friend who works near Varanasi. He told me something that stuck with me:

"The hardest part of emergency triage isn't diagnosing the patient. It's connecting the dots in real time β€” matching symptoms to acute conditions, checking against existing allergies, finding which nearby facility has an open oxygen bed, and alerting the on-call specialist before the ambulance even leaves the village."

Most AI healthcare projects you see today are simple Q&A chatbots. You tell ChatGPT you have a fever, and it regurgitates web pages or tells you to drink water and see a doctor.

When I saw the FalkorDB Graph Hacks, I knew I didn’t want to build another chatbot that answers prompts with polite text. I wanted to build an agent that reasons across connected medical infrastructure and takes real-world action.

Meet CareGraph AI β€” an autonomous, voice-driven triage and emergency bed reservation agent built on FalkorDB, LiveKit, Murf Falcon, and Twilio.


πŸ›‘ Why Vector Search & SQL Completely Broke Down

Before writing a single Cypher query, I asked myself: Can't I just build this with Pinecone or Postgres?

The answer was an immediate no, and here is why:

  1. Vector RAG is blind to multi-hop relationships: Vector embeddings are great at finding text similarity ("What are pneumonia symptoms?"). But they are terrible at structural graph constraints: Find a hospital within 15 km that has an open ICU bed AND an on-call Pulmonologist, while ensuring the patient's penicillin allergy is flagged to the ER desk. Embeddings don't do graph joins.
  2. Relational SQL Joins explode at 5 hops: In SQL, connecting Patient -> Symptoms -> Conditions -> Contraindicated Drugs -> Hospitals -> Specialty Doctors -> Available Beds requires 6 nested JOIN clauses across changing tables. Under concurrent emergency queries, performance degrades fast.
  3. FalkorDB does it in 14 milliseconds: Because FalkorDB runs as a Redis module storing graphs as sparse matrices with GraphBLAS linear algebra, traversing multi-hop relationship paths is basically matrix multiplication. Sub-15ms latency every single time.

🧠 The Graph Architecture: Connecting the Dots

Here is what the medical knowledge graph looks like inside FalkorDB:

[Patient: Ramesh] ──(EXHIBITS)──> [Symptom: High Fever]
       β”‚                                  β”‚
  (ALLERGIC_TO)                      (INDICATES)
       β”‚                                  β”‚
       β–Ό                                  β–Ό
[Drug: Penicillin] <──(CONTRAINDICATES)── [Condition: Acute Pneumonia]
                                                  β”‚
                                          (REQUIRES_SPECIALTY)
                                                  β”‚
                                                  β–Ό
[Hospital: BHU Center] ──(EMPLOYS)──> [Doctor: Dr. Verma (Pulmonology)]
       β”‚
   (HAS_BED)
       β”‚
       β–Ό
[Bed: ICU_04 (is_available: true)]
Enter fullscreen mode Exit fullscreen mode

⚑ The 5-Hop Cypher Query That Runs It All

When a patient speaks to the agent over voice, the spoken audio is converted to text via Deepgram, symptoms are mapped, and the agent executes this exact Cypher query against FalkorDB:

// 1. Match patient symptoms to high-risk conditions
MATCH (p:Patient {id: $patient_id})-[e:EXHIBITS]->(s:Symptom)-[i:INDICATES]->(c:Condition)
WHERE c.risk_level IN ['High', 'Critical']

// 2. Cross-reference known patient drug allergies & contraindications
OPTIONAL MATCH (p)-[:ALLERGIC_TO]->(d:Drug)<-[:CONTRAINDICATES]-(c)

// 3. Traverse to find nearby facilities with both the specialist and open bed
MATCH (h:Hospital)-[:EMPLOYS]->(doc:Doctor {specialty: c.requires_specialty, available: true}),
      (h)-[:HAS_BED]->(b:Bed {type: "ICU_Oxygen", is_available: true})

RETURN p.name AS Patient,
       c.name AS DiagnosedCondition,
       c.risk_level AS Severity,
       collect(DISTINCT d.name) AS AllergiesToAvoid,
       h.name AS TargetFacility,
       h.phone AS HospitalContact,
       doc.name AS AssignedDoctor,
       count(b) AS BedsAvailable
ORDER BY BedsAvailable DESC
LIMIT 1;
Enter fullscreen mode Exit fullscreen mode

In a single query, the agent gets the diagnosis, verifies contraindications, finds the right hospital, selects the doctor, and locates the open ICU bed.


πŸš‘ Closing the Loop: Agents That ACT (Not Just Chat)

Finding the hospital in the graph is only half the battle. If a patient is struggling to breathe at 11:30 PM, they don't need advice β€” they need action.

As soon as the query returns:

  1. The agent reassures the patient over voice: Using Murf Falcon's sub-250ms voice synthesis (hi-IN-shweta), the patient hears an empathetic voice in Hindi or English: "Ramesh ji, we have identified acute pneumonia symptoms. We are reserving an ICU oxygen bed for you at BHU Trauma Center right now."
  2. Autonomous PSTN Outbound Call: The agent triggers a Twilio telephony dispatch call directly to the BHU Emergency Desk: > "Emergency Dispatch Alert from CareGraph AI: Reserving ICU Bed #04 for incoming patient Ramesh Kumar (54 M, Acute Pneumonia). Flag: Penicillin allergy. On-call doctor Dr. Verma notified."
  3. Graph State Mutation: The bed node in FalkorDB is mutated in real time: SET b.is_available = false, b.reserved_for = 'Ramesh Kumar'.
  4. Persistent Session Memory (Track 02): An (:AgentSession) node is linked to the patient. Exactly 24 hours later, the Outbound Follow-up Agent queries FalkorDB to place an automated follow-up call checking on the patient's recovery status.

πŸ› οΈ The Tech Stack

  • Graph Engine: FalkorDB (Cypher Query Language + GraphBLAS linear algebra)
  • Voice Pipeline: Murf Falcon (sub-250ms multilingual Indian TTS) + Deepgram Nova-2 STT
  • Telephony & Realtime WebRTC: Twilio REST API + LiveKit
  • Frontend / Dashboard: Next.js 14 + Tailwind CSS + Interactive Canvas Graph Physics
  • Deployment: Vercel Production Edge

πŸ’‘ What Building on FalkorDB Taught Me

Coming from SQL and Vector databases, thinking in graph traversals felt like unlocking a superpower:

  1. Context without token bloat: Instead of stuffing 20 pages of hospital directories and allergy guidelines into an LLM context window (and praying it doesn't hallucinate), the relationships are explicitly enforced by graph edges.
  2. Graph memory scales effortlessly: Storing agent decisions as graph nodes (AgentSession) turns memory from a messy chat log into a structured history you can query with Cypher.
  3. Speed matters in emergencies: FalkorDB's C-based matrix implementation meant our multi-hop emergency queries executed in ~14ms.

πŸ”— Try It Out & Inspect the Code

I would love to hear your thoughts in the comments! How are you approaching agentic memory and graph coordination in your own projects? Drop a like ❀️ or unicorn πŸ¦„ if you found this breakdown useful!

Top comments (0)