<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: rohitkumar31</title>
    <description>The latest articles on DEV Community by rohitkumar31 (@rohitkumar31).</description>
    <link>https://dev.to/rohitkumar31</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4078486%2F5b3bfbff-64f7-428f-9bdb-7de9d32f00a9.png</url>
      <title>DEV Community: rohitkumar31</title>
      <link>https://dev.to/rohitkumar31</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rohitkumar31"/>
    <language>en</language>
    <item>
      <title>Building Saathi: A Voice Agent for Health Access in Rural India</title>
      <dc:creator>rohitkumar31</dc:creator>
      <pubDate>Sat, 15 Aug 2026 05:04:10 +0000</pubDate>
      <link>https://dev.to/rohitkumar31/building-saathi-a-voice-agent-for-health-access-in-rural-india-1e73</link>
      <guid>https://dev.to/rohitkumar31/building-saathi-a-voice-agent-for-health-access-in-rural-india-1e73</guid>
      <description>&lt;p&gt;Millions of people in rural and semi-urban India don't have easy access to basic health guidance. A simple question — "is this fever serious?", "where's the nearest hospital?", "do I need to see a doctor?" — often means a long trip, a language barrier, or simply not knowing where to start. Most digital health tools assume typing, reading English, and a smartphone app. That leaves out exactly the people who need help most.&lt;/p&gt;

&lt;p&gt;Voice fixes this. No typing, no app literacy required, and — critically — it can speak the way people actually talk: Hindi, English, or a natural mix of both.&lt;/p&gt;

&lt;p&gt;That's what I built over 10 days as part of 10 Days of Voice Agents — VoiceForBharat Edition: Saathi, a voice assistant for the Health Access track.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Saathi does
&lt;/h2&gt;

&lt;p&gt;Saathi is a voice agent a caller can talk to about everyday health concerns. It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gives safe, general guidance on whether a symptom needs home care, a doctor visit, or urgent attention&lt;/li&gt;
&lt;li&gt;Never diagnoses and never names a medicine — it stays firmly inside what's safe for a non-medical assistant to say&lt;/li&gt;
&lt;li&gt;Remembers returning callers (with consent) and continues from the last conversation&lt;/li&gt;
&lt;li&gt;Looks up real facility information (hours, walk-in policy) through a dedicated specialist agent&lt;/li&gt;
&lt;li&gt;Recognizes exactly when a situation is beyond it, and hands off to a human health worker — with the caller's permission&lt;/li&gt;
&lt;li&gt;Tracks its own performance on a live dashboard&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How the system works
&lt;/h2&gt;

&lt;p&gt;At a high level, every voice agent — including Saathi — is four components wired together in a loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speech-to-text (STT)&lt;/strong&gt; — turns the caller's voice into text (Saathi uses Deepgram's nova-3 model, set to language="multi" so it correctly picks up Hindi as well as English)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM&lt;/strong&gt; — the "brain" that decides what to say and which tools to call (Saathi uses Gemini)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text-to-speech (TTS)&lt;/strong&gt; — turns the reply back into voice (Murf Falcon — genuinely the fastest TTS I've used building this; the low latency is what makes the conversation feel like a real back-and-forth instead of a request-response bot)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time transport&lt;/strong&gt; — the pipe that carries audio both ways with low enough latency for a natural conversation (LiveKit)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On top of that pipeline, Saathi has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A SQLite database for caller memory, escalation requests, and call outcomes&lt;/li&gt;
&lt;li&gt;Function tools the LLM calls itself — a rule-based triage classifier, a facility lookup, an escalation creator — instead of guessing answers&lt;/li&gt;
&lt;li&gt;A second, specialist agent (Clinic &amp;amp; Appointment Specialist) that the main agent hands the conversation to for logistics questions, without the caller repeating themselves&lt;/li&gt;
&lt;li&gt;A Discord webhook integration so human escalations land somewhere real, with a reference ID&lt;/li&gt;
&lt;li&gt;A small Flask dashboard showing total/successful/failed calls, built from real call data&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The most important features
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;An Indian voice, and a language-aware pipeline.&lt;/strong&gt; Saathi speaks in an Indian English/Hindi voice via Murf Falcon, and the prompt explicitly requires Hindi to render in Devanagari script (नमस्ते), never romanized — a detail that's easy to miss and immediately makes the agent feel less robotic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A personality with hard limits, not just a system prompt.&lt;/strong&gt; Saathi's instructions are structured as IDENTITY → OBJECTIVES → KNOWLEDGE → LANGUAGE → GUARDRAILS → STYLE. The guardrails aren't suggestions — they're enforced behaviorally: no diagnosis, no drug names, and a defined escalation script for red-flag symptoms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory with consent as a hard rule, not a nice-to-have.&lt;/strong&gt; Saathi asks permission before saving anything about a caller, and if they say no, nothing is stored. For a health use case, this isn't optional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools that compute real answers instead of the LLM guessing.&lt;/strong&gt; The triage classifier is a deterministic, rule-based function — not the LLM freestyling a medical opinion. It also has a defined failure path: if a tool errors out, Saathi says so out loud and falls back to safe generic advice, instead of going silent or making something up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Escalation with a real destination.&lt;/strong&gt; When Saathi hits its limits, it creates a tracked request — sent to a real Discord channel via webhook — with a reference ID the caller can hold onto, after explicit consent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A specialist handoff.&lt;/strong&gt; Saathi stays a generalist for health guidance; a separate Clinic &amp;amp; Appointment Specialist agent takes over for facility-logistics questions, introduces itself, and hands the conversation back if the topic shifts back to a health question.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hardest part: it wasn't the AI, it was the plumbing
&lt;/h2&gt;

&lt;p&gt;If I'm honest, the single biggest time sink across all 10 days wasn't prompt design or tool logic — it was local network/DNS reliability. The LiveKit worker would register successfully, then intermittently fail to establish the actual room connection with a getaddrinfo failed error, or the local Python process would go unresponsive under system load and get killed and restarted by the worker supervisor.&lt;/p&gt;

&lt;p&gt;What I learned from debugging this over and over:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A startup that takes 40-60+ seconds instead of ~7-10 seconds is an early warning sign of system load about to cause a connection drop — that gap became my signal to close other apps and retry&lt;/li&gt;
&lt;li&gt;Switching DNS to 8.8.8.8 / 8.8.4.4 helped more than anything else&lt;/li&gt;
&lt;li&gt;When a call genuinely can't connect in time, the honest move is to show your working code and explain the network issue plainly, rather than pretend it worked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second real difficulty was environment variable duplication between the frontend and backend — LiveKit credentials need to match exactly in both .env.local files, and a single mismatched key produces a generic "invalid API key" error that doesn't tell you which key is wrong. Double-checking both files side by side, line by line, was the fix every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to build your own
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. The four core pieces you need:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An STT provider (Deepgram, etc.)&lt;/li&gt;
&lt;li&gt;An LLM (Gemini, OpenAI, etc.)&lt;/li&gt;
&lt;li&gt;A TTS provider — I'd recommend Murf Falcon for latency&lt;/li&gt;
&lt;li&gt;A real-time transport layer (LiveKit is the easiest path)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Setting up and running the project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fork the Murf LiveKit Starter repository&lt;/li&gt;
&lt;li&gt;Follow its README for uv sync (backend) and pnpm install (frontend)&lt;/li&gt;
&lt;li&gt;Run the backend with &lt;code&gt;uv run python src/agent.py dev&lt;/code&gt; and the frontend with &lt;code&gt;pnpm dev&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Where API keys go — and where they must NOT go:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy .env.example to .env.local in both backend/ and frontend/ — never commit .env.local, it's already gitignored&lt;/li&gt;
&lt;li&gt;You'll need: a LiveKit Cloud project (URL, API key, secret), a Murf API key, a Deepgram API key, and an LLM provider key&lt;/li&gt;
&lt;li&gt;Never paste real keys into chat, screenshots, or your repo — treat them like passwords&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Connecting and testing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With both the backend and frontend running, open localhost:3000, click the start button, allow microphone access, and talk&lt;/li&gt;
&lt;li&gt;Watch the backend terminal for a "registered worker" log line as confirmation the agent is live&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. The code:&lt;/strong&gt;&lt;br&gt;
My repository: &lt;a href="https://github.com/rohitkumar31/murf-livekit-starter" rel="noopener noreferrer"&gt;https://github.com/rohitkumar31/murf-livekit-starter&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd improve next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Swap the local rule-based triage classifier for a reviewed, larger medical red-flag dataset&lt;/li&gt;
&lt;li&gt;Replace the hand-built facility dataset with a real state health department API&lt;/li&gt;
&lt;li&gt;Add outbound calling fully (Twilio + LiveKit SIP) for proactive follow-up reminders&lt;/li&gt;
&lt;li&gt;Add automatic language detection confidence scoring to catch mis-transcriptions in noisy environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Repository: &lt;a href="https://github.com/rohitkumar31/murf-livekit-starter" rel="noopener noreferrer"&gt;https://github.com/rohitkumar31/murf-livekit-starter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Built with Murf Falcon — the fastest TTS API I used across this build&lt;/li&gt;
&lt;li&gt;Part of 10 Days of Voice Agents — VoiceForBharat Edition by Murf AI&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you're building your own voice agent for an underserved use case, happy to answer questions — drop a comment.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>healthtech</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
