<?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: Takshak Singh Rajawat</title>
    <description>The latest articles on DEV Community by Takshak Singh Rajawat (@taksshak).</description>
    <link>https://dev.to/taksshak</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%2F3811177%2F5d4d42df-4bcd-4847-8610-1602a25264f1.png</url>
      <title>DEV Community: Takshak Singh Rajawat</title>
      <link>https://dev.to/taksshak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/taksshak"/>
    <language>en</language>
    <item>
      <title>ArthSakhi: Building a Voice Agent That Knows When to Speak, Act, and Ask for Help</title>
      <dc:creator>Takshak Singh Rajawat</dc:creator>
      <pubDate>Sat, 15 Aug 2026 18:03:15 +0000</pubDate>
      <link>https://dev.to/taksshak/arthsakhi-building-a-voice-agent-that-knows-when-to-speak-act-and-ask-for-help-4db8</link>
      <guid>https://dev.to/taksshak/arthsakhi-building-a-voice-agent-that-knows-when-to-speak-act-and-ask-for-help-4db8</guid>
      <description>&lt;p&gt;A 10-day journey building a responsible financial-literacy voice agent for Bharat with LiveKit, Gemini, Deepgram, and Murf Falcon.&lt;br&gt;
Project: ArthSakhi (अर्थसखी)&lt;br&gt;
Track: Financial Services&lt;br&gt;
Built for: The Murf AI 10 Days of Voice Agents - VoiceForBharat Edition&lt;/p&gt;




&lt;p&gt;The idea&lt;br&gt;
Many financial services are technically available but still difficult to access.&lt;br&gt;
The information may be hidden behind complicated websites, long forms, unfamiliar terminology, or language barriers. For someone who is more comfortable speaking than typing, a voice interface can make the first step much easier.&lt;br&gt;
That was the idea behind ArthSakhi: a voice-based financial-literacy assistant that helps users understand government schemes, ask basic eligibility questions, learn about required documents, and reach appropriate support when the situation is beyond the agent's role.&lt;br&gt;
ArthSakhi is not a bank, government department, financial adviser, or approval authority. It provides guidance, uses verified tools where available, explains limitations, and directs users to official or human support when necessary.&lt;br&gt;
What ArthSakhi does&lt;br&gt;
ArthSakhi can:&lt;br&gt;
Explain basic financial-literacy concepts.&lt;br&gt;
Guide users through supported government-scheme questions.&lt;br&gt;
Ask non-sensitive questions for basic eligibility checks.&lt;br&gt;
Explain document requirements.&lt;br&gt;
Remember consent-related preferences.&lt;br&gt;
Make controlled outbound reminder calls.&lt;br&gt;
Respect opt-out phrases such as "stop" and "do not call again."&lt;br&gt;
Create consent-based human-support requests.&lt;br&gt;
Track successful and unsuccessful call outcomes.&lt;br&gt;
Hand scheme-specific questions to a dedicated specialist agent.&lt;/p&gt;

&lt;p&gt;The goal was not to make one agent answer everything. The goal was to make the system useful without making it careless.&lt;br&gt;
Why voice&amp;nbsp;matters&lt;br&gt;
Voice is especially useful when users:&lt;br&gt;
Are more comfortable speaking than typing.&lt;br&gt;
Prefer Hindi, English, or Hinglish conversations.&lt;br&gt;
Find long forms and text-heavy websites difficult.&lt;br&gt;
Need information explained in simpler language.&lt;br&gt;
Want to ask a question without knowing the exact technical terms.&lt;/p&gt;

&lt;p&gt;A user can say:&lt;br&gt;
"Mujhe is scheme ke liye kaunse documents chahiye?"&lt;br&gt;
Instead of searching through multiple pages, the agent can understand the intent and guide the conversation step by step.&lt;br&gt;
System architecture&lt;br&gt;
The voice path looks like this:&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;br&gt;
The caller speaks through a browser or SIP endpoint.&lt;br&gt;
LiveKit carries the real-time audio.&lt;br&gt;
Deepgram converts speech into text.&lt;br&gt;
Gemini interprets the request and decides what should happen.&lt;br&gt;
Python tools perform structured actions.&lt;br&gt;
SQLite stores safe operational data.&lt;br&gt;
Murf Falcon converts the response into natural speech.&lt;br&gt;
LiveKit sends the response back to the caller.&lt;/p&gt;

&lt;p&gt;The core components&lt;br&gt;
ComponentRole in ArthSakhiLiveKitReal-time browser voice and SIP transportDeepgramSpeech-to-textGeminiReasoning, intent detection, and tool selectionMurf FalconNatural text-to-speechLinphoneControlled SIP endpoint for testingPythonAgent logic and tool implementationSQLiteConsent, escalation, and call-outcome storageDashboardDisplays real call metrics&lt;br&gt;
Murf Falcon was particularly important because a voice agent is experienced through its responses, not just its backend logic. Fast and natural speech helps the interaction feel more conversational.&lt;br&gt;
The most important design decisions&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clear boundaries before clever responses
ArthSakhi has a defined role. It can explain and guide, but it should not pretend to be an official decision-maker.
The agent must not claim that:
A scheme application has been approved.
A transaction has been blocked.
A refund has been processed.
A fraud complaint has been resolved.
A caller is definitely eligible when only a basic check was completed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The final decision belongs to the relevant government department, bank, or authorized institution.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Privacy by&amp;nbsp;default
The system avoids requesting or displaying:
OTPs.
PINs.
Passwords.
CVVs.
Full account numbers.
Card numbers.
Aadhaar or PAN numbers.
Raw audio.
Full conversation transcripts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agent uses only the minimum safe information required for a flow.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Consent-aware memory
Memory should not mean storing everything a user says.
ArthSakhi remembers only information that is useful for a future interaction and permitted by the user. Consent is required before saving caller preferences or using them for reminders.
This was an important shift in my thinking: useful memory is selective, explainable, and controllable.&lt;/li&gt;
&lt;li&gt;Tools instead of unsupported generation
The agent uses tools for actions that should be structured and traceable:
Scheme eligibility checks.
Document guidance.
Human-support request creation.
Opt-out checks.
Duplicate-call prevention.
Call-outcome recording.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A tool gives the agent a defined action and a defined result instead of asking the model to improvise everything.&lt;br&gt;
Outbound calls with&amp;nbsp;consent&lt;br&gt;
For controlled outbound testing, I connected LiveKit SIP with Linphone.&lt;br&gt;
Outbound calls require more responsibility because the user did not initiate the conversation. ArthSakhi begins by explaining:&lt;br&gt;
Who is calling.&lt;br&gt;
Why the call is being made.&lt;br&gt;
How the caller can stop future reminders.&lt;/p&gt;

&lt;p&gt;It recognizes phrases such as:&lt;br&gt;
stop&lt;br&gt;
do not call again&lt;br&gt;
unsubscribe&lt;br&gt;
The system also handles:&lt;br&gt;
Unanswered calls.&lt;br&gt;
SIP connection failures.&lt;br&gt;
Data-source failures.&lt;br&gt;
Duplicate-call prevention.&lt;br&gt;
No automatic retries.&lt;/p&gt;

&lt;p&gt;The purpose is not simply to make an outbound call. It is to make the call respectfully.&lt;br&gt;
Human escalation&lt;br&gt;
Some requests should move from AI guidance to human support.&lt;br&gt;
ArthSakhi can create a support request for cases such as:&lt;br&gt;
Suspected fraud.&lt;br&gt;
Unauthorized transactions.&lt;br&gt;
Disputed charges.&lt;br&gt;
Account-specific banking issues.&lt;br&gt;
Situations requiring an official decision.&lt;/p&gt;

&lt;p&gt;Before creating the request, it explains what will be shared and asks for explicit consent.&lt;br&gt;
A safe request may include:&lt;br&gt;
Issue: Caller reported a suspicious banking message.&lt;br&gt;
Checked: Caller was advised not to share OTPs or PINs.&lt;br&gt;
Urgency: High.&lt;br&gt;
Language: Hinglish.&lt;br&gt;
Follow-up: Phone.&lt;br&gt;
Reference ID: ASH-2026-XXXXXXXX.&lt;br&gt;
It must not include account numbers, OTPs, PINs, passwords, or government IDs.&lt;br&gt;
Measuring whether a call&amp;nbsp;worked&lt;br&gt;
A connected call is not automatically a successful call.&lt;br&gt;
For ArthSakhi, a successful call means one of two things happened:&lt;br&gt;
The agent completed a scheme eligibility flow and communicated the result.&lt;br&gt;
The agent created a consented human-support request and gave the caller a reference ID.&lt;/p&gt;

&lt;p&gt;If the caller disconnects before reaching either outcome, the call is recorded as failed. In this context, "failed" means the defined user goal was not completed; it does not necessarily mean the software crashed.&lt;br&gt;
The dashboard displays:&lt;br&gt;
Total calls.&lt;br&gt;
Successful calls.&lt;br&gt;
Failed calls.&lt;/p&gt;

&lt;p&gt;These values are calculated from actual browser and SIP call records stored in SQLite rather than being hardcoded.&lt;br&gt;
Specialist handoff&lt;br&gt;
For scheme-specific questions, ArthSakhi hands the conversation to a separate Government Scheme Eligibility Specialist.&lt;br&gt;
The main agent handles:&lt;br&gt;
"What does financial literacy mean?"&lt;br&gt;
The specialist handles:&lt;br&gt;
"Am I eligible for PMJDY, and what documents do I need?"&lt;br&gt;
Before transferring, ArthSakhi says:&lt;br&gt;
"I'll connect you to our government-scheme eligibility specialist for more focused guidance."&lt;br&gt;
The specialist receives:&lt;br&gt;
The user's latest question.&lt;br&gt;
A short conversation summary.&lt;br&gt;
Preferred language.&lt;br&gt;
Scheme name, if known.&lt;br&gt;
Safe, non-sensitive context.&lt;/p&gt;

&lt;p&gt;The caller does not need to repeat the full problem.&lt;br&gt;
A simplified handoff looks like this:&lt;br&gt;
@function_tool&lt;br&gt;
async def transfer_to_scheme_specialist(&lt;br&gt;
    self,&lt;br&gt;
    context: RunContext,&lt;br&gt;
) -&amp;gt; tuple[GovernmentSchemeEligibilitySpecialist, str]:&lt;br&gt;
    specialist = GovernmentSchemeEligibilitySpecialist(&lt;br&gt;
        chat_ctx=self.chat_ctx.copy(&lt;br&gt;
            exclude_instructions=True,&lt;br&gt;
        )&lt;br&gt;
    )&lt;br&gt;
    return (&lt;br&gt;
        specialist,&lt;br&gt;
        "I'll connect you to our government-scheme eligibility specialist "&lt;br&gt;
        "for more focused guidance.",&lt;br&gt;
    )&lt;br&gt;
The specialist has its own instructions and limits. It does not handle fraud, account-specific banking complaints, or sensitive payment information.&lt;br&gt;
A difficult part: integration is where the complexity appears&lt;br&gt;
The hardest part was not making the agent speak once. It was coordinating all the pieces around a real conversation:&lt;br&gt;
Browser audio.&lt;br&gt;
SIP audio.&lt;br&gt;
Speech recognition.&lt;br&gt;
LLM decisions.&lt;br&gt;
Tool calls.&lt;br&gt;
Text-to-speech.&lt;br&gt;
Consent storage.&lt;br&gt;
Call cleanup.&lt;br&gt;
Dashboard writes.&lt;br&gt;
Agent handoffs.&lt;/p&gt;

&lt;p&gt;Each part can fail independently.&lt;br&gt;
Some issues I had to work through included:&lt;br&gt;
SIP connections failing.&lt;br&gt;
Calls ending before the intended outcome.&lt;br&gt;
Data sources becoming unavailable.&lt;br&gt;
Duplicate outbound calls.&lt;br&gt;
Unclear or denied consent.&lt;br&gt;
Cleanup logic running more than once.&lt;br&gt;
Dashboard metrics pointing to the wrong SQLite database.&lt;br&gt;
LiveKit APIs differing between installed versions.&lt;br&gt;
OpenCode and local tooling requiring platform-specific setup.&lt;/p&gt;

&lt;p&gt;The most useful lesson was to inspect the installed SDK instead of guessing its API. For example:&lt;br&gt;
uv run python -c "import inspect; from livekit.agents import Agent; print(inspect.signature(Agent))"&lt;br&gt;
This kind of inspection is faster and safer than repeatedly writing code against an API that may not exist in the installed version.&lt;br&gt;
Another lesson was to define success before implementing analytics. Without a clear success condition, "successful call" becomes a vague technical status instead of a user outcome.&lt;br&gt;
Build your own voice&amp;nbsp;agent&lt;br&gt;
You do not need to build every feature at once. Start with one complete voice loop:&lt;br&gt;
User speaks&lt;br&gt;
→ Speech-to-text&lt;br&gt;
→ LLM response&lt;br&gt;
→ Text-to-speech&lt;br&gt;
→ User hears the response&lt;br&gt;
Then add tools, memory, safeguards, and analytics one layer at a time.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the&amp;nbsp;project
git clone YOUR_PUBLIC_REPOSITORY_URL
cd murf-livekit-starter
Replace the placeholder with your actual public repository URL.&lt;/li&gt;
&lt;li&gt;Install dependencies
This project uses Python and a frontend. Follow the commands in the repository's package files and existing documentation.
Typical commands are:
uv sync
npm install
Run these from the correct project directories.&lt;/li&gt;
&lt;li&gt;Add secrets&amp;nbsp;locally
Create a local environment file in the location expected by the project, for example:
backend/.env
Use placeholder structure such as:
LIVEKIT_URL=your_livekit_url
LIVEKIT_API_KEY=your_livekit_api_key
LIVEKIT_API_SECRET=your_livekit_api_secret
DEEPGRAM_API_KEY=your_deepgram_api_key
GOOGLE_API_KEY=your_gemini_api_key
MURF_API_KEY=your_murf_api_key
Never publish:
API keys.
SIP credentials.
Phone numbers.
Caller information.
Database files containing private data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add environment files and local databases to&amp;nbsp;.gitignore:&lt;br&gt;
.env&lt;br&gt;
.env.*&lt;br&gt;
*.sqlite3&lt;br&gt;
*.sqlite3-shm&lt;br&gt;
*.sqlite3-wal&lt;br&gt;
The exact variable names should match the project's code. Do not copy these names blindly if your implementation uses different ones.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start the&amp;nbsp;services
Use the commands already defined in the repository. A typical setup may include:
uv run python backend/src/agent.py dev
And, in the frontend directory:
npm run dev
Open the local URL printed by the frontend terminal.&lt;/li&gt;
&lt;li&gt;Test the conversation
Start with:
What does financial literacy mean?
Then try:
Am I eligible for PMJDY, and what documents do I need?
Finally, test safety behavior:
I received a suspicious banking message.
Verify that:
General questions stay with the main agent.
Scheme questions reach the specialist.
Fraud questions follow the human-escalation flow.
Sensitive information is never requested.
The dashboard records the appropriate call outcome.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Troubleshooting&lt;br&gt;
The browser cannot access the microphone&lt;br&gt;
Check:&lt;br&gt;
Browser microphone permission.&lt;br&gt;
The correct local URL.&lt;br&gt;
Whether another application is using the microphone.&lt;br&gt;
Whether the frontend is connected to the running backend.&lt;/p&gt;

&lt;p&gt;SIP or Linphone does not&amp;nbsp;connect&lt;br&gt;
Check:&lt;br&gt;
LiveKit URL and credentials.&lt;br&gt;
SIP participant configuration.&lt;br&gt;
Linphone account details.&lt;br&gt;
Whether the SIP endpoint is registered.&lt;br&gt;
Backend logs for connection or authentication errors.&lt;/p&gt;

&lt;p&gt;Never publish SIP credentials in a README or screenshot.&lt;br&gt;
The dashboard shows zero&amp;nbsp;calls&lt;br&gt;
The dashboard may be reading a different SQLite file from the agent.&lt;br&gt;
Check:&lt;br&gt;
The database path printed by the dashboard.&lt;br&gt;
The database path used by the agent.&lt;br&gt;
Whether the call_outcomes table exists.&lt;br&gt;
Whether the agent writes a record when the call ends.&lt;/p&gt;

&lt;p&gt;Specialist handoff&amp;nbsp;fails&lt;br&gt;
LiveKit Agents APIs can differ between installed versions. Inspect the installed API rather than copying a method name from another version:&lt;br&gt;
uv run python -c "import inspect; from livekit.agents import Agent; print(inspect.signature(Agent))"&lt;br&gt;
Also check the installed package version and keep the handoff implementation compatible with that version.&lt;br&gt;
A port is already in&amp;nbsp;use&lt;br&gt;
Find the process using the port or start the service on another local port. Keep the frontend and backend configuration consistent.&lt;br&gt;
What I would improve&amp;nbsp;next&lt;br&gt;
ArthSakhi is a challenge project and local demonstration, not a production financial service.&lt;br&gt;
Before real-world deployment, I would improve:&lt;br&gt;
Verified, regularly updated scheme data.&lt;br&gt;
Stronger multilingual evaluation.&lt;br&gt;
Regional-language voice testing.&lt;br&gt;
Authentication for the support dashboard.&lt;br&gt;
Secure production database storage.&lt;br&gt;
Monitoring and audit logs.&lt;br&gt;
Better noisy-audio and interruption handling.&lt;br&gt;
More SIP test coverage.&lt;br&gt;
Human-support status tracking.&lt;br&gt;
Formal privacy and security review.&lt;/p&gt;

&lt;p&gt;What the challenge changed for&amp;nbsp;me&lt;br&gt;
At the beginning, I thought building a voice agent mainly meant connecting speech-to-text, an LLM, and text-to-speech.&lt;br&gt;
By the end, I understood that the difficult and valuable work sits around the conversation:&lt;br&gt;
What is the agent allowed to do?&lt;br&gt;
What should it remember?&lt;br&gt;
When should it ask for consent?&lt;br&gt;
When should it use a tool?&lt;br&gt;
When should it stop?&lt;br&gt;
When should a human take over?&lt;br&gt;
How do we know whether the user actually reached the intended outcome?&lt;/p&gt;

&lt;p&gt;ArthSakhi started as a financial-literacy voice assistant. Over ten days, it became a small but complete voice-agent system with memory, tools, outbound calling, escalation, analytics, and specialist handoffs.&lt;br&gt;
The central lesson was simple:&lt;br&gt;
A responsible voice agent is not the one that answers everything.&lt;br&gt;
It is the one that knows what to say, what not to ask, and when to bring in help.&lt;br&gt;
Links&lt;br&gt;
Repository:&amp;nbsp;&lt;br&gt;
LinkedIn post:&amp;nbsp;&lt;br&gt;
Challenge: 10 Days of Voice Agents - VoiceForBharat Edition&lt;/p&gt;

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