<?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: Nipun Goel</title>
    <description>The latest articles on DEV Community by Nipun Goel (@nipun_goel_720eefc9d5f127).</description>
    <link>https://dev.to/nipun_goel_720eefc9d5f127</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%2F4078089%2F32a12aef-65dc-4408-8ad5-6fd440ee0eac.jpg</url>
      <title>DEV Community: Nipun Goel</title>
      <link>https://dev.to/nipun_goel_720eefc9d5f127</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nipun_goel_720eefc9d5f127"/>
    <language>en</language>
    <item>
      <title>Building FinSaathi: A Voice-First Financial Assistant for Bharat</title>
      <dc:creator>Nipun Goel</dc:creator>
      <pubDate>Sat, 15 Aug 2026 07:51:24 +0000</pubDate>
      <link>https://dev.to/nipun_goel_720eefc9d5f127/building-finsaathi-a-voice-first-financial-assistant-for-bharat-5179</link>
      <guid>https://dev.to/nipun_goel_720eefc9d5f127/building-finsaathi-a-voice-first-financial-assistant-for-bharat-5179</guid>
      <description>&lt;p&gt;A voice-first financial assistant for Bharat, built during the 10 Days of Voice Agents — VoiceForBharat Edition.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Real-World Problem: Making Financial Assistance More Conversational
&lt;/h2&gt;

&lt;p&gt;Financial services and government schemes can be difficult to navigate. Users may need to understand eligibility criteria, required documents, application information, deadlines, or what to do when something goes wrong.&lt;/p&gt;

&lt;p&gt;For many users, especially users who are more comfortable speaking in Hindi, English, or Hinglish than typing long queries, a voice interface can provide a more natural way to access assistance.&lt;/p&gt;

&lt;p&gt;This led to the idea behind &lt;strong&gt;FinSaathi&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of making the user navigate through multiple forms and pages, FinSaathi allows the user to simply describe what they need.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"PMJJBY ke liye main eligible hoon?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Mere account se ek unauthorized transaction hua hai."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is not to replace banks, government portals, or human support teams. The goal is to create a conversational first layer that can understand intent, provide appropriate assistance, perform supported actions, and know when the conversation should be handed to a human or specialist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Voice Matters
&lt;/h3&gt;

&lt;p&gt;A text interface gives users time to edit and rewrite their questions. A voice conversation is different: the user explains their situation naturally and the system has to understand the intent in real time.&lt;/p&gt;

&lt;p&gt;The interaction becomes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speak → Understand → Decide → Act → Respond&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That simple loop became the foundation of FinSaathi.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Responsible Product Positioning: Assistant, Not Financial Authority
&lt;/h2&gt;

&lt;p&gt;FinSaathi is designed as an assistance system, not as a bank employee, financial regulator, or replacement for human support.&lt;/p&gt;

&lt;h3&gt;
  
  
  What FinSaathi Is
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A conversational financial assistance interface.&lt;/li&gt;
&lt;li&gt;A voice-first way to access supported information.&lt;/li&gt;
&lt;li&gt;A tool-using AI agent.&lt;/li&gt;
&lt;li&gt;A system with persistent user data for supported workflows.&lt;/li&gt;
&lt;li&gt;A bridge to human support.&lt;/li&gt;
&lt;li&gt;A platform that can route specialized requests to specialist agents.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What FinSaathi Is Not
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A replacement for a bank.&lt;/li&gt;
&lt;li&gt;A replacement for a government portal.&lt;/li&gt;
&lt;li&gt;A system that should request passwords, PINs, OTPs, or CVVs.&lt;/li&gt;
&lt;li&gt;A system with unlimited access to private financial accounts.&lt;/li&gt;
&lt;li&gt;A guaranteed financial decision-maker.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Safety Guardrails
&lt;/h3&gt;

&lt;p&gt;Financial conversations require strong safety boundaries.&lt;/p&gt;

&lt;p&gt;FinSaathi explicitly avoids requesting sensitive authentication information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OTPs.&lt;/li&gt;
&lt;li&gt;PINs.&lt;/li&gt;
&lt;li&gt;Passwords.&lt;/li&gt;
&lt;li&gt;CVVs.&lt;/li&gt;
&lt;li&gt;Full card details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the agent cannot perform a requested action directly, it should communicate that limitation rather than inventing an action.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. What Was Built: The 10-Day Evolution
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Day&lt;/th&gt;
&lt;th&gt;Focus&lt;/th&gt;
&lt;th&gt;What was added&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Day 1&lt;/td&gt;
&lt;td&gt;Core Voice Agent&lt;/td&gt;
&lt;td&gt;Initial real-time conversational voice experience.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 2&lt;/td&gt;
&lt;td&gt;Personality &amp;amp; Guardrails&lt;/td&gt;
&lt;td&gt;Defined objectives, behaviour, and safety boundaries.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 3&lt;/td&gt;
&lt;td&gt;Indian Conversations&lt;/td&gt;
&lt;td&gt;Hindi, English, and Hinglish interaction patterns.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 4&lt;/td&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Persistent user information using the database.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 5&lt;/td&gt;
&lt;td&gt;Tools &amp;amp; Eligibility&lt;/td&gt;
&lt;td&gt;Application-specific tools and scheme eligibility workflows.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 6&lt;/td&gt;
&lt;td&gt;Outbound Calling&lt;/td&gt;
&lt;td&gt;Agent-initiated phone conversations through the calling layer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 7&lt;/td&gt;
&lt;td&gt;Human Escalation&lt;/td&gt;
&lt;td&gt;Human-support requests with generated reference IDs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 8&lt;/td&gt;
&lt;td&gt;Call Analytics&lt;/td&gt;
&lt;td&gt;Real call outcome tracking and dashboard metrics.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 9&lt;/td&gt;
&lt;td&gt;Specialist Handoff&lt;/td&gt;
&lt;td&gt;Routing government-scheme workflows to a specialist agent.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 10&lt;/td&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;td&gt;Architecture, implementation details, challenges, and lessons learned.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important part was that the features were not built as isolated demos. Each new capability had to work with the voice experience that already existed.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Technical Architecture
&lt;/h2&gt;

&lt;p&gt;FinSaathi is built as a full-stack voice-agent system.&lt;/p&gt;

&lt;p&gt;At a high level, the user speaks through the real-time communication layer. The speech is processed by the voice pipeline, the AI agent determines the next action, and the response is converted back into speech using Murf Falcon.&lt;/p&gt;

&lt;p&gt;The agent can also access application-specific tools, memory, human escalation, analytics, and specialist workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  End-to-End Pipeline
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Transport:&lt;/strong&gt; LiveKit manages the real-time voice connection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech Recognition:&lt;/strong&gt; User speech is converted into text by the configured speech-to-text layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Core:&lt;/strong&gt; The LLM-powered agent understands the request and determines the appropriate response or action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools:&lt;/strong&gt; The agent can invoke application-specific workflows such as eligibility checks or escalation creation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory &amp;amp; Database:&lt;/strong&gt; Relevant information is persisted in SQLite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specialist Routing:&lt;/strong&gt; Specific conversations can be transferred to a specialist agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human Escalation:&lt;/strong&gt; Situations requiring human support can create a support request with a reference ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics:&lt;/strong&gt; Call outcomes are stored and surfaced through the analytics dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech Synthesis:&lt;/strong&gt; Murf Falcon converts the generated response into natural speech.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Architecture Diagram
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjp264l0mqcggakq60lmq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjp264l0mqcggakq60lmq.png" alt="Architecture" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Technology Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Next.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Agent&lt;/td&gt;
&lt;td&gt;LiveKit Agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-Time Transport&lt;/td&gt;
&lt;td&gt;LiveKit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text-to-Speech&lt;/td&gt;
&lt;td&gt;Murf Falcon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Layer&lt;/td&gt;
&lt;td&gt;FastAPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;SQLite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phone Calling&lt;/td&gt;
&lt;td&gt;SIP / LiveKit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  5. Building the Agent
&lt;/h2&gt;

&lt;p&gt;The first version of FinSaathi was intentionally kept simple.&lt;/p&gt;

&lt;p&gt;Instead of trying to build every feature at once, I started with the core voice loop and gradually connected the additional services around it.&lt;/p&gt;

&lt;p&gt;The basic voice-agent pipeline can be thought of as four major layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speech-to-Text — converts the user's speech into text.&lt;/li&gt;
&lt;li&gt;LLM / Agent — understands the request and decides what to do.&lt;/li&gt;
&lt;li&gt;Tools — allow the agent to perform real actions.&lt;/li&gt;
&lt;li&gt;Text-to-Speech — converts the final response back into natural speech.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LiveKit provides the real-time communication layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-Time Voice with LiveKit
&lt;/h3&gt;

&lt;p&gt;The simplified flow is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User speaks → LiveKit → Speech Recognition → AI Agent → Response → Murf Falcon → User&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This makes the interaction feel much closer to a normal conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  The AI Agent
&lt;/h3&gt;

&lt;p&gt;The AI agent is the decision-making layer of FinSaathi. Its responsibility is to understand the user's intent and determine whether the request can be answered directly or whether a tool or specialist is required.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;User: "PMJJBY ke liye main eligible hoon?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent can identify this as an eligibility request, collect information, invoke the eligibility workflow, store the result, and explain the outcome.&lt;/p&gt;

&lt;p&gt;The overall loop is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understand → Decide → Act → Respond&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Giving the Agent Tools
&lt;/h2&gt;

&lt;p&gt;An LLM can generate useful responses, but it cannot reliably perform application-specific operations without access to tools.&lt;/p&gt;

&lt;p&gt;For FinSaathi, tools were introduced for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Government-scheme information.&lt;/li&gt;
&lt;li&gt;Eligibility checks.&lt;/li&gt;
&lt;li&gt;Document requirements.&lt;/li&gt;
&lt;li&gt;User information.&lt;/li&gt;
&lt;li&gt;Human-support escalation.&lt;/li&gt;
&lt;li&gt;Call-outcome tracking.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simplified tool pattern looks like this:&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="nd"&gt;@function_tool&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;check_eligibility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_information&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;perform_eligibility_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;user_information&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model decides &lt;strong&gt;when&lt;/strong&gt; the tool is needed, while the actual business logic remains inside the tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Memory and Persistent Data
&lt;/h2&gt;

&lt;p&gt;A voice assistant becomes more useful when it can remember relevant information across conversations.&lt;/p&gt;

&lt;p&gt;FinSaathi uses SQLite to persist information required by the application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User information.&lt;/li&gt;
&lt;li&gt;Eligibility results.&lt;/li&gt;
&lt;li&gt;Escalation requests.&lt;/li&gt;
&lt;li&gt;Call outcomes.&lt;/li&gt;
&lt;li&gt;Analytics data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent → database.py → SQLite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;while dashboard requests follow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend → FastAPI → database.py → SQLite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This kept database operations in one place instead of scattering SQL logic across components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Database Access Pattern
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_escalations&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB_PATH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row_factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt;

    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM escalations ORDER BY created_at DESC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Human Escalation: Knowing When AI Should Step Aside
&lt;/h2&gt;

&lt;p&gt;Not every financial situation should be handled entirely by an AI agent.&lt;/p&gt;

&lt;p&gt;For a potentially unauthorized transaction, FinSaathi can provide safe guidance and ask whether the user wants human support.&lt;/p&gt;

&lt;p&gt;The workflow is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User reports issue → Safe guidance → User gives consent → Escalation created → Reference ID generated → Human Support Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A unique reference ID is generated for every escalation.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FS-A5323F&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A stored escalation can contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request ID.&lt;/li&gt;
&lt;li&gt;User ID.&lt;/li&gt;
&lt;li&gt;Reason.&lt;/li&gt;
&lt;li&gt;Summary.&lt;/li&gt;
&lt;li&gt;What was checked.&lt;/li&gt;
&lt;li&gt;Urgency.&lt;/li&gt;
&lt;li&gt;Language.&lt;/li&gt;
&lt;li&gt;Preferred follow-up method.&lt;/li&gt;
&lt;li&gt;Status.&lt;/li&gt;
&lt;li&gt;Created timestamp.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0bl8n682wyof46xgmvyx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0bl8n682wyof46xgmvyx.png" alt="Human escalation" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Escalation Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@function_tool&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;create_escalation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;urgency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;normal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;preferred_followup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;request_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_escalation_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;urgency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;urgency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;preferred_followup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;preferred_followup&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;request_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. Call Analytics
&lt;/h2&gt;

&lt;p&gt;For FinSaathi, a successful call means that the intended financial workflow was completed or that an appropriate resolution or escalation was reached.&lt;/p&gt;

&lt;p&gt;A failed call does not necessarily mean that the software crashed. A user may leave before completing an eligibility workflow.&lt;/p&gt;

&lt;p&gt;The dashboard records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total calls.&lt;/li&gt;
&lt;li&gt;Successful calls.&lt;/li&gt;
&lt;li&gt;Failed calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actual Call → Outcome → Database → FastAPI → Analytics Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The values come from actual browser or SIP interactions rather than hardcoded demo numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analytics Recording
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;record_call_outcome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;call_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;call_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SUCCESS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkk0cbuvvp06xujei4sxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkk0cbuvvp06xujei4sxt.png" alt="Call Analytics" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Outbound Calling
&lt;/h2&gt;

&lt;p&gt;FinSaathi was extended beyond incoming browser conversations.&lt;/p&gt;

&lt;p&gt;The outbound workflow allows the system to initiate supported phone conversations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application Data → Outbound Logic → SIP / LiveKit → Voice Agent → User&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the challenging parts was debugging the call lifecycle. There were situations where the AI greeting started but the call terminated before the conversation could continue.&lt;/p&gt;

&lt;p&gt;The investigation required checking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Worker lifecycle.&lt;/li&gt;
&lt;li&gt;SIP configuration.&lt;/li&gt;
&lt;li&gt;Network connections.&lt;/li&gt;
&lt;li&gt;Agent state.&lt;/li&gt;
&lt;li&gt;Call state.&lt;/li&gt;
&lt;li&gt;Real-time transport.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This taught me that voice debugging requires looking at the complete lifecycle rather than only the AI response.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Specialist Agent Handoff
&lt;/h2&gt;

&lt;p&gt;As FinSaathi grew, putting every workflow into one large agent became less attractive.&lt;/p&gt;

&lt;p&gt;The solution was to introduce specialist agents.&lt;/p&gt;

&lt;p&gt;For government-scheme conversations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Main Agent → Government Scheme Specialist → Eligibility / Scheme Workflow → Result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The specialist can focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Government schemes.&lt;/li&gt;
&lt;li&gt;Eligibility.&lt;/li&gt;
&lt;li&gt;Benefits.&lt;/li&gt;
&lt;li&gt;Required documents.&lt;/li&gt;
&lt;li&gt;Application information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A handoff should not feel like starting a completely new conversation. The specialist needs enough context from the previous conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context-Preserving Handoff
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@function_tool&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;copied_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat_ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;exclude_instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="p"&gt;)&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;GovernmentSchemeSpecialist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;chat_ctx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;copied_context&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;return &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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connecting you with our government scheme specialist.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgw65j2cydcufqg0d13ya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgw65j2cydcufqg0d13ya.png" alt="Specialist " width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Visual Evidence From the Build
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A. Main FinSaathi Interface
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feefuy4mj5lpu96zps5vh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feefuy4mj5lpu96zps5vh.png" alt="Home Page" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  B. Active Voice Conversation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5nv205tsrplwwm9zgiy5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5nv205tsrplwwm9zgiy5.png" alt="Voice" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  C. Human Support Dashboard
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxa9obo3voo4tyahrpnvr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxa9obo3voo4tyahrpnvr.png" alt="Human Dashboard" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  D. Call Analytics Dashboard
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkfkl3rzxvyc3ivhlhvc0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkfkl3rzxvyc3ivhlhvc0.png" alt="Call Analytics" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  13. Verified Implementation Highlights
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Example 1: Tool-Based Eligibility
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@function_tool&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;check_eligibility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_information&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;perform_eligibility_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;user_information&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps the eligibility logic deterministic and testable while allowing the agent to decide when the workflow is needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2: Human Escalation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@function_tool&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;create_escalation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;urgency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;preferred_followup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;request_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_escalation_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;urgency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;urgency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;preferred_followup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;preferred_followup&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;request_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 3: Analytics
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;record_call_outcome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;call_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;call_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SUCCESS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 4: Specialist Handoff
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@function_tool&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;copied_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat_ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;exclude_instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;GovernmentSchemeSpecialist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;chat_ctx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;copied_context&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  14. Hard Technical Challenges and Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Challenge 1: Outbound Call Lifecycle
&lt;/h3&gt;

&lt;p&gt;An outbound call could start with an AI greeting and then terminate unexpectedly.&lt;/p&gt;

&lt;p&gt;The important realization was that the generated response was not necessarily the problem.&lt;/p&gt;

&lt;p&gt;I had to investigate the worker lifecycle, SIP configuration, network connectivity, room state, agent state, and call termination events.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Voice debugging requires observing the entire real-time lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 2: FastAPI Dependency and ASGI Setup
&lt;/h3&gt;

&lt;p&gt;While building the dashboard API, I encountered a missing FastAPI dependency and later an ASGI loading error where Uvicorn could not find the expected &lt;code&gt;app&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;The debugging process was:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install dependency → verify import → verify module → verify app object → start Uvicorn → test endpoint&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Verify each backend layer independently before connecting it to the frontend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 3: Database and API Separation
&lt;/h3&gt;

&lt;p&gt;The database module does not need to run as a separate process.&lt;/p&gt;

&lt;p&gt;The agent can directly use:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;agent.py → database.py → SQLite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The dashboard uses:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend → FastAPI → database.py → SQLite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Understanding this distinction made the architecture much clearer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 4: Specialist Handoff
&lt;/h3&gt;

&lt;p&gt;A specialist handoff is not simply a function call. The new agent needs enough context to understand the user's previous conversation while keeping its own instructions separate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Context preservation and instruction isolation are both important in multi-agent systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  15. Architectural Design Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Decision 1: Shared Database Layer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Choice:&lt;/strong&gt; Keep database operations inside &lt;code&gt;database.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Agent tools and API routes can reuse the same data-access functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decision 2: FastAPI for Dashboard APIs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Choice:&lt;/strong&gt; Use FastAPI as the API layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; The frontend receives structured data while the database remains behind the backend boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decision 3: Tool-Based Actions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Choice:&lt;/strong&gt; Use function tools for eligibility, escalation, analytics, and other supported workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; The agent decides when an action is required while the application remains responsible for performing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decision 4: Specialist Agents
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Choice:&lt;/strong&gt; Route domain-specific conversations to specialist agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Smaller responsibilities, clearer instructions, and easier future expansion.&lt;/p&gt;

&lt;h2&gt;
  
  
  16. Practical Step-by-Step Build Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;You will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python with &lt;code&gt;uv&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Node.js for the frontend.&lt;/li&gt;
&lt;li&gt;A LiveKit project.&lt;/li&gt;
&lt;li&gt;A Murf API key.&lt;/li&gt;
&lt;li&gt;Credentials for the configured speech-to-text and LLM providers.&lt;/li&gt;
&lt;li&gt;SQLite.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Clone the Repository
&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/NipunGoel02/murf-ai-project
&lt;span class="nb"&gt;cd &lt;/span&gt;murf-ai-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LIVEKIT_URL=your_livekit_url
LIVEKIT_API_KEY=your_livekit_api_key
LIVEKIT_API_SECRET=your_livekit_api_secret
MURF_API_KEY=your_murf_api_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never commit real credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Install Backend Dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;backend
uv &lt;span class="nb"&gt;sync&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Start the Agent
&lt;/h3&gt;

&lt;p&gt;Use the LiveKit Agents startup command defined in the repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Start the Frontend
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;frontend
npm &lt;span class="nb"&gt;install
&lt;/span&gt;pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the package manager and scripts defined by the repository if they differ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Start the Human-Support API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run uvicorn src.escalation_api:app &lt;span class="nt"&gt;--reload&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7: Test a Conversation
&lt;/h3&gt;

&lt;p&gt;Open the frontend and test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A normal financial question.&lt;/li&gt;
&lt;li&gt;A government-scheme question.&lt;/li&gt;
&lt;li&gt;An eligibility workflow.&lt;/li&gt;
&lt;li&gt;A human escalation.&lt;/li&gt;
&lt;li&gt;A specialist handoff.&lt;/li&gt;
&lt;li&gt;A completed call.&lt;/li&gt;
&lt;li&gt;An incomplete call.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  17. Security: Keep Secrets and Caller Data Private
&lt;/h2&gt;

&lt;p&gt;A public repository should never contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API keys.&lt;/li&gt;
&lt;li&gt;API secrets.&lt;/li&gt;
&lt;li&gt;SIP credentials.&lt;/li&gt;
&lt;li&gt;Private phone numbers.&lt;/li&gt;
&lt;li&gt;Caller information.&lt;/li&gt;
&lt;li&gt;OTPs.&lt;/li&gt;
&lt;li&gt;PINs.&lt;/li&gt;
&lt;li&gt;Passwords.&lt;/li&gt;
&lt;li&gt;Account numbers.&lt;/li&gt;
&lt;li&gt;Private database files.&lt;/li&gt;
&lt;li&gt;Full private conversation transcripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use environment variables for secrets.&lt;/p&gt;

&lt;p&gt;Before publishing the repository, inspect the files and Git history to ensure that secrets were not accidentally committed.&lt;/p&gt;

&lt;p&gt;The public analytics dashboard should also avoid exposing sensitive caller information.&lt;/p&gt;

&lt;h2&gt;
  
  
  18. Practical Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue 1: The Agent Speaks and Then the Call Ends
&lt;/h3&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LiveKit worker logs.&lt;/li&gt;
&lt;li&gt;SIP state.&lt;/li&gt;
&lt;li&gt;Room state.&lt;/li&gt;
&lt;li&gt;Agent process state.&lt;/li&gt;
&lt;li&gt;Network connectivity.&lt;/li&gt;
&lt;li&gt;Call termination events.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue 2: FastAPI Says &lt;code&gt;app&lt;/code&gt; Is Missing
&lt;/h3&gt;

&lt;p&gt;Verify that the module exposes:&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;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start it using the correct module path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run uvicorn src.escalation_api:app &lt;span class="nt"&gt;--reload&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue 3: Dashboard Data Does Not Change
&lt;/h3&gt;

&lt;p&gt;Debug the complete path:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent → Database → API → Browser&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Verify the database record first, then the API response, and finally the frontend request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issue 4: Specialist Does Not Have Enough Context
&lt;/h3&gt;

&lt;p&gt;Make sure the handoff transfers relevant conversation context while keeping specialist instructions separate.&lt;/p&gt;

&lt;h2&gt;
  
  
  19. What I Would Improve Next
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. More Financial Specialists
&lt;/h3&gt;

&lt;p&gt;Future specialists could cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Banking support.&lt;/li&gt;
&lt;li&gt;Insurance.&lt;/li&gt;
&lt;li&gt;Loans.&lt;/li&gt;
&lt;li&gt;Credit cards.&lt;/li&gt;
&lt;li&gt;Government benefits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Better Observability
&lt;/h3&gt;

&lt;p&gt;The analytics system could track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Average call duration.&lt;/li&gt;
&lt;li&gt;Tool usage.&lt;/li&gt;
&lt;li&gt;Handoff rate.&lt;/li&gt;
&lt;li&gt;Escalation rate.&lt;/li&gt;
&lt;li&gt;Failure reasons.&lt;/li&gt;
&lt;li&gt;Per-workflow success rate.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. More Robust Telephony
&lt;/h3&gt;

&lt;p&gt;The SIP layer could be extended with production carrier integrations and more robust call-state handling.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. More Indian Languages
&lt;/h3&gt;

&lt;p&gt;The system could be extended to support more Indian languages and regional speech patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Better Human Support
&lt;/h3&gt;

&lt;p&gt;Human agents could receive privacy-safe context so users do not have to repeat their entire issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  20. What I Learned
&lt;/h2&gt;

&lt;p&gt;At first, a voice agent looked like:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speech → AI → Speech&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After these 10 days, I realized that a useful voice agent needs much more:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voice + LLM + Memory + Tools + Safety + Database + Real-Time Transport + Human Escalation + Analytics + Specialist Handoffs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The biggest lesson was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A useful voice agent is not just an AI that can talk. It is a system that can understand, act, remember, measure its performance, and know when a human or specialist should take over.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;FinSaathi started as a simple voice conversation and gradually became a complete financial assistance workflow.&lt;/p&gt;

&lt;p&gt;The most valuable part of the challenge was learning how these pieces fit together into one system.&lt;/p&gt;

&lt;h2&gt;
  
  
  21. Project Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/NipunGoel02/murf-ai-project" rel="noopener noreferrer"&gt;https://github.com/NipunGoel02/murf-ai-project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Built using &lt;strong&gt;Murf Falcon&lt;/strong&gt;, the fastest TTS API.&lt;/p&gt;

&lt;h2&gt;
  
  
  22. Closing
&lt;/h2&gt;

&lt;p&gt;Building FinSaathi during the &lt;strong&gt;10 Days of Voice Agents — VoiceForBharat Edition&lt;/strong&gt; was an opportunity to work with voice AI beyond simple prompt engineering.&lt;/p&gt;

&lt;p&gt;I worked with real-time communication, speech, LLM orchestration, tools, persistent data, outbound calling, human escalation, analytics, and specialist-agent routing.&lt;/p&gt;

&lt;p&gt;The biggest takeaway was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The hardest part of a voice agent is not making it speak. The hardest part is making everything around the conversation reliable.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;FinSaathi is still a prototype, but it represents the kind of voice-first system I want to continue building: conversational, useful, safe, and connected to real-world workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  References and Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;LiveKit Agents: &lt;a href="https://docs.livekit.io/agents" rel="noopener noreferrer"&gt;https://docs.livekit.io/agents&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Murf AI: &lt;a href="https://murf.ai/" rel="noopener noreferrer"&gt;https://murf.ai/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;FastAPI: &lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;https://fastapi.tiangolo.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Next.js: &lt;a href="https://nextjs.org/docs" rel="noopener noreferrer"&gt;https://nextjs.org/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Python: &lt;a href="https://docs.python.org/3/" rel="noopener noreferrer"&gt;https://docs.python.org/3/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Building FinSaathi: A Voice-First Financial Assistant for Bharat 🇮🇳 10 Days of Voice Agents — VoiceForBharat Edition</title>
      <dc:creator>Nipun Goel</dc:creator>
      <pubDate>Fri, 14 Aug 2026 18:21:12 +0000</pubDate>
      <link>https://dev.to/nipun_goel_720eefc9d5f127/building-finsaathi-a-voice-first-financial-assistant-for-bharat-10-days-of-voice-agents--2f94</link>
      <guid>https://dev.to/nipun_goel_720eefc9d5f127/building-finsaathi-a-voice-first-financial-assistant-for-bharat-10-days-of-voice-agents--2f94</guid>
      <description>&lt;p&gt;Over the last 10 days, I built FinSaathi, a voice-first AI assistant for the Financial Services track of the VoiceForBharat challenge.&lt;br&gt;
The goal was simple: build an assistant that can talk naturally with users, understand financial and government-scheme related queries, remember relevant information, use tools, and know when a human or specialist should take over.&lt;br&gt;
What started as a basic voice agent gradually became a complete system with memory, tools, outbound calling, human escalation, call analytics, and specialist-agent handoffs.&lt;br&gt;
💡 The Problem&lt;br&gt;
Financial and government-scheme processes can involve eligibility requirements, documents, deadlines, and complicated terminology.&lt;br&gt;
For users who are more comfortable speaking than typing, voice can make these interactions much more natural.&lt;br&gt;
For example, a user can simply ask:&lt;br&gt;
"PMJJBY ke liye main eligible hoon?"&lt;br&gt;
Instead of navigating through multiple forms, FinSaathi can understand the request, collect the required information, perform an eligibility check, and explain the result conversationally.&lt;br&gt;
The goal is not to replace banks or human support, but to provide a conversational first layer of assistance and escalate situations when human help is required.&lt;br&gt;
🏗️ Architecture&lt;br&gt;
                         USER&lt;br&gt;
                           │&lt;br&gt;
                           ▼&lt;br&gt;
                      LiveKit&lt;br&gt;
                           │&lt;br&gt;
                           ▼&lt;br&gt;
                    Speech-to-Text&lt;br&gt;
                           │&lt;br&gt;
                           ▼&lt;br&gt;
                     LLM / Agent&lt;br&gt;
                           │&lt;br&gt;
              ┌────────────┼────────────┐&lt;br&gt;
              ▼            ▼            ▼&lt;br&gt;
           Memory        Tools      Escalation&lt;br&gt;
              │            │            │&lt;br&gt;
              └────────────┼────────────┘&lt;br&gt;
                           ▼&lt;br&gt;
                       SQLite DB&lt;br&gt;
                           │&lt;br&gt;
                    ┌──────┴──────┐&lt;br&gt;
                    ▼             ▼&lt;br&gt;
             Human Support    Analytics&lt;br&gt;
                Dashboard     Dashboard&lt;br&gt;
                           │&lt;br&gt;
                           ▼&lt;br&gt;
                       Murf Falcon&lt;br&gt;
                           │&lt;br&gt;
                           ▼&lt;br&gt;
                          USER&lt;br&gt;
Technology Stack&lt;br&gt;
Component&lt;br&gt;
Technology&lt;br&gt;
Frontend&lt;br&gt;
Next.js / React&lt;br&gt;
AI Agent&lt;br&gt;
LiveKit Agents&lt;br&gt;
Real-time Transport&lt;br&gt;
LiveKit&lt;br&gt;
Text-to-Speech&lt;br&gt;
Murf Falcon&lt;br&gt;
Backend&lt;br&gt;
Python&lt;br&gt;
API&lt;br&gt;
FastAPI&lt;br&gt;
Database&lt;br&gt;
SQLite&lt;br&gt;
Calling&lt;br&gt;
SIP / LiveKit&lt;br&gt;
🎙️ Key Features&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Indian Voice &amp;amp; Natural Conversations
FinSaathi uses Murf Falcon for text-to-speech and supports natural Hindi/Hinglish conversations.
The goal was to make the interaction feel more like talking to an assistant rather than interacting with a traditional chatbot.&lt;/li&gt;
&lt;li&gt;Safety Guardrails
Financial conversations require strong safety boundaries.
For example, when a user reports an unauthorized transaction, FinSaathi warns them not to share:
OTP
PIN
Password
CVV
Card details
The agent also clearly explains when it does not have direct access to a user's bank account or transaction system.&lt;/li&gt;
&lt;li&gt;User Memory
FinSaathi stores relevant user information in a SQLite database so it can be reused in future conversations.
The database logic is separated into its own layer:
Agent
↓
database.py
↓
SQLite
↓
users table
This made it easier to extend the project without mixing database operations throughout the agent code.&lt;/li&gt;
&lt;li&gt;Government Scheme Eligibility
FinSaathi can use tools to perform government-scheme eligibility checks.
User asks about scheme
    ↓
Collect required information
    ↓
Eligibility tool
    ↓
Eligible / Not Eligible
    ↓
Database
    ↓
User receives result
The eligibility result can also be used to determine whether the user's intended task was successfully completed.&lt;/li&gt;
&lt;li&gt;Outbound Calling
FinSaathi can proactively contact eligible users using outbound calling.
Database
↓
Check deadlines / eligible users
↓
Outbound calling logic
↓
SIP / LiveKit
↓
AI Agent
↓
User
Setting up and debugging the SIP and LiveKit calling flow was one of the most challenging parts of the project.&lt;/li&gt;
&lt;li&gt;Human Escalation
FinSaathi can recognize situations where human support is more appropriate.
For example, for an unauthorized transaction, the agent can ask:
"Agar aap chahein, toh main aapki situation ke liye ek human support request create kar sakti hoon."
After the user gives consent, the system creates an escalation and generates a unique reference ID.
Example:
FS-A5323F
The request is stored with information such as:
Reason: possible_fraud
Urgency: HIGH
Status: OPEN
Preferred Follow-up: phone
The human-support dashboard then allows the request to move through:
OPEN
↓
IN_PROGRESS
↓
RESOLVED&lt;/li&gt;
&lt;li&gt;Call Analytics
FinSaathi also records the outcome of conversations.
For this project, a successful interaction means that the user's intended task was completed, such as completing an eligibility check or receiving the required information.
The dashboard displays:
Total Calls
Successful Calls
Failed Calls
These values come from actual browser or SIP interactions rather than hardcoded numbers.
Actual Call
↓
Determine Outcome
↓
call_analytics
↓
FastAPI
↓
Analytics Dashboard
A failed call does not necessarily mean a technical failure. For example, if a user leaves before completing an eligibility check, the interaction can be recorded as unsuccessful.&lt;/li&gt;
&lt;li&gt;Specialist Agent Handoff
Instead of making one agent responsible for every type of question, FinSaathi can hand government-scheme related conversations to a Government Scheme Specialist.
            Main Agent
                │
      Government scheme?
                │
               YES
                ↓
    Government Scheme Specialist
                │
                ↓
   Eligibility / Documents /
   Benefits / Scheme Information
This makes the architecture more modular and allows additional specialist agents to be added in the future.
🧩 Challenges I Faced
The project definitely did not work perfectly on the first attempt.
One of the biggest challenges was real-time calling and LiveKit/SIP integration.
During testing, I encountered errors such as:
WinError 64
ConnectionResetError
DuplexClosed
I also faced an outbound-call issue where the AI would start speaking but the call could terminate before the conversation continued.
Debugging this required checking:
LiveKit worker lifecycle
SIP configuration
Network connections
Agent processes
Call state
Real-time transport
This taught me that building a voice agent is not only about the LLM. The real-time infrastructure around the agent matters just as much.
Another important lesson was separating responsibilities between the agent, database, API, and frontend.
For example:
Agent → database.py → SQLite
while the human-support dashboard uses:
Frontend → FastAPI → database.py → SQLite
This separation made the system easier to extend and debug.🚀 What I Learned
Before this challenge, I thought building a voice agent was mainly:
Speech → AI → Speech
After these 10 days, I realized that a useful voice agent needs much more:
Voice
+
LLM
+
Memory
+
Tools
+
Safety
+
Real-time communication
+
Database
+
Human escalation
+
Analytics
+
Specialist handoffs
The biggest lesson for me was:
A useful voice agent isn't just an AI that can talk. It's a system that can understand, act, remember, measure its performance, and know when a human or specialist should take over.
Building FinSaathi during the 10 Days of Voice Agents — VoiceForBharat Edition gave me hands-on experience with all of these pieces.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
