<?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>Forem: Prince Raj</title>
    <description>The latest articles on Forem by Prince Raj (@prince_raj).</description>
    <link>https://forem.com/prince_raj</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%2F3882564%2F1ed442f8-5d60-4cec-a854-271d4963a1d3.jpg</url>
      <title>Forem: Prince Raj</title>
      <link>https://forem.com/prince_raj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/prince_raj"/>
    <language>en</language>
    <item>
      <title>Part 2: The Dataset - Labels, Heuristics, Synthetic Data, and Why AI Starts Before the Model</title>
      <dc:creator>Prince Raj</dc:creator>
      <pubDate>Fri, 17 Apr 2026 10:34:50 +0000</pubDate>
      <link>https://forem.com/prince_raj/part-2-the-dataset-labels-heuristics-synthetic-data-and-why-ai-starts-before-the-model-3c4l</link>
      <guid>https://forem.com/prince_raj/part-2-the-dataset-labels-heuristics-synthetic-data-and-why-ai-starts-before-the-model-3c4l</guid>
      <description>&lt;p&gt;Before we begin, if you have come directly to this post (Part 2 of 6), here is &lt;a href="https://dev.to/prince_raj/part-1-what-we-built-a-tiny-ai-system-for-support-ticket-classification-4ihl"&gt;Part 1&lt;/a&gt; where I explain the basics and set the expectations from this series.&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/prince_raj/part-1-what-we-built-a-tiny-ai-system-for-support-ticket-classification-4ihl" class="crayons-story__hidden-navigation-link"&gt;Part 1: What We Built - A Tiny AI System for Support Ticket Classification&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/prince_raj" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F3882564%2F1ed442f8-5d60-4cec-a854-271d4963a1d3.jpg" alt="prince_raj profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/prince_raj" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Prince Raj
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Prince Raj
                
              
              &lt;div id="story-author-preview-content-3510897" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/prince_raj" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F3882564%2F1ed442f8-5d60-4cec-a854-271d4963a1d3.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Prince Raj&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/prince_raj/part-1-what-we-built-a-tiny-ai-system-for-support-ticket-classification-4ihl" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 16&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/prince_raj/part-1-what-we-built-a-tiny-ai-system-for-support-ticket-classification-4ihl" id="article-link-3510897"&gt;
          Part 1: What We Built - A Tiny AI System for Support Ticket Classification
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/go"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;go&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backend&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/machinelearning"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;machinelearning&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/prince_raj/part-1-what-we-built-a-tiny-ai-system-for-support-ticket-classification-4ihl" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;6&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/prince_raj/part-1-what-we-built-a-tiny-ai-system-for-support-ticket-classification-4ihl#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;h2&gt;
  
  
  The part most people skip
&lt;/h2&gt;

&lt;p&gt;When many developers first approach AI, they jump straight to the model.&lt;/p&gt;

&lt;p&gt;They ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which neural network should I use?&lt;/li&gt;
&lt;li&gt;Should I use transformers?&lt;/li&gt;
&lt;li&gt;How many layers should I add?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are fair questions, but not the first questions.&lt;/p&gt;

&lt;p&gt;For this project, the first real job was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;define what the model is supposed to mean&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds obvious, but it is the foundation of everything else.&lt;/p&gt;

&lt;p&gt;If your labels are vague, inconsistent, or impossible to infer from text, the model will struggle no matter how fancy the architecture is.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five things this model predicts
&lt;/h2&gt;

&lt;p&gt;This classifier does not output one label. It outputs five:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;department&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sentiment&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lead_intent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;churn_risk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;intent&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means every training example needs a shape like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"refund nahi mila yet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"billing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sentiment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"negative"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lead_intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"low"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"churn_risk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"refund"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the &lt;strong&gt;canonical schema&lt;/strong&gt; of the training set.&lt;/p&gt;

&lt;p&gt;Plain-English version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every ticket must be translated into one consistent answer sheet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why schema design matters
&lt;/h2&gt;

&lt;p&gt;Imagine you have data from three places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a banking support dataset&lt;/li&gt;
&lt;li&gt;a sentiment dataset&lt;/li&gt;
&lt;li&gt;a general intent dataset&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of them naturally match your product.&lt;/p&gt;

&lt;p&gt;One dataset may have &lt;code&gt;label=payment_issue&lt;/code&gt;. Another may only know positive vs negative sentiment. Yet another may say nothing about churn risk at all. So the job is not only "load data."&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;convert different sources into one shared language&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is what the dataset pipeline in this project does.&lt;/p&gt;

&lt;h2&gt;
  
  
  The label strategy
&lt;/h2&gt;

&lt;p&gt;Let’s go through each output the way a backend engineer would.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Department
&lt;/h2&gt;

&lt;p&gt;This is a routing problem. The question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which team should probably handle this?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;refund -&amp;gt; billing&lt;/li&gt;
&lt;li&gt;password reset -&amp;gt; technical&lt;/li&gt;
&lt;li&gt;tracking issue -&amp;gt; logistics&lt;/li&gt;
&lt;li&gt;pricing request -&amp;gt; sales&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This label is operational.&lt;br&gt;
It exists to move work to the right queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Sentiment
&lt;/h2&gt;

&lt;p&gt;This measures emotional tone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;positive&lt;/li&gt;
&lt;li&gt;neutral&lt;/li&gt;
&lt;li&gt;negative&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not the same as intent.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A pricing question can be neutral.&lt;/li&gt;
&lt;li&gt;A refund request can be negative.&lt;/li&gt;
&lt;li&gt;A thank-you note can be positive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This label helps downstream prioritization and messaging.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Lead intent
&lt;/h2&gt;

&lt;p&gt;This is where business context starts to matter.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Does this message look like a buying opportunity?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;demo request -&amp;gt; high&lt;/li&gt;
&lt;li&gt;pricing inquiry -&amp;gt; high&lt;/li&gt;
&lt;li&gt;feature request -&amp;gt; medium&lt;/li&gt;
&lt;li&gt;complaint -&amp;gt; low&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This label is not just language understanding. It is &lt;strong&gt;business interpretation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That matters later, because it is one reason small custom models can beat general-purpose LLMs on narrow tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Churn risk
&lt;/h2&gt;

&lt;p&gt;This estimates whether the customer may leave.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cancellation request -&amp;gt; high&lt;/li&gt;
&lt;li&gt;repeated refund frustration -&amp;gt; high&lt;/li&gt;
&lt;li&gt;neutral tracking question -&amp;gt; low&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, this is partly semantic and partly business logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Intent
&lt;/h2&gt;

&lt;p&gt;This is the most specific task.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;refund&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cancellation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delivery_issue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pricing_inquiry&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;technical_issue&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Turning messy data into this schema
&lt;/h2&gt;

&lt;p&gt;The training pipeline pulls data from multiple sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hugging Face datasets like &lt;code&gt;banking77&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sentiment data like &lt;code&gt;tweet_eval/sentiment&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Intent datasets like &lt;code&gt;clinc_oos&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Local JSONL files&lt;/li&gt;
&lt;li&gt;Synthetic examples&lt;/li&gt;
&lt;li&gt;Manual correction data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But raw source labels do not line up nicely with our five-task schema. So we normalize them.&lt;/p&gt;

&lt;p&gt;Technical term:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is &lt;strong&gt;schema normalization&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Plain-English version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We take many different spreadsheets and convert them into one house format.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where heuristics come in
&lt;/h2&gt;

&lt;p&gt;Here is an important beginner lesson:&lt;/p&gt;

&lt;p&gt;Not every training label has to come from a human manually writing every field.&lt;/p&gt;

&lt;p&gt;Sometimes a dataset gives you only one known label. You can infer the others using domain rules.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;if intent is &lt;code&gt;refund&lt;/code&gt;, department is probably &lt;code&gt;billing&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;if intent is &lt;code&gt;pricing_inquiry&lt;/code&gt;, lead intent is probably &lt;code&gt;high&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;if intent is &lt;code&gt;complaint&lt;/code&gt;, sentiment is probably &lt;code&gt;negative&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;if intent is &lt;code&gt;cancellation&lt;/code&gt;, churn risk is probably &lt;code&gt;high&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is exactly what this project does.&lt;/p&gt;

&lt;p&gt;In plain language:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When we know one strong clue, we can responsibly fill in related labels.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not perfect.&lt;br&gt;
But it is often very useful when building a practical system from mixed data sources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why synthetic data was necessary
&lt;/h2&gt;

&lt;p&gt;This is one of my favorite parts of the project, because it is very relatable for backend engineers.&lt;/p&gt;

&lt;p&gt;Real support data is usually messy in two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;it is incomplete&lt;/li&gt;
&lt;li&gt;it is uneven&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Maybe you have lots of billing messages but not many sales leads.&lt;br&gt;
Maybe you have clean English examples but not Hinglish.&lt;br&gt;
Maybe you do not have enough high-churn refund tickets.&lt;/p&gt;

&lt;p&gt;So the pipeline generates synthetic tickets using templates.&lt;/p&gt;

&lt;p&gt;Examples of synthetic patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I want a refund for my subscription"&lt;/li&gt;
&lt;li&gt;"Refund nahi mila for my order"&lt;/li&gt;
&lt;li&gt;"Can I get a demo for my team?"&lt;/li&gt;
&lt;li&gt;"Payment failed but money got deducted"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it adds style noise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;typos&lt;/li&gt;
&lt;li&gt;shorthand&lt;/li&gt;
&lt;li&gt;uppercase&lt;/li&gt;
&lt;li&gt;casual phrasing&lt;/li&gt;
&lt;li&gt;Hinglish variants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plain-English version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We manufacture extra training examples for situations we care about but do not have enough of.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Technical term:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is &lt;strong&gt;synthetic data generation&lt;/strong&gt; or &lt;strong&gt;data augmentation&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Hinglish normalization matters
&lt;/h2&gt;

&lt;p&gt;A lot of AI tutorials quietly assume clean English input. Real production systems do not get that luxury.&lt;/p&gt;

&lt;p&gt;Users write things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;refund chahiye&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;paisa mila nahi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;app kharab hai&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jaldi fix karo&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you ignore that kind of variation, your model will feel fragile in production.&lt;/p&gt;

&lt;p&gt;So this project includes simple but valuable normalization rules that map common Hinglish words to normalized English equivalents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;nahi&lt;/code&gt; -&amp;gt; &lt;code&gt;not&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;paisa&lt;/code&gt; -&amp;gt; &lt;code&gt;money&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kharab&lt;/code&gt; -&amp;gt; &lt;code&gt;broken&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chahiye&lt;/code&gt; -&amp;gt; &lt;code&gt;want&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not "full multilingual AI."&lt;br&gt;
It is something more practical:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;targeted robustness for the language patterns your users actually type&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The corrections loop is the most production-friendly part
&lt;/h2&gt;

&lt;p&gt;This project also supports a &lt;code&gt;corrections.jsonl&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;That means once the model is live, you can capture corrected labels and feed them back into training.&lt;/p&gt;

&lt;p&gt;The workflow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Model makes a prediction in production&lt;/li&gt;
&lt;li&gt;Human or system corrects bad labels&lt;/li&gt;
&lt;li&gt;Corrected example gets appended to &lt;code&gt;corrections.jsonl&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Next training run boosts those corrections&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I love this because it feels very familiar to backend teams. It is not mystical. It is a feedback loop.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You ship.&lt;/li&gt;
&lt;li&gt;You observe.&lt;/li&gt;
&lt;li&gt;You correct.&lt;/li&gt;
&lt;li&gt;You retrain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is how production systems grow up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Training and validation split
&lt;/h2&gt;

&lt;p&gt;After collecting all examples, the pipeline splits them into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Training data&lt;/li&gt;
&lt;li&gt;Validation data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why do we need validation?&lt;/p&gt;

&lt;p&gt;Because if we only measure performance on the same examples the model learned from, the scores can be misleading.&lt;/p&gt;

&lt;p&gt;Plain-English version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Training data is the study material. Validation data is the exam.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The project also tries to stratify by intent when splitting.&lt;/p&gt;

&lt;p&gt;That means it attempts to preserve label balance, so the validation set does not accidentally miss important classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple but important truth
&lt;/h2&gt;

&lt;p&gt;At this point, we still have not talked about embeddings, dense layers, or PyTorch math.&lt;/p&gt;

&lt;p&gt;And that is the point.&lt;/p&gt;

&lt;p&gt;The AI project already contains a lot of engineering value before the neural network starts training:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schema design&lt;/li&gt;
&lt;li&gt;Label definitions&lt;/li&gt;
&lt;li&gt;Heuristics&lt;/li&gt;
&lt;li&gt;Dataset normalization&lt;/li&gt;
&lt;li&gt;Synthetic example generation&lt;/li&gt;
&lt;li&gt;Production corrections&lt;/li&gt;
&lt;li&gt;Validation setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why I keep telling backend engineers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You already have a lot of the mindset needed for AI systems.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Good AI pipelines reward the same habits as good backend systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistent contracts&lt;/li&gt;
&lt;li&gt;Thoughtful data modeling&lt;/li&gt;
&lt;li&gt;Clear assumptions&lt;/li&gt;
&lt;li&gt;Measurable feedback loops&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If you can only remember one thing from this article
&lt;/h2&gt;

&lt;p&gt;Remember this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Training data is not "whatever text you found."&lt;br&gt;
Training data is a product design decision.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You are deciding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the model should notice&lt;/li&gt;
&lt;li&gt;What tradeoffs it should care about&lt;/li&gt;
&lt;li&gt;What your labels really mean in the business&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the real beginning of AI work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;p&gt;In Part 3, we will finally answer the question that makes many people feel like AI is magic:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does text become numbers?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I will explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bag-of-words&lt;/li&gt;
&lt;li&gt;Keyword flags&lt;/li&gt;
&lt;li&gt;Token IDs&lt;/li&gt;
&lt;li&gt;Embeddings&lt;/li&gt;
&lt;li&gt;Why this project combines all of them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I’ll do it in plain language first, then connect each idea to the proper technical terms. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: AI was used to frame the article.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>backend</category>
    </item>
    <item>
      <title>Part 1: What We Built - A Tiny AI System for Support Ticket Classification</title>
      <dc:creator>Prince Raj</dc:creator>
      <pubDate>Thu, 16 Apr 2026 14:07:48 +0000</pubDate>
      <link>https://forem.com/prince_raj/part-1-what-we-built-a-tiny-ai-system-for-support-ticket-classification-4ihl</link>
      <guid>https://forem.com/prince_raj/part-1-what-we-built-a-tiny-ai-system-for-support-ticket-classification-4ihl</guid>
      <description>&lt;h2&gt;
  
  
  Why this series exists
&lt;/h2&gt;

&lt;p&gt;If you are a backend engineer, you already know how to build reliable systems.&lt;/p&gt;

&lt;p&gt;You know how requests flow through services.&lt;br&gt;
You know how data gets cleaned before it is useful.&lt;br&gt;
You know how APIs hide complicated internals behind simple contracts.&lt;/p&gt;

&lt;p&gt;AI systems are not as magical as they look from the outside.&lt;/p&gt;

&lt;p&gt;They are still systems.&lt;br&gt;
They still have inputs, processing stages, outputs, tradeoffs, and production constraints.&lt;/p&gt;

&lt;p&gt;In this series, I am going to break down a real project I built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a tiny support ticket classifier&lt;/li&gt;
&lt;li&gt;trained in Python&lt;/li&gt;
&lt;li&gt;exported to JSON&lt;/li&gt;
&lt;li&gt;served in pure Go&lt;/li&gt;
&lt;li&gt;fast enough to run in a few milliseconds on CPU&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a "train a giant LLM on a cluster" story.&lt;/p&gt;

&lt;p&gt;This is a practical story for backend engineers who want to understand how AI products are actually assembled.&lt;/p&gt;
&lt;h3&gt;
  
  
  Github Repos:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Inference: &lt;a href="https://github.com/pncraz/tickets-inf" rel="noopener noreferrer"&gt;Built in pure Go&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Trainig on dataset: &lt;a href="https://github.com/pncraz/tickets-trainig" rel="noopener noreferrer"&gt;Python service&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What the model does
&lt;/h2&gt;

&lt;p&gt;The input is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one raw text support ticket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output is richer than a single label. The model predicts five things at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;department&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sentiment&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lead_intent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;churn_risk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;intent&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So for one ticket like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I was charged twice and need a refund"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;the system can produce something like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;department: &lt;code&gt;billing&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;sentiment: &lt;code&gt;negative&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;lead_intent: &lt;code&gt;low&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;churn_risk: &lt;code&gt;high&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;intent: &lt;code&gt;refund&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes it a &lt;strong&gt;multi-task classifier&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Plain-English version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We built one small brain that answers five related questions about the same ticket.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The full system in layman terms
&lt;/h2&gt;

&lt;p&gt;Before we get technical, here is the project in everyday language.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw ticket
   -&amp;gt;
Clean the text
   -&amp;gt;
Pull out useful clues
   -&amp;gt;
Turn those clues into numbers
   -&amp;gt;
Pass the numbers through a tiny neural network
   -&amp;gt;
Get 5 answers
   -&amp;gt;
Package the result for production use
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let me expand each block.&lt;/p&gt;

&lt;h2&gt;
  
  
  Block 1: Raw ticket
&lt;/h2&gt;

&lt;p&gt;This is the message a user writes.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"refund nahi mila yet"&lt;/li&gt;
&lt;li&gt;"pricing for enterprise plan?"&lt;/li&gt;
&lt;li&gt;"app is not working after reset"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this stage, the text is messy.&lt;br&gt;
People type casually.&lt;br&gt;
They use typos.&lt;br&gt;
They mix Hindi and English.&lt;br&gt;
They write with emotion.&lt;/p&gt;
&lt;h2&gt;
  
  
  Block 2: Clean the text
&lt;/h2&gt;

&lt;p&gt;The model cannot reason about raw text the way a human does.&lt;br&gt;
So first we normalize it.&lt;/p&gt;

&lt;p&gt;That means things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;convert to lowercase&lt;/li&gt;
&lt;li&gt;replace URLs with &lt;code&gt;&amp;lt;url&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;replace emails with &lt;code&gt;&amp;lt;email&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;replace numbers with &lt;code&gt;&amp;lt;num&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;normalize Hinglish words like &lt;code&gt;nahi&lt;/code&gt; to &lt;code&gt;not&lt;/code&gt; and &lt;code&gt;paisa&lt;/code&gt; to &lt;code&gt;money&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plain-English version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We reduce unnecessary variation so the model sees the same idea in a more consistent form.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Technical term:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is &lt;strong&gt;text preprocessing&lt;/strong&gt; or &lt;strong&gt;normalization&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Block 3: Pull out useful clues
&lt;/h2&gt;

&lt;p&gt;After cleaning the text, we extract signals.&lt;/p&gt;

&lt;p&gt;We do not rely on only one trick.&lt;br&gt;
We use a hybrid set of features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bag-of-words counts&lt;/li&gt;
&lt;li&gt;keyword flags&lt;/li&gt;
&lt;li&gt;token embeddings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why three kinds?&lt;/p&gt;

&lt;p&gt;Because each one catches something different.&lt;/p&gt;

&lt;p&gt;Bag-of-words helps with direct vocabulary signals.&lt;br&gt;
Keyword flags help with business-important phrases like &lt;code&gt;refund&lt;/code&gt;, &lt;code&gt;cancel&lt;/code&gt;, or &lt;code&gt;not working&lt;/code&gt;.&lt;br&gt;
Embeddings help the model capture softer meaning patterns.&lt;/p&gt;

&lt;p&gt;Plain-English version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Instead of asking the model to "just understand everything," we hand it several different kinds of clues.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Block 4: Turn those clues into numbers
&lt;/h2&gt;

&lt;p&gt;Neural networks do not consume text directly.&lt;br&gt;
They consume arrays of numbers.&lt;/p&gt;

&lt;p&gt;So the cleaned ticket becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one numeric vector for word counts&lt;/li&gt;
&lt;li&gt;one numeric vector for keyword flags&lt;/li&gt;
&lt;li&gt;one numeric vector from averaged token embeddings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then we combine them into one final feature vector.&lt;/p&gt;

&lt;p&gt;Technical term:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is &lt;strong&gt;feature engineering&lt;/strong&gt; plus &lt;strong&gt;vectorization&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Block 5: Pass the numbers through a tiny neural network
&lt;/h2&gt;

&lt;p&gt;This project uses a very small network.&lt;/p&gt;

&lt;p&gt;At a high level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feature vector
   -&amp;gt;
Dense layer
   -&amp;gt;
ReLU
   -&amp;gt;
Dense layer
   -&amp;gt;
ReLU
   -&amp;gt;
5 output heads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each output head is responsible for one prediction task.&lt;/p&gt;

&lt;p&gt;Why this shape?&lt;/p&gt;

&lt;p&gt;Because the tasks are related.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;refund&lt;/code&gt; often points to &lt;code&gt;billing&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;angry language can affect &lt;code&gt;sentiment&lt;/code&gt; and &lt;code&gt;churn_risk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;pricing questions often affect &lt;code&gt;department&lt;/code&gt; and &lt;code&gt;lead_intent&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the model first learns a &lt;strong&gt;shared internal representation&lt;/strong&gt; and then each task gets its own small output layer.&lt;/p&gt;

&lt;p&gt;Technical term:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a &lt;strong&gt;shared-base multi-head neural network&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Block 6: Get 5 answers
&lt;/h2&gt;

&lt;p&gt;Each head produces a score.&lt;br&gt;
Then the system converts scores into labels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;softmax&lt;/code&gt; for multi-class outputs like department or intent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sigmoid&lt;/code&gt; for binary output like churn risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plain-English version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The model does not directly shout "billing." It first scores all options, then picks the most likely one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Block 7: Package the result for production
&lt;/h2&gt;

&lt;p&gt;Training happens in Python.&lt;br&gt;
Production inference happens in Go.&lt;/p&gt;

&lt;p&gt;That design was intentional.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because I wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;easy training with PyTorch&lt;/li&gt;
&lt;li&gt;a simple export format&lt;/li&gt;
&lt;li&gt;a lightweight production runtime&lt;/li&gt;
&lt;li&gt;low latency&lt;/li&gt;
&lt;li&gt;low memory usage&lt;/li&gt;
&lt;li&gt;no external ML runtime in production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the trained model is exported into JSON, and the Go service loads that artifact and runs the forward pass manually.&lt;/p&gt;

&lt;p&gt;Plain-English version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Python is the workshop. Go is the factory floor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Mapping the real project to these blocks
&lt;/h2&gt;

&lt;p&gt;Here is how the actual project maps to the conceptual flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Training side
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;preprocess.py&lt;/code&gt;
Cleans text, normalizes Hinglish, replaces URLs/emails/numbers, injects style noise for synthetic data&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;features.py&lt;/code&gt;
Builds bag-of-words vocab, embedding vocab, keywords, and encodes text&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;datasets.py&lt;/code&gt;
Loads Hugging Face datasets, local JSONL files, corrections, and normalizes everything into one schema&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;synth.py&lt;/code&gt;
Generates synthetic support-ticket examples to improve domain coverage&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;model.py&lt;/code&gt;
Defines the tiny hybrid neural network&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;train.py&lt;/code&gt;
Handles training, validation, class weights, metrics, early stopping, and artifact creation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;export.py&lt;/code&gt;
Writes the trained model to JSON for production&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Inference side
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;features/&lt;/code&gt;
Rebuilds the same preprocessing and feature extraction logic in Go&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;model/&lt;/code&gt;
Loads exported JSON and defines dense layers, embeddings, softmax, sigmoid, and validation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;quantization/&lt;/code&gt;
Supports int8 inference for smaller and faster runtime&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;inference/&lt;/code&gt;
Orchestrates prediction and creates the final result object&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;benchmark/&lt;/code&gt;
Compares the local model against hosted models like GPT-5-mini&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I did not use an LLM for everything
&lt;/h2&gt;

&lt;p&gt;This question comes up a lot now.&lt;/p&gt;

&lt;p&gt;Why build a tiny model at all when an LLM can classify text?&lt;/p&gt;

&lt;p&gt;Because production engineering is about fit, not hype.&lt;/p&gt;

&lt;p&gt;For this use case, the tiny model has real advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;much lower latency&lt;/li&gt;
&lt;li&gt;much lower cost&lt;/li&gt;
&lt;li&gt;predictable output shape&lt;/li&gt;
&lt;li&gt;simpler deployment&lt;/li&gt;
&lt;li&gt;easier control over labels&lt;/li&gt;
&lt;li&gt;easier offline benchmarking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LLMs are great when you need open-ended reasoning or generation.&lt;/p&gt;

&lt;p&gt;But if you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;narrow labels&lt;/li&gt;
&lt;li&gt;stable routing&lt;/li&gt;
&lt;li&gt;predictable performance&lt;/li&gt;
&lt;li&gt;cheap per-request inference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;then a smaller custom model can be the better tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  The main lesson from this project
&lt;/h2&gt;

&lt;p&gt;The most important idea I want you to take from Part 1 is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An AI application is not "a model."&lt;br&gt;
It is a pipeline.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model matters, yes.&lt;br&gt;
But so do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your labels&lt;/li&gt;
&lt;li&gt;your preprocessing&lt;/li&gt;
&lt;li&gt;your synthetic data&lt;/li&gt;
&lt;li&gt;your export format&lt;/li&gt;
&lt;li&gt;your inference runtime&lt;/li&gt;
&lt;li&gt;your benchmark setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you only focus on the neural network block, you miss most of the engineering work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is coming next
&lt;/h2&gt;

&lt;p&gt;In Part 2, I will go one level deeper into the most underrated part of AI work:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the dataset and label design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is where this project really starts.&lt;br&gt;
Not in PyTorch.&lt;br&gt;
Not in matrix multiplication.&lt;br&gt;
Not in fancy model architecture.&lt;/p&gt;

&lt;p&gt;It starts with deciding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what we want the system to predict&lt;/li&gt;
&lt;li&gt;what "good" labels even mean&lt;/li&gt;
&lt;li&gt;how to combine real data, heuristics, and synthetic examples into one usable training set&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can understand that piece, the rest of the system becomes much easier to follow.&lt;/p&gt;

&lt;p&gt;Disclosure: AI was used to frame the article.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>go</category>
      <category>backend</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
