<?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: Abhigyan Pal</title>
    <description>The latest articles on DEV Community by Abhigyan Pal (@abhigyan_pal_ec33d468fe46).</description>
    <link>https://dev.to/abhigyan_pal_ec33d468fe46</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3364241%2F41918496-289c-46af-8143-a72f9b621ca3.jpg</url>
      <title>DEV Community: Abhigyan Pal</title>
      <link>https://dev.to/abhigyan_pal_ec33d468fe46</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abhigyan_pal_ec33d468fe46"/>
    <language>en</language>
    <item>
      <title>Building a Voice-Controlled Local AI Agent</title>
      <dc:creator>Abhigyan Pal</dc:creator>
      <pubDate>Wed, 15 Apr 2026 17:55:05 +0000</pubDate>
      <link>https://dev.to/abhigyan_pal_ec33d468fe46/building-a-voice-controlled-local-ai-agent-302h</link>
      <guid>https://dev.to/abhigyan_pal_ec33d468fe46/building-a-voice-controlled-local-ai-agent-302h</guid>
      <description>&lt;p&gt;I built a voice-controlled AI agent that takes spoken input, converts it to text, classifies intent, executes local tools, and shows the full pipeline in a Gradio UI. The goal was to make the system practical, safe, and easy to debug end-to-end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The system follows a simple 4-stage pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Input Layer (UI)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Users can provide commands through microphone recording, audio upload, or text input (for quick testing).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speech-to-Text (STT)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Audio is transcribed using &lt;strong&gt;AssemblyAI&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Intent Understanding (LLM Router)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Transcribed text is sent to a &lt;strong&gt;Groq-hosted Llama 3.3 70B&lt;/strong&gt; model, which returns structured JSON intents such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;create_file&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;write_code&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;summarize&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;general_chat&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tool Execution Layer&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The app routes each detected intent to a tool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;file creation&lt;/li&gt;
&lt;li&gt;code generation and save&lt;/li&gt;
&lt;li&gt;summarization&lt;/li&gt;
&lt;li&gt;chat response&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The UI then displays:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;transcribed text&lt;/li&gt;
&lt;li&gt;detected intents&lt;/li&gt;
&lt;li&gt;action(s) taken&lt;/li&gt;
&lt;li&gt;final result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All file operations are sandboxed to an &lt;code&gt;output/&lt;/code&gt; directory for safety.&lt;/p&gt;

&lt;h2&gt;
  
  
  Models and Why I Chose Them
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) AssemblyAI for STT
&lt;/h3&gt;

&lt;p&gt;I initially considered local models (Whisper/wav2vec), but for this machine and timeline, API-based STT was more reliable and faster to integrate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why AssemblyAI:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generous free tier&lt;/li&gt;
&lt;li&gt;strong transcription quality&lt;/li&gt;
&lt;li&gt;simple Python SDK&lt;/li&gt;
&lt;li&gt;avoids local GPU dependency&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2) Groq + Llama 3.3 70B for Intent + Generation
&lt;/h3&gt;

&lt;p&gt;For intent classification and text/code generation, I used Groq’s hosted Llama model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Groq:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fast inference latency&lt;/li&gt;
&lt;li&gt;good structured-output behavior (JSON intent schema)&lt;/li&gt;
&lt;li&gt;strong instruction following for routing + generation&lt;/li&gt;
&lt;li&gt;straightforward integration in Python&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Challenges I Faced
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) STT model configuration mismatches
&lt;/h3&gt;

&lt;p&gt;A major challenge was AssemblyAI configuration compatibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;speech_model&lt;/code&gt; was deprecated by API expectations&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;speech_models&lt;/code&gt; required specific values (&lt;code&gt;universal-3-pro&lt;/code&gt;, &lt;code&gt;universal-2&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;enum values in SDK and accepted server values were not always intuitive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I resolved this by explicitly setting supported &lt;code&gt;speech_models&lt;/code&gt; values.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Language drift (Hindi vs English output)
&lt;/h3&gt;

&lt;p&gt;During testing, English speech was sometimes transcribed in Hindi script due to language auto-detection. This cascaded into Hindi LLM responses.&lt;/p&gt;

&lt;p&gt;I fixed this by forcing English in STT config and aligning LLM prompts to respond in English.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Intent ambiguity in compound commands
&lt;/h3&gt;

&lt;p&gt;User prompts like “create a file and write your capabilities” can be interpreted as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create file + generate code&lt;/li&gt;
&lt;li&gt;create file + write plain text&lt;/li&gt;
&lt;li&gt;chat + file write&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the current intent set does not include a dedicated &lt;code&gt;write_text&lt;/code&gt; intent, the model sometimes chose &lt;code&gt;write_code&lt;/code&gt;, producing code when plain text was expected. This highlighted an important product gap: intent taxonomies must match real user phrasing.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Safety vs usability
&lt;/h3&gt;

&lt;p&gt;I needed to enable local file actions while minimizing risk. Restricting writes to &lt;code&gt;output/&lt;/code&gt; and adding a confirmation toggle balanced safety with usability.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Worked Well
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Clear modular design (&lt;code&gt;stt.py&lt;/code&gt;, &lt;code&gt;intent.py&lt;/code&gt;, &lt;code&gt;tools/*&lt;/code&gt;, &lt;code&gt;app.py&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Human-in-the-loop confirmation before file operations&lt;/li&gt;
&lt;li&gt;Compound-intent execution support&lt;/li&gt;
&lt;li&gt;Persistent memory support and reset controls&lt;/li&gt;
&lt;li&gt;Benchmark script to evaluate intent accuracy and generation latency&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This project showed that a practical voice agent is less about one “smart model” and more about &lt;strong&gt;pipeline reliability&lt;/strong&gt;: robust STT config, strict intent schema, safe tool boundaries, and transparent UI feedback. The next meaningful improvement would be adding a &lt;code&gt;write_text&lt;/code&gt; intent and richer compound-intent planning so user requests map more naturally to expected outcomes.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>agents</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
