<?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: Shourya Parashar</title>
    <description>The latest articles on DEV Community by Shourya Parashar (@im-shourya).</description>
    <link>https://dev.to/im-shourya</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%2F3898002%2F6284c5d3-4556-4805-bc4e-8fc555bbaf7e.jpg</url>
      <title>DEV Community: Shourya Parashar</title>
      <link>https://dev.to/im-shourya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/im-shourya"/>
    <language>en</language>
    <item>
      <title>Building a Voice RAG System Under a 200ms Latency Budget</title>
      <dc:creator>Shourya Parashar</dc:creator>
      <pubDate>Sat, 05 Sep 2026 03:30:00 +0000</pubDate>
      <link>https://dev.to/im-shourya/building-a-voice-rag-system-under-a-200ms-latency-budget-1cap</link>
      <guid>https://dev.to/im-shourya/building-a-voice-rag-system-under-a-200ms-latency-budget-1cap</guid>
      <description>&lt;p&gt;What happens when you combine Voice &lt;strong&gt;AI + RAG + multilingual retrieval&lt;/strong&gt;, but give yourself a strict &lt;strong&gt;200ms latency budget&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;That was the challenge behind my &lt;strong&gt;HH Goa 2026 Task 2&lt;/strong&gt; project.&lt;/p&gt;

&lt;p&gt;I built a voice-driven RAG system on the &lt;strong&gt;AI4Bharat MSMARCO-XI&lt;/strong&gt; dataset, designed to retrieve relevant information, generate grounded answers, and gracefully refuse when the evidence isn't strong enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Voice
  ↓
Speech-to-Text
  ↓
Query Guard
  ↓
Hybrid Retrieval
  ↓
RRF + MMR
  ↓
Grounded Answer
  ↓
Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What made it interesting?
&lt;/h3&gt;

&lt;p&gt;Instead of relying only on vector search, I combined:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dense retrieval&lt;/li&gt;
&lt;li&gt;BM25+ sparse retrieval&lt;/li&gt;
&lt;li&gt;Reciprocal Rank Fusion&lt;/li&gt;
&lt;li&gt;MMR reranking&lt;/li&gt;
&lt;li&gt;Multiple chunking strategies&lt;/li&gt;
&lt;li&gt;Retrieval confidence checks&lt;/li&gt;
&lt;li&gt;Prompt-injection protection&lt;/li&gt;
&lt;li&gt;Grounding verification&lt;/li&gt;
&lt;li&gt;Extractive fallback answers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal wasn't just to make the system answer.&lt;/p&gt;

&lt;p&gt;It was to make it &lt;strong&gt;answer only when it has enough evidence&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The part I cared about most: latency
&lt;/h3&gt;

&lt;p&gt;I instrumented every stage and benchmarked the complete pipeline.&lt;/p&gt;

&lt;p&gt;The final results:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;P50&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7.87 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P70&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9.62 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P100&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;40.71 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Benchmark runs&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;927&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Within 200ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I also tested the actual HTTP service separately, instead of relying only on in-process benchmarks.&lt;/p&gt;

&lt;h3&gt;
  
  
  A few lessons
&lt;/h3&gt;

&lt;p&gt;The biggest takeaway wasn't a particular model or framework.&lt;/p&gt;

&lt;p&gt;It was that &lt;strong&gt;good AI systems are often about making the right engineering trade-offs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A bigger model isn't always better.&lt;/p&gt;

&lt;p&gt;More retrieval isn't always better.&lt;/p&gt;

&lt;p&gt;And sometimes the best answer is simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"I don't have enough evidence to answer that."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This project pushed me to think about RAG not just as &lt;em&gt;retrieval + generation&lt;/em&gt;, but as a complete system with &lt;strong&gt;latency, reliability, safety, and verification&lt;/strong&gt; built into the architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Built with
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Python&lt;/code&gt; · &lt;code&gt;FastAPI&lt;/code&gt; · &lt;code&gt;BM25+&lt;/code&gt; · &lt;code&gt;Dense Retrieval&lt;/code&gt; · &lt;code&gt;RRF&lt;/code&gt; · &lt;code&gt;MMR&lt;/code&gt; · &lt;code&gt;Sarvam&lt;/code&gt; · &lt;code&gt;Claude&lt;/code&gt; · &lt;code&gt;Docker&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you're interested in the implementation, the complete project is here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/im-shourya/HHGOA-TASK2" rel="noopener noreferrer"&gt;https://github.com/im-shourya/HHGOA-TASK2&lt;/a&gt;&lt;/p&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%2F3y0jx1xv1pl7b6nao3yv.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%2F3y0jx1xv1pl7b6nao3yv.png" alt=" " width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Built for &lt;strong&gt;HH Goa 2026 — Shortlisting Task 2&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  AI #RAG #Python #LLM #MachineLearning #VoiceAI #InformationRetrieval
&lt;/h1&gt;

</description>
      <category>rag</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>KanbanFlow</title>
      <dc:creator>Shourya Parashar</dc:creator>
      <pubDate>Sat, 25 Apr 2026 20:37:33 +0000</pubDate>
      <link>https://dev.to/im-shourya/kanbanflow-3am9</link>
      <guid>https://dev.to/im-shourya/kanbanflow-3am9</guid>
      <description>&lt;p&gt;I Built a Zero-Backend Kanban Board with React + TypeScript — Here's What I Learned&lt;/p&gt;

&lt;p&gt;No server. No database. No login. Just pure React — and it actually works great.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I Built KanbanFlow&lt;/strong&gt;&lt;br&gt;
Every Kanban tool I used asked me to sign up, connect to a server, or pay for features I didn't need. I wanted something that just &lt;strong&gt;opened and worked&lt;/strong&gt; — instantly, privately, offline.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://kanbanflow.shouryaparashar.in" rel="noopener noreferrer"&gt;KanbanFlow&lt;/a&gt; — a fully-featured Kanban board that lives entirely in your browser. No account. No backend. No setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What It Does&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unlimited columns and tasks&lt;/strong&gt; — fully customizable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drag &amp;amp; drop&lt;/strong&gt; task movement across columns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Priority tagging&lt;/strong&gt; — High, Medium, Low, None&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Due dates&lt;/strong&gt; with overdue highlighting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live search&lt;/strong&gt; + priority filtering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dark / Light theme&lt;/strong&gt; toggle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-saves to localStorage&lt;/strong&gt; — data persists across sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React 18 + Vite 5 + TypeScript 5 + Tailwind CSS + React Router v6&lt;/p&gt;

&lt;p&gt;No Redux. No external state library. Just React's &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useReducer&lt;/code&gt; — keeping it lean.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Interesting Part — localStorage as a Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most people reach for Firebase or Supabase immediately. But for a personal productivity tool, &lt;code&gt;localStorage&lt;/code&gt; is genuinely underrated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Auto-save board state on every change&lt;/span&gt;
&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;kanban-board&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Load on mount&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBoard&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Board&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;kanban-board&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;saved&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saved&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;defaultBoard&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instant persistence with zero latency&lt;/li&gt;
&lt;li&gt;Works completely offline&lt;/li&gt;
&lt;li&gt;No auth, no API keys, no cost&lt;/li&gt;
&lt;li&gt;Data stays on the user's machine (privacy win)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tradeoff? No cross-device sync. For a personal board, that's totally acceptable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drag &amp;amp; Drop Without a Library&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of reaching for &lt;code&gt;react-beautiful-dnd&lt;/code&gt; or &lt;code&gt;dnd-kit&lt;/code&gt;, I implemented drag and drop using the native HTML5 Drag and Drop API — which kept the bundle size tiny.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleDragStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DragEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataTransfer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taskId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleDrop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DragEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetColumnId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataTransfer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taskId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;moveTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetColumnId&lt;/span&gt;&lt;span class="p"&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;strong&gt;Project Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I kept the component tree flat and predictable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── types/kanban.ts         # All types + constants
├── components/kanban/
│   ├── TaskCard.tsx
│   ├── KanbanColumn.tsx
│   ├── TaskForm.tsx
│   ├── Header.tsx
│   └── Toolbar.tsx
└── pages/
    └── Index.tsx           # Main orchestrator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One rule I followed: &lt;strong&gt;no component does more than one thing&lt;/strong&gt;. &lt;code&gt;KanbanColumn&lt;/code&gt; renders a column. &lt;code&gt;TaskCard&lt;/code&gt; renders a card. &lt;code&gt;Index.tsx&lt;/code&gt; wires them together.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://kanbanflow.shouryaparashar.in" rel="noopener noreferrer"&gt;kanbanflow.shouryaparashar.in&lt;/a&gt; &lt;br&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/im-shourya/KanbanFlow" rel="noopener noreferrer"&gt;github.com/im-shourya/KanbanFlow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Built by &lt;a href="https://shouryaparashar.in" rel="noopener noreferrer"&gt;Shourya Parashar&lt;/a&gt; — Full Stack Developer.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you found this useful, drop a ⭐ on GitHub — it genuinely helps!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
