<?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: Rahan Judes Michael</title>
    <description>The latest articles on DEV Community by Rahan Judes Michael (@gitmwon).</description>
    <link>https://dev.to/gitmwon</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%2F1387922%2F90b51f2d-e1f4-4940-a97a-9db8d8d3e621.jpg</url>
      <title>DEV Community: Rahan Judes Michael</title>
      <link>https://dev.to/gitmwon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gitmwon"/>
    <language>en</language>
    <item>
      <title>How We Built an AI Gym Trainer Using MediaPipe, React, and RAG 💪🤖</title>
      <dc:creator>Rahan Judes Michael</dc:creator>
      <pubDate>Sat, 06 Jun 2026 15:04:20 +0000</pubDate>
      <link>https://dev.to/gitmwon/how-we-built-an-ai-gym-trainer-using-mediapipe-react-and-rag-5a61</link>
      <guid>https://dev.to/gitmwon/how-we-built-an-ai-gym-trainer-using-mediapipe-react-and-rag-5a61</guid>
      <description>&lt;p&gt;We've all been there.&lt;/p&gt;

&lt;p&gt;You start doing a workout, feel incredibly confident about your form, and then realize you've been doing squats that look more like an interpretive dance routine.&lt;/p&gt;

&lt;p&gt;That got me and my friend thinking:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if a personal trainer could fit inside your laptop and tell you when you're doing an exercise correctly?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So we built an AI Gym Trainer that can analyze exercise form in real time, count repetitions, and answer fitness-related questions through a RAG-powered assistant.&lt;/p&gt;

&lt;p&gt;Rather than training a machine learning model from scratch, we used MediaPipe's pose estimation capabilities and combined them with custom angle calculations and rule-based logic to create an intelligent workout companion.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Many beginners, including us, don't always know whether an exercise is being performed correctly. A workout might feel effective, but poor form can reduce results and even increase the risk of injury.&lt;/p&gt;

&lt;p&gt;We wanted to explore whether computer vision and AI could provide instant feedback and help users train with more confidence all from a simple webcam.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Application 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.amazonaws.com%2Fuploads%2Farticles%2F9e6skk1dfnrd3lj109k7.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.amazonaws.com%2Fuploads%2Farticles%2F9e6skk1dfnrd3lj109k7.png" alt="Dashboard section 1" width="800" height="371"&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Focmx7mxxxmp3ch84t8ca.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.amazonaws.com%2Fuploads%2Farticles%2Focmx7mxxxmp3ch84t8ca.png" alt="Dashboard section 2" width="800" height="371"&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fzp35b70fvnyqf4k6jsjo.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.amazonaws.com%2Fuploads%2Farticles%2Fzp35b70fvnyqf4k6jsjo.png" alt="Dashboard section 3" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercise Tracking
&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.amazonaws.com%2Fuploads%2Farticles%2F8kw4xcnhw7ts0fzou01q.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.amazonaws.com%2Fuploads%2Farticles%2F8kw4xcnhw7ts0fzou01q.png" alt="Live tracking 1" width="800" height="371"&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fx9mupdfs94w7qesex384.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.amazonaws.com%2Fuploads%2Farticles%2Fx9mupdfs94w7qesex384.png" alt="Live tracking 2" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fitness Assistant
&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.amazonaws.com%2Fuploads%2Farticles%2Fgmnjqaqlf6lqueoqnm2x.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.amazonaws.com%2Fuploads%2Farticles%2Fgmnjqaqlf6lqueoqnm2x.png" alt="AI Agent" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The project is split into two main parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A real-time exercise tracking system that analyzes user movements.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A RAG-powered fitness assistant that answers workout-related 
questions.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&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.amazonaws.com%2Fuploads%2Farticles%2Fk8w3bbd7nvgg0dj5w657.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.amazonaws.com%2Fuploads%2Farticles%2Fk8w3bbd7nvgg0dj5w657.png" alt="Main Architecture" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-Time Exercise Analysis
&lt;/h2&gt;

&lt;p&gt;This is where the magic happens or where the application politely tells you that your "perfect squat" isn't actually perfect. 😅&lt;/p&gt;

&lt;p&gt;The exercise analysis pipeline processes webcam input in real time and continuously monitors the user's movements to provide instant feedback.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pose Detection with MediaPipe
&lt;/h3&gt;

&lt;p&gt;The first step is getting the system to understand what the user is doing.&lt;/p&gt;

&lt;p&gt;We use MediaPipe Pose to detect 33 body landmarks in real time, including key joints such as the shoulders, elbows, hips, knees, and ankles.&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.amazonaws.com%2Fuploads%2Farticles%2Fl02k1c1n3nvkortq4mm5.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.amazonaws.com%2Fuploads%2Farticles%2Fl02k1c1n3nvkortq4mm5.png" alt="Pose Landmarks" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think of it as giving the computer a very basic understanding of human anatomy without requiring it to survive medical school.&lt;/p&gt;

&lt;h3&gt;
  
  
  Angle Calculation
&lt;/h3&gt;

&lt;p&gt;Once the landmarks are detected, we calculate joint angles between different body parts.&lt;/p&gt;

&lt;p&gt;For example, during a bicep curl, the elbow angle changes as the arm moves up and down. By tracking these changes, the system can determine which stage of the exercise the user is currently in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Validation
&lt;/h3&gt;

&lt;p&gt;Now comes the part where the application becomes your strict gym buddy.&lt;/p&gt;

&lt;p&gt;Instead of training a custom model, we use rule-based logic and predefined angle thresholds for each exercise.&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.amazonaws.com%2Fuploads%2Farticles%2Fr3oho56jfd1mzga0gjf0.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.amazonaws.com%2Fuploads%2Farticles%2Fr3oho56jfd1mzga0gjf0.png" alt="Form correction" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the movement meets the expected criteria, everything looks good. If not, the system provides feedback to help the user correct their form before they accidentally invent a brand-new exercise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repetition Counting
&lt;/h3&gt;

&lt;p&gt;Finally, the system keeps track of exercise stages such as "up" and "down".&lt;/p&gt;

&lt;p&gt;Whenever a complete movement cycle is detected, the repetition counter increases automatically.&lt;/p&gt;

&lt;p&gt;No more arguing with yourself about whether that last rep counted—it does the counting for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the System Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pose Detection: Teaching a Computer to Recognize a Human 🕺
&lt;/h3&gt;

&lt;p&gt;The first challenge was getting the application to understand what it was looking at.&lt;/p&gt;

&lt;p&gt;Using MediaPipe Pose, we detect 33 body landmarks in real time, including key joints such as the shoulders, elbows, hips, knees, and ankles.&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.amazonaws.com%2Fuploads%2Farticles%2Fnqyi8hrkla8ruy94a1i3.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.amazonaws.com%2Fuploads%2Farticles%2Fnqyi8hrkla8ruy94a1i3.png" alt="Form Landmarks" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These landmarks act as the "skeleton" that the rest of the system uses for analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Angle Calculation: Turning Movements into Numbers 📐
&lt;/h3&gt;

&lt;p&gt;Once the landmarks are detected, we calculate joint angles between different body parts.&lt;/p&gt;

&lt;p&gt;For example, during a bicep curl, the elbow angle changes as the arm moves up and down. By tracking these changes, the system can understand where the user is in the exercise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const lm = pose.getLandmarks();

        if (lm) {
          const right = pose.calculateAngle(lm[16], lm[14], lm[12]);
          const left = pose.calculateAngle(lm[11], lm[13], lm[15]);

          const back = pose.calculateAngle(lm[24], lm[12], lm[11]);

          const shoulderLevel = Math.abs(
            pose.calculateAngle(lm[11], lm[23], lm[24]) -
              pose.calculateAngle(lm[12], lm[24], lm[23])
          );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, the application doesn't know whether you're exercising correctly—it just knows a bunch of angles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Validation &amp;amp; Rep Counting: The Strict Gym Buddy 💪
&lt;/h3&gt;

&lt;p&gt;This is where the fun begins.&lt;/p&gt;

&lt;p&gt;Instead of training a custom machine learning model, we use rule-based logic and angle thresholds to evaluate each exercise.&lt;/p&gt;

&lt;p&gt;For example, during a bicep curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newMsg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;back&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;back&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;newMsg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;KEEP YOUR BACK STRAIGHT!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shoulderLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;newMsg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SHOULDERS NOT LEVEL!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;newMsg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Straighten LEFT arm!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;newMsg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Straighten RIGHT arm!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;newMsg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&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;If the movement follows the expected pattern, the repetition is counted. If not, the system lets the user know that their form needs improvement.&lt;/p&gt;

&lt;p&gt;Think of it as having a gym buddy who's constantly watching your workout—but instead of saying "one more rep bro," it's checking whether that rep actually counts.&lt;/p&gt;

&lt;h2&gt;
  
  
  RAG-Powered Fitness Assistant 🤖
&lt;/h2&gt;

&lt;p&gt;While building the exercise tracker, we realized that users might have questions beyond just counting reps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions like:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;How do I improve my squat form?&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Which muscles does a deadlift target?&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;How many sets should a beginner perform?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Rather than hardcoding answers or relying solely on a general-purpose chatbot, we integrated a Retrieval-Augmented Generation (RAG) pipeline to provide more relevant and context-aware responses.&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.amazonaws.com%2Fuploads%2Farticles%2Fxfqoq9swz5xg566ise66.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.amazonaws.com%2Fuploads%2Farticles%2Fxfqoq9swz5xg566ise66.png" alt="AI Agent" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is simple: before generating an answer, the system first retrieves relevant information from a fitness knowledge base and then passes that context to the LLM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Interaction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;User&lt;/strong&gt;&lt;/u&gt;: How do I improve my squat form?&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Assistant&lt;/strong&gt;&lt;/u&gt;: Keep your knees aligned with your toes, maintain a neutral spine, and aim to reach at least parallel depth while keeping your heels grounded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core RAG Workflow&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;while&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;receive_json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;user_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;assistantId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistantId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;detect_intent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recommend&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
                &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recommend_workout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exercise&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
                &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;launch_exercise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
                &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_rag_answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exercise&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exercise&lt;/span&gt;&lt;span class="sh"&gt;"&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;char&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.02&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistantId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;assistantId&lt;/span&gt;
                    &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;done&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistantId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;assistantId&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;WebSocketDisconnect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;targetWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;fitnessGoal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;

&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/generate_plan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_plan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;
        &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;
        &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;
        &lt;span class="n"&gt;target_weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;targetWeight&lt;/span&gt;
        &lt;span class="n"&gt;fitness_goal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fitnessGoal&lt;/span&gt;

        &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        You are an expert fitness coach. Your task is to create a structured weekly workout plan tailored to the user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s profile and goals.

        STRICT CONSTRAINTS:
        1. Schedule workouts ONLY for Monday through Friday. Saturday and Sunday MUST be rest days.
        2. Assign  4 exercises per workout day.
        3. You MUST ONLY select exercises from the &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Available Exercises&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; list provided below. Do NOT hallucinate, recommend, or include any exercises outside of this list under any circumstances.

        USER PROFILE:
        - Age: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
        - Height: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
        - Weight: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
        - Target Weight: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;target_weight&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
        - Fitness Goal: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fitness_goal&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

        AVAILABLE EXERCISES:
        mentioned in the fitness trainer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s knowledge base
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach helps the assistant generate responses grounded in fitness-specific information rather than relying entirely on the model's general knowledge.&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.amazonaws.com%2Fuploads%2Farticles%2F40nfwo0w9jk7c7ca2sgb.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.amazonaws.com%2Fuploads%2Farticles%2F40nfwo0w9jk7c7ca2sgb.png" alt="Out of range question" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In simple terms, instead of saying "Trust me, bro," the assistant actually looks up relevant information before answering.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Biggest Challenge We Faced: Making It Truly Real-Time ⚡
&lt;/h2&gt;

&lt;p&gt;When we first built the project, everything worked perfectly... until we connected it to the frontend.&lt;/p&gt;

&lt;p&gt;Our initial implementation ran MediaPipe entirely in Python. The React frontend would capture video frames, send them to the Python backend for processing, and then wait for the results to be sent back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial Architecture&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2Fbhqgbjena66w7cff13qo.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.amazonaws.com%2Fuploads%2Farticles%2Fbhqgbjena66w7cff13qo.png" alt="Inintial Architecture" width="778" height="931"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While this approach was functional, it introduced noticeable latency. Every frame had to travel from the browser to the backend and back again before feedback could be displayed.&lt;/p&gt;

&lt;p&gt;The result?&lt;/p&gt;

&lt;p&gt;Laggy pose tracking&lt;br&gt;
Delayed feedback&lt;br&gt;
A user experience that felt far from real-time&lt;/p&gt;

&lt;p&gt;Not exactly what you want from a virtual fitness coach.&lt;/p&gt;

&lt;p&gt;The Solution&lt;/p&gt;

&lt;p&gt;After some experimentation, we decided to move MediaPipe directly into the React application.&lt;/p&gt;

&lt;p&gt;Instead of sending video frames to the backend, pose detection could now run directly in the browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimized Architecture&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2Ftkvuks7tx5bq8iur1705.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.amazonaws.com%2Fuploads%2Farticles%2Ftkvuks7tx5bq8iur1705.png" alt="Optimized Architecture" width="750" height="930"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This eliminated the constant round-trip communication between the frontend and backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Impact
&lt;/h3&gt;

&lt;p&gt;The improvement was immediately noticeable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Smoother pose tracking&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Faster feedback&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reduced backend workload&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A much more responsive user experience&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This challenge taught us an important lesson: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;building AI applications isn't just about models and algorithms. Sometimes the biggest performance gains come from making better architectural decisions.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Results 🎯
&lt;/h2&gt;

&lt;p&gt;After weeks of debugging, tweaking angle thresholds, and asking ourselves "why isn't this working?", we finally had a system that could track exercises in real time and answer fitness-related questions through a RAG-powered assistant.&lt;/p&gt;

&lt;p&gt;Exercise Tracking in Action&lt;/p&gt;

&lt;p&gt;The application was tested across multiple exercises, including:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💪 Bicep Curl&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2Fdk2gth70fizf7ym45pq3.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.amazonaws.com%2Fuploads%2Farticles%2Fdk2gth70fizf7ym45pq3.png" alt="Bicep Curl 1" width="800" height="422"&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fs5ow7ct693vak3y6ca8w.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.amazonaws.com%2Fuploads%2Farticles%2Fs5ow7ct693vak3y6ca8w.png" alt="Bicep Curl 2" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🏋️Hammer Curl&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2Fagonth2gxb2csxwmefk9.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.amazonaws.com%2Fuploads%2Farticles%2Fagonth2gxb2csxwmefk9.png" alt="Hammer Curl 1" width="800" height="422"&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fp9bej7zqy4enau58hwlg.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.amazonaws.com%2Fuploads%2Farticles%2Fp9bej7zqy4enau58hwlg.png" alt="Hammer Curl 2" width="800" height="422"&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fecpd1ko719biglhn6ke2.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.amazonaws.com%2Fuploads%2Farticles%2Fecpd1ko719biglhn6ke2.png" alt="Hammer Curl 3" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using MediaPipe landmarks and custom rule-based logic, the system can:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Track body movements in real time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Count repetitions automatically&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Identify correct and incorrect form&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Provide instant workout feedback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And perhaps most importantly, it never loses count halfway through a workout. 😄&lt;/p&gt;

&lt;h3&gt;
  
  
  Meet the Fitness Assistant 🤖
&lt;/h3&gt;

&lt;p&gt;We also integrated a RAG-powered fitness assistant that can answer workout and fitness-related questions.&lt;/p&gt;

&lt;p&gt;Whether it's improving squat technique, understanding muscle groups, or learning about training concepts, the assistant retrieves relevant information before generating a response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chatbot Demo&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2Fdp3g6nfsn094vq5slcrl.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.amazonaws.com%2Fuploads%2Farticles%2Fdp3g6nfsn094vq5slcrl.png" alt="AI Agent" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We're Most Proud Of&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Looking back, the most satisfying part wasn't the rep counter or even the chatbot.&lt;/p&gt;

&lt;p&gt;It was taking several different technologies—Computer Vision, MediaPipe, React, Python, and RAG—and combining them into a single application that feels practical and interactive.&lt;/p&gt;

&lt;p&gt;There's still plenty of room for improvement, but seeing the system analyze exercises in real time and have meaningful fitness conversations made all the debugging sessions worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Support for additional exercises&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fine-tuning the speech recognition model&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mobile application support&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Building this AI Gym Trainer was an exciting experience that combined computer vision, real-time processing, and generative AI into a single project.&lt;/p&gt;

&lt;p&gt;We're continuing to improve the project and would love to hear your thoughts, suggestions, and feedback.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;a href="https://github.com/gitmwon/AI-gym-trainer" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you found this project interesting, feel free to star the repository or share any ideas for future improvements!&lt;/p&gt;

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