<?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: Sohel Khilji</title>
    <description>The latest articles on DEV Community by Sohel Khilji (@sohel_khilji_71868a2d459a).</description>
    <link>https://dev.to/sohel_khilji_71868a2d459a</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%2F4078865%2F264d1209-ae7e-41bb-9954-6028010b0f97.png</url>
      <title>DEV Community: Sohel Khilji</title>
      <link>https://dev.to/sohel_khilji_71868a2d459a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sohel_khilji_71868a2d459a"/>
    <language>en</language>
    <item>
      <title>Building Jan Sahay: Real-Time AI Voice Agent</title>
      <dc:creator>Sohel Khilji</dc:creator>
      <pubDate>Sat, 15 Aug 2026 12:33:27 +0000</pubDate>
      <link>https://dev.to/sohel_khilji_71868a2d459a/building-jan-sahay-real-time-ai-voice-agent-5795</link>
      <guid>https://dev.to/sohel_khilji_71868a2d459a/building-jan-sahay-real-time-ai-voice-agent-5795</guid>
      <description>&lt;p&gt;Over the past ten days as part of the &lt;strong&gt;Murf AI Voice for Bharat Challenge&lt;/strong&gt;, I built &lt;strong&gt;Jan Sahay (जन सहाय)&lt;/strong&gt;—an AI voice assistant engineered to bring financial literacy, government scheme guidance, and transaction safety directly to Indian citizens through real-time spoken voice interactions.&lt;/p&gt;

&lt;p&gt;In a country as linguistically diverse as India, navigating text-heavy web portals, complex scheme eligibility forms, and digital banking procedures can be overwhelming. &lt;strong&gt;Jan Sahay&lt;/strong&gt; bridges this gap by transforming dense public documentation into natural, sub-second spoken conversations.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Why Jan Sahay? The Mission &amp;amp; Target Users
&lt;/h2&gt;

&lt;p&gt;For millions of citizens across India, accessing benefits under schemes like &lt;strong&gt;PM Kisan&lt;/strong&gt;, &lt;strong&gt;PM Awas Yojana&lt;/strong&gt;, or &lt;strong&gt;Sukanya Samriddhi Yojana&lt;/strong&gt; involves navigating complex bureaucracy and paperwork. Furthermore, millions of first-time digital payment users face daily risks regarding unauthorized transactions and digital banking fraud.&lt;/p&gt;

&lt;p&gt;I chose the &lt;strong&gt;Financial Services&lt;/strong&gt; track because voice-first interaction is the most accessible interface for public literacy. &lt;strong&gt;Jan Sahay&lt;/strong&gt; provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Natural Spoken Guidance:&lt;/strong&gt; Low-latency voice interaction tuned for Indian accents and phrasing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant Scheme Assessment:&lt;/strong&gt; Direct eligibility evaluation and clear document checklists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy &amp;amp; Safety Safeguards:&lt;/strong&gt; Built-in PII scrubbing and consent-backed human escalation workflows.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. System Architecture: Real-Time Audio Pipeline
&lt;/h2&gt;

&lt;p&gt;Jan Sahay utilizes a decoupled, real-time pipeline connected over &lt;strong&gt;WebRTC&lt;/strong&gt; using &lt;strong&gt;LiveKit Agents&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────┐       Audio Stream (WebRTC)       ┌──────────────────────────┐
│             ├──────────────────────────────────►│  Deepgram Nova-3 (STT)   │
│ User Client │                                   └────────────┬─────────────┘
│  (Next.js)  │                                                │ Spoken Text
│             │                                   ┌────────────▼─────────────┐
│             │◄──────────────────────────────────┤   Google Gemini (LLM)    │
└─────────────┘       Audio Stream (WebRTC)       │   + Dynamic Tools &amp;amp; VAD  │
                                                  └────────────┬─────────────┘
                                                               │ Synthesized Text
                                                  ┌────────────▼─────────────┐
                                                  │ Murf Falcon 2 (TTS API)  │
                                                  └──────────────────────────┘

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speech-to-Text (STT):&lt;/strong&gt; &lt;strong&gt;Deepgram Nova-3&lt;/strong&gt; transcribes caller speech in real-time, handling accent variations and background noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM &amp;amp; Tool Orchestration:&lt;/strong&gt; &lt;strong&gt;Google Gemini&lt;/strong&gt; evaluates user intent, executes database tools, scrubs PII, and handles agent state transitions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text-to-Speech (TTS):&lt;/strong&gt; &lt;strong&gt;Murf Falcon 2&lt;/strong&gt; synthesizes plain text responses into natural Indian-accented speech with sub-second latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport Layer:&lt;/strong&gt; &lt;strong&gt;LiveKit Agents&lt;/strong&gt; handles full-duplex WebRTC audio streaming, Voice Activity Detection (VAD), and session state.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  3. Key Features Built Across the Challenge
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sub-Second Voice Synthesis (Murf Falcon 2):&lt;/strong&gt; Leveraging Murf Falcon 2 enabled Jan Sahay to achieve sub-second voice synthesis, making the interaction feel natural and human.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated PII Scrubbing (&lt;code&gt;sanitize_text()&lt;/code&gt;):&lt;/strong&gt; To preserve user privacy, the agent automatically filters out sensitive personal identifiers (such as account numbers, PINs, OTPs, identity credentials, and PAN details) before logging caller history to SQLite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consent-Backed Human Escalation:&lt;/strong&gt; When callers report fraud or disputed transactions, Jan Sahay explicitly requests user consent before generating an escalation ticket (&lt;code&gt;ESC-2026-XXXXX&lt;/code&gt;) for human support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Agent Specialist Handoff:&lt;/strong&gt; In-depth scheme inquiries trigger a function call (&lt;code&gt;transfer_to_scheme_specialist&lt;/code&gt;). The main agent announces the transfer out loud (&lt;em&gt;"I am connecting you to our Government Schemes Specialist..."&lt;/em&gt;), and the &lt;strong&gt;SchemeSpecialist&lt;/strong&gt; takes over using LiveKit's &lt;code&gt;AgentSession.update_agent()&lt;/code&gt; while preserving session context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilient Session Lifecycle Tracking:&lt;/strong&gt; Configured LiveKit's &lt;code&gt;add_shutdown_callback&lt;/code&gt; to guarantee that call metrics, call outcomes, and analytics flush safely to SQLite even if the call disconnects abruptly.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Engineering Challenges &amp;amp; Solutions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Challenge 1: Context Loss During Multi-Agent Handoff
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem:&lt;/strong&gt; Swapping execution from the main assistant to the specialized agent initially reset the conversation context, forcing users to repeat themselves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution:&lt;/strong&gt; Used &lt;code&gt;context.session.update_agent(specialist)&lt;/code&gt; to dynamically transition execution while retaining the active &lt;code&gt;AgentSession&lt;/code&gt; history.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenge 2: Disconnect Cleanup &amp;amp; Analytics Loss
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem:&lt;/strong&gt; When callers closed their browser tab mid-conversation, standard cleanup routines failed to trigger, leading to lost call outcome logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution:&lt;/strong&gt; Registered LiveKit lifecycle hooks (&lt;code&gt;add_shutdown_callback&lt;/code&gt;), ensuring that session metadata and database records flush instantly upon transport state changes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. How to Build &amp;amp; Run Jan Sahay Locally
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Clone Repository &amp;amp; Virtual Environment Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/0xzerex/murf-livekit-starter.git
&lt;span class="nb"&gt;cd &lt;/span&gt;murf-livekit-starter/backend
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv

&lt;span class="c"&gt;# Activate environment (Windows)&lt;/span&gt;
.venv&lt;span class="se"&gt;\S&lt;/span&gt;cripts&lt;span class="se"&gt;\a&lt;/span&gt;ctivate
&lt;span class="c"&gt;# Linux/macOS: source .venv/bin/activate&lt;/span&gt;

pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configure Environment Variables
&lt;/h3&gt;

&lt;p&gt;Create an &lt;code&gt;.env.local&lt;/code&gt; file in your root folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LIVEKIT_URL=wss://your-project.livekit.cloud
LIVEKIT_API_KEY=your_livekit_api_key
LIVEKIT_API_SECRET=your_livekit_api_secret
MURF_API_KEY=your_murf_falcon_api_key
DEEPGRAM_API_KEY=your_deepgram_api_key
GOOGLE_API_KEY=your_gemini_api_key

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Run the Agent Backend
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python src/agent.py dev

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Code Highlight: Implementing Specialist Handoff
&lt;/h2&gt;

&lt;p&gt;Here is how the main assistant transfers execution to the &lt;code&gt;SchemeSpecialist&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;livekit.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;function_tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;scheme_specialist&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SchemeSpecialist&lt;/span&gt;

&lt;span class="nd"&gt;@function_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;transfer_to_scheme_specialist&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Transfer the caller to the Government Schemes Specialist for detailed eligibility guidance.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transfer_to_scheme_specialist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RunContext&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Announce handoff clearly out loud
&lt;/span&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I am connecting you to our Government Schemes Specialist. Please hold on a moment.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Instantiate specialist agent &amp;amp; transfer active session state
&lt;/span&gt;    &lt;span class="n"&gt;specialist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SchemeSpecialist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;specialist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Transferred successfully to Scheme Specialist.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Repository &amp;amp; Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/0xzerex/murf-livekit-starter/tree/Day10" rel="noopener noreferrer"&gt;Jan Sahay Source Code (Day 10 Branch)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Challenge:&lt;/strong&gt; 10 Days of Voice Agents — VoiceForBharat Edition by Murf AI&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>voiceforbharat</category>
      <category>murffalcon</category>
      <category>10daysofaivoiceagents</category>
      <category>murfaivoiceagentschallenge</category>
    </item>
  </channel>
</rss>
