<script data-pm-proxy="intercept"></script><?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[K-Means Karan]]></title><description><![CDATA[Join the cluster today to dive into ML and MLOps.]]></description><link>https://kmeanskaran.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!Pr5K!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F017bb32a-b33a-4062-9686-9356bf16936b_1024x1024.png</url><title>K-Means Karan</title><link>https://kmeanskaran.substack.com</link></image><generator>Substack</generator><lastBuildDate>Thu, 03 Sep 2026 05:11:05 GMT</lastBuildDate><atom:link href="/__u/kmeanskaran.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Karan Shingde]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[kmeanskaran@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[kmeanskaran@substack.com]]></itunes:email><itunes:name><![CDATA[Karan Shingde]]></itunes:name></itunes:owner><itunes:author><![CDATA[Karan Shingde]]></itunes:author><googleplay:owner><![CDATA[kmeanskaran@substack.com]]></googleplay:owner><googleplay:email><![CDATA[kmeanskaran@substack.com]]></googleplay:email><googleplay:author><![CDATA[Karan Shingde]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[A Complete AI Agent Playbook: Design, Build and Deploy]]></title><description><![CDATA[I built a real five-agent system, shipped it to AWS, and wrote down every wall I hit. The code is open source.]]></description><link>https://kmeanskaran.substack.com/p/a-complete-ai-agent-playbook-design</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/a-complete-ai-agent-playbook-design</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Wed, 02 Sep 2026 15:02:18 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!nEXd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Put a frontier model into a badly designed agent system and you get a more articulate failure.</p><p>I did not start with that sentence. I started with a project, and the sentence is what I had left after it.</p><p>The project is <strong>agent-harness-ops</strong>, and the trilogy I just finished on <em>AI That Ships</em> is the writeup. Not a tutorial I invented and then coded up. The other way round: I built the thing, hit every wall in it, and the three articles are the walls, in the order I hit them.</p><p>So this post is both. The code, and the writing it produced.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!nEXd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!nEXd!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png 424w, /__u/substackcdn.com/image/fetch/$s_!nEXd!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png 848w, /__u/substackcdn.com/image/fetch/$s_!nEXd!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png 1272w, /__u/substackcdn.com/image/fetch/$s_!nEXd!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!nEXd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png" width="1456" height="572" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ea8079e9-b771-4a3c-8350-94177845d307_2386x938.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:572,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:215366,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/213868098?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!nEXd!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png 424w, /__u/substackcdn.com/image/fetch/$s_!nEXd!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png 848w, /__u/substackcdn.com/image/fetch/$s_!nEXd!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png 1272w, /__u/substackcdn.com/image/fetch/$s_!nEXd!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea8079e9-b771-4a3c-8350-94177845d307_2386x938.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Complete Guide</figcaption></figure></div><div><hr></div><h2>The project</h2><p><strong>DevVoice</strong> turns a GitHub README into a reviewed X thread, LinkedIn post, and dev.to article. Five agents: an extractor that pulls grounded facts from the source, three platform writers, and a reviewer that fact-checks the drafts back against the original. A human approves before anything is final.</p><p>Stack: FastAPI, Celery, Redis, PostgreSQL, LangChain DeepAgents, Langfuse for tracing, React and nginx on the front. Model providers are swappable, with Ollama as the default so it costs nothing to run.</p><p>It lives on two branches, and the split maps onto the articles.</p><p><strong><a href="https://github.com/kmeanskaran/agent-harness-ops/tree/master">master, the local version</a></strong> The harness and the backend. Clone it, copy <code>.env.example</code>, <code>docker compose up --build</code>, and it runs on your laptop. Parts 1 and 2 are this branch, explained.</p><p><strong><a href="https://github.com/kmeanskaran/agent-harness-ops/tree/aws-deployment">aws-deployment, the AWS version</a></strong> The same application plus everything needed to run it in the cloud. Terraform for VPC, ECS Fargate, RDS, ElastiCache, ALB, IAM, Secrets Manager, CloudWatch. GitHub Actions over OIDC, so no AWS credentials are stored anywhere. Bedrock through the task role, so no model API key exists either. Two environments from one folder using Terraform workspaces. <code>make aws-setup</code> once, <code>git push</code> after that. Part 3 is this branch, explained.</p><p>Run master first. Read aws-deployment when you want the second half.</p><div><hr></div><h2>Part 1: System Design for Agent Systems</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!PCsg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!PCsg!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!PCsg!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!PCsg!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!PCsg!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!PCsg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg" width="1230" height="492" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:492,&quot;width&quot;:1230,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!PCsg!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!PCsg!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!PCsg!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!PCsg!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8e56812-447b-44fc-acaf-4d59181bd3e0_1230x492.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Part 1</figcaption></figure></div><p>Building the five agents taught me that almost none of the engineering is in the model. It is in the harness around it.</p><p>What the article covers: tools, prompts, memory, orchestration, and where a human sits in the loop. Then the evaluation framework, because none of this is testable the way ordinary code is.</p><p>What I got wrong first, and fixed:</p><ul><li><p>I reached for parallel agents because they sound faster. They are not. They create a coordination problem. Sequential subagents won on clear data flow, early exit, and debuggability.</p></li><li><p>I let a dynamic value drift above the static block in my prompts. Nothing errored. The cache hit rate went to zero and the bill quietly doubled.</p></li><li><p>I gated on importance. Everything looks important, so the gate fired constantly and I learned to click approve without reading. Gate on irreversibility instead.</p></li><li><p>I trusted the model to decide it was finished. That is the least reliable stop condition there is. Add a step budget, a wall-clock budget, and a token budget. You own three of the four exits.</p></li></ul><p><strong><a href="https://medium.com/ai-that-ships/system-design-for-agent-systems-part-1-6ba828d20f2f?sk=fe07c077b43e1351400b72c385c46bed">Read Part 1</a></strong></p><div><hr></div><h2>Part 2: Designing the Backend for Agent Systems</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!I9Tk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!I9Tk!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!I9Tk!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!I9Tk!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!I9Tk!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!I9Tk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg" width="1375" height="550" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:550,&quot;width&quot;:1375,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!I9Tk!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!I9Tk!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!I9Tk!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!I9Tk!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F715a6b36-0f28-441d-83a0-3a0618a2e1a1_1375x550.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Part 2</figcaption></figure></div><p>The first version of DevVoice was one synchronous endpoint that ran the agent and returned 90 seconds later. It is the natural thing to write and it is wrong in six ways, each of which becomes an incident on a different day.</p><p>What the article covers: the eight layers under the harness. Identity, API, queue, workers, the model-call seam, tool execution, state and sessions, delivery.</p><p>What building it taught me:</p><ul><li><p><code>POST /jobs</code> returns 202 in milliseconds. Persist first, then enqueue. Reverse that and a worker picks up a job the store has never heard of.</p></li><li><p>Idempotency is not optional. In a normal API a duplicate submit is untidy. Here it is a second bill.</p></li><li><p>Intermediate states are the entire UX. &#8220;running&#8221; for 90 seconds reads as broken. <code>extracting &#8594; drafting &#8594; reviewing</code> reads as working.</p></li><li><p>I sized workers with web-service reflexes and left roughly 10x on the floor. An agent worker is blocked on a socket 70 to 95% of its life.</p></li><li><p>One file imports the provider SDK. Caching, tier routing, retries, circuit breaking and fallback all live behind that seam. Routing by task took a run from $0.300 to $0.087.</p></li><li><p>Retry the transport, never the reasoning.</p></li></ul><p><strong><a href="https://medium.com/ai-that-ships/designing-the-backend-for-agent-systems-part-2-f2900737c322?sk=4d9d729ab8e2f79aaf2e5e37e8823cd9">Read Part 2</a></strong></p><div><hr></div><h2>Part 3: Deployment of Agent Systems to AWS ECS</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!-XmZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!-XmZ!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!-XmZ!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!-XmZ!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!-XmZ!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!-XmZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg" width="1145" height="458" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:458,&quot;width&quot;:1145,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!-XmZ!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!-XmZ!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!-XmZ!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!-XmZ!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4b81ab4-7e1e-4cc2-8de4-179b757dbda1_1145x458.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Part 3</figcaption></figure></div><p>Then I put it on AWS, and found a category of bug that cannot exist on a laptop.</p><p>What the article covers: twelve steps from laptop to production, Terraform describing the infrastructure, GitHub Actions doing the deploying, dev and prod. No prior AWS experience assumed.</p><p>What the deployment taught me:</p><ul><li><p>Three containers on Fargate: frontend, api, worker. Only the frontend is reachable from the internet. The worker has no address at all.</p></li><li><p>Give the worker roughly double the API&#8217;s memory and CPU. It holds an entire agent run for the life of the job.</p></li><li><p>One Terraform folder, two workspaces. Never copy the folder per environment. Copies drift, and the drift is always found during an incident.</p></li><li><p>Restricting an agent in the prompt is a request. Restricting it in the task role is a fact.</p></li><li><p>A green pipeline is not proof. I had a deployment that looked perfectly healthy and could not call the model, because nothing before the first real job ever tries.</p></li><li><p>One model passed every quick test, then in the real pipeline listed the same directory forty times without converging. Test with an end-to-end job, not a single call.</p></li></ul><p><strong><a href="https://medium.com/ai-that-ships/deployment-of-agent-systems-to-aws-ecs-part-3-f29fc36e818a?sk=ab53a24ace2d601a27ef423bf7a065c0">Read Part 3</a></strong></p><div><hr></div><h2>What survived</h2><p>Swap the model. Swap the framework. Swap what the agent does entirely. All three parts hold, because their shape follows from the workload rather than the model: slow, I/O-bound, non-deterministic, priced per unit.</p><p>Those four properties are not going anywhere. Design for them from the first commit and deployment is configuration. Design for the web shape and deployment is a rewrite.</p><p>The articles are free to read, no membership needed. The code is at <a href="https://github.com/kmeanskaran/agent-harness-ops">github.com/kmeanskaran/agent-harness-ops</a>: <code>master</code> to run it locally, <code>aws-deployment</code> to put it on AWS.</p><p>Follow me on X: <a href="https://x.com/kmeanskaran">@kmeanskaran</a></p>]]></content:encoded></item><item><title><![CDATA[7 AI/ML Interview Strategies Beyond LeetCode and Roadmaps]]></title><description><![CDATA[Smart strategies you should follow over random roadmaps to become AI/ML engineer in 2026.]]></description><link>https://kmeanskaran.substack.com/p/7-aiml-interview-strategies-beyond</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/7-aiml-interview-strategies-beyond</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Mon, 10 Aug 2026 16:01:52 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b235cabe-9363-41c9-aaad-63c3a5c55be0_1772x888.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You don&#8217;t fail interviews because you don&#8217;t know enough. Most candidates fail because they&#8217;re preparing for the wrong interview.</p><p>They solve 500 LeetCode problems, build five Gen AI chatbots, collect ten certificates, fine-tune Qwen models and still hear, <em><span>&#8220;We&#8217;ll get back to you.&#8221;</span></em></p><p>After interviewing with startups and MNCs, getting rejected, receiving offers, conducting interviews and sitting through countless interview rounds, I realized something:</p><blockquote><p><strong><span>Companies don&#8217;t hire the most knowledgeable candidate. They hire the candidate who reduces their risk.</span></strong></p></blockquote><p>This guide is everything I wish someone had told me before my first interview.</p><div><hr></div><h1><strong>1. How HIRING actually works</strong></h1><p>This the most common interview process for ML Engineering (When I say ML this applies to AI as well, in later section we will discuss about the core differences).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!nEWY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!nEWY!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png 424w, /__u/substackcdn.com/image/fetch/$s_!nEWY!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png 848w, /__u/substackcdn.com/image/fetch/$s_!nEWY!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png 1272w, /__u/substackcdn.com/image/fetch/$s_!nEWY!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!nEWY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png" width="1076" height="560" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/afaa93b7-4206-417b-b5d8-06c394b581da_1076x560.jpeg&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:560,&quot;width&quot;:1076,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:48217,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/210484599?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafaa93b7-4206-417b-b5d8-06c394b581da_1076x560.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!nEWY!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png 424w, /__u/substackcdn.com/image/fetch/$s_!nEWY!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png 848w, /__u/substackcdn.com/image/fetch/$s_!nEWY!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png 1272w, /__u/substackcdn.com/image/fetch/$s_!nEWY!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d15b3c-77c4-408d-8126-8e00d7162acd_1076x560.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>General MLE interview pipeline</p><ol><li><p><strong><span>Resume: </span></strong>HRs (non-tech) match your resume with the job description, while technical reviewers evaluate whether your skills align with the team&#8217;s current technical requirements and product needs.</p></li><li><p><strong><span>Recruiter Screen: </span></strong>A short screening call to verify your experience, discuss your background, notice period, salary expectations, and occasionally ask a few basic technical questions.</p></li><li><p>T<strong><span>echnical Round: </span></strong>Coding interviews covering DSA, machine learning fundamentals, project discussions, and sometimes take-home assignments or implementing ML algorithms from scratch.</p></li><li><p><strong><span>System Design rounds for ML</span></strong>: You&#8217;ll be asked to design an end-to-end ML system, discuss your take-home assignment, or solve production-scale ML, Agentic AI, and distributed systems problems (especially for mid-to-senior roles).</p></li><li><p><strong><span>Hiring Manger: </span></strong>A discussion about your experience, role expectations, compensation, joining timeline, and how well you fit the team.</p></li><li><p><strong><span>Culture/CEO/Founder</span></strong>: Evaluates your communication, attitude, ownership, and overall alignment with the company&#8217;s culture and values.</p></li></ol><p>This article covers what you can do on the <strong><span>technical side of the interview</span></strong> to get shortlisted, crack the interviews, and land the job.</p><div><hr></div><h1><strong>2. Start with Projects (even you are senior)</strong></h1><p>The most important stage of preparation is knowing where to start. Honestly, there is a lot of noise on the internet. Some people talk about tools, some fake career stories, some genuinely get great opportunities at a young age, and some get placed in SF startups.</p><p>But you are sitting in front of your laptop, dreaming about their success stories. I know this should be a technical article, but what matters most is having the right mindset and clarity.</p><p>I hope you already have the fundamentals of AI/ML</p><h2><strong><span>Stage 1</span></strong></h2><p>To get your first job, you need to build <strong><span>SERIOUS BORING PROJECTS</span></strong>.</p><p>Let me be clear. If you&#8217;re looking for a job, it&#8217;s not necessary to build a product with real users. If you can, that&#8217;s a cherry on top. But here, I&#8217;m covering what works for everyone.</p><p>A boring project means stopping the habit of building fancy projects with weak engineering. An Agentic AI chatbot that audits documents but has no queue workers or caching, or a VLM that solves sign language but has high latency, isn&#8217;t enough.</p><p>You need to understand:</p><ul><li><p>The ML lifecycle</p></li><li><p>How orchestration works</p></li><li><p>How to design the backend for AI projects</p></li><li><p>How to use caching and improve latency</p></li></ul><p>A project like forecasting stock prices with LSTMs sounds boring today. But what if you add Agentic AI to generate reports? What if you can train multiple stocks with around 40% less compute?</p><blockquote><p>around this idea, with a complete engineering pipeline deployed on AWS.I built</p><p><a href="https://github.com/kmeanskaran/stock-agent-ops">Stock-Agent-Ops</a></p></blockquote><p>Simply build two end-to-end projects: one focused on LLM fine-tuning or traditional ML, and another on Agentic AI. Ask Claude or ChatGPT to simulate a real engineering pipeline, then build and deploy it on AWS, GCP, or Azure.</p><h2><strong>Stage 2</strong></h2><p>In this stage, improve your production, collaboration, and soft skills, especially if you&#8217;re already employed.</p><p>Candidates with these skills are valued the most because technical skills can always be learned, but communication and project ownership are essential.</p><blockquote><p><em><span>Stage 2 becomes much more important in the later stages of interviews.</span></em></p></blockquote><div><hr></div><h1><strong>3. Resume Creation</strong></h1><p>We&#8217;re in 2026, and a resume is just a formal document that showcases your professional experience. It does <strong><span>not</span></strong> define your worth.</p><p>LinkedIn, Glassdoor, and Indeed are highly saturated. Recruiters usually post a job, review the profiles of early applicants first, and shortlist from that pool. If they don&#8217;t find a suitable candidate, they move on to the remaining applicants.</p><p>ATS optimization was a bigger concern a few years ago. Today, your focus should be on creating a resume that clearly showcases your technical skills, projects, and achievements. Learn how to write effective cold DMs and invest in personal branding. Over time, these will create more opportunities than simply clicking <strong><span>Easy Apply</span></strong>.</p><p>This article isn&#8217;t about resume preparation, but you can use my resume as an example.</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://x.com/kmeanskaran/status/2076191698578034853&quot;,&quot;full_text&quot;:&quot;This is the resume I used recently to switch to AI/ML/MLOps Engineer positions.\n\nI participated in three interviews: two Series A startups and one MNC.\n\n1 they rejected, 1 I rejected, and 1 I accepted.\n\nIt is very basic and boring, as I never add freelancing or extra work here. &quot;,&quot;username&quot;:&quot;kmeanskaran&quot;,&quot;name&quot;:&quot;Karan&#129483;&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/2070955029062889472/R8e67i6T_normal.jpg&quot;,&quot;date&quot;:&quot;2026-07-12T06:27:29.000Z&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/HNAdV2CbMAAslH5.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/56Iy5e59Fx&quot;}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:19,&quot;retweet_count&quot;:17,&quot;like_count&quot;:352,&quot;impression_count&quot;:34575,&quot;expanded_url&quot;:null,&quot;video_url&quot;:null,&quot;video_preview_media_key&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><div><hr></div><h1><strong>4. Technical Round (Most Important)</strong></h1><h2><strong>A. DSA</strong></h2><p>The most common question is:</p><p><em><strong><span>&#8220;Is DSA important?&#8221;</span></strong></em></p><p>My answer is:</p><p><em><strong><span>&#8220;Yes, but maybe not in the future.&#8221;</span></strong></em></p><p>The real question is <strong><span>how much DSA do you need, and who&#8217;s interviewing you?</span></strong></p><p>As of July 2026, almost all MNCs and around 40% of startups ask DSA questions (based on my experience). If you&#8217;re targeting large tech companies, then yes, DSA is important.</p><p>But there&#8217;s a catch.</p><p>Recruiters know AI can generate code. Live coding is no longer just about getting the correct answer. They want to understand <strong><span>how you think, communicate, and approach the problem</span></strong>.</p><p>In some of my interviews, I couldn&#8217;t fully solve the problem, but I still moved to the next round because of my approach.</p><p>For most ML engineering roles, focus on:</p><ul><li><p>Arrays</p></li><li><p>Strings</p></li><li><p>Patterns</p></li><li><p>Two Pointers</p></li><li><p>Sliding Window</p></li><li><p>Linked Lists (important)</p></li><li><p>Trees (important)</p></li><li><p>Graphs (rare)</p></li><li><p>Dynamic Programming (rare for most ML roles)</p></li></ul><p>Master the first five topics well. They cover most Python data structure questions. Don&#8217;t spend months grinding every DSA topic.</p><h2><strong>B. ML Coding Rounds</strong></h2><p>The second most important area is ML coding.</p><p>Some research-focused roles may ask you to implement ML algorithms from scratch or solve tensor-level problems.</p><p>Personally, I&#8217;ve rarely been asked these questions.</p><p>If you&#8217;re applying for AI, ML, or MLOps engineering roles, these rounds are much less common. Always align your preparation with the role and its expectations.</p><h2><strong>C. Take-Home Assignments (The Future of Hiring)</strong></h2><p>Many startups, and even some MNCs, now prefer take-home assignments.</p><p>These could be a prototype, MVP, or a series of engineering tasks.</p><p>You have complete freedom to choose your tools, architecture, and implementation. Yes, you can use AI, and recruiters generally expect that.</p><p>The twist comes during the interview.</p><p>The interviewer is usually a senior engineer, and you can&#8217;t bluff your way through. They&#8217;ll ask questions about every design decision, trade-off, and implementation detail. An experienced engineer can quickly tell if you don&#8217;t understand your own project.</p><p>This is one of the best opportunities to make an impression.</p><blockquote><p><em><span>Personally, I enjoy take-home assignments because they let me think about the system from a business and engineering perspective instead of solving isolated coding problems.</span></em></p></blockquote><p>Remember, the interviewer wants to understand your technical thinking and whether you can fit into the existing engineering pipeline. Your reasoning matters far more than the buzzwords you use.</p><p>I&#8217;ve made the mistake of throwing around terms like AI, Celery, Kafka, and distributed systems just to sound impressive.</p><p>Don&#8217;t do that.</p><h2><strong>D. Unexpected Questions</strong></h2><p>The market is unpredictable, and many companies don&#8217;t even know exactly what they&#8217;re looking for.</p><p>Some may ask about SQL, backend development, statistics, APIs, or distributed systems.</p><p>Don&#8217;t try to learn everything.</p><p>Instead, shortlist the companies you want to apply to, study their products, and carefully read their job descriptions.</p><p>You&#8217;ll get a very good idea of what they&#8217;re actually looking for, and your preparation will become much more focused.</p><p>See this diagram.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!YaMN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!YaMN!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png 424w, /__u/substackcdn.com/image/fetch/$s_!YaMN!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png 848w, /__u/substackcdn.com/image/fetch/$s_!YaMN!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png 1272w, /__u/substackcdn.com/image/fetch/$s_!YaMN!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!YaMN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png" width="1456" height="1453" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1453,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2765075,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/210484599?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!YaMN!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png 424w, /__u/substackcdn.com/image/fetch/$s_!YaMN!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png 848w, /__u/substackcdn.com/image/fetch/$s_!YaMN!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png 1272w, /__u/substackcdn.com/image/fetch/$s_!YaMN!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50984271-0c97-41df-ac2a-73edbe64d76e_1714x1710.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h1><strong>5. ML System Design &amp; MLOps</strong></h1><p>now we&#8217;re at the most important part of the process. This is the stage that can single-handedly land you in a pool of opportunities.</p><p>AI is becoming smarter. Companies are no longer struggling to write code for agents or neural networks.</p><p>We now have Kimi, Fable, Ops, GPT-sol, GLM, Grok, DeepSeek, and many more. Anyone can use these models to build a prototype or even a development-ready application.</p><p>But the real challenge is serving that AI application to real users. Maybe 10,000+ users per second.</p><p>You can refer to this post for learning resources. The resources I&#8217;ve listed are genuinely good and worth your time.</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://x.com/kmeanskaran/status/2072031867872882804&quot;,&quot;full_text&quot;:&quot;I conducted many ML interviews as a lead MLE in a remote startup and attended some calls as a candidate.\n\nIf you want to become an ML Engineer, follow these resources by <span class=\&quot;tweet-fake-link\&quot;>@chipro</span>.\n\nOverall interview prep:  \n<a class=\&quot;tweet-url\&quot; href=/__u/kmeanskaran.substack.com/%22https://huyenchip.com/ml-interviews-book//%22>huyenchip.com/ml-interviews-&#8230;</a>\n\nYou must read the two books by the same author&quot;,&quot;username&quot;:&quot;kmeanskaran&quot;,&quot;name&quot;:&quot;Karan&#129483;&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/2070955029062889472/R8e67i6T_normal.jpg&quot;,&quot;date&quot;:&quot;2026-06-30T18:57:48.000Z&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/HMFV_hraEAAzhUV.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/jPCdv7FEeC&quot;},{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/HMFV_hqbgAAB7Zn.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/jPCdv7FEeC&quot;}],&quot;quoted_tweet&quot;:{&quot;full_text&quot;:&quot;Can anyone share some interview questions that are now asked in ML roles of Remote US startups ?\n\nInfact, any kind of resource will be extremely helpful\n\nAsking for a friend.&quot;,&quot;username&quot;:&quot;Resorcinolworks&quot;,&quot;name&quot;:&quot;Reso&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/2033575406344036352/CHVHhmvI_normal.jpg&quot;},&quot;reply_count&quot;:12,&quot;retweet_count&quot;:127,&quot;like_count&quot;:1293,&quot;impression_count&quot;:75475,&quot;expanded_url&quot;:null,&quot;video_url&quot;:null,&quot;video_preview_media_key&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><p><span><br>Overall interview prep guide by Chip Huyen and everyone must read this.<br></span><a href="https://t.co/qtlRaXGOGB"><span>https://</span>huyenchip.com/ml-interviews-<span>book/</span></a></p><h2><strong>AI System Design vs ML System Design</strong></h2><p>Today both are slightly different. Let&#8217;s cover.</p><p><strong><span>AI System Design</span></strong></p><ul><li><p>LangGraph understanding</p></li><li><p>About Tools, Context Management, RAG and ReAct framework</p></li><li><p>In-depth design of Memory based on scenarios of product</p></li><li><p>Subagents designing</p></li><li><p>Prompt vs Semantic Caching based on scenario (HOTTEST TOPIC)</p></li><li><p>Cost saving techniques</p></li><li><p>Multi-agent orchestration</p></li><li><p>Agent evaluations</p></li><li><p>Observability of agents</p></li><li><p>Latency vs Throughput</p></li><li><p>Backend designing for AI applications</p></li><li><p>Conversation Intelligence</p></li></ul><p><strong><span>ML System Design (Works for LLMs as well)</span></strong></p><ul><li><p>General ML lifecycle</p></li><li><p>Feature store (online vs offline)</p></li><li><p>Feature Engineering pipeline</p></li><li><p>Model training/LLM fine-tuning</p></li><li><p>Offline Evaluation (Precision/Recall, F1 Score, MSE)</p></li><li><p>Mode versioning and fallback</p></li><li><p>Backend design with inference layer</p></li><li><p>Online vs Batch inference</p></li><li><p>Model quantisation</p></li><li><p>Transfer Learning/PEFT/RL</p></li></ul><blockquote><p><em><span>Well, I may have missed something, but you can always ask AI for additional topics and learn them step by step within a single project. Never learn these topics one after another in isolation. Learn them while building the same project.</span></em></p></blockquote><h2><strong>The sauce of MLOps</strong></h2><p>Honestly MLOps nothing but the summarisation above topics altogether.</p><p><em><span>MLOps Engineer = 40% AI/ML lifecycle + 25% Backend + 20% DevOps + 10% cloud + 5% Linux. Depends on organisation to organisation.</span></em></p><p>So you need,</p><ul><li><p>Docker containerisation</p></li><li><p>Backend concepts like APIs/Websockets, rate limit, caching, auth, etc.</p></li><li><p>Observability like Prometheus and Grafana</p></li><li><p>Logging</p></li><li><p>Networking and Load balancing</p></li><li><p>Strong cloud fundamentals (AWS)</p></li><li><p>Terraform</p></li><li><p>Kubernetes HPA</p></li><li><p>CI/CD</p></li></ul><p>For MLOps this is my #1 resource.</p><p><a href="https://x.com/@GokuMohandas">@GokuMohandas</a> covers every fundamental topic that every MLOps engineer should know. This is a must-read: <a href="https://madewithml.com/">madewithml.com</a></p><p>Additionally you should also learn the basics of system design.</p><blockquote><p><em><span>Watch this Youtube Tutorial to understand these concepts in one shot:</span></em></p><div id="youtube2-Vnm-ycSfJx4" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;Vnm-ycSfJx4&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/Vnm-ycSfJx4?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div></blockquote><div><hr></div><h1><strong>6. Recruiters Expectations</strong></h1><p>This is the time when you need to be very active. Sometimes recruiters want you to attend interviews back to back, while others schedule one interview every week.</p><p>At this stage, you should satisfy both the technical requirements and the communication aspect of the interview.</p><p>The second most important factor is your joining date. If you&#8217;re exceptionally talented, recruiters might wait for 2&#8211;3 months, although that&#8217;s rare. Today, most companies want a strong candidate who can join within 30&#8211;45 days while still being employed.</p><p>High availability often attracts recruiters more than additional technical skills, especially in large tech companies or startups with a high volume of applicants.</p><p>The hiring process is unpredictable.</p><p>I believe luck plays a role here.</p><p>So yes, luck matters.</p><div><hr></div><h1><strong>7. Bonus: My Experiences</strong></h1><h2><strong>When I attend an Interview</strong></h2><p>Most recruiters will ask about your expected CTC, joining date, and current work during the initial phone call. Be very clear with your answers. Decide your expected CTC beforehand and be ready to justify it.</p><p>A take-home assignment is a great opportunity to crack the interview, but you must understand the end-to-end lifecycle of your solution. If you fail to explain your decisions, you might lose the opportunity on the spot.</p><p>Always listen to the recruiter first before speaking.</p><p>For DSA, basic Python data structures and common patterns are enough. Practice easy to medium-level problems and solve them within a reasonable time. Even if you can&#8217;t finish the coding, keep explaining your thought process. Recruiters care about your approach. However, if another candidate has similar knowledge but stronger coding skills, they&#8217;ll have the advantage.</p><p>Talk more about your projects and real experience than the trendy tools and technologies you&#8217;ve seen on your X feed.</p><h2><strong><span>When I conduct an Interview</span></strong></h2><p>Here&#8217;s a polished version that keeps your message and style intact.</p><p>I&#8217;ve also been on the other side of the interview table.</p><p>Personally, I don&#8217;t ask DSA questions at all. My interviews are usually <strong><span>50% AI/ML concepts and 50% system design</span></strong>.</p><p>I ask candidates to share their screen and walk me through one of their projects, from the high-level architecture down to the implementation details. Along the way, I ask a lot of questions about their approach, design decisions, trade-offs, and results.</p><p>These conversations tell me much more than a coding problem. I can understand how enthusiastic the candidate is, how they think, and whether they have the ability to solve real organizational problems.</p><p>That&#8217;s it for today guys.</p><p>Please feel free to add your experience in comment section.</p><p>Like, share, and join the cluster</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://kmeanskaran.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/kmeanskaran.substack.com/subscribe"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[A Guide to Shipping Your Agent Harness into Production]]></title><description><![CDATA[Don't just build. Understand Agent Harness deployment as well.]]></description><link>https://kmeanskaran.substack.com/p/a-guide-to-shipping-your-agent-harness</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/a-guide-to-shipping-your-agent-harness</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 28 Jun 2026 14:31:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!InZP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This guide covers the complete engineering picture: what an Agent Harness is, the components that make it up, how to design the backend that supports it, and the optimizations that turn a working system into a production-grade one. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!InZP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!InZP!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!InZP!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!InZP!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!InZP!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!InZP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg" width="1200" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Header&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Header" title="Header" srcset="/__u/substackcdn.com/image/fetch/$s_!InZP!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!InZP!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!InZP!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!InZP!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d8c3ae-08cf-4fd2-9a92-1dc5e7308e25_1200x480.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Agent Harness into production by @kmeanskaran</figcaption></figure></div><div><hr></div><h2><strong><span>Part 1: The Agent Harness</span></strong></h2><p><strong><span>What it is</span></strong></p><p>An <strong><span>Agent Harness</span></strong> is the infrastructure layer that wraps a language model into a useful system. It is not the model. It is not the prompt. It is the scaffolding that answers every question the model itself cannot:</p><p>- Where does work product live between agent steps?</p><p>- What context does each agent see, and what is it explicitly excluded from seeing?</p><p>- How do agents coordinate without stepping on each other&#8217;s context windows?</p><p>- What happens when an agent produces bad output or a call fails?</p><p>- How is cost tracked, bounded, and controlled?</p><p>The LLM is a reasoning engine. The harness is the system that makes it useful. Every serious agent deployment is built on one explicitly designed or accidentally accumulated. The explicit version is faster, cheaper, and easier to debug.</p><p><strong><span>The five components</span></strong></p><p>A well-designed harness composes five concepts. Each one is a solution to a specific failure mode that emerges when you try to run agents in production.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!KESF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!KESF!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!KESF!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!KESF!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!KESF!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!KESF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg" width="1200" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="/__u/substackcdn.com/image/fetch/$s_!KESF!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!KESF!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!KESF!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!KESF!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b33f0e6-a9e7-4a7e-b01f-e4ca6d5a2b7d_1200x800.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">5 crucial Agent Harness steps</figcaption></figure></div><p>Agent Harness: The Five Components</p><p>The five components are:</p><ul><li><p><strong><span>Orchestrator: </span></strong> reads the brief, delegates in sequence, verifies completion, reports done</p></li><li><p><strong><span>Subagents: </span></strong>isolated execution contexts, each with one job and one output artifact</p></li><li><p><strong><span>Skills: </span></strong> per-agent knowledge documents that define role, output format, and rules</p></li><li><p><strong><span>Backend: </span></strong>the shared virtual filesystem where agents pass work product between steps</p></li><li><p><strong><span>Context Engineering: </span></strong> the discipline of controlling what each agent sees, when, and in what order</p></li></ul><p>Understanding why each component exists is more useful than memorizing the API. The design decisions that follow from understanding the <em><span>*why*</span></em> are the ones that scale.</p><div><hr></div><h2><strong><span>Part 2: Backends</span></strong></h2><p>The backend is the state management layer of the harness. It answers the question every multi-agent system must answer: <em><span>where does work product live?</span></em></p><p><strong><span>The problem with message-passing state</span></strong></p><p>The naive approach is to pass agent outputs through conversation messages. Agent A produces structured insights and returns them. The orchestrator stores the response and passes it to Agent B as message content.</p><p>This creates three compounding problems.</p><ul><li><p><strong><span>Context bloat.</span></strong> Every message in the orchestrator&#8217;s thread costs tokens on every subsequent call. After four agents have run and echoed their outputs back, the orchestrator is carrying thousands of tokens of content that only the next agent will need. You pay for it on every call until the job ends.</p></li><li><p><strong><span>No inspection surface. </span></strong>There is no way to read what Agent A produced without parsing the orchestrator&#8217;s conversation history. Debugging means wading through reasoning traces.</p></li><li><p><strong><span>Coupling.</span></strong> Agent B&#8217;s behavior depends on the exact format of Agent A&#8217;s response appearing in the conversation. A format change in A&#8217;s output schema breaks B. The coupling is invisible until it fails.</p></li></ul><p><strong><span>The virtual filesystem</span></strong></p><p>The `StateBackend` solves all three problems by giving every job a virtual filesystem is an in-memory workspace scoped to the duration of the run.</p><p>Agents don&#8217;t pass content to each other through messages. They write files to the workspace and read from it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!x1Is!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!x1Is!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!x1Is!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!x1Is!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!x1Is!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!x1Is!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg" width="1200" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="/__u/substackcdn.com/image/fetch/$s_!x1Is!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!x1Is!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!x1Is!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!x1Is!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56d99502-1baa-4a66-ad81-b120e74321ad_1200x800.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Agents orchestration with skills.md</figcaption></figure></div><p>Agents orchestration with skills.md</p><p>A typical workspace for a five-agent pipeline looks like this: a `brief.md` seeded at job start (the only input), then one file written per agent that extracted insights, drafts for each platform, and a final review notes file. When the extractor finishes, it writes its output file and confirms in one sentence. The orchestrator stores one line in its thread and not the content. The next agent reads directly from the file when it runs.</p><p>This single change reduces the orchestrator&#8217;s accumulated context by roughly 85% on a five-agent pipeline. It makes every intermediate output inspectable. And it decouples agents from each other where each agent reads a file by path, not a message by position.</p><p><strong><span>Seeding and result assembly</span></strong></p><p>The workspace starts empty. Before the orchestrator runs, seed it with everything the pipeline needs: skill files, shared context documents, and the per-job brief. Seeding separates the file system setup from the agent&#8217;s runtime where the workspace is fully defined before the first LLM call is made.</p><p>When the pipeline finishes, read the workspace to assemble the structured result. This is the only place where file content is read by the calling code.</p><p><strong><span>Best practice:</span></strong> never read workspace content during the pipeline run from the orchestrator&#8217;s code. The orchestrator infers progress from file existence which files have which appeared not file content. Content is read exactly once, at the end.</p><p><strong><span>Progress inference from the workspace</span></strong></p><p>One under appreciated property of the file-based workspace: you can infer pipeline progress from which files exist. No explicit progress callbacks needed in the agent code. The workspace state is the progress state.</p><div><hr></div><h2><strong><span>Part 3: Skills</span></strong></h2><p><strong><span>What skills are</span></strong></p><p>Every agent has a specific job. The job description is what to produce, what format it should take, what rules to follow which lives in a <strong><span>Skill file</span></strong>. Skills are markdown documents loaded into the agent&#8217;s context alongside its system prompt.</p><p>The key design decision is <strong><span>progressive disclosure</span></strong>: each agent loads only the skill it needs.</p><p>The naive approach is to include all skills for all agents. This is wrong for two reasons.</p><p><strong><span>Token cost.</span></strong> Skills are static context loaded on every call. An X writer loading LinkedIn formatting instructions pays for those tokens every time it runs and contributing nothing to the output.</p><p><strong><span>Focus degradation.</span></strong> Models occasionally apply instructions from the wrong context. An agent carrying instructions it doesn&#8217;t need will, with some non-zero probability, produce output influenced by those instructions. The more irrelevant context an agent carries, the worse this gets.</p><p>Each agent declares exactly which skill it loads. The skill resolver loads only the matching file. Five agents. Five skills. Each agent sees only its own.</p><p><strong><span>Tool scoping follows the same principle</span></strong></p><p>Tools are an extension of the skills concept. Like skills, they add tokens (tool definitions count toward input) and add behavioral surface area.</p><p>Give agents only the tools they can actually use. The reviewer agent gets a fact-checking tool and it&#8217;s the only one that verifies external claims. No other agent gets it. A writer that can&#8217;t call external APIs gets no tools. A tool it can&#8217;t use is overhead: tokens paid, behavioral risk incurred, no upside.</p><p><strong><span>Best practice:</span></strong> the skill and tool set of an agent should be the minimum required to do its specific job. Expand scope only when a specific task demands it.</p><div><hr></div><h2><strong><span>Part 4: Subagents and Isolated Contexts</span></strong></h2><p><strong><span>Why shared context windows fail</span></strong></p><p>When you run a multi-agent pipeline in a single conversation thread, every agent accumulates the full history. By the time the reviewer runs, it&#8217;s carrying the orchestrator&#8217;s planning reasoning, every writer&#8217;s output confirmation, and any back-and-forth from corrections. You pay for every one of those tokens. Quality degrades because the reviewer is reasoning in a context full of content that has nothing to do with its job.</p><p><strong><span>Subagents run in isolation</span></strong></p><p>Each subagent gets a fresh conversation: its own system prompt, its own skill, and only what it explicitly reads from the workspace.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!OhCf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!OhCf!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!OhCf!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!OhCf!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!OhCf!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!OhCf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg" width="1200" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="/__u/substackcdn.com/image/fetch/$s_!OhCf!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!OhCf!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!OhCf!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!OhCf!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff548480e-8636-4482-b300-a323994aa7f6_1200x800.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Shared Thread of agents vs Isolated Contexts (Subagents)</figcaption></figure></div><p>Shared Thread of agents vs Isolated Contexts (Subagents)</p><p>The orchestrator maintains a flat list of agent descriptions. When it decides to delegate, it picks by description. The subagent runs in its own context, does its work, writes to the workspace, and its context is garbage-collected when done.</p><p>The cost difference is significant. A five-agent pipeline run entirely in one shared thread accumulates 15,000&#8211;30,000 tokens of history by the final step. The same pipeline with isolated subagents keeps each agent&#8217;s context at 2,000&#8211;5,000 tokens. The orchestrator&#8217;s thread stays lean because it accumulates file paths and one-line confirmations, not content.</p><p><strong><span>Best practice: </span></strong>Design subagents to have exactly one output artifact in the workspace. One job, one file. This makes progress tracking trivial and outputs inspectable.</p><div><hr></div><h2><strong><span>Part 5: Context Engineering</span></strong></h2><p>Context engineering is the discipline of controlling what enters an agent&#8217;s context window, when, and in what order. It has more impact on cost and quality than any other engineering decision.</p><p><strong><span>The static-before-dynamic rule</span></strong></p><p>This is the foundational rule. It must be followed without exception.</p><p><strong><span>Static content</span></strong> is anything identical across many requests: system prompts, skill files, tool definitions, shared context documents. <strong><span>Dynamic content </span></strong>is anything that changes per request: job IDs, user input, timestamps, per-job parameters.</p><p>The correct ordering is: tool definitions first (most stable), then system prompt, then skill files, then conversation history, then the current user message (fully dynamic, never cached).</p><p>Provider-level prompt caching stores computed tensor representations of the prefix up to the first dynamic content. A cache read costs 10% of normal input price. A cache miss costs 100%.</p><p>Every violation of static-before-dynamic breaks the cache prefix. Common violations: putting a job ID or timestamp in the system prompt, embedding user-specific data in a skill file path, including environment-specific flags in system messages, or changing tool definitions between requests. The fix is always the same that move the dynamic value to the user turn message.</p><p><strong><span>Durable memory vs. per-job context</span></strong></p><p>Not all context ages the same way.</p><p><strong><span>Durable memory</span></strong> is stable across every job: project conventions, behavioral guidelines, how agents should handle edge cases. This lives in a shared document loaded as memory at graph construction time. It gets computed and cached once per worker process.</p><p><strong><span>Per-job context</span></strong> is task-specific: the user&#8217;s README, the requested platforms, the tone. This belongs in a brief document seeded into the workspace at job start where the only dynamic input to the pipeline.</p><p>The test for which category a piece of context belongs in: would it be identical across 1,000 different jobs? If yes, it&#8217;s durable memory. If it changes per job, it belongs in the brief and should never appear in the system prompt.</p><p><strong><span>Thread compaction</span></strong></p><p>For long-running pipelines, conversation threads grow. Older turns are less relevant than recent turns but still cost tokens on every subsequent call.</p><p>Thread summarization middleware handles this automatically. When the thread exceeds a configurable token threshold, older turns are compacted into a summary paragraph. The last N messages stay verbatim and recent context is the most relevant.</p><p><strong><span>Best practice:</span></strong> Don&#8217;t set the summarization threshold too low. Summarizing at 80% of context capacity gives the agent room to work without constantly compacting. Summarizing at 40% wastes tokens on summary overhead.</p><div><hr></div><h2><strong><span>Part 6: The Orchestrator</span></strong></h2><p><strong><span>Coordination, not execution</span></strong></p><p>The orchestrator&#8217;s role is exactly one thing: <em><span>read the brief, delegate in sequence, verify completion, report done</span></em>.</p><p>It explicitly does not produce content. This is a hard architectural constraint, not a guideline.</p><p>The orchestrator has the broadest context in the system. If it starts reasoning about domain-specific tasks like writing content, making factual judgments, formatting outputs and it will produce adequate results at the cost of long reasoning traces filling its context window, confusion between its coordination role and the domain role it just assumed, and bypassing the quality controls that subagents implement. Any time the orchestrator is tempted to produce domain-specific output, a subagent is missing from the design.</p><p><strong><span>Build once, reuse always</span></strong></p><p>The orchestrator&#8217;s construction is expensive: loading skill files from disk, initializing the model client, compiling the graph. Cache it at the process level. Build once per worker, reuse across every job.</p><p>A worker processing 40 jobs per hour builds the graph once and reuses it 40 times. A module-level singleton is Python&#8217;s simplest and most reliable pattern here.</p><p><strong><span>Enforcing pipeline invariants in the prompt</span></strong></p><p>The orchestrator&#8217;s system prompt is where pipeline rules are codified: only generate platforms listed in the brief, always run verification last, pass the job ID explicitly to every subagent, never write draft files directly, confirm file existence before reporting done.</p><p>These are coordination rules, not hints. Make them explicit and direct. The orchestrator&#8217;s prompt should read like a technical runbook, not a creative brief.</p><div><hr></div><h2><strong><span>Part 7: The Caching Stack</span></strong></h2><p>Caching in agent systems has more leverage than in traditional applications because you can avoid work at multiple levels. Each level has different cost savings, different hit rates, and different implementation complexity.</p><p>3-layer caching</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!ST23!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!ST23!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!ST23!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!ST23!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!ST23!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!ST23!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg" width="1122" height="1402" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1402,&quot;width&quot;:1122,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="/__u/substackcdn.com/image/fetch/$s_!ST23!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!ST23!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!ST23!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!ST23!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61e46091-cf0a-4c88-817a-effe3b1a7edf_1122x1402.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">3-layer caching</figcaption></figure></div><p><strong><span>Layer 1: Provider prompt caching</span></strong></p><p>Anthropic&#8217;s prompt cache stores computed KV tensor representations of the stable prompt prefix. Subsequent requests with identical prefixes read from cache at <em><span>10% of normal input token price.</span></em></p><p>The prerequisite is strict adherence to the static-before-dynamic ordering. Cache control is applied transparently on every system message &#8212; the call site doesn&#8217;t change.</p><p>Critical constraints engineers miss: the minimum token threshold is 1,024 tokens. Content below this fails to cache silently; no error, no warning, just a cache miss and full-price billing. Tool definition changes invalidate the entire cache hierarchy. You get at most four cache breakpoints per request.</p><p><strong><span>Layer 2: Redis LLM response cache</span></strong></p><p>Prompt caching reduces token cost but doesn&#8217;t eliminate API latency where you still make an HTTP call and wait for a response. A Redis response cache operates upstream of the API entirely: a cache hit means no HTTP call, no latency, zero cost.</p><p>Every LLM call in the system, orchestrator and all subagents automatically checks Redis before making any API call. The cache key is a hash of the full serialized message list combined with the model configuration. Including the model configuration in the key means a model upgrade creates new keys automatically.</p><p><strong><span>Version your keys on prompt changes.</span></strong> Without versioning, a broken prompt gets cached and served for hours. A version bump at deploy time flushes the entire cache without touching Redis directly.</p><p><strong><span>TTL by environment:</span></strong> Development at 5 minutes (prompt edits visible immediately), Staging at 1 hour (stable enough to catch regressions), Production at 24 hours (maximize cost savings).</p><p><strong><span>Layer 3: Content identity cache</span></strong></p><p>For systems where the same source material recurs popular open-source repos submitted by different users, documents processed multiple times and a content-identity cache can eliminate the most expensive pipeline step entirely.</p><p>Hash the raw source content. The same document with different user-specified parameters hashes to the same key because the source content is identical. This cache operates on content identity, not prompt identity. It bypasses the LLM entirely on a hit: no API call, no tokens, no latency. TTL can be much longer even seven days is reasonable for most content.</p><div><hr></div><h2><strong><span>Part 8: Token Optimization</span></strong></h2><p>Tokens are the cost unit of LLM systems. Every inefficiency compounds across every user, every request, every retry.</p><p><strong><span>Estimate before you execute</span></strong></p><p>Never run a job without estimating its token cost first. A rough estimator uses character count divided by four (a reliable approximation for English text) plus fixed overhead for skills and context files. Log this for every job. After a week of production traffic you have real P50/P95 data. The numbers that let you set alert thresholds with confidence instead of guesswork.</p><p><strong><span>Validate and truncate at the boundary</span></strong></p><p>Validate input size before the job enters the queue. When input is oversized, truncate rather than reject some users with large inputs should still get results, just from the most information-dense portion of their content.</p><p>Snap truncation to a structural boundary (paragraph break, section heading) so the model doesn&#8217;t receive mid-sentence content. Append a truncation marker so the model knows the document is incomplete.</p><p><strong><span>Model routing by task</span></strong></p><p>Not every agent in your pipeline needs the most capable (and expensive) model. Structured extraction from a markdown document is something a smaller model handles well. Multi-document cross-referencing with judgment calls benefits from stronger reasoning.</p><p>Route cheaper models to extraction, classification, and format validation. Reserve capable models for final review and complex multi-step reasoning. Done correctly, this reduces total pipeline cost by 40&#8211;60% with no quality reduction on the overall output.</p><div><hr></div><h2><strong><span>Part 9: The Async Job Architecture</span></strong></h2><p><strong><span>Why you need a job queue</span></strong></p><p>Agent pipelines take 45&#8211;120 seconds for non-trivial work. HTTP connections timeout in 30 seconds by default. Even if they don&#8217;t, holding a connection open per active job is a poor use of resources.</p><p>The correct architecture: accept the request immediately, return a job ID, run the pipeline asynchronously. The client polls for status. The result is written to a fast store the moment the worker completes. Total overhead for the poll loop: milliseconds.</p><p>Agent Orchestrator</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!cxzd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!cxzd!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!cxzd!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!cxzd!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!cxzd!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!cxzd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg" width="1200" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="/__u/substackcdn.com/image/fetch/$s_!cxzd!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!cxzd!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!cxzd!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!cxzd!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f592645-2240-41a7-96dc-a004ef4fa34a_1200x600.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Agent Orchestrator</figcaption></figure></div><p><strong><span>Celery for LLM workloads</span></strong></p><p>LLM tasks are I/O-bound, not CPU-bound. A worker thread spends most of its time waiting for API responses. This means you can run far more concurrency than CPU cores. The `gevent` pool uses cooperative multitasking where threads yield during I/O waits, allowing other tasks to run. A 4-core machine running 32 concurrent LLM jobs is reasonable when each job spends 70&#8211;80% of its time waiting for API responses.</p><p><strong><span>The dual-store pattern</span></strong></p><p>Redis is fast but ephemeral. Postgres is durable but slower. Use both for different purposes.</p><p>Redis handles the real-time polling use case like clients check status every few seconds and need sub-millisecond responses. Postgres handles the historical use case: user job history, billing, debugging jobs from yesterday.</p><p>The write pattern: write to both on every state change. The read pattern: check Redis first, fall back to Postgres if the key has expired. Never make Redis your source of truth. TTL expiration is silent.</p><div><hr></div><h2><strong><span>Part 10: Development Workflow</span></strong></h2><p><strong><span>Local model first, cloud model for validation</span></strong></p><p>Development to Production</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!RQpJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!RQpJ!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!RQpJ!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!RQpJ!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!RQpJ!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!RQpJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg" width="1200" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="/__u/substackcdn.com/image/fetch/$s_!RQpJ!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!RQpJ!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!RQpJ!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!RQpJ!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c75aac3-4c95-4a59-bacd-528542335815_1200x800.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Development to Production</figcaption></figure></div><p>Separate development iteration from cost by building your harness to accept any LangChain-compatible model. Use a local Ollama model during development is free, fast, no API key needed.</p><p>Local output is lower quality than frontier models. It is good enough to verify that files are written to the correct workspace paths, the orchestrator delegates in the correct sequence, result assembly parses workspace files into the expected structure, and error handling works as designed.</p><p>When a skill file change needs quality validation, flip to the cloud provider for a single test run. Switch back immediately. This separation makes the iteration cycle for prompt and skill development essentially free.</p><p><strong><span>Testing the harness, not the model</span></strong></p><p>Unit tests for an agent harness should test harness behavior, not model output. The model is non-deterministic; the harness is not.</p><p><strong><span>What to test</span></strong>: workspace seeding produces the expected file structure, result assembly correctly reads each file type, token estimation returns correct totals for known inputs, truncation snaps to paragraph boundaries correctly, cache key generation is deterministic, and state transitions follow the defined valid transition map.</p><p>What not to test at the unit level: whether the model produces good content. That&#8217;s integration testing with a real model, run periodically, not on every commit.</p><div><hr></div><h2><strong><span>Part 11: Observability</span></strong></h2><p>Observability in LLM systems is harder than in traditional systems because the most important failure mode is qualitative degradation <em><span>(invisible without the right tooling)</span></em>. A slow API call shows up in latency metrics. An agent that produces subtly wrong content doesn&#8217;t.</p><p><strong><span>Structured logs</span></strong></p><p>Every log line should be machine-parseable. Consistent field names across all log lines like job ID, status, step, elapsed time, whether the response was cached means you can grep, filter, and aggregate across your entire log history without a structured logging system. With this format, extracting P95 latency is a shell one-liner against your log file.</p><p><strong><span>LLM call tracing</span></strong></p><p>Structured logs give you job-level visibility. A tracing layer gives you call-level visibility: the full prompt, the response, actual token counts, per-call latency broken down by time-to-first-token and generation time, and the complete call tree across orchestrator and subagents.</p><p>When a user reports wrong output, you open the trace for their job ID and see exactly what prompt produced the problem. Without this, debugging hallucinations or incorrect agent behavior is guesswork.</p><p><strong><span>Cache hit rate as a cost signal</span></strong></p><p>Track cache performance explicitly. A sudden drop in LLM response cache hit rate is a signal that a prompt changed which usually means a dynamic value leaked into a previously static section, a model was upgraded, or a skill file was accidentally modified. Alert on this. It&#8217;s a cost event that&#8217;s easy to miss until the billing cycle closes.</p><div><hr></div><h2><strong><span>Summary: Design Principles</span></strong></h2><p>Every decision in this guide comes from one of five principles.</p><p><strong><span>Minimize accumulated context.</span></strong> Agents that carry less context are cheaper, faster, and more focused. Every component like the workspace backend, subagent isolation, thread compaction serves this principle.</p><p><strong><span>Static before dynamic, always.</span></strong> Prompt caching is the highest-ROI optimization in a deployed agent system. It requires static content to come before dynamic content in every prompt, without exception.</p><p><strong><span>Scope knowledge to role.</span></strong> Agents should know exactly what they need to do their job. Skills, tools, and context files should be narrowed to the minimum. Unnecessary context costs tokens and degrades focus.</p><p><strong><span>Separate concerns cleanly.</span></strong> Orchestrators coordinate. Subagents execute. Backends hold state. These roles should not overlap. When they do, debugging becomes significantly harder.</p><p><strong><span>Estimate, validate, and bound before spending.</span></strong> Token costs compound. Input validation, pre-execution estimation, and hard ceilings prevent runaway spend from becoming a production incident.</p><p>The infrastructure described here is not glamorous. None of it shows up in a demo. All of it is the difference between an agent that works on your laptop and a system that serves real users reliably.</p><div><hr></div><h2><strong><span>Closing Thoughts</span></strong></h2><p>This guide is written from the other perspective: the one where you have real users, real costs, and a system that has to work at 3am when you&#8217;re not watching it.</p><p>The five components don&#8217;t solve interesting AI problems. They solve boring infrastructure problems. The boring problems are the ones that kill production systems.</p><p>I will be publishing one project on Agent Harness and Ops with video demo. Agent-Harness-Ops project deployment will be on</p><p><a href="https://x.com/@Railway">@Railway</a></p><p> to understand CI/CD lifecycle.</p><p>The model is the easy part. It was always the easy part.</p><p>Follow</p><p><a href="https://x.com/@kmeanskaran">@kmeanskaran</a></p><p> for more deployment and Ops article on AI/ML.</p><h2><strong><span>Further reading:</span></strong></h2><ul><li><p><a href="https://arxiv.org/pdf/2604.08224">Externalization in LLM Agents: Memory, Skills, Protocols and Harness Engineering (arXiv 2604.08224)</a></p></li><li><p><a href="https://platform.claude.com/docs/en/build-with-claude/prompt-caching">Prompt Caching &#8212; Anthropic API Docs</a></p></li><li><p><a href="https://arxiv.org/pdf/2601.06007">Don&#8217;t Break the Cache: Prompt Caching for Long-Horizon Agentic Tasks (arXiv 2601.06007)</a></p></li><li><p><a href="https://arxiv.org/pdf/2507.08944">Optimizing Sequential Multi-Step Tasks with Parallel LLM Agents (arXiv 2507.08944)</a></p></li><li><p><a href="https://redis.io/blog/context-window-overflow/">Context Window Overflow &#8212; Redis Blog</a></p></li><li><p><a href="https://medium.com/@ramadnsyh/taming-the-ai-inference-queue-redis-celery-rabbitmq-at-scale-84798bb21beb">Taming the AI Inference Queue: Redis, Celery &amp; RabbitMQ at Scale</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[LangChain DeepAgents Explained: How Agent Harnesses Beat Classic AI Agents]]></title><description><![CDATA[LangChain DeepAgents Explained with complete guide on architecture, components and real use cases.]]></description><link>https://kmeanskaran.substack.com/p/how-agent-harnesses-beat-classic</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/how-agent-harnesses-beat-classic</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 14 Jun 2026 04:30:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rr2L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You have probably used a classic AI agent before. You type a prompt, the model replies, and the interaction ends. That works fine for simple tasks. But the moment you try to automate something real, something that spans multiple steps, touches external systems, or needs to remember what happened five minutes ago, the whole thing falls apart.</p><p>The model is not the problem. The architecture is.</p><p>This is exactly what agent harnesses are built to fix. And once you understand the difference, you will see why the harness is not an optional upgrade. It is a fundamentally different way of building with AI.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!rr2L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!rr2L!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png 424w, /__u/substackcdn.com/image/fetch/$s_!rr2L!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png 848w, /__u/substackcdn.com/image/fetch/$s_!rr2L!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png 1272w, /__u/substackcdn.com/image/fetch/$s_!rr2L!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!rr2L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png" width="1456" height="924" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:924,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2341751,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/201858112?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!rr2L!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png 424w, /__u/substackcdn.com/image/fetch/$s_!rr2L!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png 848w, /__u/substackcdn.com/image/fetch/$s_!rr2L!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png 1272w, /__u/substackcdn.com/image/fetch/$s_!rr2L!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b823d8-b33a-4f9e-b29f-89faac4b7208_1550x984.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>What a Classic Agent Actually Is</h2><p>A classic AI agent is a language model sitting behind a chat interface. You send a prompt. The model generates a response. That is the entire loop.</p><p>Every request is stateless. The model has no awareness of what it did in the previous step. It cannot break a task into parts. It cannot write to a file, run a script, check whether its output was correct, or try again if something went wrong.</p><p>This works well for:</p><ul><li><p>Answering a specific question</p></li><li><p>Summarizing a document</p></li><li><p>Drafting a short piece of text</p></li></ul><p>It breaks down immediately when the task requires:</p><ul><li><p>Multiple dependent steps</p></li><li><p>External tool calls</p></li><li><p>Quality validation</p></li><li><p>Memory across steps</p></li><li><p>Recovery from partial failure</p></li></ul><p>A classic agent is a single shot. The harness is what turns that into a reliable workflow.</p><div><hr></div><h2>What an Agent Harness Is</h2><p>An agent harness is the system built around a model. It is the layer that gives a language model the ability to plan, act, remember, delegate, and recover.</p><p>The model provides intelligence. The harness provides execution.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!_Z4a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!_Z4a!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png 424w, /__u/substackcdn.com/image/fetch/$s_!_Z4a!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png 848w, /__u/substackcdn.com/image/fetch/$s_!_Z4a!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png 1272w, /__u/substackcdn.com/image/fetch/$s_!_Z4a!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!_Z4a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png" width="1456" height="1542" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3dec037c-0cdc-4e62-b3df-fad9b6e338de_2720x2880.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1542,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:484117,&quot;alt&quot;:&quot;by Claude Opus 4.8&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/201858112?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dec037c-0cdc-4e62-b3df-fad9b6e338de_2720x2880.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="by Claude Opus 4.8" title="by Claude Opus 4.8" srcset="/__u/substackcdn.com/image/fetch/$s_!_Z4a!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png 424w, /__u/substackcdn.com/image/fetch/$s_!_Z4a!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png 848w, /__u/substackcdn.com/image/fetch/$s_!_Z4a!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png 1272w, /__u/substackcdn.com/image/fetch/$s_!_Z4a!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17cad447-39fb-4d1f-8924-756deeb243a2_2720x2880.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>LangChain&#8217;s DeepAgents is one of the clearest implementations of this pattern. It is an open source agent harness built on LangChain and LangGraph, designed specifically for long-running, multi-step tasks. It ships with planning tools, a virtual filesystem, subagent delegation, context engineering, persistent memory, skills, sandboxed code execution, and human-in-the-loop support all out of the box.</p><p>The stack underneath it is layered deliberately:</p><ul><li><p><strong>LangGraph</strong> is the graph runtime that handles durable execution, streaming, and stateful workflows</p></li><li><p><strong>LangChain&#8217;s </strong><code>create_agent</code> is a minimal harness on top of LangGraph, good for lightweight agents</p></li><li><p><strong>DeepAgents</strong> is the full harness on top of <code>create_agent</code>, bundling everything a long-running agent needs</p></li></ul><p>You use DeepAgents when you want the complete harness without building it yourself. You drop to <code>create_agent</code> when you want something thinner. You drop to LangGraph directly when you need a fully custom execution graph.</p><div><hr></div><h2>Why You Should Prefer the Harness</h2><p>Before going into each component, it is worth being direct about why this matters.</p><p>A classic agent fails not because the underlying model is bad but because the model has no scaffolding to do sustained work. It cannot hold state across steps, cannot verify its own output, cannot delegate to a focused subagent, and cannot recover gracefully when something breaks midway through a complex task.</p><p>The harness solves all of these. It turns a capable model into a capable system. If your task has more than two or three sequential steps, involves any external data source, or needs results you can trust rather than results you have to manually verify, the harness is the correct choice. Classic agents are for demos and simple assistants. Harnesses are for work that actually ships.</p><div><hr></div><h2>The Components in Detail</h2><h3>1. Planning</h3><p>The first thing a harnessed agent does when given a complex task is create a plan. DeepAgents ships with a built-in <code>write_todos</code> tool that forces the model to decompose the objective into steps before taking any action.</p><p>This might sound trivial. It is not. Without explicit planning, a model tends to jump straight into execution and lose coherence after the first few steps. With a visible todo list, the agent knows exactly where it is in the task, what comes next, and what is still outstanding. It can also adapt the plan mid-task as it learns more.</p><p>For a research-to-article workflow, the plan might look like:</p><ol><li><p>Extract key sections from the source paper</p></li><li><p>Research supplementary background on the topic</p></li><li><p>Draft the article from structured notes</p></li><li><p>Review the draft against the source for accuracy</p></li><li><p>Finalize and format for publication</p></li></ol><p>Each step is tracked. If step 3 fails, the agent does not restart from step 1. It retries from where it failed, with the filesystem holding everything that was already done.</p><div><hr></div><h3>2. Backends and Virtual Filesystem</h3><p>The virtual filesystem is one of the most important components in the harness and the one most people overlook.</p><p>A classic agent has no persistent workspace. Every piece of context lives in the prompt, and as the task grows, the context window fills up and older information gets dropped. For anything beyond a short task, this is a serious problem.</p><p>DeepAgents exposes a filesystem surface to the agent through built-in tools (<code>ls</code>, <code>read_file</code>, <code>write_file</code>, <code>edit_file</code>, <code>glob</code>, <code>grep</code>). These tools operate through a pluggable backend. The backend is what decides where files actually live and how they persist.</p><p>DeepAgents ships with several built-in backends:</p><p><strong>StateBackend (default)</strong> is ephemeral. Files are stored in LangGraph agent state for the current thread. This is the scratch pad: great for intermediate results that the agent writes during a task and reads back later. Files persist across multiple agent turns on the same thread via checkpoints, and they are shared between the main agent and its subagents.</p><p><strong>FilesystemBackend</strong> reads and writes real files under a configurable root directory on your local machine. You specify the root, and the agent has access to everything under it. Best for local development CLIs and coding assistants where the agent needs to interact with your actual project files.</p><p><strong>StoreBackend</strong> uses the LangGraph cross-thread store, which means files persist across threads, not just within one. This is the backend for long-term storage: memories, instructions, or reference data that should survive across multiple conversations.</p><p><strong>CompositeBackend</strong> is the router. It lets you point different filesystem paths to different backends. For example, the default workspace can be ephemeral (StateBackend) but anything under <code>/memories/</code> goes to the durable StoreBackend. This is maximally flexible and is how most production setups are configured.</p><p>The <code>read_file</code> tool natively supports multimodal content across all backends. Images (<code>.png</code>, <code>.jpg</code>, <code>.gif</code>, <code>.webp</code>), video, audio, PDFs, and PowerPoint files are all returned as multimodal content blocks that the model can actually read and reason about.</p><p>The practical effect is that intermediate work gets offloaded to files rather than staying in the context window. Research notes go to a file. The draft goes to a file. Reviewer feedback goes to a file. The context stays clean, and no work is lost between steps.</p><div><hr></div><h3>3. Context Engineering</h3><p>Context engineering is the difference between an agent that works for five minutes and one that works for five hours.</p><p>The official LangChain docs define it as providing the right information and tools in the right format so your agent can accomplish tasks reliably. Deep agents have access to several kinds of context, and the harness manages all of them:</p><p><strong>Input context</strong> is what goes into the agent&#8217;s prompt at startup: the system prompt, loaded memories, loaded skills. This is static and applied at the beginning of each run.</p><p><strong>Runtime context</strong> is configuration passed at invoke time: user metadata, API keys, connection details. It propagates automatically to subagents.</p><p><strong>Context compression</strong> is the automatic mechanism that keeps the agent within its context window limits as a task runs long. As conversation history grows, the harness summarizes it. When tool results come back large, the harness offloads them to the filesystem and lets the agent read them back in pieces. Skills and memory are loaded on demand, not all at once.</p><p><strong>Context isolation</strong> uses subagents to quarantine heavy work. A research subagent processes ten documents in its own context window and returns only a clean summary to the main agent. The main agent never sees the raw noise, which means it stays sharp and does not lose track of earlier steps.</p><p><strong>Long-term memory</strong> is persistent storage across threads using the virtual filesystem, which feeds back into input context on future runs.</p><p>This layered approach is what lets a deep agent run for a long time, across many steps and many tool calls, without degrading. A classic agent has no equivalent. It fills up and fails.</p><div><hr></div><h3>4. Subagents</h3><p>Complex tasks are almost always made of distinct, separable responsibilities. A research task needs a researcher. A writing task needs a writer. A review task needs a reviewer. Trying to do all of these inside one agent with one context window is inefficient and unreliable.</p><p>A harnessed agent solves this by spawning subagents. Each subagent runs in its own isolated context window, with its own tools and system prompt, focused on exactly one job. The main orchestrator sees only the final result from each subagent, not all the intermediate steps that subagent took to get there.</p><p>This has two major benefits. First, context stays clean. The orchestrator is not drowning in research noise when it is trying to write. Second, subagents can run in parallel where tasks are independent, cutting total execution time. DeepAgents supports async subagents for exactly this: fire off multiple tasks concurrently and collect results when they finish.</p><p>Subagents share the filesystem backend with their parent. Any file a subagent writes is available to the main agent and to other subagents. This is how they coordinate: one subagent writes research notes to a file, another reads those notes and drafts the article.</p><p>In DeepAgents, any LangGraph <code>CompiledStateGraph</code> can be passed in as a subagent. This means custom orchestration logic plugs in alongside the built-in harness defaults without any friction. You can also configure subagents with different models, different tools, and different permissions than the parent agent.</p><div><hr></div><h3>5. Memory</h3><p>Memory in a harness operates at two levels.</p><p><strong>Short-term memory</strong> is task-scoped. It holds everything relevant to the current job: the plan, the current draft, the working notes, the review feedback. This lives in the filesystem (typically the StateBackend) and is cleared or archived when the task completes.</p><p><strong>Long-term memory</strong> persists across sessions and across threads. User preferences, writing style rules, domain knowledge, past corrections. This uses the StoreBackend or a CompositeBackend with a durable route (like <code>/memories/</code>). The agent loads what is relevant from the memory store at the start of a session and carries that context forward.</p><p>The LangChain docs describe memory as what lets agents learn and improve across conversations. The harness loads memories into the system prompt as input context, and the agent can also write new memories to the filesystem during a run. This means the agent is not just consuming persistent knowledge but actively updating it based on what it learns.</p><p>Classic agents have neither form of memory. Every session starts from zero. Every interaction requires the user to re-explain context that should already be known. Long-term memory is what turns a capable agent into one that actually learns how you work and improves over time.</p><div><hr></div><h3>6. Skills</h3><p>Skills are reusable agent capabilities that provide specialized workflows and domain knowledge. They follow the Agent Skills specification and are loaded from the filesystem when relevant.</p><p>Think of a skill as a detailed briefing for a specific type of work. A research skill tells the agent how to structure extracted notes, what metadata to capture, and how to handle conflicting sources. A writing skill defines tone, format, target reading level, and citation style. A reviewing skill defines quality criteria, what to flag, and how to return feedback.</p><p>DeepAgents supports both community skills (from the Agent Skills ecosystem at agentskills.io) and LangChain&#8217;s own skill library (langchain-skills on GitHub), which provides ready-to-use skills that improve agent performance on LangChain ecosystem tasks. You can also create your own.</p><p>Skills are not hardcoded into the agent. They are files that can be updated based on real usage. If a reviewing skill produces consistently weak feedback on a certain type of content, you update the skill file and every future reviewer subagent automatically improves.</p><p>This is what makes harnessed agents maintainable at scale. You are not rewriting prompts scattered across different parts of your code. You are editing a single skill file that propagates everywhere it is used.</p><div><hr></div><h3>7. Sandboxes</h3><p>Agents generate code, interact with filesystems, and run shell commands. Because you cannot predict what an agent might do, the execution environment should be isolated so it cannot access credentials, files, or the network on your host system. Sandboxes provide this isolation.</p><p>In DeepAgents, sandboxes are a type of backend. Unlike standard backends (State, Filesystem, Store) which only expose file operations, sandbox backends also give the agent an <code>execute</code> tool for running arbitrary shell commands. When you configure a sandbox backend, the agent gets all the standard filesystem tools plus shell execution inside a secure boundary.</p><p>This is especially important for:</p><ul><li><p><strong>Coding agents</strong> that need to run shell commands, use git, clone repositories, and run build/test pipelines</p></li><li><p><strong>Data analysis agents</strong> that need to load files, install dependencies, and run scripts</p></li><li><p><strong>Any agent that executes untrusted or generated code</strong></p></li></ul><p>DeepAgents supports multiple sandbox providers: Modal, Daytona, Deno, and a local VFS option for development. Sandboxes can be scoped per thread (each conversation gets its own sandbox) or per assistant (shared across conversations). Files can be seeded into the sandbox before the agent starts, and artifacts can be retrieved after execution completes.</p><p>The core principle is simple: the agent can do anything inside the sandbox but nothing outside it. Your host system, credentials, and network stay protected.</p><div><hr></div><h3>8. Human-in-the-Loop</h3><p>Not every decision should be made autonomously. Some actions carry real-world consequences: sending a message, writing to a production database, deleting a file, deploying code. These should have a human approval step before execution.</p><p>DeepAgents supports this through LangGraph&#8217;s interrupt capabilities. You configure which tools require approval using the <code>interrupt_on</code> parameter, and the harness handles the rest.</p><p>Each tool can be configured independently:</p><ul><li><p><code>True</code> enables interrupts with default behavior: the human can approve, edit, or reject the tool call</p></li><li><p><code>False</code> disables interrupts for that tool</p></li><li><p><strong>Custom configuration</strong> lets you restrict the allowed decisions (for example, approve and reject only, no editing)</p></li></ul><pre><code><code>agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[delete_file, read_file, send_email],
    interrupt_on={
        "delete_file": True,
        "read_file": False,
        "send_email": {"allowed_decisions": ["approve", "reject"]},
    },
    checkpointer=checkpointer,
)
</code></code></pre><p>When the agent hits an interrupt, it pauses, surfaces the tool call details to the user, and waits. The user can approve it as-is, edit the arguments before execution, or reject it entirely. If rejected, the agent revises its approach and tries again.</p><p>Subagent interrupts are also supported: if a subagent&#8217;s tool requires approval, the interrupt bubbles up to the human rather than being silently executed.</p><p>This is not an add-on. It is a first-class primitive in the harness. And it is what makes harnessed agents trustworthy for tasks that classic agents could never be given access to in the first place.</p><div><hr></div><h3>9. Tools</h3><p>A classic agent can generate text. A harnessed agent can take actions.</p><p>DeepAgents can call any tool you define: plain Python functions, LangChain <code>@tool</code>-decorated functions, tool dicts, and tools from any MCP (Model Context Protocol) server. You pass them directly to <code>create_deep_agent</code> via the <code>tools=</code> parameter, and they sit alongside the built-in harness tools.</p><p>The schema is inferred automatically from your function signature and docstring. You do not need to define a separate schema in most cases.</p><pre><code><code>from deepagents import create_deep_agent

def internet_search(query: str, max_results: int = 5):
    """Run a web search"""
    return search_client.search(query, max_results=max_results)

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[internet_search],
)
</code></code></pre><p>MCP support is where this gets powerful. MCP is an open protocol that connects agents to a growing ecosystem of external servers (databases, APIs, file systems, browsers, and more) through a standard interface. Instead of writing custom integration code for each service, you point your deep agent at an MCP server and it gets all the tools that server exposes. One interface, any service.</p><p>On top of your custom tools, every deep agent inherits a set of built-in harness tools: <code>ls</code>, <code>read_file</code>, <code>write_file</code>, <code>edit_file</code>, <code>glob</code>, <code>grep</code> for filesystem operations, <code>execute</code> for shell commands (sandbox backends only), <code>task</code> for spawning subagents, and <code>write_todos</code> for planning. These are always available without configuration.</p><div><hr></div><h2>Where the Harness Wins: Real Use Cases</h2><h4>1. Deep Research Pipelines</h4><p>A classic agent summarizes one document. A harnessed agent surveys ten sources, cross-references findings, identifies contradictions, and synthesizes a structured report. Each source gets its own research subagent. Notes are stored to the filesystem. A synthesis subagent works from accumulated files rather than from memory. The output is reproducible and reviewable.</p><h4>2. Autonomous Coding Agents</h4><p>Fixing a bug means reading the relevant files, understanding the surrounding context, writing the fix, running tests, reading the output, and iterating. A classic agent can write code. It cannot run it, read the test results, and loop back. A harnessed agent with a sandbox backend can do the full loop: read, write, execute, observe, revise. All inside an isolated environment that protects your host system.</p><h4>3. Multi-Stage Content Pipelines</h4><p>Research, outline, draft, fact-check, review, format. Each stage is a separate subagent with a specific skill loaded. Intermediate files persist between stages. A failure in the review step does not mean rerunning research from scratch.</p><h4>4. Iterative Workflows with Feedback Gates</h4><p>Some tasks are loops by nature. A design agent that produces a spec, routes it for review, gets feedback, revises, and repeats needs state across iterations. The harness tracks iteration count, stores each version, loads previous reviewer comments as context, and pauses for human sign-off when needed via <code>interrupt_on</code>.</p><div><hr></div><h2>Comparing the Two Directly</h2><p><strong>Execution</strong> </p><p>Classic Agent &#8594; One prompt, one output </p><p>Agent Harness &#8594; Multi-step workflow with planning and todo tracking</p><p></p><p><strong>Memory</strong> </p><p>Classic Agent &#8594; None </p><p>Agent Harness &#8594; Short-term (StateBackend) + long-term (StoreBackend) persistent memory</p><p></p><p><strong>Tools</strong> </p><p>Classic Agent &#8594; Very limited </p><p>Agent Harness &#8594; Custom functions, MCP servers, APIs, databases, file I/O</p><p></p><p><strong>Context Management</strong> </p><p>Classic Agent &#8594; None </p><p>Agent Harness &#8594; Auto-summarization, offloading, compression, isolation via subagents</p><p></p><p><strong>Subagents</strong> </p><p>Classic Agent &#8594; No </p><p>Agent Harness &#8594; Isolated context, parallel execution, async support</p><p></p><p><strong>Skills</strong> </p><p>Classic Agent &#8594; No </p><p>Agent Harness &#8594; Modular, reusable, updateable, community ecosystem</p><p></p><p><strong>Code Execution</strong> </p><p>Classic Agent &#8594; No </p><p>Agent Harness &#8594; Sandboxed shell via Modal, Daytona, Deno, or local VFS</p><p></p><p><strong>Human Oversight</strong> </p><p>Classic Agent &#8594; None </p><p>Agent Harness &#8594; Per-tool interrupt configuration with approve/edit/reject</p><p></p><p><strong>Failure Recovery</strong> </p><p>Classic Agent &#8594; None </p><p>Agent Harness &#8594; Retry from last successful step, filesystem holds completed work</p><p></p><p><strong>Model Flexibility</strong></p><p>Classic Agent &#8594; Usually tied to one provider </p><p>Agent Harness &#8594; Any tool-calling model (OpenAI, Anthropic, Google, open-weight via Ollama/vLLM)</p><div><hr></div><h2>The Bottom Line</h2><p>A language model is a reasoning engine. It is powerful but it is stateless, toolless, and memoryless by default.</p><p>An agent harness is what makes that reasoning engine useful for sustained, real-world work. Tools, backends, context engineering, subagents, memory, skills, sandboxes, human-in-the-loop, planning. Each component addresses a specific failure mode of the classic agent. Together they close the gap between a capable model and a capable system.</p><p>The model gives intelligence. The harness gives execution.</p><p>I am currently building a one complete end-to-end Agent Harness and will deploy on Railway using CI/CD and AgentOps setup.</p><p>Follow me on <a href="http://www.x.com/@kmeanskaran.com">X</a> for more update</p><p>Signing off&#8230;</p><div><hr></div><p><em>References: </em></p><p><em>LangChain Deep Agents Documentation: <a href="http://docs.langchain.com/oss/python/deepagents">http://docs.langchain.com/oss/python/deepagents</a></em></p><p><em>The Anatomy of an Agent Harness: <a href="https://www.langchain.com/blog/the-anatomy-of-an-agent-harness">https://www.langchain.com/blog/the-anatomy-of-an-agent-harness</a></em></p>]]></content:encoded></item><item><title><![CDATA[Only guide you need to deploy your any AI/ML projects on AWS]]></title><description><![CDATA[Ship AI projects that actually run, scale, and make sense in production with AWS.]]></description><link>https://kmeanskaran.substack.com/p/only-guide-you-need-to-deploy-your</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/only-guide-you-need-to-deploy-your</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 12 Apr 2026 05:17:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!fnYl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Deployment is THE MOST important skill in current AI era</p><p><em>Note: I am using AI and ML interchangeable</em></p><p>Building software today is not hard anymore.<br>With tools like Claude Code and Codex, you can build something meaningful in 48 hours.</p><blockquote><p>I did the same with</p><p><a href="https://x.com/@desysflow">@desysflow</a> &#127744;.<br>It generates mermaid diagrams, HLD, LLD, and even non tech reports for stakeholders. Check this repo:</p><p><a href="https://github.com/kmeanskaran/desysflow-oss">github.com/kmeanskaran/desysflow-oss</a></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!fnYl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!fnYl!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png 424w, /__u/substackcdn.com/image/fetch/$s_!fnYl!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png 848w, /__u/substackcdn.com/image/fetch/$s_!fnYl!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png 1272w, /__u/substackcdn.com/image/fetch/$s_!fnYl!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!fnYl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2770449,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/193941494?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!fnYl!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png 424w, /__u/substackcdn.com/image/fetch/$s_!fnYl!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png 848w, /__u/substackcdn.com/image/fetch/$s_!fnYl!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png 1272w, /__u/substackcdn.com/image/fetch/$s_!fnYl!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ab5f70e-f011-4102-a8fe-4adacd7ac17c_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>So building is solved.</p><p>But shipping is not.</p><p>That is where most people fail.</p><p>Even if you have access to powerful AI tools, you still need to understand some core systems to actually deploy and run your AI projects in production.</p><p>You do not need everything.<br>You just need the right fundamentals.</p><h2><strong>Why AWS</strong></h2><p>AWS has everything.</p><p>That is exactly the problem.</p><p>If you try to learn all of it, you will never ship.</p><p>Instead, focus only on what helps you deploy.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!MA5t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!MA5t!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png 424w, /__u/substackcdn.com/image/fetch/$s_!MA5t!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png 848w, /__u/substackcdn.com/image/fetch/$s_!MA5t!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png 1272w, /__u/substackcdn.com/image/fetch/$s_!MA5t!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!MA5t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png" width="1456" height="1453" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1453,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:866680,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/193941494?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!MA5t!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png 424w, /__u/substackcdn.com/image/fetch/$s_!MA5t!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png 848w, /__u/substackcdn.com/image/fetch/$s_!MA5t!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png 1272w, /__u/substackcdn.com/image/fetch/$s_!MA5t!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F230d0f5c-3979-48d6-8b08-0bfb97de5012_1714x1710.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h1><strong>A. Backend Design</strong></h1><p>This is where your AI system actually becomes a product.</p><p>Most people overcomplicate this part. It is actually simple if you think in terms of flow.</p><h3><strong>1. REST APIs are simple, but not enough</strong></h3><p>For most ML systems, your backend starts with one main endpoint.</p><p><em>/prediction</em></p><p>User sends input, model returns output. Simple.</p><p>Then people think, let me add /train.</p><p>This is where things go wrong.</p><p>Training is not an API problem. It is a system problem.</p><p>Training takes time. Sometimes minutes, sometimes hours.<br>If you try to handle that inside a REST API, your system will break or timeout.</p><p>So instead of thinking &#8220;how to expose training&#8221;, think &#8220;how to orchestrate training&#8221;.</p><p>That shift changes everything.</p><h3><strong>2. Rate limiting is not about security, it is about survival</strong></h3><p>In AI systems, every request has a cost.</p><p>If your /prediction endpoint is open without control, you are basically giving away money.</p><p>One script, one loop, and your bill is gone.</p><p>Even worse, if training jobs are triggered multiple times, your infrastructure will get overloaded.</p><p>So rate limiting becomes mandatory.</p><p>Not just per user, but per API key and per IP.</p><p>It is not an optimization. It is protection.</p><h3><strong>3. You need to stop thinking synchronously</strong></h3><p>Most ML tasks are not instant.</p><p>Training, batch jobs, heavy inference. These things take time.</p><p>If your API waits for everything, your system will feel slow and unreliable.</p><p>This is where a distributed task queue comes in.</p><p>Instead of doing the work immediately, you push it to a queue.<br>Workers pick it up and process it in the background.</p><p>Now your API becomes fast, and your system becomes scalable.</p><p>This pattern alone will take you very far.</p><h3><strong>4. Caching is your unfair advantage</strong></h3><p>One thing you will notice in real systems is repetition.</p><p>Same prompts. Same inputs. Same outputs.</p><p>If you recompute everything every time, you are wasting compute and money.</p><p>Caching solves this.</p><p>Store previous results, and return them when the same request comes again.</p><p>This is extremely powerful in:</p><ul><li><p>LLM applications</p></li><li><p>Recommendation systems</p></li><li><p>Repeated inference scenarios</p></li></ul><p>It makes your system faster and cheaper at the same time.</p><h3><strong>5. Not every prediction should be real time</strong></h3><p>This is a mistake many beginners make.</p><p>They assume everything must be instant.</p><p>But some predictions are heavy. Some depend on pipelines. Some take time.</p><p>Instead of forcing real time, make it asynchronous.</p><p>Accept the request, return a job ID, process it in the background.</p><p>Now your system is stable, and users still get results.</p><h3><strong>6. Model versioning is what saves you later</strong></h3><p>In the beginning, you have one model.</p><p>Then you improve it. Then you retrain it. Then you tweak features.</p><p>Now you have multiple versions.</p><p>If you are not tracking versions, you are in trouble.</p><p>You will not know:</p><ul><li><p>Which model is live</p></li><li><p>Which one performed better</p></li><li><p>How to rollback</p></li></ul><p>Model versioning brings control.</p><p>It lets you experiment without breaking production.</p><h3>7. Queue and Worker System</h3><p>A task queue alone is not enough. You need workers to actually execute the jobs.</p><p>Think of it like this.</p><p>Your API does not do the heavy work.<br>It only pushes tasks to a queue.</p><p>Workers are the ones that:</p><ul><li><p>Pick tasks from the queue</p></li><li><p>Run training jobs</p></li><li><p>Execute heavy inference</p></li><li><p>Process data pipelines</p></li></ul><p>This separation is powerful.</p><p>You can scale workers independently based on load.<br>More jobs &#8594; add more workers.<br>Less load &#8594; reduce workers.</p><p>This keeps your system efficient and prevents your API from getting overloaded.</p><p>In real ML systems, this pattern is everywhere.<br>API for control. Queue for scheduling. Workers for execution.</p><h3><strong>8. Monitoring is not optional</strong></h3><p>Once your system is live, things will break.</p><p>Not because your code is bad, but because real world data is messy.</p><p>You need to see:</p><ul><li><p>API latency</p></li><li><p>Errors</p></li><li><p>Model performance</p></li><li><p>Resource usage</p></li></ul><p>Without monitoring, you are guessing.</p><p>With monitoring, you are engineering.</p><h3><strong>9. Feature store solves a silent problem</strong></h3><p>One of the most common hidden issues in ML systems is mismatch.</p><p>Your training data pipeline and your production pipeline are slightly different.</p><p>That small difference breaks your model performance.</p><p>A feature store ensures consistency.</p><p>You compute features once and reuse them in both training and inference.</p><p>This reduces bugs and improves reliability.</p><h3><strong>10. CI/CD makes you fast</strong></h3><p>If you are manually deploying every change, you will slow down very quickly.</p><p>Use GitHub Actions to automate your pipeline.</p><p>Push code &#8594; run tests &#8594; build Docker &#8594; deploy</p><p>Now your system evolves continuously.</p><p>You spend less time deploying and more time improving.</p><h3><strong>11. Security is usually ignored, until it hurts</strong></h3><p>Most ML engineers ignore security in the beginning.</p><p>That works until it does not.</p><p>You need:</p><ul><li><p>Authentication</p></li><li><p>Authorization</p></li><li><p>API key control</p></li><li><p>Secure secret handling</p></li></ul><p>And most importantly, never expose your model endpoints openly.</p><p>Treat your model like an asset.</p><div><hr></div><h1><strong>B. Containerization</strong></h1><p>This is what makes your system portable.</p><h3><strong>Docker simplifies everything</strong></h3><p>Instead of worrying about environments, dependencies, and setups, you package everything into a container.</p><p>Now your model runs the same everywhere.</p><p>This is especially important in ML because dependency issues are very common.</p><p>With Docker, you remove that uncertainty.</p><h3><strong>CUDA and GPU workloads</strong></h3><p>If you are using GPUs, things get more complex.</p><p>CUDA setup is painful if done manually.</p><p>Docker solves this as well.</p><p>Using NVIDIA CUDA images, you get pre configured environments.</p><p>This makes GPU deployment predictable and reproducible.</p><div><hr></div><h1><strong>C. Observability</strong></h1><p>Once deployed, you need visibility.</p><h3><strong>Track your experiments</strong></h3><p>Use tools like MLflow and Weights &amp; Biases.</p><p>They help you track:</p><ul><li><p>Metrics</p></li><li><p>Parameters</p></li><li><p>Model performance</p></li></ul><p>This is how you move from guessing to knowing.</p><h3><strong>Monitor your system</strong></h3><p>Use Prometheus and Grafana.</p><p>They give you visibility into:</p><ul><li><p>System health</p></li><li><p>Resource usage</p></li><li><p>API performance</p></li></ul><h3><strong>Your model will degrade</strong></h3><p>No model stays perfect.</p><p>Data changes. Users change.</p><p>This leads to:</p><ul><li><p>Data drift</p></li><li><p>Concept drift</p></li></ul><p>If you do not detect this early, your model silently fails.</p><p>So always monitor data and plan retraining.</p><div><hr></div><h1><strong>D. Kubernetes</strong></h1><p>You do not need Kubernetes on day one.</p><p>But when you scale, it becomes useful.</p><p>It helps you:</p><ul><li><p>Deploy services</p></li><li><p>Auto scale</p></li><li><p>Handle failures</p></li></ul><p>In ML, it is especially useful for multi node setups and GPU workloads.</p><div><hr></div><h1><strong>E. Terraform</strong></h1><p>Setting up infrastructure manually does not scale.</p><p>Terraform lets you define everything as code.</p><p>Now your infrastructure is:</p><ul><li><p>Reproducible</p></li><li><p>Version controlled</p></li><li><p>Easy to scale</p></li></ul><div><hr></div><h1><strong>F. AWS Usage</strong></h1><p>You only need a few services to get started.</p><ul><li><p>IAM for access control</p></li><li><p>S3 for storage</p></li><li><p>EC2 for compute</p></li><li><p>ECR for Docker images</p></li><li><p>EKS when you scale</p></li><li><p>Billing alerts to stay safe</p></li><li><p>AWS Bedrock for managed models</p></li></ul><p>That is enough for most projects</p><h3><strong>Why SageMaker should not be your first choice</strong></h3><p>Amazon SageMaker is powerful, but it comes with tradeoffs.</p><p>It pushes you into:</p><ul><li><p>Notebook based workflows</p></li><li><p>AWS specific ecosystem</p></li><li><p>Higher costs</p></li></ul><p>In early stages, flexibility matters more.</p><p>If you use Docker based deployment, you stay portable.</p><p>You can move to any cloud or even on prem later.</p><p>That freedom is important.</p><div><hr></div><h1><strong>G. Minimal Setup</strong></h1><p>You do not need a complex system to start.</p><p>Just use:</p><ul><li><p>FastAPI</p></li><li><p>Docker</p></li><li><p>Redis</p></li><li><p>One EC2 instance</p></li><li><p>S3</p></li></ul><p>That is enough to deploy real AI systems.</p><div><hr></div><h1><strong>H. Flow Diagram</strong></h1><pre><code><code>User &#8594; API
     &#8594; Rate Limit
     &#8594; Cache
     &#8594; Queue
     &#8594; Worker
     &#8594; Model
     &#8594; Storage
     &#8594; Response</code></code></pre><div><hr></div><h1><strong>F. I made an end-to-end project on MLOps</strong></h1><p>Stock Agent Ops:</p><p><a href="https://github.com/kmeanskaran/stock-agent-ops/">github.com/kmeanskaran/stock-agent-ops/</a></p><p>Which generates the Bloomberg style financial report by giving ticker id of US stocks as input. Entire ML pipeline generates including classic LSTM for time-series forecasting and agentic AI for generating report.</p><p>Read these articles:</p><p><a href="/__u/kmeanskaran.substack.com/p/part-1-designing-an-agentic-mlops">Part 1: Designing a Production-Grade Agentic MLOps System</a></p><p><a href="/__u/kmeanskaran.substack.com/p/part-2-deploying-a-production-grade">Part 2: Deploying a Production-Grade Agentic MLOps System on AWS</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!OodP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!OodP!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png 424w, /__u/substackcdn.com/image/fetch/$s_!OodP!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png 848w, /__u/substackcdn.com/image/fetch/$s_!OodP!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png 1272w, /__u/substackcdn.com/image/fetch/$s_!OodP!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!OodP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png" width="1456" height="916" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:916,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2071714,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/193941494?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!OodP!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png 424w, /__u/substackcdn.com/image/fetch/$s_!OodP!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png 848w, /__u/substackcdn.com/image/fetch/$s_!OodP!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png 1272w, /__u/substackcdn.com/image/fetch/$s_!OodP!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c082cb-34aa-4a24-990e-8b84cc27921d_2194x1380.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Building AI is easy now.</p><p>Everyone can do it.</p><p>But deployment is where real engineering starts.</p><p>That is where systems break, costs rise, and complexity shows up.</p><p>If you focus on these fundamentals, you will be ahead of most people.</p><p>Start simple.<br>Ship fast.<br>Learn from production.</p><p>That is how you actually become an AI engineer.</p><p>Follow <a href="https://x.com/@kmeanskaran">@kmeanskaran</a> on X for more Applied AI/ML content</p><p></p>]]></content:encoded></item><item><title><![CDATA[Learn LLMs Like an Engineer Not a Researcher: A Complete Guide]]></title><description><![CDATA[What engineers actually need to know to build and ship LLM powered products.]]></description><link>https://kmeanskaran.substack.com/p/learn-llms-like-an-engineer-not-a</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/learn-llms-like-an-engineer-not-a</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 05 Apr 2026 04:30:52 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!VSV0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are learning large language models as an engineer, your goal is not just to understand them but to build, optimize, and ship them. This requires clarity across three layers: how the model works internally, how it is trained and fine tuned, and how it runs efficiently in production.</p><p>This guide walks through the full stack with a focus on what actually matters when you are building systems. You can anytime </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!VSV0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!VSV0!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png 424w, /__u/substackcdn.com/image/fetch/$s_!VSV0!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png 848w, /__u/substackcdn.com/image/fetch/$s_!VSV0!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png 1272w, /__u/substackcdn.com/image/fetch/$s_!VSV0!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!VSV0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png" width="1104" height="976" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:976,&quot;width&quot;:1104,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2096661,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/192623026?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!VSV0!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png 424w, /__u/substackcdn.com/image/fetch/$s_!VSV0!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png 848w, /__u/substackcdn.com/image/fetch/$s_!VSV0!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png 1272w, /__u/substackcdn.com/image/fetch/$s_!VSV0!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3758ae4-90cd-4a85-9232-d956ed76504a_1104x976.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>1. The Core Mental Model</h2><p>At the simplest level, an LLM does one thing:</p><p>It predicts the next token given previous tokens.</p><p>Everything else is built around making this prediction accurate, efficient, and useful.</p><p>Pipeline:</p><p>Text &#8594; Tokens &#8594; Embeddings &#8594; Transformer &#8594; Probabilities &#8594; Tokens</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!CvxT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!CvxT!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png 424w, /__u/substackcdn.com/image/fetch/$s_!CvxT!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png 848w, /__u/substackcdn.com/image/fetch/$s_!CvxT!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png 1272w, /__u/substackcdn.com/image/fetch/$s_!CvxT!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!CvxT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png" width="1456" height="890" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:890,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Journey of a single token through the LLM Architecture&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Journey of a single token through the LLM Architecture" title="Journey of a single token through the LLM Architecture" srcset="/__u/substackcdn.com/image/fetch/$s_!CvxT!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png 424w, /__u/substackcdn.com/image/fetch/$s_!CvxT!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png 848w, /__u/substackcdn.com/image/fetch/$s_!CvxT!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png 1272w, /__u/substackcdn.com/image/fetch/$s_!CvxT!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6110940-97ca-43ad-b5a9-4236ea9f4ad0_1903x1163.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>2. Tokenization and Embeddings</h2><p>Before anything reaches the model, text is converted into tokens. These are integer IDs representing subwords or characters.</p><p>Tokens are then mapped into embeddings, which are dense vectors. These vectors capture semantic meaning and are the actual inputs to the model.</p><p>From an engineering perspective:</p><ul><li><p>Token count directly affects cost and latency</p></li><li><p>Better tokenization improves performance in code and reasoning tasks</p></li></ul><div><hr></div><h2>3. Positional Encoding (RoPE)</h2><p>Transformers do not understand order by default. If you shuffle words, the model would treat them the same without positional information.</p><p>RoPE (Rotary Positional Encoding) solves this by encoding relative position using rotation in vector space.</p><p>Instead of adding position as a separate signal, RoPE rotates embedding vectors based on position.</p><p>Why this matters:</p><ul><li><p>Captures relative distance between tokens</p></li><li><p>Generalizes better to long context</p></li><li><p>Used in modern models like LLaMA</p></li></ul><p>Engineering insight:</p><p>RoPE helps the model understand how far apart tokens are, not just their absolute position.</p><div><hr></div><h2>4. Self Attention: The Core Mechanism</h2><p>Self attention is the heart of transformers.</p><p>Each token looks at all other tokens and decides which ones matter.</p><p>Mathematically, attention computes a similarity between tokens and uses it to combine information.</p><p>Intuition:</p><ul><li><p>Query asks a question</p></li><li><p>Key represents what each token contains</p></li><li><p>Value is the actual information</p></li></ul><p>The model computes how much each token should attend to others and aggregates relevant information.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!75v6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!75v6!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png 424w, /__u/substackcdn.com/image/fetch/$s_!75v6!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png 848w, /__u/substackcdn.com/image/fetch/$s_!75v6!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png 1272w, /__u/substackcdn.com/image/fetch/$s_!75v6!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!75v6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png" width="1456" height="951" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:951,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Understanding and Coding the Self-Attention Mechanism of Large Language  Models From Scratch | Sebastian Raschka, PhD&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Understanding and Coding the Self-Attention Mechanism of Large Language  Models From Scratch | Sebastian Raschka, PhD" title="Understanding and Coding the Self-Attention Mechanism of Large Language  Models From Scratch | Sebastian Raschka, PhD" srcset="/__u/substackcdn.com/image/fetch/$s_!75v6!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png 424w, /__u/substackcdn.com/image/fetch/$s_!75v6!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png 848w, /__u/substackcdn.com/image/fetch/$s_!75v6!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png 1272w, /__u/substackcdn.com/image/fetch/$s_!75v6!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8e8cf7e-1cbc-43bb-97c7-608cb3237a99_1766x1154.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>5. Causal Attention: Enabling Generation</h2><p>In generation tasks, the model must not see the future.</p><p>Causal attention ensures that each token only attends to previous tokens.</p><p>This makes the model autoregressive, meaning it generates text one token at a time.</p><p>Without causal masking, the model would cheat by looking ahead.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!9Ojr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!9Ojr!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png 424w, /__u/substackcdn.com/image/fetch/$s_!9Ojr!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png 848w, /__u/substackcdn.com/image/fetch/$s_!9Ojr!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png 1272w, /__u/substackcdn.com/image/fetch/$s_!9Ojr!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!9Ojr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png" width="927" height="431" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:431,&quot;width&quot;:927,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Beginners' Guide to Causal Attention | by GurSanjjam Singh Alang | Medium&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Beginners' Guide to Causal Attention | by GurSanjjam Singh Alang | Medium" title="Beginners' Guide to Causal Attention | by GurSanjjam Singh Alang | Medium" srcset="/__u/substackcdn.com/image/fetch/$s_!9Ojr!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png 424w, /__u/substackcdn.com/image/fetch/$s_!9Ojr!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png 848w, /__u/substackcdn.com/image/fetch/$s_!9Ojr!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png 1272w, /__u/substackcdn.com/image/fetch/$s_!9Ojr!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72521869-97a8-4432-afc0-8261f65fc2b0_927x431.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>6. Multi Head Attention and Its Variants</h2><p>Instead of using a single attention mechanism, transformers use multiple heads.</p><h3>Multi Head Attention (MHA)</h3><p>Each head learns a different relationship:</p><ul><li><p>Syntax</p></li><li><p>Semantics</p></li><li><p>Long range dependencies</p></li></ul><p>This improves representation power.</p><h3>Multi Query Attention (MQA)</h3><p>All heads share keys and values.</p><p>Benefit:</p><ul><li><p>Reduces memory usage</p></li><li><p>Faster inference</p></li></ul><h3>Grouped Query Attention (GQA)</h3><p>Heads are grouped, and each group shares keys and values.</p><p>This balances performance and efficiency.</p><p>From an engineering perspective:</p><ul><li><p>MHA is powerful but heavy</p></li><li><p>MQA and GQA are optimized for production</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!DdMX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!DdMX!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png 424w, /__u/substackcdn.com/image/fetch/$s_!DdMX!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png 848w, /__u/substackcdn.com/image/fetch/$s_!DdMX!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png 1272w, /__u/substackcdn.com/image/fetch/$s_!DdMX!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!DdMX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png" width="1400" height="579" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:579,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;DeepSeek Technical Analysis &#8212; (2)Multi-Head Latent Attention | by Jinpeng  Zhang | Medium&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="DeepSeek Technical Analysis &#8212; (2)Multi-Head Latent Attention | by Jinpeng  Zhang | Medium" title="DeepSeek Technical Analysis &#8212; (2)Multi-Head Latent Attention | by Jinpeng  Zhang | Medium" srcset="/__u/substackcdn.com/image/fetch/$s_!DdMX!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png 424w, /__u/substackcdn.com/image/fetch/$s_!DdMX!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png 848w, /__u/substackcdn.com/image/fetch/$s_!DdMX!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png 1272w, /__u/substackcdn.com/image/fetch/$s_!DdMX!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6010110f-f2dc-49dc-9aea-ec639641ff60_1400x579.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li></ul><div><hr></div><h2>7. Transformer Block</h2><p>A transformer is built by stacking blocks.</p><p>Each block contains:</p><ul><li><p>Attention layer</p></li><li><p>Feed forward network</p></li><li><p>Residual connections</p></li><li><p>Layer normalization</p></li></ul><p>Flow:<br>Input &#8594; Attention &#8594; Add &#8594; Norm &#8594; FFN &#8594; Add &#8594; Norm</p><h3>Residual Connections</h3><p>They add the input back to the output of a layer.</p><p>This stabilizes training and allows deeper networks.</p><h3>Layer Normalization</h3><p>Normalizes activations to keep training stable.</p><div><hr></div><h2>8. Feed Forward Network and SwiGLU</h2><p>After attention, each token passes through a feed forward network.</p><p>This is where computation happens independently per token.</p><p>Modern models use SwiGLU activation instead of ReLU.</p><p>Why SwiGLU matters:</p><ul><li><p>Better gradient flow</p></li><li><p>Improved performance</p></li><li><p>More expressive transformations</p></li></ul><p>From an engineering point of view:<br>Attention gathers information<br>FFN processes it</p><div><hr></div><h2>9. Training: From Data to Intelligence</h2><p>Training starts with pretraining.</p><h3>Pretraining</h3><p>Objective: predict next token</p><p>This is done on massive datasets using cross entropy loss.</p><p>What the model learns:</p><ul><li><p>Language structure</p></li><li><p>Facts</p></li><li><p>Patterns</p></li><li><p>Basic reasoning</p></li></ul><h3>Training Challenges</h3><ul><li><p>Distributed systems</p></li><li><p>GPU utilization</p></li><li><p>Data quality</p></li><li><p>Memory constraints</p></li></ul><p>Better data often matters more than bigger models.</p><div><hr></div><h2>10. Fine Tuning and Alignment</h2><p>After pretraining, the model needs to be shaped.</p><h3>Supervised Fine Tuning (SFT)</h3><p>Train on instruction response pairs.</p><p>This teaches:</p><ul><li><p>Format</p></li><li><p>Style</p></li><li><p>Behavior</p></li></ul><h3>Instruction Tuning</h3><p>Expose the model to diverse tasks.</p><p>This improves generalization.</p><h3>Alignment Methods</h3><h4>RLHF</h4><p>Uses human feedback and reinforcement learning.</p><h4>DPO</h4><p>Directly learns from preferred vs rejected responses.</p><h4>GRPO</h4><p>Learns by comparing multiple outputs within a group.</p><p>Key idea:<br>Alignment shapes behavior, not knowledge.</p><div><hr></div><h2>11. Parameter Efficient Fine Tuning</h2><p>Full fine tuning is expensive.</p><h3>LoRA</h3><p>Adds small trainable matrices while freezing the base model.</p><p>Benefits:</p><ul><li><p>Low memory usage</p></li><li><p>Fast training</p></li></ul><h3>QLoRA</h3><p>Combines LoRA with quantization.</p><p>Enables training large models on small hardware.</p><div><hr></div><h2>12. Quantization: Making Models Deployable</h2><p>Quantization reduces precision to save memory.</p><p>Formats:</p><ul><li><p>FP16</p></li><li><p>INT8</p></li><li><p>INT4</p></li></ul><p>Benefits:</p><ul><li><p>Lower memory usage</p></li><li><p>Faster inference</p></li></ul><p>Tradeoff:</p><ul><li><p>Slight accuracy loss</p></li></ul><p>Common methods:</p><ul><li><p>GPTQ</p></li><li><p>AWQ</p></li><li><p>QLoRA</p></li></ul><p>Quantization is critical for production systems.</p><div><hr></div><h2>13. Inference: The Real System</h2><p>Inference is where everything runs. Mainly focus on vLLM</p><p>Loop:<br>Input &#8594; Predict token &#8594; Append &#8594; Repeat</p><h3>KV Cache</h3><p>Stores intermediate values to avoid recomputation.</p><p>Reduces compute but increases memory usage.</p><h3>FlashAttention</h3><p>Optimizes attention computation by reducing memory movement.</p><h3>PagedAttention</h3><p>Manages KV cache using fixed size memory blocks.</p><p>Prevents fragmentation and improves efficiency.</p><h3>Continuous Batching</h3><p>Dynamically processes requests to maximize GPU usage.</p><h3>Speculative Decoding</h3><p>Uses a smaller model to speed up generation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!acsK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!acsK!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png 424w, /__u/substackcdn.com/image/fetch/$s_!acsK!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png 848w, /__u/substackcdn.com/image/fetch/$s_!acsK!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png 1272w, /__u/substackcdn.com/image/fetch/$s_!acsK!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!acsK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png" width="1273" height="668" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:668,&quot;width&quot;:1273,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;vLLM - MLOps Dictionary | Hopsworks&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="vLLM - MLOps Dictionary | Hopsworks" title="vLLM - MLOps Dictionary | Hopsworks" srcset="/__u/substackcdn.com/image/fetch/$s_!acsK!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png 424w, /__u/substackcdn.com/image/fetch/$s_!acsK!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png 848w, /__u/substackcdn.com/image/fetch/$s_!acsK!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png 1272w, /__u/substackcdn.com/image/fetch/$s_!acsK!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F425b0a5b-25fa-4494-b7b6-78adcbd51277_1273x668.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>14. Decoding Strategies</h2><p>The model outputs probabilities. Decoding converts them into tokens.</p><p>Options:</p><ul><li><p>Greedy</p></li><li><p>Sampling</p></li><li><p>Top k</p></li><li><p>Top p</p></li><li><p>Temperature</p></li></ul><p>These control creativity and determinism.</p><div><hr></div><h2>15. Reasoning Models</h2><p>Reasoning models generate intermediate steps.</p><p>Techniques:</p><ul><li><p>Chain of thought</p></li><li><p>Self consistency</p></li><li><p>Tool usage</p></li></ul><p>Tradeoff:</p><ul><li><p>Better accuracy</p></li><li><p>Higher cost and latency</p></li></ul><div><hr></div><h2>16. Training Tools and Practical Stack</h2><p>To work as an engineer, you need tools.</p><h3>Hugging Face</h3><ul><li><p>Model loading</p></li><li><p>Training pipelines</p></li><li><p>Datasets</p></li></ul><h3>Unsloth</h3><ul><li><p>Faster LoRA and QLoRA training</p></li><li><p>Lower memory usage</p></li><li><p>Optimized kernels</p></li></ul><h3>vLLM</h3><ul><li><p>High-performance LLM inference</p></li><li><p>PagedAttention for efficient KV cache</p></li><li><p>Continuous batching for better throughput</p></li><li><p>Optimized GPU utilization for production</p></li></ul><h3>Typical workflow:</h3><ul><li><p>Load base model</p></li><li><p>Apply LoRA</p></li><li><p>Train with Unsloth</p></li><li><p>Evaluate</p></li><li><p>Export for inference</p></li><li><p>Serve using vLLM</p></li></ul><div><hr></div><h2>17. The Real Engineering Insight</h2><p>To build LLM systems, you must understand tradeoffs:</p><ul><li><p>Accuracy vs latency</p></li><li><p>Memory vs speed</p></li><li><p>Cost vs quality</p></li></ul><p>Most real world work is about balancing these.</p><div><hr></div><h2>18. Final Mental Model</h2><p>An LLM system is made of layers:</p><p>Model layer:</p><ul><li><p>Attention</p></li><li><p>Transformer blocks</p></li></ul><p>Training layer:</p><ul><li><p>Pretraining</p></li><li><p>Fine tuning</p></li><li><p>Alignment</p></li></ul><p>System layer:</p><ul><li><p>KV cache</p></li><li><p>FlashAttention</p></li><li><p>PagedAttention</p></li><li><p>Batching</p></li></ul><p>Optimization layer:</p><ul><li><p>LoRA</p></li><li><p>Quantization</p></li></ul><div><hr></div><h2>Conclusion</h2><p>Learning LLMs as an engineer means going beyond theory.</p><p>You need to understand:</p><ul><li><p>How attention works</p></li><li><p>How models are trained</p></li><li><p>How behavior is aligned</p></li><li><p>How systems are optimized</p></li></ul><p>I am recently learning about fine-tuning LLMs, distributed training, reasoning model and inference engineering till deployment. </p><p>Upcoming articles, will be more on LLM engineering and inference. I am going to design an entire LLM inference pipeline and update on X.</p><p>Follow me on <a href="http://x.com/@kmeanskaran">X</a>.</p>]]></content:encoded></item><item><title><![CDATA[Part 2: Deploying a Production-Grade Agentic MLOps System on AWS]]></title><description><![CDATA[Designing and Deploying a Scalable Agentic ML System on AWS]]></description><link>https://kmeanskaran.substack.com/p/part-2-deploying-a-production-grade</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/part-2-deploying-a-production-grade</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 01 Mar 2026 04:30:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!f7JL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Disclaimer</h2><p>In <a href="/__u/kmeanskaran.substack.com/p/part-1-designing-an-agentic-mlops">Part 1: Designing a Production-Grade Agentic MLOps System</a>, we saw how to build <em>Stock-Agent-Ops</em> &#8212; an Agentic MLOps system that predicts the next 7 days (technically 5 trading days) of closing stock prices. It also generates sentiment analysis, line plots, and recent news related to the stock for financial reporting.</p><blockquote><p>Refer to <a href="https://github.com/karan842/stock-agent-ops/tree/aws-deployment">GitHub repo</a>, I moved AWS infra on <em>aws-deployment</em> branch.</p></blockquote><p>I recommend you read that article first to understand how we designed this system (me, ChatGPT, and AntiGravity) from scratch. Although both articles are kept at a high-level abstraction; otherwise, this would easily turn into a 200-page eBook.</p><p>To learn more about the complete system design and deep AWS technical details, read the following README files:</p><ol><li><p><a href="https://github.com/karan842/stock-agent-ops/blob/master/doc/system_design.md">A complete ML System Design</a></p></li><li><p><a href="https://github.com/karan842/stock-agent-ops/blob/aws-deployment/doc/AWS.md">AWS Infra Design</a> </p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!f7JL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!f7JL!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!f7JL!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!f7JL!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!f7JL!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!f7JL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg" width="1456" height="805" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:805,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:140744,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/188289472?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!f7JL!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!f7JL!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!f7JL!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!f7JL!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d98ae99-8344-41be-8890-ed0e6f69850d_2048x1132.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Pre-AWS Theme</h2><p>In this article, we are not going to discuss what AWS is or explain its services. Instead, we will focus on how to connect the dots and deploy the system quickly with minimal setup.</p><p>In the local version, I&#8217;ve been running the entire application using Docker Compose. Currently, I have three main Docker images:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Crl3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Crl3!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png 424w, /__u/substackcdn.com/image/fetch/$s_!Crl3!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png 848w, /__u/substackcdn.com/image/fetch/$s_!Crl3!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Crl3!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Crl3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png" width="1208" height="624" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:624,&quot;width&quot;:1208,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:134741,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/188289472?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Crl3!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png 424w, /__u/substackcdn.com/image/fetch/$s_!Crl3!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png 848w, /__u/substackcdn.com/image/fetch/$s_!Crl3!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Crl3!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe342e8f7-207a-4313-9b51-6c9b6c11fd2b_1208x624.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>1. FastAPI Backend</h4><p>(ML + Agentic AI + classic microservice structure + caching + rate limiting)</p><h4>2. Frontend UI</h4><p>(Streamlit UI for the financial dashboard)</p><h4>3. Monitoring UI</h4><p>(Streamlit dashboard for data drift detection, agent observability, and visual logs for the entire system)</p><p>Apart from these, we also have other Docker images for supporting tools and services:</p><ul><li><p>Redis (for caching)</p></li><li><p>Qdrant (vector database)</p></li><li><p>Prometheus and Grafana (for overall system observability)</p></li></ul><p>I&#8217;ve used Docker Compose for the local setup to run everything together &#8212; you can refer to Part 1 for that. Additionally, I&#8217;ve used local Ollama models for LLM tasks and embeddings.</p><p>Now, we need to prepare the application for AWS deployment. First, we must map everything from the code level to the infrastructure level. We will start by fixing the code-level components for AWS compatibility, and then move to infrastructure decisions like Docker and Kubernetes.</p><p>This is a best practice to ensure seamless integration from local development to production. It&#8217;s not just about running Docker on the cloud and we must also adapt internal logic. For example, in our case, we currently rely on a local Ollama setup, which cannot remain the same in production.</p><p>Let&#8217;s now look at each deployment step in detail.</p><div><hr></div><h2>Set AWS</h2><p>It is an easy step. Let me break it down:</p><ul><li><p>Create an AWS account (Free Tier &#8212; $100 credits if eligible)</p></li><li><p>Install AWS CLI</p></li><li><p>Configure an AWS IAM user and user group</p></li><li><p>Add the access keys to your local terminal</p></li></ul><p>You can simply copy-paste these steps into ChatGPT to get more precise, step-by-step instructions tailored to your system.</p><div><hr></div><h2>Replace Ollama with AWS Bedrock</h2><p>In the Agentic AI part, we used Ollama models:</p><ul><li><p><strong>LLM:</strong> <code>gpt-oss:20b-cloud</code></p></li><li><p><strong>Embedding model:</strong> <code>nomic-text-embed</code></p></li></ul><p>This is exactly what I meant by moving from the code level to the infrastructure level. At the code level, we need to replace Ollama with AWS Bedrock.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!IeMK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!IeMK!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png 424w, /__u/substackcdn.com/image/fetch/$s_!IeMK!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png 848w, /__u/substackcdn.com/image/fetch/$s_!IeMK!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png 1272w, /__u/substackcdn.com/image/fetch/$s_!IeMK!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!IeMK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png" width="928" height="712" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:712,&quot;width&quot;:928,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:154273,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/188289472?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!IeMK!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png 424w, /__u/substackcdn.com/image/fetch/$s_!IeMK!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png 848w, /__u/substackcdn.com/image/fetch/$s_!IeMK!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png 1272w, /__u/substackcdn.com/image/fetch/$s_!IeMK!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6faa06a3-a557-4583-8c55-9d5e489af8d1_928x712.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In this project, I&#8217;ve used:</p><ul><li><p><strong>LLM:</strong> <code>openai.gpt-oss-20b-1:0</code></p></li><li><p><strong>Embedding model:</strong> <code>amazon.titan-embed-text-v1</code></p></li></ul><p>Everything else at the code level remains the same. Only the model provider changes from a locally hosted Ollama setup to managed foundation models via AWS Bedrock.</p><div><hr></div><h2>Kubernetes Service Mesh</h2><p>The <code>k8s/</code> folder defines how our application runs inside EKS. This is where we convert our local Docker Compose setup into a production-ready Kubernetes environment.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!bpfm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!bpfm!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png 424w, /__u/substackcdn.com/image/fetch/$s_!bpfm!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png 848w, /__u/substackcdn.com/image/fetch/$s_!bpfm!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png 1272w, /__u/substackcdn.com/image/fetch/$s_!bpfm!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!bpfm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png" width="670" height="359.3977591036415" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:766,&quot;width&quot;:1428,&quot;resizeWidth&quot;:670,&quot;bytes&quot;:321783,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/188289472?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!bpfm!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png 424w, /__u/substackcdn.com/image/fetch/$s_!bpfm!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png 848w, /__u/substackcdn.com/image/fetch/$s_!bpfm!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png 1272w, /__u/substackcdn.com/image/fetch/$s_!bpfm!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99dde21-3910-42a3-b8ed-256c0765957e_1428x766.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Everything runs inside a dedicated <code>mlops</code> namespace so the system stays isolated and organized. For sensitive data like API keys and AWS credentials, we use Kubernetes Secrets. In CI/CD, these are injected from GitHub Secrets, so nothing sensitive is hardcoded.</p><p>Our main services, <code>fastapi</code>, <code>frontend</code>, and <code>monitoring-app</code> are deployed with defined CPU and memory limits to keep the cluster stable. We also configure basic health checks so Kubernetes can automatically restart any container that becomes unhealthy.</p><p>For storage, we use persistent volumes backed by <em>AWS EBS</em>. This ensures that vector data in Qdrant and cached data in Redis remain safe even if pods restart.</p><p>For observability, Prometheus collects metrics from the backend, and Grafana visualizes system performance and health.</p><p>This structure keeps the system clean, stable, and production-ready without making it overly complex.</p><p>We will push Docker images to AWS Elastic Container Registry (ECR), provision EC2 instances, and spin up an AWS Elastic Kubernetes Service (EKS) cluster with two worker nodes running on EC2.</p><p>Don&#8217;t worry we&#8217;ll use Terraform to provision and configure everything in one go. No manual setup, no console clicking. One command, and the entire infrastructure comes to life.</p><div><hr></div><h2>Infrastructure as Code (Terraform)</h2><p>The <code>terraform/</code> directory is the blueprint of our cloud environment. Instead of manually creating AWS resources, we define everything as code and let Terraform provision it in a repeatable and structured way.</p><p>Terraform handles the core infrastructure: networking, the Kubernetes cluster, container registry, and identity management.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!c9lp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!c9lp!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png 424w, /__u/substackcdn.com/image/fetch/$s_!c9lp!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png 848w, /__u/substackcdn.com/image/fetch/$s_!c9lp!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png 1272w, /__u/substackcdn.com/image/fetch/$s_!c9lp!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!c9lp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png" width="802" height="574" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:574,&quot;width&quot;:802,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:62736,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/188289472?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!c9lp!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png 424w, /__u/substackcdn.com/image/fetch/$s_!c9lp!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png 848w, /__u/substackcdn.com/image/fetch/$s_!c9lp!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png 1272w, /__u/substackcdn.com/image/fetch/$s_!c9lp!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d6b17e-860e-46ff-a8c0-8d1bbadb4466_802x574.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In <code>vpc.tf</code>, we define the networking layer. Workloads run inside private subnets so they are not directly exposed to the internet. A NAT Gateway allows secure outbound communication (like pulling models or talking to AWS Bedrock), while an Application Load Balancer in public subnets manages inbound traffic safely.</p><p>In <code>eks.tf</code>, we provision a managed EKS cluster (v1.29) with <code>t3.xlarge</code> node groups. The 16GB RAM is important for running the FastAPI backend with heavy ML libraries. Each node is configured with 50GB EBS storage to avoid disk pressure during large image pulls.</p><p>In <code>ecr.tf</code>, we create private ECR repositories for each microservice to enable secure and fast image pulls within AWS.</p><p>In <code>iam.tf</code>, we configure IRSA using an OIDC provider. Instead of injecting AWS keys into pods, services assume IAM roles directly with scoped permissions for resources like Bedrock and CloudWatch.</p><p>Once defined, everything is controlled through Terraform commands:<br>1. <code>terraform apply</code> provisions or updates the full infrastructure.<br>2. <code>terraform destroy</code> removes it cleanly when needed.</p><p>This makes the entire environment reproducible, manageable, and production-ready from the infrastructure layer itself.</p><div><hr></div><h2>GitHub CI/CD Pipeline</h2><p>CI/CD (Continuous Integration and Continuous Deployment) ensures that every code change moves automatically from development to production without manual intervention.</p><p>In this project, GitHub Actions handles the entire automation. The <code>.github/workflows/deploy.yml</code> file acts as the orchestrator for every update pushed to the repository.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!F6kr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!F6kr!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png 424w, /__u/substackcdn.com/image/fetch/$s_!F6kr!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png 848w, /__u/substackcdn.com/image/fetch/$s_!F6kr!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png 1272w, /__u/substackcdn.com/image/fetch/$s_!F6kr!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!F6kr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png" width="1456" height="757" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:757,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:228450,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/188289472?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!F6kr!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png 424w, /__u/substackcdn.com/image/fetch/$s_!F6kr!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png 848w, /__u/substackcdn.com/image/fetch/$s_!F6kr!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png 1272w, /__u/substackcdn.com/image/fetch/$s_!F6kr!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c52458-466c-4e64-a4f6-f0accb3aecbd_2812x1462.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://github.com/karan842/stock-agent-ops/blob/aws-deployment/.github/workflows/deploy.yml">Detail CI/CD structure</a></p><p>Whenever new code is pushed, the pipeline starts by syncing infrastructure. It runs <code>terraform apply</code> to ensure any infrastructure changes such as updated variables or instance upgrades are reflected in AWS before deploying the new version.</p><p>Next comes the Docker build stage. The images are built from the project root. This is critical because the backend needs access to modules from both the <code>backend/</code> and <code>src/</code> directories. Building from the root ensures imports work correctly and prevents runtime errors.</p><p>Once built, the images are tagged with the specific Git SHA. This makes every deployment traceable to a commit. The images are then securely pushed to private ECR repositories.</p><p>After pushing, the workflow dynamically updates the Kubernetes manifests. Using a simple <code>sed</code> replacement, repository placeholders in the YAML files are replaced with the actual AWS Account ID registry URL. This keeps the configuration environment-aware without hardcoding values.</p><p>Finally, deployment happens using <code>kubectl apply</code>, followed by <code>kubectl rollout restart</code>. This ensures rolling updates, allowing the new version to be deployed without downtime.</p><p>In simple terms, the CI/CD pipeline automates infrastructure synchronization, Docker image creation, registry updates, and Kubernetes rollout, turning every commit into a production-ready deployment.</p><div><hr></div><h3>Running the application</h3><p>After executing the CI/CD pipeline, you can see all the Docker images running inside the Kubernetes cluster from the EKS dashboard.</p><p>At this point, you just need to access the monitoring dashboard, frontend application, and Grafana dashboard to verify everything is working as expected.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!qFqG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!qFqG!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png 424w, /__u/substackcdn.com/image/fetch/$s_!qFqG!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png 848w, /__u/substackcdn.com/image/fetch/$s_!qFqG!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png 1272w, /__u/substackcdn.com/image/fetch/$s_!qFqG!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!qFqG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png" width="1456" height="943" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:943,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1367535,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/188289472?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!qFqG!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png 424w, /__u/substackcdn.com/image/fetch/$s_!qFqG!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png 848w, /__u/substackcdn.com/image/fetch/$s_!qFqG!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png 1272w, /__u/substackcdn.com/image/fetch/$s_!qFqG!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d1970-d10e-4b95-86a3-581b34dcf17b_3420x2214.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The complete application workflow and overall system design have already been covered in:</p><ol><li><p><a href="https://github.com/karan842/stock-agent-ops/blob/master/doc/system_design.md">A complete ML System Design</a></p></li><li><p><a href="https://github.com/karan842/stock-agent-ops/blob/aws-deployment/doc/AWS.md">AWS Infra Design</a> </p></li></ol><p>Now the important thing is, the applications are running on an EKS cluster with 2 <code>t3.xlarge</code> nodes. This setup is powerful but it costs a lot. If you leave it running, the bill can increase very fast.</p><p>Make sure to configure AWS Billing Alerts before testing anything. Set a budget limit so you get notified if usage crosses a threshold. Otherwise, the bill can skyrocket.</p><p>After running and testing the application, monitor the pricing regularly and destroy all AWS resources to stop burning your wallet.</p><div><hr></div><h3>Destroy All Services</h3><p>After running all services on AWS we must destroy them before turning off your computer. So we will destroy all services, as our CI/CD is perfectly configured. So you can re-run the workflow to cold start entire system. We will use terraform to destory AWS services and recheck using AWS commands. I have written bash script to nuke AWS. <a href="https://github.com/karan842/stock-agent-ops/tree/aws-deployment/scripts">See this directory of bash scripts.</a></p><div><hr></div><h3>Final Takeaway</h3><ul><li><p>Always run your setup on a local machine before moving to AWS.</p></li><li><p>For faster, scalable, and accurate deployment, start from the code level and then move to infrastructure.</p></li><li><p>Always set a billing alert. I usually set it to $10 for PoC projects.</p></li><li><p>Spin up EKS with minimal nodes first. Don&#8217;t overprovision in the beginning.</p></li><li><p>Once your basic AWS setup works without errors, scaling becomes much easier.</p></li><li><p>A data drift admin dashboard is extremely important to monitor the ML model&#8217;s performance behind the scenes.</p></li><li><p>MLOps is not limited to the ML service. It also involves backend, infrastructure, monitoring, and deployment workflows.</p></li><li><p>Start using caching for ML inference to save both cost and response time.</p></li><li><p>Infra + ML Engineer will be a high-demand role very soon.</p></li><li><p>Terraform is one of the best tools you can use for building reliable Ops pipelines.</p></li><li><p>Always destroy AWS services when you are not using them.</p></li><li><p>Machine Learning is iterative. Don&#8217;t chase a perfect solution from day one.</p></li><li><p>Full-stack ML now means Data Engineering + ML + Backend + DevOps + Frontend + Cloud. AI can generate code, but it still struggles at infrastructure-level thinking.</p></li></ul><p>If you like this project and article then follow me on <a href="http://x.com/@kmeanskaran">X</a> and subscribe to my <a href="/__u/kmeanskaran.substack.com/">Substack newsletter</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!API8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!API8!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png 424w, /__u/substackcdn.com/image/fetch/$s_!API8!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png 848w, /__u/substackcdn.com/image/fetch/$s_!API8!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png 1272w, /__u/substackcdn.com/image/fetch/$s_!API8!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!API8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png" width="1456" height="764" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:764,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1206308,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/188289472?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!API8!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png 424w, /__u/substackcdn.com/image/fetch/$s_!API8!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png 848w, /__u/substackcdn.com/image/fetch/$s_!API8!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png 1272w, /__u/substackcdn.com/image/fetch/$s_!API8!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87840fc7-c9dd-457b-8d2c-0fd780dbc3ae_2672x1402.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Thanks for reading this blog and supporting this project. Up next, I&#8217;ll be sharing more about MLOps and how to set up Agents at scale.</p><p>If you&#8217;d like to know more about me or need help solving ML + Ops problems, feel free to reach out. I&#8217;d be happy to contribute to your team.</p><p>Here&#8217;s my website: <a href="http://kmeanskaran.com">kmeanskaran.com</a></p><p>Signing off! </p>]]></content:encoded></item><item><title><![CDATA[Part 1: Designing a Production-Grade Agentic MLOps System]]></title><description><![CDATA[A practical guide to combining LSTM forecasting, transfer learning, and AI agents in real-world ML systems]]></description><link>https://kmeanskaran.substack.com/p/part-1-designing-an-agentic-mlops</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/part-1-designing-an-agentic-mlops</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 04 Jan 2026 04:30:39 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Nn3C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>&#8220;How to design a ML system?&#8221;</em></p><p><em>&#8220;What is MLOps? and how can I learn?&#8221;</em></p><p><em>&#8220;How to work outside Jupyter Notebook?&#8221;</em></p><p><em>&#8220;What tools do I need?&#8221;</em></p><p>These are some of the most frequently asked questions by ML practitioners who want to design and build end-to-end machine learning systems, including MLOps.To address this, I designed a production-grade, end-to-end ML and Agentic AI project. This is Part 1, where I explain how to think about system design and decision-making while working on real-world ML projects.</p><p>In Part 2, I will cover deployment on AWS.</p><p>For more such updates, follow me on <a href="http://x.com/@kmeanskaran">X</a>.</p><pre><code>BEFORE READING THIS BLOG:
1. <a href="https://x.com/kmeanskaran/status/2005977660929999325?s=20">Watch this live demo video</a>
2. <a href="https://github.com/karan842/stock-agent-ops/blob/master/doc/system_design.md">See the system design doc</a></code></pre><h2>Introduction</h2><p>When we say <em>Machine Learning</em>, many people think only about <code>model.fit()</code> and Jupyter notebooks. That is exactly where the difference between research ML and applied ML begins.</p><p>If you want to work in startups, big tech, or on the applied side of ML where systems directly drive business value, this article is written for you.</p><p>Let&#8217;s begin.</p><p>In this project, I am designing a <strong>Stock Agent</strong> that generates a Bloomberg-style financial report for the next five days of stock performance. It includes metrics such as Open, High, Low, Close, and other derived indicators.</p><p>Here is the interesting part. We are not using LLMs or any generative AI model to predict stock prices. Instead, we use an LSTM-based time series model for forecasting. This makes the project a strong combination of classical machine learning and Agentic AI.</p><p>Throughout this article, we will focus on how to design this problem for a production-grade environment. We will also cover edge cases and system-level considerations that most people tend to ignore, but which matter the most in real-world ML systems.</p><pre><code>DISCLAIMER:

This project focuses on building an end-to-end machine learning system rather than maximizing prediction accuracy. While I do consider the quality and performance of the ML model, this work is intended as a proof of concept, with primary emphasis on system design and engineering decisions.

You are free to experiment with models other than LSTM or apply hyperparameter tuning to improve performance. This system should not be used for making real stock trading decisions. It is created purely for learning and educational purposes.

I am human and I do make mistakes. If you notice any issues or have suggestions for improvement, please feel free to share them in the comments.</code></pre><h2>The Problem</h2><p>Design a system that predicts five-day stock performance and delivers a clean UI where users can input a stock ticker. The system generates a Bloomberg-style report that includes next week&#8217;s forecasted prices, current market news, sentiment classification such as Bullish, Bearish, or Neutral, and a visual chart for the forecast.</p><p>That defines the problem clearly.</p><p>Now the next step is to design the framework and structure the code into well-defined modules, with each component handling a specific responsibility. In real-world production systems, different teams work on different modules, and clean separation is critical for scalability and maintainability.</p><p>Let&#8217;s start designing the system.</p><div><hr></div><h2>How to Design</h2><div><hr></div><p>Looking at the requirements, we need two core outputs: forecasted stock prices and a structured financial report. This naturally leads us to two major ML components in the system.</p><ol><li><p>A classical machine learning model for time series forecasting.</p></li><li><p>An Agentic AI layer to generate a financial report based on the model outputs and market context.</p></li></ol><p>For time series forecasting, the most commonly used models are SARIMAX, Prophet, and LSTM. I chose LSTM, and here is why.</p><p>We are working with stock market data, which we source from the well-known Yahoo Finance API. Since we are forecasting US stocks, it is important to understand broader market behavior. Every stock market has an index that reflects overall trends, economic signals, and technical patterns. In the case of the US market, the S&amp;P 500 serves this role.</p><p>Because LSTM is a neural network, it allows us to apply transfer learning. We first train an LSTM model on the S&amp;P 500 index, which acts as the parent model. This model learns general market behavior. By freezing its weights, we then train child models for individual stocks such as Apple or Nvidia. This helps child models benefit from broader market knowledge while adapting to stock-specific patterns.</p><p>For experimentation, tracking, and storing model artifacts, we use MLflow along with DagsHub.</p><p>Now that the core decisions are clear, let&#8217;s look at the high-level system design.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Nn3C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Nn3C!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png 424w, /__u/substackcdn.com/image/fetch/$s_!Nn3C!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png 848w, /__u/substackcdn.com/image/fetch/$s_!Nn3C!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Nn3C!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Nn3C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png" width="1456" height="1830" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1830,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1030364,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/182701128?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Nn3C!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png 424w, /__u/substackcdn.com/image/fetch/$s_!Nn3C!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png 848w, /__u/substackcdn.com/image/fetch/$s_!Nn3C!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Nn3C!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa6e83b6-be55-4f32-9c10-5b1692950074_4701x5910.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Feeling confused? I have already documented a complete, detailed system-level design and explanation in the GitHub repository. For deeper technical details, I recommend reading that first.</p><p>To train the model, we begin with feature engineering and preprocessing. This step focuses on generating meaningful features that directly impact forecasting performance. After that, we move into model training using LSTM along with transfer learning, which we discussed earlier.</p><p>Moving forward, we need a robust inference pipeline. This pipeline uses an online feature store powered by Feast to serve weekly stock predictions in a reliable and scalable manner.</p><p>So far, we have covered training and inference. However, real engineering begins after this point, especially when we integrate Agentic AI and design the backend systems that support it.</p><p>Let&#8217;s go through these components one by one.</p><div><hr></div><h2>Where to use Agentic AI?</h2><p>A common question I often get is why we do not use Agentic AI directly for both forecasting and report generation. After all, it is easy to integrate Agentic AI with the Yahoo Finance API and let it do everything.</p><p>This is a good question, and it highlights where many startups and engineering teams fail.</p><p>LLMs and Agentic AI are not the solution to every AI problem. They are excellent at tasks such as question answering with given context, summarizing information, and extracting or scraping textual data from the internet. However, they are not well suited for learning continuous and complex temporal patterns.</p><p>Stock price forecasting is exactly that kind of problem. In fact, Agentic AI should not be used for forecasting at all.</p><p>Instead, the right approach is to use a dedicated time series model for prediction and then pass the forecasted outputs to an Agentic AI layer. That is precisely what we do here.</p><p>The LSTM model generates the future price predictions. These outputs are then provided to the Agentic AI, whose responsibility is to gather relevant market news for the given stock ticker, analyze sentiment, and generate a structured financial report. Additionally, I use a critic agent to evaluate the quality and consistency of the generated report.</p><p>This is how classical machine learning using LSTM and Agentic AI are integrated in a practical, production-oriented system</p><div><hr></div><p>If you think I contribute in your learning, then feel free to sponsor me</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://buymeacoffee.com/kmeanskaran" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!bNQ9!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png 424w, /__u/substackcdn.com/image/fetch/$s_!bNQ9!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png 848w, /__u/substackcdn.com/image/fetch/$s_!bNQ9!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png 1272w, /__u/substackcdn.com/image/fetch/$s_!bNQ9!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!bNQ9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png" width="430" height="120.71559633027523" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:306,&quot;width&quot;:1090,&quot;resizeWidth&quot;:430,&quot;bytes&quot;:24146,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://buymeacoffee.com/kmeanskaran&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/182701128?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!bNQ9!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png 424w, /__u/substackcdn.com/image/fetch/$s_!bNQ9!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png 848w, /__u/substackcdn.com/image/fetch/$s_!bNQ9!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png 1272w, /__u/substackcdn.com/image/fetch/$s_!bNQ9!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dbcbc1f-a74c-4b66-bcaf-f0f77fd8f7b7_1090x306.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h2>Backend&#8212;The backbone</h2><p>There is no point in repeating everything from scratch, as I have already defined everything from A to Z in the system design document.</p><p>But let me share the key points:</p><ul><li><p>We need a microservice architecture for this project, as we are connecting multiple independent components. ML systems are hard to debug, and a monolithic architecture is not recommended.</p></li><li><p>Keep parent and child training and prediction APIs separate.</p></li><li><p>Connect Redis for caching forecast outputs.</p></li><li><p>Use Qdrant to store generated stock reports in a vector database for ticker-based filtering and caching. Here, we do not need semantic caching, as we are caching reports for individual stocks.</p></li><li><p>After receiving a stock name request, first check whether the model output is present in Redis. If not, train the model from scratch. While doing this, check whether parent model weights are present. If not:</p><pre><code>train the parent model &#8594; train the child model using parent weights &#8594; generate predictions &#8594; store them in Redis &#8594; call the Agentic AI API to fetch data from Redis &#8594; generate a financial report &#8594; serve it to the UI &#8594; store the report in Qdrant.</code></pre></li><li><p>We also provide additional APIs, such as hard delete, to remove all model weights and flush both Qdrant and Redis.</p></li><li><p>The backend is asynchronous, but this is not ideal when handling a large number of concurrent requests. That is why we use rate limiting with different request limits for training and inference endpoints.</p></li><li><p>Finally, we use Docker to containerize the backend application.</p><div><hr></div></li></ul><h2>Observability </h2><p>This is one of the most important parts of an ML system. In most ML pipelines, it is rarely discussed or properly implemented. However, as you move toward infrastructure-level and enterprise-grade ML, this becomes a necessity.</p><p>In simple terms, observability is used to monitor the overall health of the system. For ML systems, this also includes data drift and model drift detection. Since we are using Agentic AI, evaluation of agent outputs is also required. Along with that, monitoring backend and system health is mandatory.</p><p>For this project, we focus only on data drift detection for the parent model. This is because we do not keep the same parent model for more than a week, and child models can be retrained whenever required. This keeps the setup simple.</p><p>For general system monitoring, I am using Prometheus and Grafana.</p><div><hr></div><h2>Frontend and UX</h2><p>Here, we have two primary frontends:</p><ol><li><p>A user interface for generating stock reports, focused on end users.</p></li><li><p>A monitoring dashboard for training the parent model, detecting data drift, evaluating generated reports, and viewing system logs, focused on the ML team.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!KgJ-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!KgJ-!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png 424w, /__u/substackcdn.com/image/fetch/$s_!KgJ-!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png 848w, /__u/substackcdn.com/image/fetch/$s_!KgJ-!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KgJ-!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!KgJ-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:520982,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/182701128?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!KgJ-!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png 424w, /__u/substackcdn.com/image/fetch/$s_!KgJ-!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png 848w, /__u/substackcdn.com/image/fetch/$s_!KgJ-!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KgJ-!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa88369bb-b31f-41f4-b4c4-57270e53ef04_1920x1080.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>These are UIs for this project. </p><div><hr></div><h2>Future improvements</h2><ul><li><p>The LSTM model is underfitted and needs improvement.</p></li><li><p>Model versioning is implemented in the code but is not actively used.</p></li><li><p>Cron jobs are required for parent model training and data-drift-based retraining.</p></li><li><p>Better evaluation mechanisms are needed for Agentic AI outputs.</p><div><hr></div></li></ul><h2>Key Takeaways</h2><ul><li><p>Always think from a business perspective.</p></li><li><p>The more fancy tools you use, the harder debugging becomes.</p></li><li><p>Use AI for coding, but you need to be very strong in system design.</p></li><li><p>AI agents are not the solution to every problem, but you should always evaluate where they fit.</p></li><li><p>Write code outside Jupyter notebooks.</p></li><li><p>I built this project with the help of ChatGPT, AntiGravity, and Grok, without following any tutorial.</p><div><hr></div></li></ul><p>his is just Part 1. In Part 2, I will deploy the entire system on AWS using services such as EC2, ECR, and EKS. I will also use Terraform for infrastructure provisioning. That will be covered in the next article, which I will release soon.</p><p>If you liked this blog post, I am confident you will enjoy my other content as well. I can predict that too. &#128521;</p><ul><li><p><a href="http://kmeanskaran.com">Visit my website</a></p></li><li><p><a href="http://x.com/@kmeanskaran">Follow me on X</a></p></li><li><p><a href="http://linkedin.com/in/kmeanskaran">Follow me on LinkedIn</a></p></li><li><p><a href="https://buymeacoffee.com/kmeanskaran">Buy me a coffee</a></p></li></ul><p>Until next time :)</p>]]></content:encoded></item><item><title><![CDATA[Introduction to Dynamic Pricing]]></title><description><![CDATA[How Modern Companies Use AI to Change Prices Every Second Without You Noticing]]></description><link>https://kmeanskaran.substack.com/p/introduction-to-dynamic-pricing</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/introduction-to-dynamic-pricing</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 30 Nov 2025 04:30:39 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7xbf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Dynamic pricing means changing a product&#8217;s price in real time based on what is happening in the market. The goal is to maximize revenue, profit, or growth. You see this everywhere. Airlines change ticket prices based on demand. Hotels adjust rates during festivals. Amazon updates product prices many times a day. Uber increases fares during rain or traffic spikes. Online ads change bids every second.</p><p>In simple terms, prices are not fixed. They move based on demand, supply, competition and timing. When demand is low, prices fall to push more sales. When demand rises, prices increase because customers are willing to pay more. Dynamic pricing tries to match the right price to the right moment.</p><p>Most of these decisions come from algorithms. These algorithms use data like sales history, past prices, seasonality, competitor prices and time patterns. Then they estimate the price that gives the highest revenue or profit. As more data comes in, the algorithms update themselves and get better with time.</p><p>Today we&#8217;re going to look at what dynamic pricing is and how big product-based companies adjust prices every second. I&#8217;ll also share my experience building such systems.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!7xbf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!7xbf!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png 424w, /__u/substackcdn.com/image/fetch/$s_!7xbf!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png 848w, /__u/substackcdn.com/image/fetch/$s_!7xbf!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png 1272w, /__u/substackcdn.com/image/fetch/$s_!7xbf!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!7xbf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6231210,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/177800464?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!7xbf!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png 424w, /__u/substackcdn.com/image/fetch/$s_!7xbf!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png 848w, /__u/substackcdn.com/image/fetch/$s_!7xbf!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png 1272w, /__u/substackcdn.com/image/fetch/$s_!7xbf!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989050c2-4065-42b1-b2e7-cc2da69b1aeb_2816x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Generated by Google Nano Banana Pro</figcaption></figure></div><h1><strong>Real Examples of Dynamic Pricing in Action</strong></h1><h3><strong>1. Uber Pricing: How Uber Adjusts Fares in Real Time</strong></h3><p>Uber uses one of the most advanced real-time pricing systems in the world.<br>Here is how it works in a technical sense:</p><ul><li><p>Uber constantly measures <strong>demand</strong> (ride requests) and <strong>supply</strong> (available drivers) in small geographic zones called geohashes.</p></li><li><p>When demand is higher than supply, the system triggers dynamic pricing. Fares increase so that more drivers come online and move toward that area.</p></li><li><p>Uber used to rely on simple surge multipliers. Modern versions now use more advanced models such as <strong>Bayesian inference</strong>, <strong>gradient boosting models</strong>, and <strong>auction-style pricing logic</strong>.</p></li><li><p>The system also studies rider behavior and driver acceptance. For example, if many riders reject the fare, the algorithm adjusts the multiplier downward.</p></li><li><p>Uber sometimes uses <strong>per rider pricing</strong>, which means two people standing near each other may see different prices based on predicted acceptance.</p></li><li><p>Once supply increases or demand cools, the prices return to normal automatically.</p></li></ul><p>Uber&#8217;s goal is not only revenue. The system tries to restore balance in the network so that rides are available when people need them.</p><h3><strong>2. Google Ads Smart Bidding: Dynamic Pricing For Ad Auctions</strong></h3><p>Google Ads uses dynamic pricing in the form of automated bidding for every ad auction. This is known as Smart Bidding.</p><p>This is what happens under the hood:</p><ul><li><p>When an ad auction begins, Google evaluates hundreds of real-time signals for that impression. These include device, location, time, browser, keywords, user history, demographics, and remarketing lists.</p></li><li><p>Google has machine learning models trained on huge amounts of historical conversion data. The models predict the probability of conversion and expected value for that particular user.</p></li><li><p>Based on your goal (for example Target CPA or Target ROAS), Smart Bidding sets the optimal bid for that exact auction.</p></li><li><p>The bid can be higher for users with high conversion probability and lower for users with low probability.</p></li><li><p>The system continuously learns from new data and updates the probability estimates.</p></li></ul><p>This makes Smart Bidding one of the best examples of dynamic pricing in the digital space. The &#8220;price&#8221; here is the bid amount for each impression.</p><div><hr></div><h1><strong>How Dynamic Pricing Systems Work Internally</strong></h1><p>Dynamic pricing systems usually have two main parts:</p><ol><li><p>A <strong>demand forecasting model</strong></p></li><li><p>A <strong>pricing engine</strong> that uses optimization or reinforcement learning</p></li></ol><p>Let us break this down.</p><div><hr></div><p>If you feel my content adds value to your ML journey, show some support to your centroid. It helps me make your K-Means cluster even better.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://buymeacoffee.com/kmeanskaran" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!QmsX!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png 424w, /__u/substackcdn.com/image/fetch/$s_!QmsX!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png 848w, /__u/substackcdn.com/image/fetch/$s_!QmsX!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QmsX!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!QmsX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png" width="210" height="58.95412844036697" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:306,&quot;width&quot;:1090,&quot;resizeWidth&quot;:210,&quot;bytes&quot;:24146,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://buymeacoffee.com/kmeanskaran&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/177800464?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!QmsX!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png 424w, /__u/substackcdn.com/image/fetch/$s_!QmsX!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png 848w, /__u/substackcdn.com/image/fetch/$s_!QmsX!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QmsX!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cd4606-b4b7-4afb-b197-eef6b42a2d01_1090x306.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h1><strong>Demand Forecasting Models</strong></h1><p>A dynamic pricing engine first needs to forecast demand. It must answer the question:<br><em>If I set this price today, how much will I sell?</em></p><p>Different models are used here.</p><h3><strong>Classical Time Series Models</strong></h3><p>Models like ARIMA, SARIMA or Exponential Smoothing use historical patterns to predict demand. They work well when data is stable and follows trends or seasonality.</p><h3><strong>Machine Learning Models</strong></h3><p>Tree models like Random Forest or Gradient Boosting accept many features such as:</p><ul><li><p>Price</p></li><li><p>Time of day</p></li><li><p>Day of week</p></li><li><p>Holidays</p></li><li><p>Competitor prices</p></li><li><p>Marketing spend</p></li><li><p>Product attributes</p></li><li><p>Inventory levels</p></li></ul><p>They capture complex relations and usually perform well for e-commerce or retail data.</p><h3><strong>Deep Learning Models</strong></h3><p>Neural networks like RNN, LSTM and Transformers can learn long term sequences and patterns in sales data. These models help when patterns shift or when the dataset is large.</p><p>The output of forecasting is a demand curve. This curve tells the system how demand changes for each possible price.</p><div><hr></div><h1><strong>Pricing Algorithms: Optimization and Reinforcement Learning</strong></h1><p>Once the system can forecast demand, it chooses a price using one of two strategies.</p><div><hr></div><h3><strong>1. Greedy Optimization (Simple and Widely Used)</strong></h3><p>This method looks at immediate revenue:</p><p><strong>Revenue = Price &#215; Predicted Demand</strong></p><p>The system checks a range of possible prices and picks the one that gives the highest revenue right now. It is fast and easy to use, but it ignores long term effects.</p><div><hr></div><h3><strong>2. Reinforcement Learning (Advanced and Future Focused)</strong></h3><p>Reinforcement learning treats pricing as a sequence of decisions.<br>Today&#8217;s price affects customer behavior tomorrow.</p><p>RL works like this:</p><ul><li><p><strong>State:</strong> market conditions (demand, supply, inventory, competitor prices, time)</p></li><li><p><strong>Action:</strong> choose a price</p></li><li><p><strong>Reward:</strong> revenue or profit</p></li><li><p><strong>Goal:</strong> maximize long term revenue</p></li></ul><p>RL algorithms learn through experience. They explore different prices, observe results and slowly build an optimal pricing policy.</p><p>Common RL methods here include:</p><ul><li><p>Q Learning</p></li><li><p>Deep Q Networks</p></li><li><p>Policy Gradient</p></li><li><p>Actor Critic</p></li><li><p>Multi Armed Bandits</p></li></ul><p>Companies often train these RL agents inside simulated environments to avoid experimenting on real customers. Once trained, the RL agent is deployed and monitored.</p><div><hr></div><h1><strong>Building a Full Dynamic Pricing System</strong></h1><p>A real production-ready system usually follows these steps:</p><h3><strong>1. Data Collection</strong></h3><p>Collect historical sales data, prices, competitor data, product attributes, holidays and other context.</p><h3><strong>2. Forecast Demand</strong></h3><p>Train time series or ML models to predict demand for different prices.</p><h3><strong>3. Choose Pricing Strategy</strong></h3><p>Pick between greedy optimization or RL based on product and business goals.</p><h3><strong>4. Add Constraints</strong></h3><p>Add rules like minimum margin, price ceilings, inventory limits or regulatory boundaries.</p><h3><strong>5. Train and Validate</strong></h3><p>Test the model on past data.<br>If using RL, train in a simulated environment built from demand models.</p><h3><strong>6. Deploy and Monitor</strong></h3><p>Deploy the pricing engine.<br>Run A/B tests.<br>Track revenue, conversion, customer impact and model drift.<br>Retrain regularly.</p><div><hr></div><h1><strong>Why Dynamic Pricing Matters Today</strong></h1><p>Dynamic pricing is becoming a core skill for ML engineers, product teams and business operations. It reflects how modern companies make decisions in real time using data and machine learning.<br>Tech companies like Uber, Amazon and Google rely heavily on dynamic pricing and bidding systems to run large scale marketplaces and advertising platforms.</p><p>A well designed pricing system can significantly increase revenue, improve availability, balance supply and create a better customer experience. At the same time, it requires caution because pricing decisions affect user trust and long term business stability.</p><p>Dynamic pricing sits at the intersection of machine learning, economics and strategy. It will only grow more important in the coming decade.</p><div><hr></div><h1>How&#8217;s my Experience</h1><p>I designed an RL-based dynamic pricing system that predicts the optimal price of a product by analysing the past price-to-units relationship, time-series patterns, and forecasted demand. Let me break it down.</p><p>At <a href="http://aihello.com">AiHello</a>, our eCommerce automation platform builds multiple AI-driven services to help Amazon sellers make smarter decisions. One of these services focuses on setting product prices in a way that increases sales at slightly higher price points, while still avoiding over-pricing. Since we already have a demand-forecasting service in our data warehouse, we can directly use its output to simulate and estimate the impact of different price levels.</p><p>Statistically, there are many correlations between pricing features and demand, but dynamic pricing cannot rely only on metrics like MSE or R2. The real behaviour of a pricing system can only be validated in production. This is why A/B testing or deploying the model for a small set of products is essential.</p><p>Reinforcement Learning then becomes the final layer of optimisation. Around 80% of the work depends on strong statistical and machine-learning fundamentals, while the remaining 20% comes from the RL module. RL helps explore all possible price scenarios and choose the one that achieves higher sales while maintaining healthy price efficiency.</p><p><a href="https://x.com/kmeanskaran/status/1969123879495807431?s=20">See my X post about this project experience</a></p><div><hr></div><p>That&#8217;s it for today. I&#8217;m looking forward to writing more exciting blogs on ML, MLOps, and GenAI. See you soon!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://kmeanskaran.substack.com/p/introduction-to-dynamic-pricing?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/kmeanskaran.substack.com/p/introduction-to-dynamic-pricing?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://kmeanskaran.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/kmeanskaran.substack.com/subscribe"><span>Subscribe now</span></a></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://buymeacoffee.com/kmeanskaran" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!aWq9!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png 424w, /__u/substackcdn.com/image/fetch/$s_!aWq9!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png 848w, /__u/substackcdn.com/image/fetch/$s_!aWq9!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aWq9!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!aWq9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png" width="134" height="37.61834862385321" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:306,&quot;width&quot;:1090,&quot;resizeWidth&quot;:134,&quot;bytes&quot;:24146,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://buymeacoffee.com/kmeanskaran&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/177800464?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!aWq9!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png 424w, /__u/substackcdn.com/image/fetch/$s_!aWq9!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png 848w, /__u/substackcdn.com/image/fetch/$s_!aWq9!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aWq9!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99fc6dba-59c7-449d-b520-c870dab2b545_1090x306.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div>]]></content:encoded></item><item><title><![CDATA[Tackle Any Machine Learning Problem ]]></title><description><![CDATA[Best strategies for successful ML projects.]]></description><link>https://kmeanskaran.substack.com/p/tackle-any-machine-learning-problem</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/tackle-any-machine-learning-problem</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 02 Nov 2025 04:30:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!x6iA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Machine Learning (ML) projects are fascinating and quite different from traditional web development.<br>When you build a website, your main focus areas are database management, CRUD operations, scalability, efficiency, and concurrency. You mostly deal with code and tools.</p><p>But ML projects involve both data and code. Along with programming, you need to understand, clean, and reason about data.<br>That&#8217;s what makes ML both challenging and exciting.</p><p>Most people believe ML is just about training models in Jupyter Notebooks. Yes, that&#8217;s a part of it, but not the whole story. Model training is important, but it&#8217;s not everything. The real complexity lies in what happens before and after training: data understanding, feature engineering, evaluation, and deployment.</p><p>When I&#8217;m assigned a new ML project, I usually start with just two things: the business problem statement and the data.<br>The problem statement tells me why this ML service is needed in the product, and the data tells me what I&#8217;m working with. It&#8217;s usually messy, huge, and confusing at first glance.</p><p>I talk with the manager or CEO to understand the business side. They know why this ML service matters and what the expectations are. My job is to translate that into a working ML pipeline.</p><p>Once I understand the problem and the data, I start building the project step by step.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!x6iA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!x6iA!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png 424w, /__u/substackcdn.com/image/fetch/$s_!x6iA!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png 848w, /__u/substackcdn.com/image/fetch/$s_!x6iA!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png 1272w, /__u/substackcdn.com/image/fetch/$s_!x6iA!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!x6iA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1255433,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/177664013?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!x6iA!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png 424w, /__u/substackcdn.com/image/fetch/$s_!x6iA!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png 848w, /__u/substackcdn.com/image/fetch/$s_!x6iA!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png 1272w, /__u/substackcdn.com/image/fetch/$s_!x6iA!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fede6b625-5561-4cff-991a-7df06d1ff05f_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>1. Understand Data and Problem Statement</h3><p>In this stage, talk with your product manager and CEO. They will explain the problem statement and what they expect from the ML system.<br>Write everything down, even if you don&#8217;t understand it immediately. They won&#8217;t talk in technical terms, and that&#8217;s fine. Translating those expectations into technical understanding is your responsibility.</p><p>Create a Google Doc or Notion page for the project outline. Keep updating it as you gain clarity. Discuss with teammates and managers regularly until you fully understand the business objective and the data.</p><p>When it comes to data, study the schema, update frequency, and column data types. If your dataset is in SQL, write a simple query with a LIMIT clause to fetch a few thousand records. Load it into a Pandas DataFrame and explore using <code>df.head()</code>, <code>df.info()</code>, and <code>df.describe()</code>. This helps you identify null values, data inconsistencies, and unexpected types.</p><p>Jupyter Notebook is perfect for this step because it helps you explore, visualize, and document everything together.</p><div><hr></div><h3>2. Statistics and Feature Engineering</h3><p>Statistics and probability are essential in understanding data before you move to model training.<br>Start with the basics: mean, median, standard deviation, and count for each feature. Plot boxplots to find outliers, and use histograms or line plots to understand the distribution. Check skewness to see if the data needs normalization or transformation.</p><p>For text data, check if there are missing or incomplete values and whether the dataset is imbalanced. If the data is multilingual, identify the languages present. For image data, check resolution consistency and missing labels. In such cases, image augmentation techniques like flipping, rotation, or cropping can improve the dataset.</p><p>For tabular data, study how features correlate by plotting heatmaps or using correlation coefficients. You can also apply techniques like PCA or SelectKBest to reduce dimensionality and improve model performance.</p><p>The more time you spend understanding and engineering your features, the better your results will be. A well-prepared dataset often performs better than a complex model trained on messy data.</p><div><hr></div><h3>3. Model Selection</h3><p>Model training is the heart of ML, but it shouldn&#8217;t consume all your time. Choose your model wisely based on the nature of your data.</p><ul><li><p>If your data is tabular and the task is classification or regression, start with <code>XGBoost</code> or <code>LightGBM</code>.</p></li><li><p>For time series forecasting, try <code>Prophet</code> or <code>ARIMA</code> models.</p></li><li><p>For NLP tasks, <code>BERT</code> or <code>DistilBERT</code> work well. If you&#8217;re working on generative or LLM-based tasks, try <code>Qwen</code> or <code>Llama</code> models.</p></li><li><p>For image classification, <code>YOLO</code> or <code>EfficientNet</code> are reliable choices.</p></li></ul><p>The real magic lies in the pipeline, not in the model.<br>I&#8217;ve seen many engineers pick complicated models too early. The code becomes messy, and debugging turns into a nightmare. Especially during backpropagation, small issues can waste hours.</p><p>Always start simple. Focus on solving the business problem first. You can add complexity later if needed.<br>Use tools like <em>MLflow</em> or <em>Weights &amp; Biases</em> for tracking your experiments and model versions.</p><div><hr></div><h3>4. Evaluate the Pipeline, Not Just the Model</h3><p>ML isn&#8217;t only about accuracy or F1-score. A model that performs well in a notebook might fail in production. That&#8217;s why you should evaluate the entire pipeline, not just the model.</p><p>Track common metrics like MSE, Precision, Recall, and F1-score, but go further. Perform A/B testing to see how your model impacts real business outcomes. Measure latency, throughput, and memory usage.</p><p>Try to break your pipeline intentionally. Feed invalid inputs or extreme values and see how it behaves. This helps you understand its robustness and limitations.</p><p>Also, evaluate how your ML system affects business KPIs such as conversions, retention, or cost savings. Metrics without real-world meaning don&#8217;t add much value.</p><div><hr></div><h3>5. Importance of Edge Cases</h3><p>You&#8217;ve probably read this online many times: </p><pre><code><em>The model behaves differently in production.</em></code></pre><p>It&#8217;s absolutely true!</p><p>In production, your model faces noisy, incomplete, or completely new data. That&#8217;s why you need to think beyond technical performance and consider real-world behavior.</p><p>When testing your pipeline or API, use different kinds of inputs and note the outcomes. If the ML service meets the desired criteria, move it to production. Once live, monitor it using A/B tests, performance dashboards, and feedback loops.</p><p>You can use tools like Prometheus and Grafana for latency and performance tracking, or Evidently AI for detecting data drift. Retraining pipelines using Airflow or Prefect can help keep your model updated as data changes.</p><p>Always note why something failed, not just that it failed. Continuous improvement is the key to building stable and scalable ML systems.</p><div><hr></div><p>Machine Learning projects succeed when you combine data understanding, thoughtful feature engineering, clean pipelines, and strong monitoring. The goal isn&#8217;t to build the flashiest model but to solve a real business problem efficiently.</p><p>Focus on clarity, structure, and results. Everything else will follow.</p><h2>From my experience </h2><ul><li><p>Communicate with the team, managers, CEO (if you&#8217;re into startup), or SMEs.</p></li><li><p>Data is everything! Better data &#8594; better model performance.</p></li><li><p>Do not overcomplicate your ML project. It&#8217;s so difficult to debug.</p></li><li><p>Follow iterative approach for your projects.</p></li><li><p>Pipeline is important than model for business.</p></li><li><p>You don&#8217;t need fancy tools and frameworks for better result.</p></li><li><p>Use AI for coding and ask it to help you in constructing the architecture.</p></li></ul><p></p><p>For better technical understanding about designing ML project, read this OG book:</p><ul><li><p><em><a href="https://www.amazon.in/Designing-Machine-Learning-Systems-Production-Ready/dp/9355422679">Designing Machine Learning Systems by Chip Huyen</a> </em></p></li></ul><div><hr></div><p>Thanks, for reading this article! </p><p>I summarised a simple framework to follow for your next ML project. So even if you are a beginner, this is a good way start looking at your ML projects. </p><p>Subscribe to my newsletter for such more interesting blogs in AI/ML and MLOps.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://kmeanskaran.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/kmeanskaran.substack.com/subscribe"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[How to Orchestrate Machine Learning Workflows]]></title><description><![CDATA[Automate Your Machine Learning Workflows Easily&#129337;]]></description><link>https://kmeanskaran.substack.com/p/how-to-orchestrate-ml-workflows</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/how-to-orchestrate-ml-workflows</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 12 Oct 2025 04:30:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2EmB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>1.  What is Orchestration?</h2><p>Machine learning projects are never a single-step job. They include several stages like d<em>ata collection, data cleaning, feature engineering, model training, testing, and deployment</em>. Each stage depends on the successful completion of the previous one.</p><p>When you do all this manually, it becomes tiring and error-prone. Imagine having to re-run the entire process every time you change a small part of your code or dataset. You would have to remember the order of steps, monitor logs, and keep track of outputs. This is manageable for small experiments, but once the project grows it becomes a headache.</p><p>That&#8217;s where <em><strong>orchestration</strong></em> solves the problem.<br>Orchestration means automating and managing the entire workflow of your machine learning project so that tasks run in the correct order, automatically, without manual effort.</p><p>Think of orchestration as a &#8220;smart manager&#8221; for your ML workflow.</p><ul><li><p>It knows which tasks need to run first and which depend on others.</p></li><li><p>It can stop the pipeline if something fails, retry the step, or skip unnecessary tasks.</p></li><li><p>It can run your workflows on schedule (cron jobs): daily, weekly, or after a trigger.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!2EmB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!2EmB!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png 424w, /__u/substackcdn.com/image/fetch/$s_!2EmB!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png 848w, /__u/substackcdn.com/image/fetch/$s_!2EmB!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png 1272w, /__u/substackcdn.com/image/fetch/$s_!2EmB!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!2EmB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png" width="728" height="477.5931034482759" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:761,&quot;width&quot;:1160,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:1407471,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://kmeanskaran.substack.com/i/175462985?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feec9f094-1b7f-440e-a0ef-571409569a93_1920x1080.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!2EmB!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png 424w, /__u/substackcdn.com/image/fetch/$s_!2EmB!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png 848w, /__u/substackcdn.com/image/fetch/$s_!2EmB!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png 1272w, /__u/substackcdn.com/image/fetch/$s_!2EmB!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96be2e3a-f18b-4545-841b-368b33567a93_1160x761.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">by Karan Shingde</figcaption></figure></div><p>For example, consider a simple ML pipeline:</p><ol><li><p>Load your dataset</p></li><li><p>Clean and transform it</p></li><li><p>Train the ML model</p></li><li><p>Evaluate model accuracy</p></li><li><p>Deploy it if accuracy is high enough (yes, we can create if-else conditions in pipelines).</p></li></ol><p>If any step fails, the orchestration tool can stop the workflow or retry automatically.<br>This helps avoid wasted time, broken pipelines, or manual reruns.</p><p>With orchestration, your ML system becomes smooth, reliable, and scalable. You can schedule workflows, monitor them in real-time, and even handle multiple projects together.</p><div><hr></div><h2>2. Why Orchestration Makes ML Projects Faster</h2><p>Orchestration makes machine learning workflows more efficient and reliable. Instead of manually running scripts, everything happens automatically in a defined sequence.</p><p>It saves time because once you set up the workflow, you can schedule it or trigger it when new data arrives. It also <strong>reduces errors</strong> since each task runs with clear dependencies, no missing steps or wrong order.</p><pre><code><strong>Example scenario: </strong>Let&#8217;s say you want to retrain your recommendation model every Sunday at 11 PM. With orchestration, you can schedule this workflow once. Every week, it will automatically fetch the latest data, train the model, check accuracy, and push it to production &#8212; all without human help.</code></pre><p>This brings speed, safety, and control to your ML workflow. These three things every production-grade ML system needs.</p><div><hr></div><h2>3. How to Design Orchestration DAGs</h2><p>A <em>DAG (Directed Acyclic Graph)</em> is the heart of ML orchestration. It defines how your tasks connect and in what order they should run. The term &#8220;acyclic&#8221; means tasks move forward, they never loop back.</p><p>In simple words, a DAG is like a <strong>flowchart</strong> for your ML pipeline. Each box is a task, and arrows show which task depends on which.</p><p>For example, a basic ML DAG might look like this:</p><ol><li><p>Load data</p></li><li><p>Clean data</p></li><li><p>Train model</p></li><li><p>Evaluate performance</p></li><li><p>Deploy if accuracy is above threshold</p></li></ol><p>You can also add conditions (if-else) inside DAGs. For instance, deploy only if accuracy &gt; 85%, else trigger a retraining step.</p><p></p><p>When designing DAGs, keep these things in mind:</p><ul><li><p>Each task should do one specific job.</p></li><li><p>Always define dependencies clearly (what runs after what).</p></li><li><p>Handle failures and retries properly.</p></li><li><p>Add scheduling for recurring workflows (like weekly retraining).</p></li></ul><p>A good DAG turns your ML process into a repeatable, fault-tolerant pipeline that&#8217;s easy to track and scale.</p><p>But,</p><h4><em>What&#8217;s the difference between DAGs Orchestration and Kubernetes Orchestration?</em></h4><p>While both DAGs and Kubernetes handle automation, they serve different purposes.<br>A DAG (Directed Acyclic Graph) in ML orchestration focuses on workflow logic that is defining the order in which tasks like data cleaning, training, and deployment run. It&#8217;s about <em>what runs and when</em>.<br><strong>Kubernetes</strong>, on the other hand, handles infrastructure orchestration like managing containers, scaling pods, and ensuring resources are available. It&#8217;s about <em>where and how things run</em>.</p><p>In simple terms:</p><ul><li><p>DAGs orchestrate the ML workflow</p></li><li><p>Kubernetes orchestrates the system that runs the workflow</p></li></ul><p>Practice building your machine learning projects in a modular way and execute the entire pipeline as a flow from data ingestion to deployment. This approach helps you standardize your process and make your projects production ready.</p><div><hr></div><h2>4. Orchestrate ML workflow using Prefect</h2><p>Modern data workflows often involve multiple dependent steps &#8212; data ingestion, model training, evaluation, and conditional decisions. Managing all of this manually can get messy. This is where <strong>Prefect</strong> comes in.</p><p>Prefect is a modern workflow orchestration framework that lets you build, schedule, and monitor data pipelines<strong> </strong>directly in Python without the complexity of static DAG definitions or YAML files.</p><p>It turns normal Python functions into tasks and automatically manages their execution order, retries, caching, and logging all while keeping your code clean and intuitive.</p><h3>Key Features</h3><ul><li><p><strong>Pure Python orchestration</strong> &#8212; no DSLs or complex configs.</p></li><li><p><strong>Dynamic DAGs</strong> built at runtime (not hardcoded).</p></li><li><p><strong>Retry, caching, and scheduling</strong> with one line of code.</p></li><li><p><strong>Easy observability</strong> via the Prefect UI (local or cloud).</p></li><li><p><strong>Flexible execution</strong> &#8212; run locally, in Docker, or on Kubernetes.</p></li></ul><p>To get started, follow the <a href="https://docs.prefect.io/v3/get-started/install">Prefect installation guide</a> from the official documentation.</p><p>Here&#8217;s a simple Prefect flow that trains a regression model and decides whether to retrain based on its performance:</p><pre><code>from prefect import flow, task
from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import pandas as pd


@task
def load_data():
    data = load_diabetes(as_frame=True)
    df = data.frame
    print(f&#8221;Dataset loaded with shape: {df.shape}&#8221;)
    return df


@task
def train_model(df: pd.DataFrame):
    X = df.drop(columns=[&#8221;target&#8221;])
    y = df[&#8221;target&#8221;]
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    model = LinearRegression()
    model.fit(X_train, y_train)
    preds = model.predict(X_test)
    mse = mean_squared_error(y_test, preds)
    print(f&#8221;Model trained. MSE = {mse:.3f}&#8221;)
    return mse


@task
def evaluate_performance(mse: float):
    if mse &lt; 3000:
        print(f&#8221;Great performance! MSE = {mse:.2f}&#8221;)
    else:
        print(f&#8221;Needs improvement. MSE = {mse:.2f}&#8221;)


@flow(name=&#8221;Intro ML Orchestration Flow&#8221;)
def diabetes_flow():
    df = load_data()
    mse = train_model(df)
    evaluate_performance(mse)


if __name__ == &#8220;__main__&#8221;:
    diabetes_flow()</code></pre><h3>Understanding the Flow</h3><ol><li><p><code>load_data()</code> downloads the diabetes dataset and returns it as a DataFrame.</p></li><li><p><code>train_model()</code> trains a linear regression model and computes Mean Squared Error (MSE).</p></li><li><p><code>if&#8211;else</code><strong> branching</strong> inside the flow checks the MSE:</p><ul><li><p>If the model performs well &#8594; trigger a success notification.</p></li><li><p>Otherwise &#8594; print a retraining message and handle fallback logic.</p></li></ul></li><li><p><code>notify()</code> logs or alerts based on the outcome.</p></li></ol><p>What&#8217;s powerful here is that you can write <strong>plain Python conditions</strong>, and Prefect still manages the orchestration, dependencies, and logging behind the scenes automatically building a <strong>DAG (Directed Acyclic Graph)</strong> of tasks.</p><div><hr></div><h3><em>Prefect vs. Airflow &#8212; The Simplicity Advantage</em></h3><p>Unlike <a href="https://airflow.apache.org/docs/">Airflow</a>, which requires static DAG definitions, special operators, and a complex setup, Prefect lets you orchestrate workflows using pure Python code.<br>No YAMLs, no boilerplate just decorators and logic you already know.</p><p>You can run it locally, visualize it in the Prefect UI, and scale it to production all without changing a single line of code.<br>That&#8217;s why Prefect is often called <em>&#8220;the Airflow you&#8217;d actually enjoy using.&#8221;</em></p><h3>Useful Links</h3><ul><li><p><strong><a href="https://www.prefect.io">Prefect Homepage</a></strong></p></li><li><p><strong><a href="https://docs.prefect.io/latest/getting-started/installation/">Installation Guide &amp; Docs</a></strong></p></li><li><p><strong><a href="https://docs.prefect.io/latest/concepts/flows/">Core Concepts</a></strong></p></li></ul><div><hr></div><p>I hope this gave you a clear idea of how orchestration works and how easy Prefect makes it to build production-ready ML pipelines. I wrote this for beginners who want to move beyond notebooks and start thinking like engineers.</p><p><em>This isn&#8217;t a sponsored post</em> I just stumbled upon Prefect recently and loved how simple it feels.</p><p>If you&#8217;re new here, hit subscribe! I&#8217;ll be sharing more posts on ML, LLMs, MLOps, and career insights that actually make sense in the real world.</p><p>Thanks, see you soon ;)</p><p>Follow me on X: <a href="http://x.com/@kmeanskaran">@kmeanskaran</a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://kmeanskaran.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/kmeanskaran.substack.com/subscribe"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Complete Guide to MLOps: 10 Essential Steps from a Bird’s-Eye View]]></title><description><![CDATA[Learn how to turn a simple ML notebook into a production-ready system with MLOps.]]></description><link>https://kmeanskaran.substack.com/p/complete-guide-to-mlops-10-essential</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/complete-guide-to-mlops-10-essential</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 31 Aug 2025 06:02:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zv0C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>What is MLOps?</h3><p>Everyone knows it is a well-known term in the tech industry. It is often seen as DevOps for machine learning, right? But it is not that straightforward. In this blog, I will explain why you need MLOps for ML projects and how you can design a system using MLOps.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!zv0C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!zv0C!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png 424w, /__u/substackcdn.com/image/fetch/$s_!zv0C!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png 848w, /__u/substackcdn.com/image/fetch/$s_!zv0C!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zv0C!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!zv0C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!zv0C!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png 424w, /__u/substackcdn.com/image/fetch/$s_!zv0C!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png 848w, /__u/substackcdn.com/image/fetch/$s_!zv0C!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zv0C!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c99e0a-ea17-4ed4-8875-e4cd8caa9f6f_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image by Karan Shingde (generated using ChatGPT)</figcaption></figure></div><h3>Why MLOps?</h3><p>We all use Jupyter Notebook or Google Colab to code our machine learning projects. We install the dependencies, import them, write the code, and run it step by step in cells.</p><p>In more ML terms:</p><ol><li><p>Install dependencies or libraries like NumPy, Pandas, and Torch.</p></li><li><p>Import them in the top cells.</p></li><li><p>Import data using Pandas, clean it, apply normalization techniques, and do a train-test split.</p></li><li><p>Import models from Torch or Scikit-learn.</p></li><li><p>Train the model.</p></li><li><p>Evaluate the model and plot a confusion matrix or regression line.</p></li><li><p>Save the notebook and the model, then feel like we know machine learning.</p></li></ol><p>From point 1 to point 6 everything works well, but look at point 7. We save the models in binary files (.pkl, .pth), but these files do not perform any real-time tasks. So how can we say our ML project is complete?</p><p>This is where MLOps comes in. Before moving forward, let me explain. MLOps is a general term, but when you work on a project you usually work with pipelines. A pipeline is a sequence of modules or functions that move data and actions from start to end. So instead of learning MLOps only in general terms, let us dive deeper and understand what a pipeline is for machine learning projects.</p><p></p><h3>Frame the problem statement</h3><p>The first step is to understand the business objective. Ask what the product is expected to achieve. If it is a B2C product that customers will use directly, low latency becomes a priority because users expect fast responses. If it is a B2B product meant to automate business tasks or support decision-making, then accuracy and reliability are more important than speed.</p><p>Next, look at the data. This is where you will find both the problems and the solutions. As a Machine Learning Engineer, I highly recommend learning statistics and feature engineering because they are key to building strong models.</p><p>Once you understand the business expectations and the patterns in the data, you reach the most critical stage of the ML pipeline. At this point, you can start experimenting with state-of-the-art algorithms, unless your company is focused on research. In my practice, if the data is tabular (classification, regression, or even time-series), I usually start with XGBoost. In 2025, XGBoost remains one of the most powerful algorithms for classic ML problems. For text data, you can use BERT or Sentence-BERT, and for text generation you can simply load pre-trained LLMs like Llama, Qwen, and others.</p><p>The approach should be to first explore the data and do simple model training. Then evaluate the model&#8217;s performance and discuss the metrics with your team.</p><blockquote><p>Remember, machine learning metrics matter only to the ML team. The business side cares about numbers and growth. So even if your model shows 90% accuracy with good precision and recall, it means the model is ready for A/B testing, not for direct production.</p></blockquote><p></p><h3>Turning a notebook into pipeline</h3><p>This is where actual MLOps begins. Many beginner ML engineers think machine learning is only about building a model and saving it on their system. In real-world projects, we take the messy notebook code and convert it into a clean, modular Python format.</p><p>Here&#8217;s what you can do:</p><ol><li><p>Break each part of your project into separate pipelines. For example, have one for importing data, another for cleaning data, one for feature engineering, one for splitting the data into train, test, and validation sets, and others for training and evaluation.</p></li><li><p>Write separate Python files for each module, and make sure you have a good understanding of Python modules and object-oriented programming (OOP).</p></li><li><p>Create a main script that runs everything in sequence.</p></li></ol><p>These are some of the most important things to consider before diving into MLOps.</p><p></p><h3>Complete MLOps cycle</h3><p>Here&#8217;s the 10 essential steps of MLOps lifecycle&#128071;</p><p><strong>1. Problem Definition &amp; Data Collection: </strong>Every ML project starts with a clear goal, like predicting sales or detecting fraud. Once the problem is defined, we collect raw data from databases, APIs, sensors, or logs. Data is the foundation, so gathering the right and reliable data is important.<br><strong>Tools:</strong> SQL, MongoDB, Kafka, Google BigQuery, APIs.</p><p><strong>2. Data Cleaning &amp; Preprocessing: </strong>Raw data often has missing values, duplicates, and errors. Cleaning makes it reliable by filling gaps, removing noise, and standardizing formats. Preprocessing also includes normalizing and splitting data into training, validation, and testing sets.<br><strong>Tools:</strong> Pandas, NumPy, PySpark</p><p><strong>3. Data Versioning &amp; Storage: </strong>Data keeps changing over time, so versioning is needed to track changes and ensure reproducibility. Storing processed datasets securely also makes collaboration easier. This step avoids confusion between different dataset versions.<br><strong>Tools:</strong> DVC, Git-LFS</p><p><strong>4. Model Development: </strong>Here, data scientists experiment with ML algorithms and architectures. They train models, compare performance, and tune parameters to achieve the best results. This step is like the &#8220;research&#8221; part of MLOps.<br><strong>Tools:</strong> PyTorch, TensorFlow, Scikit-learn, HuggingFace, XGBoost</p><p><strong>5. Experiment Tracking:</strong> Many experiments are run with different settings, so tracking results is necessary. Tracking helps compare metrics, hyperparameters, and outcomes to choose the best model. This avoids confusion and makes research organized.<br><strong>Tools:</strong> MLflow, Weights &amp; Biases, Comet.</p><p><strong>6. Model Validation &amp; Testing: </strong>Before deployment, models must be validated on unseen data to check accuracy, fairness, and robustness. Testing ensures the model is not biased and works well under real-world conditions. This step prevents failures later.<br><strong>Tools:</strong> pytest</p><p><strong>7. Model Packaging &amp; CI/CD: </strong>Once the model is ready, it is packaged into a deployable format (like Docker containers). CI/CD pipelines automate testing, integration, and deployment, reducing manual work. This makes the system reliable and repeatable.<br><strong>Tools:</strong> Docker, GitHub Actions, Jenkins, CircleCI.</p><p><strong>8. Model Deployment: </strong>Models are deployed into production so users or applications can use them. Deployment can be batch (scheduled jobs) or real-time (API-based). Proper scaling is also important to handle many requests.<br><strong>Tools:</strong> FastAPI, Flask, Kubernetes, AWS Sagemaker, GCP Vertex AI.</p><p><strong>9. Monitoring &amp; Logging: </strong>After deployment, models need monitoring to check performance, accuracy, and system health. Logs capture errors and unusual patterns, while monitoring helps detect model drift and data changes. This ensures reliability.<br><strong>Tools:</strong> Prometheus, Grafana, ELK Stack</p><p><strong>10. Continuous Training &amp; Feedback Loop: </strong>Over time, data and user behavior change, so models must be retrained regularly. Continuous training uses new data to keep models updated. Feedback from users also helps improve accuracy and usefulness.<br><strong>Tools:</strong> Airflow, Kubeflow, Prefect, MLflow Pipelines.</p><p></p><h3>Bonus:</h3><p>MLOps is not just about tools. It is more about the practices you follow in your machine learning project to develop, deploy, and monitor systems quickly. As data keeps growing, we need to automate projects at the same pace, and this is where MLOps becomes important. The pipeline shown above is not fixed. It depends on your company and the tools being used.</p><p>If you are a beginner, I highly recommend learning Python modular coding and Docker at the very least. Learning FastAPI is also a great choice, and understanding how system design works in software engineering is essential. Concepts like response models, APIs, and rate limiting are very important for machine learning projects too.</p><p>In applied ML, where MLOps is most relevant, you need to be stronger in software engineering skills than in pure ML.</p><p></p><h3>Sources:</h3><ol><li><p><a href="https://www.amazon.in/Designing-Machine-Learning-Systems-Production-Ready/dp/9355422679">Book: Designing Machine Learning Systems by Chip Huyen </a></p></li><li><p><a href="https://www.youtube.com/watch?v=gqrl4QpfHzo&amp;list=PL_MIDuPM12MOcQQjnLDtWCCCuf1Cv-nWL">Marvelous MLOps Youtube Playlist</a></p></li><li><p><a href="https://t.co/XFzqEsEHwM">YouTube playlist on complete MLOps in Hindi</a></p></li></ol><div><hr></div><p>I am writing more about MLOps, so you can subscribe to my Substack <strong>K-Means Karan</strong> where I plan to share detailed technical content on MLOps. I am also building a project on MLOps for beginners and intermediate engineers.</p><p>Do follow me on Medium for more content. You can also connect with me on <a href="https://www.x.com/kmeanskaran">X</a> and <a href="https://www.linkedin.com/in/karanshingde">LinkedIn</a>, where I share thoughts on ML, MLOps, and my career journey.</p><p>Thanks for reading, share this article, and see you soon!</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://kmeanskaran.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading K-Means Karan! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Freelance, layoff, and remote AI Engineer — My tech journey]]></title><description><![CDATA[Freelance, layoff, and remote AI Engineer &#8212; My tech journey]]></description><link>https://kmeanskaran.substack.com/p/freelance-layoff-and-remote-ai-engineer-my-tech-journey-ea044e179336</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/freelance-layoff-and-remote-ai-engineer-my-tech-journey-ea044e179336</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Mon, 30 Jun 2025 09:36:13 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1866bc8e-84a7-4039-843a-aa6bfdd2a168_891x446.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Freelance, layoff, and remote AI Engineer&#8202;&#8212;&#8202;My tech&nbsp;journey</h3><p>Choosing ML as journey, failed 12 interviews, laid off, freelancing, technical writing, and remote AI lead. Let&#8217;s unzip my&nbsp;journey.</p><h4>Table of&nbsp;Contents</h4><ol><li><p><a href="#9832">Pre Tech&nbsp;Journey</a></p></li><li><p><a href="#e6ac">The First&nbsp;Code</a></p></li><li><p><a href="#b918">Choosing Machine&nbsp;Learning</a></p></li><li><p><a href="#82f4">First Interview for ML&nbsp;Intern</a></p></li><li><p><a href="#2868">First Internship</a></p></li><li><p><a href="#a25e">Unemployment and&nbsp;MLOps</a></p></li><li><p><a href="#8959">Laid off within a&nbsp;Month</a></p></li><li><p><a href="#c7de">Freelance and Build in&nbsp;Public</a></p></li><li><p><a href="#c48a">From Remote Hire to Leading AI&nbsp;Team</a></p></li><li><p><a href="#271c">Takeaways (Don&#8217;t miss&nbsp;this)</a></p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!FDh9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!FDh9!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png 424w, /__u/substackcdn.com/image/fetch/$s_!FDh9!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png 848w, /__u/substackcdn.com/image/fetch/$s_!FDh9!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png 1272w, /__u/substackcdn.com/image/fetch/$s_!FDh9!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!FDh9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/836441fd-8587-403f-9cac-db409a968673_891x446.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!FDh9!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png 424w, /__u/substackcdn.com/image/fetch/$s_!FDh9!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png 848w, /__u/substackcdn.com/image/fetch/$s_!FDh9!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png 1272w, /__u/substackcdn.com/image/fetch/$s_!FDh9!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F836441fd-8587-403f-9cac-db409a968673_891x446.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><h4>Pre Tech&nbsp;Journey</h4><p>In 2019, I appeared for the JEE exam, hoping to get into a B.Tech college, but I didn&#8217;t make the cut. At that point, I had no clue about coding or even how a laptop worked. Still, everyone around me was talking about Computer Engineering, and their excitement pulled me in. I decided to pursue it&nbsp;too.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!ZagA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!ZagA!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!ZagA!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!ZagA!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!ZagA!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!ZagA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!ZagA!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!ZagA!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!ZagA!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!ZagA!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1834de57-f4ec-4d08-a93d-7e57dd5b42ae_1024x315.jpeg 1456w" sizes="100vw"></picture><div></div></div></a><figcaption class="image-caption">My JEE marksheet, which I find embarrassing</figcaption></figure></div><p>I filled out the form for a B.Sc. in Computer Science. Due to late admissions and limited seats, I had to pay a donation fee to get in. Eventually, I got admission into Garware College, under Pune University. It wasn&#8217;t a dream start, but it was a beginning.</p><p>By April 2020, I had learned a bit of C programming and SQL through college lectures. But I struggled and ended up scoring just 8 out of 50 in the programming exam. Then the pandemic hit. Colleges shut down, exams got cancelled, and to my surprise, even students who had failed were promoted.</p><h4>The First&nbsp;Code</h4><p>In July 2020, I bought my first laptop, finally stepping into the world of coding. Until then, during my first year of college, I was learning to code using just pen and paper. I didn&#8217;t even know how to install software, but before the laptop arrived, I had already started learning&nbsp;Python.</p><p>Python quickly became my comfort zone. It&#8217;s still my primary language today. Looking back, I believe it&#8217;s better to stick with one language in the beginning instead of constantly switching. It helps you build depth and confidence.</p><p>With help from a college friend, I set up VS Code and got Python running. From there, I began following the Python playlist by Telusko on YouTube. I genuinely enjoyed coding in Python, but like many beginners, I got distracted. People around me kept saying, &#8220;You need C++ if you want to get a job in IT.&#8221; So I gave in and started learning&nbsp;C++.</p><p>But honestly, I never really clicked with it. Concepts like calloc, malloc, and pointers just didn&#8217;t make sense to me, no matter how many times I tried. Eventually, I went back to&nbsp;Python.</p><p>I began exploring data structures like arrays, stacks, and linked lists in Python. Even though I didn&#8217;t enjoy DSA much, I kept pushing through because of peer pressure. Everyone kept saying it was crucial for getting&nbsp;placed.</p><p>By the end of 2020, I had spent nearly five months learning libraries like Pandas, NumPy, and Matplotlib. I didn&#8217;t even know what machine learning was back then. I was just following Python tutorials and reading documentation on W3Schools, moving step by step with whatever I could&nbsp;find.</p><h4>Choosing Machine&nbsp;Learning</h4><p>One day, I was searching on Google and saw a list of the highest-paying jobs of the 21st century. One job that caught my eye was &#8220;Data Scientist.&#8221; I had heard this word before in a Python video, but now I wanted to learn&nbsp;more.</p><p>I searched for a roadmap to become a data scientist and found something new&#8202;&#8212;&#8202;<em>Machine Learning</em>. It sounded interesting. I started watching beginner videos on YouTube from channels like Great Learning and Intellipaat to understand what it&nbsp;was.</p><p>I began with simple topics like Linear Regression, Logistic Regression, Decision Trees, and K-Means. That&#8217;s also when I created my own online name <strong>k-means karan</strong> (you can follow me on <a href="http://x.com/@kmeanskaran">X</a>). I started using Jupyter Notebook to play with data. I was learning how to clean data, choose features, and train&nbsp;models.</p><p>After a few months, in mid-2021, I found Kaggle a website where you can practice real machine learning problems. I spent a lot of time there, and it helped me understand how to look at data and think about the problem before writing&nbsp;code.</p><p>Here is my GitHub where I share the projects I worked on:<br>&#128309; <a href="https://github.com/karan842/Data-Science-Projects">github.com/karan842/Data-Science-Projects</a></p><p>After learning basic machine learning and some statistics, I wanted to go deeper. I started learning about <em>neural networks</em>. At that time, my math wasn&#8217;t strong, so it took me almost 4 months to understand how they work. Slowly, I learned about different types like ANN, CNN, RNN, and&nbsp;LSTM.</p><p>To learn the basics of statistics, machine learning, and neural networks, I followed <a href="https://www.youtube.com/@krishnaik06">Krish Naik</a>&#8217;s YouTube videos. I also added neural network projects to the same GitHub repository.</p><p>Later, I started reading books on machine learning. Books helped me understand how models actually work inside. I believe reading technical books is a great way to build strong knowledge and improve your&nbsp;skills.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!y977!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!y977!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!y977!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!y977!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!y977!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!y977!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!y977!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!y977!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!y977!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!y977!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee7057c-2282-4d13-83b7-611e09dc4071_1024x952.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Book collection till 2025&nbsp;June</figcaption></figure></div><h4>First interview for ML&nbsp;Intern</h4><p>I still remember when I got my first interview call for a Machine Learning internship in May 2022. I was very excited and prepared for it for a whole week. But once the interview started, I realized how unprepared I actually was. I couldn&#8217;t even speak confidently during the introduction. I was nervous and didn&#8217;t know what to&nbsp;expect.</p><p>The interviewer asked me to share my screen and solve a problem in Python. It was a basic question about checking if two words are anagrams. I only managed to write a simple for loop and couldn&#8217;t figure out the full logic. After that, he started asking more technical questions. He asked about neural networks, XGBoost, CNNs, how inference works, and even Transformers and BERT. I couldn&#8217;t answer most of&nbsp;them.</p><p>Then another person joined the call. She started asking questions about data engineering, databases, OLAP, and OLTP. I had no idea what to&nbsp;say.</p><p>The next night, I received an email from HR with the usual rejection message:</p><p><strong>&#8220;Sorry, we&#8217;re not moving forward at this&nbsp;time.&#8221;</strong></p><p>I felt disappointed and lost a bit of confidence. But instead of giving up, I started preparing again. I used pen and paper to go through machine learning basics and started practicing algorithms using Python. To be honest, I still don&#8217;t enjoy solving problems on LeetCode, but I know it is important for interviews.</p><p>That interview did not go well, but just one week later, I got a message from Internshala.</p><h4>First Internship</h4><p>After a week, I got a call from the CEO of a fintech company based in Pune. He spoke kindly and offered me a position. The surprising part was, he didn&#8217;t ask any technical questions or even check my code. I had just finished my final semester exams of B.Sc. CS, so I accepted the offer and joined the&nbsp;startup.</p><p>The office was around 35 to 40 KMs from my home. I had to take two buses every day to reach there. On my first day, I met a senior, the HR, and the CEO. During our introduction, the CEO told me I would be working on the backend using&nbsp;Django.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!TKy_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!TKy_!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!TKy_!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!TKy_!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!TKy_!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!TKy_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!TKy_!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!TKy_!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!TKy_!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!TKy_!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ff001f-c8e2-405e-b23e-dbce906cb425_1024x355.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">First Paycheck</figcaption></figure></div><p>I was shocked. The role was offered as a Data Science internship, but now I had to work on backend development. I didn&#8217;t know Django and had no interest in backend work. Still, I tried to give my&nbsp;best.</p><p>For the next three months, I struggled a lot. I was not able to perform well, and I knew it. Along with me, three other interns also left the company. Finally, I gathered the courage to call the CEO and told him I wanted to leave. He refused to give me my last month&#8217;s stipend and also did not provide a relieving letter.</p><p>Just four days later, I got another opportunity. I joined quickly because I hadn&#8217;t enrolled for a Master&#8217;s degree and didn&#8217;t want to stay unemployed.</p><p>But this new company turned out to be a scam. I was working in a small room with a single person who called himself the CEO. There were no real projects, no team, and no proper work. On the second day, I left the place. It was a scary and bad experience. Since I never received an offer letter, I had nothing in hand. No salary, no experience, nothing.</p><h4>Unemployment and&nbsp;MLOps</h4><p>After the internship experience, I was unemployed. Most of my friends had either started a new degree or were already working somewhere. That period was very tough for me. My daily routine was boring and repetitive&#8202;&#8212;&#8202;waking up early, going to the gym, updating my resume, and applying for every possible job on LinkedIn, Naukri, and&nbsp;Indeed.</p><p>One day while reading job descriptions, I came across a new word&#8202;&#8212;&#8202;<em>MLOps</em>. I didn&#8217;t know what it meant, so I searched for it on YouTube and started learning. I found a video by Krish Naik about MLOps and began following his content regularly.</p><p>At the same time, I tried applying what I learned. I took one of my Kaggle projects, an NLP-BERT notebook, and converted it into a basic MLOps workflow. It wasn&#8217;t a full MLOps setup, but it was my way of exploring the field step by&nbsp;step.</p><p>Here are the blog posts I wrote during that time:<br>&#128313; <a href="https://medium.com/@karanshingde/design-machine-learning-system-for-nlp-bert-mlops-681a9af59f66">Design ML System for NLP BERT + MLOps</a><br>&#128313; <a href="https://medium.com/@karanshingde/machine-learning-in-production-your-comprehensive-101-practical-guide-c7de0b5ad011">ML in Production: A Practical Beginner&nbsp;Guide</a></p><p>These blogs also include GitHub repositories, so feel free to check them&nbsp;out.</p><p>Those unemployment days were hard, but I promised myself not to waste a single day. I kept learning, kept building. During that phase, I gave around 12 interviews and failed all of them. But I didn&#8217;t&nbsp;stop.</p><p>By January 2023, I was feeling mentally tired. That&#8217;s when I decided to go for my Master&#8217;s degree starting in June. I also made a habit of sharing whatever I was learning on LinkedIn. That habit is still helping me today I now get messages from CEOs and HRs noticing my&nbsp;work.</p><p>I&#8217;ll be sharing more about MLOps strategies and practical ideas in my upcoming blog posts. If you&#8217;re interested, don&#8217;t forget to subscribe to my Medium newsletter.</p><h4>Laid off within a&nbsp;month</h4><p>In February 2023, I finally got another internship offer, and I joined as soon as possible. During the technical interview, I secretly searched the internet for the syntax of some Pandas operations to pass a few test cases. Somehow, I cleared the round and felt excited to work with this new&nbsp;company.</p><p>On March 1, I joined a Zoom call with the India head. That call changed how I saw machine learning completely. During our conversation, I confidently said, &#8220;I&#8217;m a Kaggle notebook master with 5 medals.&#8221; He smiled and replied, &#8220;That&#8217;s toy machine learning. In the real world, you need to work on every part of the pipeline.&#8221; That one line hit me hard and gave me the push I needed to&nbsp;grow.</p><p>On my first day, I was given a CSV file and a task outline. I had to clean and process the data using a Pandas script so it matched the expected output. It looked simple, but I couldn&#8217;t solve it on my own. It took me two weeks, and I still failed to finish it properly. One day, I even went out without informing my manager. Because of that, I received a warning for being unprofessional.</p><p>March went by, and I was still stuck on the same task. It felt impossible. Back then, ChatGPT-3.5-turbo had just launched, and it wasn&#8217;t as helpful as it is today. I couldn&#8217;t upload files or explain my errors well, and I kept going in&nbsp;circles.</p><p>Even though my manager knew I was copying code, he still gave me another chance. He introduced me to a new tool called <strong>LangChain</strong>, which was very new at the time. I enjoyed exploring it, but relying on ChatGPT for coding didn&#8217;t help me much. I needed to understand the logic&nbsp;better.</p><p>Then came April 7, 2023&#8202;&#8212;&#8202;a Friday morning. Around 10 AM, my manager called me. He told me that they were letting me go because of poor performance and lack of sincerity. The next day was my birthday. That Friday afternoon, I cried a lot. It felt like a heavy failure. I couldn&#8217;t believe that since finishing college, I still hadn&#8217;t landed a stable&nbsp;offer.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!a4Jz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!a4Jz!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!a4Jz!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!a4Jz!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!a4Jz!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!a4Jz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!a4Jz!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!a4Jz!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!a4Jz!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!a4Jz!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8683e9f-75c5-43e0-b441-5219ca3f8062_1024x1645.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">The last&nbsp;call</figcaption></figure></div><p>But looking back, that experience was a big lesson. I&#8217;m actually thankful I faced these rejections early in my career. They gave me the strength and confidence to handle bigger challenges later in&nbsp;life.</p><h4>Freelancing and Build in&nbsp;Public</h4><p>Just a week after my last internship ended, I got a call from two of my B.Sc. professors. They were working on their PhD research at Pune University and needed help with technical experiments. That call became my first real opportunity to earn money as a freelancer.</p><p>I started working with both professors at the same time, helping them with different research projects. They shared research papers and GitHub repositories, and my job was to run the code, test different models, and suggest the best technical solutions for their thesis&nbsp;work.</p><p>Until August 2023, I continued working with them. They paid me $150 for each experiment and later gave me $950 for completing the full project. Around the same time, I also worked with a Master&#8217;s student from Mumbai University to build a basic RAG (Retrieval-Augmented Generation) app.</p><p>In August, something unexpected happened. I received a message from the founder of one of Pune&#8217;s biggest data science companies. He was planning to build an AI startup and wanted to discuss the idea with me. I met him and his business partner, and we had a good conversation. But the very next day, I received another offer&#8202;&#8212;&#8202;a contract-based ML Engineer role at a small startup. Because I needed money urgently, I chose to join the startup and had to decline the AI startup&nbsp;offer.</p><p>Well, that&#8217;s life. You don&#8217;t always get to choose&nbsp;both.</p><p>The startup I joined turned out to be a blessing. I learned more than I could ever measure from MLOps on real-estate datasets with millions of entries to research work and neural networks. I was their youngest team member, and the CEO and his wife, who ran the company together, had over 30 years of experience in tech and AI, mostly in the US. They treated me like family and taught me lessons that felt more like guidance from a father&nbsp;figure.</p><p>At the same time, I had enrolled in a Master&#8217;s degree in Computer Science at the same college where I did my B.Sc. One of my freelance clients was a professor there, and with his help, I got admission in the last round without much&nbsp;effort.</p><p>Life became very busy. I was managing both college and office, changing buses every day, walking long distances, and still coding in the evenings. But that was a golden period for me. I was learning everything I had once only dreamed of&#8202;&#8212;&#8202;and that phase truly shaped my&nbsp;future.</p><p>I also continued sharing my journey on LinkedIn. That habit helped me get freelance projects and job opportunities. Later, I started writing on Twitter, which opened new doors in consulting and technical writing.</p><p>In December 2023, I got my first paid freelance project to write technical content about Generative AI and LLMs. You can find those articles in my previous Medium publications. I&#8217;ve realized I&#8217;m pretty good at technical writing and I hope you&#8217;re enjoying this story as much as I enjoy telling&nbsp;it.</p><h4>From Remote Hire to Leading AI&nbsp;Team</h4><p>In April 2024, I received an offer for a Junior Machine Learning role from a Canadian startup. I accepted it without thinking twice. At that time, I had just one year left to complete my M.Sc. in Computer Science. The job was fully remote and offered better pay than both my previous contract-based work and freelance writing combined. So, I&nbsp;joined.</p><p>Working remotely turned out to be a turning point in my career. I learned much more than just machine learning. I got hands-on experience with distributed training, reinforcement learning, and many other advanced topics. As time passed, I started picking up skills beyond coding&#8202;&#8212;&#8202;project management, task ownership, and even leading a remote team of engineers.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!vk2K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!vk2K!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!vk2K!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!vk2K!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!vk2K!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!vk2K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!vk2K!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!vk2K!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!vk2K!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!vk2K!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F869ac431-18ed-4a92-9345-763dd11685b7_768x1024.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Public Relation&nbsp;Days</figcaption></figure></div><p>That part changed everything. Being able to work remotely and still lead a team made me more confident and trustworthy in the eyes of other employers and CEOs. Today, I&#8217;m proudly leading a team of AI engineers&#8202;&#8212;&#8202;all remotely.</p><p>Over the months, I also developed strong problem-solving skills. I started solving real-time business problems using ML, not just toy datasets. In September 2023, I traveled to Delhi for a Hackathon at Mastercard&#8217;s office. The trip was sponsored by my company, and it was a great chance to meet fellow developers. Since then, I&#8217;ve been attending AI/ML meetups regularly in Pune and Bengaluru to learn, connect, and&nbsp;grow.</p><p>Now, I finally have a stable job and income. But life has brought me new challenges at a different level. I often share these experiences on my <a href="https://x.com/kmeanskaran">Twitter</a> so others can learn from them too. Remote work comes with its own set of struggles and excitement. I&#8217;ll write about that in a separate blog sometime&nbsp;soon.</p><p>Right now, I&#8217;m focusing on writing more technical blogs around Machine Learning, MLOps, and topics like Federated Learning. So stay tuned if you&#8217;re curious about what&#8217;s&nbsp;next.</p><h3>Takeaways (Don&#8217;t Miss&nbsp;This)</h3><p>Here are some of the key lessons I&#8217;ve learned along the way. If you&#8217;re just starting out, these might help guide your&nbsp;journey:</p><h4>1. Machine&nbsp;Learning</h4><ul><li><p>Don&#8217;t just stick to Jupyter Notebooks or Google Colab. Try to build complete ML pipelines from start to finish. Learn how to deploy your models and make them useful in the real&nbsp;world.</p></li><li><p>Good data leads to better results. Spend more time collecting quality data and doing feature engineering instead of chasing complex or fancy models. (These days, LLM research feels like a leaderboard race, but basics still&nbsp;matter.)</p></li><li><p>Focus on learning statistics, math, the basics of machine learning, deep learning, and transformers. These are the foundations that will stay relevant, even when today&#8217;s SOTA (state-of-the-art) models are replaced tomorrow.</p></li></ul><h4>2. Career</h4><ul><li><p>Don&#8217;t just dream about a job title or a big company. Dream about the kind of work you actually want to do. That makes all the difference.</p></li><li><p>You can have 1000 strong skills, but if you don&#8217;t share them online, nobody will know. Build your presence, talk about your work or you&#8217;ll miss real&nbsp;chances.</p></li><li><p>CEOs are interesting people. If you&#8217;re ambitious, they&#8217;ll notice it and share real startup stories and life lessons that you won&#8217;t hear anywhere&nbsp;else.</p></li><li><p>Stay healthy. If you don&#8217;t take care of your body, your confidence will drop. And in today&#8217;s world, people do respect those who look and feel&nbsp;active.</p></li><li><p>Learn how to communicate well. Build your storytelling skills. Honestly, this is even more powerful than machine learning skills. The way you explain your journey, ideas, and impact can open more doors than any algorithm.</p></li></ul><p>Thanks for reading my journey. I hope it didn&#8217;t feel boring because every line here comes from real struggle, learning, and&nbsp;growth.</p><p>I&#8217;ll be writing more technical blogs soon on topics like Machine Learning, MLOps, and real-world projects. If you&#8217;re interested in those, stay&nbsp;tuned.</p><p>Let&#8217;s connect on Twitter (X), where I regularly share my learnings, experiments, and experiences: <a href="https://x.com/kmeanskaran">@kmeanskaran</a></p><p>Also, feel free to visit <a href="https://karanshingde.vercel.app/">my website</a> if you want to know more about my work in detail. I&#8217;m always open to collaborations, feedback, and conversations.</p><div><hr></div><p><a href="https://levelup.gitconnected.com/freelance-layoff-and-remote-ai-engineer-my-tech-journey-ea044e179336">Freelance, layoff, and remote AI Engineer&#8202;&#8212;&#8202;My tech journey</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Every AI Engineer should learn Next JS.]]></title><description><![CDATA[I Earned $150 Building an SEO Landing Page in 4 Days &#8212; And It&#8217;s More Than That: Create UIs Fast with AI]]></description><link>https://kmeanskaran.substack.com/p/every-ai-engineer-should-learn-next-js-554f634a5f47</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/every-ai-engineer-should-learn-next-js-554f634a5f47</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sun, 09 Mar 2025 07:52:20 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ef83ac17-a6eb-456c-8d4a-3c8568f2136f_1024x559.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>I Earned $150 Building an SEO Landing Page in 4 Days&#8202;&#8212;&#8202;And It&#8217;s More Than That: Create UIs Fast with&nbsp;AI</h4><blockquote><p>&#8220;Nobody cares your AI model or architecture if your UI is ugly.&#8202;&#8212;&#8202;Unknown&#8221;</p></blockquote><p><strong>Disclaimer:</strong> This blog reflects my personal experience and isn&#8217;t a guarantee that this approach will work for everyone. It&#8217;s not a Next.js tutorial or a guide on how to learn Next.js. Instead, it&#8217;s about why Next.js is a valuable secondary skill for freelancing and how it can set you apart from other AI engineers by enabling you to build full-stack applications with practice. Note that, I already have an idea about React&nbsp;JS.</p><blockquote><p>Client&#8217;s website: <a href="https://www.shreeshotblasting.com/">https://www.shreeshotblasting.com/</a></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!wOTq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!wOTq!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png 424w, /__u/substackcdn.com/image/fetch/$s_!wOTq!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png 848w, /__u/substackcdn.com/image/fetch/$s_!wOTq!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png 1272w, /__u/substackcdn.com/image/fetch/$s_!wOTq!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!wOTq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!wOTq!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png 424w, /__u/substackcdn.com/image/fetch/$s_!wOTq!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png 848w, /__u/substackcdn.com/image/fetch/$s_!wOTq!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png 1272w, /__u/substackcdn.com/image/fetch/$s_!wOTq!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc214dbd3-cf7c-431c-b38c-2f5f35cfb251_1024x559.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Iconic handshake</figcaption></figure></div><h3>Introduction</h3><p>When we say, &#8220;I am an AI/ML Engineer,&#8221; it usually means we&#8217;re backend engineers who work on AI models. Yes, that&#8217;s our role in the real application system. Let&#8217;s be honest: most AI engineers don&#8217;t like frontend development, and I used to be one of them. For four years of my coding journey, I only focused on AI and Machine Learning. It felt rewarding, but after getting a job and some expertise in one area, I saw the value in exploring other tech skills too. For AI Engineers (or ML Engineers&#8202;&#8212;&#8202;the terms are often the same), learning frontend development can be really worthwhile. In this article, I&#8217;ll show you how to learn frontend development from the view of a Python fan and an AI engineer who thinks frontend is actually pretty&nbsp;simple.</p><h3>Why Next&nbsp;JS?</h3><p>Streamlit might look like a toy project for quick prototypes, but if you&#8217;re serious about building quality, stand-out UI applications, it&#8217;s time to learn a real-world UI framework like <strong><a href="https://nextjs.org/">Next.js</a></strong>. So, why is Next.js the best framework out there? It&#8217;s special because it takes the power of <strong><a href="https://react.dev/">React.js</a></strong> is a popular library for building dynamic user interfaces and supercharges it with features like server-side rendering (SSR), static site generation (SSG), and a built-in routing system, all out of the&nbsp;box.</p><p>Unlike React.js, which is just a library focused on the view layer, Next.js is a full-fledged framework that simplifies development by handling optimizations, SEO, and performance without requiring you to stitch together countless third-party tools.</p><p>You might wonder: if React.js exists, why bother with Next.js? The answer is simple&#8202;&#8212;&#8202;React.js gives you a blank canvas, but Next.js provides a structured masterpiece, saving you time and effort while delivering faster, more scalable applications. It&#8217;s the difference between assembling a car from scratch and driving one off the lot, tuned for speed and reliability. That&#8217;s why Next.js stands out as the go-to choice for modern developers.</p><h3>Where to&nbsp;Start?</h3><p>I know most AI developers hate working on the frontend! We can easily understand complex things like the transformers architecture&#8202;&#8212;&#8202;some of us can even build it from scratch&#8202;&#8212;&#8202;but we still think HTML and CSS are the hardest and most boring parts (especially CSS). I&#8217;ll admit, even now, I don&#8217;t enjoy learning CSS properties. But thanks to tools like ChatGPT, Claude, and others, writing CSS scripts has become much&nbsp;easier.</p><p>Nowadays, you don&#8217;t need to learn everything from top to bottom. Just get a basic idea of how an application works. Spend 3&#8211;4 hours this upcoming weekend and watch a simple video. HTML and CSS might feel boring at first, but once you start learning a language like JavaScript (JS), you&#8217;ll love working with it. It&#8217;s nothing like a Python script&#8202;&#8212;&#8202;it&#8217;s exciting and&nbsp;fun!</p><blockquote><p>You know what is common between JavaScript and Python&nbsp;devs?</p></blockquote><blockquote><p>Both hates&nbsp;Java&#128541;.</p></blockquote><p>Learning JavaScript is one of the best investments you can make right now&#8202;&#8212;&#8202;it&#8217;s like investing in gold! The whole internet runs on JavaScript. You can read a simple document <em><a href="https://javascript.info/">(click here)</a> </em>to learn about JS syntax and everything you want to know. I think using AI tools is a better way to learn any language instead of spending hours watching YouTube videos or reading long documentation.</p><p>So, after spending two weekends learning HTML, CSS, and JS, it&#8217;s time to dive into the best JS library out there: React.js! React.js is where you should really focus your learning efforts. To get started with React.js, I <a href="https://youtu.be/G6D9cBaLViA?si=wzMYw0m6LEiP5VCA">recommend watching this video</a>. Try building 2&#8211;3 small projects that go from basic to advanced concepts in React.js. Your goal is simple: understand how things work and how to connect the dots to create a full AI app. Once you finish this step, it&#8217;s time to move on to&nbsp;Next.js!</p><h3>Next JS Ecosystem</h3><p>After learning JavaScript, spend a day or less on TypeScript (TS), a superset of JS with added typing. Grasp its basics like types and interfaces in a few hours. Then, explore Tailwind CSS, a utility-first framework for efficient styling, and check out ShadCN UI for customizable UI components built on Tailwind. This gives you a quick, solid start in TS and modern front-end tools.</p><ul><li><p><a href="https://youtu.be/ahCwqrYpIuM?si=6bG0OXxNhlcFwUeP">TypeScript</a></p></li><li><p><a href="https://youtu.be/DenUCuq4G04?si=oVSwmlOt1Lm1YX46">TailwindCSS</a></p></li><li><p><a href="https://youtu.be/AqmMx_JidGo?si=8UIN2LNVfRGW_s8O">Shadcn/UI</a></p></li></ul><p>You don&#8217;t need to master everything&#8202;&#8212;&#8202;just aim to understand what TypeScript, Tailwind CSS, and ShadCN UI are and how they function. Your goal is to integrate them with&nbsp;Next.js.</p><p>Now, it&#8217;s time to dive into Next.js, a powerful framework! Start with this simple tutorial <a href="https://youtu.be/cuzw4vL1z5E?si=P5gKVy36fWxUywHw">(click here)</a> to explore its features, like app-based routing, and learn the difference between pages and layouts. This will give you a clear idea of Next.js and its related libraries.</p><p>The real fun begins here: leverage AI to handle coding and debugging with prompts, saving you hours of&nbsp;effort!</p><h3>Magic of&nbsp;V0</h3><p>Vercel has recently launched <strong><a href="https://v0.dev/">v0</a></strong>, a revolutionary UI engine that generates user interfaces using Next.js based on simple user prompts. This tool is a game-changer, saving developers countless hours by eliminating the need to build projects from scratch. Even with the free tier, users get a generous number of prompt requests, sufficient to create basic structures, sections, pages, and responsive navigation bars. v0 generates TypeScript files (.tsx) that leverage shadcn and Tailwind CSS, allowing developers to focus on understanding functionality rather than wrestling with syntax. Once your project is ready, you can easily clone it locally with a single npm command&#8202;&#8212;&#8202;details for which can be found via ChatGPT&#8217;s search mode or Vercel&#8217;s official documentation.</p><h3>$150 Story</h3><p>One of my family friends recently approached me about establishing an online presence and needed a website built. At the same time, my gym membership renewal was looming, and I had to manage my finances to cover it. I promised them I&#8217;d deliver a fully functional website within four days. Coincidentally, I was learning Next.js at the time and had just come across Vercel&#8217;s v0 UI engine through a post on X. Intrigued, I opened my laptop, switched off my phone, and dove straight into the&nbsp;task.</p><p>On the first day, I used v0 to create the basic structure of the website. I experimented heavily with prompts to design the layout and components, which saved me a ton of time. By the second and third days, I cloned the project locally from Vercel using a simple command and opened ChatGPT in another tab for additional support. From there, it was a breeze. I rebuilt individual components like Home, About, Industries, and Contact, then populated them with the company data provided by my client. I even synced the contact form with their Gmail account. Hosting the site on Vercel was seamless. Vercel&#8217;s CI/CD pipeline automatically built the Next.js app with every new commit to the&nbsp;branch.</p><p>After hosting, I shared the live site with my client for feedback. They suggested a few tweaks, which I quickly implemented. On the final day, they provided me with their domain name and GoDaddy login credentials. I spent two hours researching how SEO works with Next.js, then added a sitemap.xml file to ensure Google could crawl the site. After linking the hostname, the website went live in just 20&nbsp;minutes.</p><p>In the end, they paid me $150 enough to renew my gym membership. While this was far below market rates, I offered them lifetime website updates, Google Business setup, and ongoing maintenance as part of the deal. In just four days, I leveraged AI tools like v0 and ChatGPT to deliver a professional, fully functional website for my client. This experience showed me the power of modern tools to streamline development and turn a tight deadline into a success&nbsp;story.</p><h3>More in Next&nbsp;JS</h3><p>Next.js offers an impressive array of functionalities, far beyond what I initially tapped into. So far, I&#8217;ve only used it to create a business landing page, but I&#8217;m now diving deeper into its potential for building AI-driven applications or platforms. My goal is to integrate my FastAPI backend which powers AI functionalities with a Next.js frontend to create a seamless user interface. Next.js even comes equipped with tools like NextAuth.js for authentication, making it a versatile choice for full-stack development. As I explore these capabilities, I&#8217;m excited to see how Next.js can bridge my AI backend with a dynamic, user-friendly frontend.</p><blockquote><p>If you&#8217;re using Figma, you can simply upload your Figma file to Vercel&#8217;s v0 platform, and it will generate a UI for you automatically. This integration streamlines the process, turning your designs into functional interfaces with minimal&nbsp;effort.</p></blockquote><h3>Final Thoughts</h3><p>As an AI engineer focused on training machine learning models and building multi-agent applications, I&#8217;ve come to appreciate the value of a clean, functional UI. Beyond my own projects, I&#8217;ve realized I can support small businesses by creating SEO-optimized landing pages to boost their online growth. While AI and ML remain my primary passions, Next.js has become a powerful secondary skill. I no longer spend hours coding from scratch instead, I leverage existing AI tools to generate websites in mere minutes. In the world of AI, nothing feels out of reach; it all boils down to your interest and commitment. My advice? Don&#8217;t confine yourself to a single tech stack embrace the flexibility to explore and&nbsp;adapt.</p><p>Explore new technologies and remember:</p><blockquote><p>Focus on understanding the workflow and identifying where it&#8217;s needed&#8202;&#8212;&#8202;not on memorizing syntax.</p></blockquote><p>I hope you enjoyed this blog! It&#8217;s my first time sharing a story from my tech career, and I&#8217;m excited to kick things off this way. Moving forward, I plan to write more about my experiences in tech, offering insights to help others figure out where to start&#8202;&#8212;&#8202;and, more importantly, how to finish their work efficiently. That&#8217;s all for today! If you have any questions or feedback, feel free to let me&nbsp;know.</p><p>Connect me&nbsp;on,</p><p><em><a href="http://linkedin.com/in/karanshingde/">LinkedIn</a></em> and <em><a href="http://x.com/@kmeanskaran">X</a>.</em> Also check out <strong><a href="http://karanshingde.vercel.app">MY WEBSITE</a></strong> which again I built using&nbsp;V0.</p><p>See you&nbsp;soon&#128075;!</p><div><hr></div><p><a href="https://levelup.gitconnected.com/every-ai-engineer-should-learn-next-js-554f634a5f47">Every AI Engineer should learn Next JS.</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Boost ML Projects: Switch from PIP to UV]]></title><description><![CDATA[In the evolving landscape of Python development, Astral has introduced UV, a cutting-edge Python package manager designed to revolutionize dependency management.]]></description><link>https://kmeanskaran.substack.com/p/boost-ml-projects-switch-from-pip-to-uv-14c4bdb04bb2</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/boost-ml-projects-switch-from-pip-to-uv-14c4bdb04bb2</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Tue, 07 Jan 2025 18:30:38 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/98941a46-05b9-4e46-9970-fece7a78c9f6_1024x363.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the evolving landscape of Python development, Astral has introduced <strong><a href="https://docs.astral.sh/uv/">UV</a></strong>, a cutting-edge Python package manager designed to revolutionize dependency management. Built on the robust foundation of Rust, UV delivers unparalleled speed and efficiency, significantly outperforming the traditional PIP in installing dependencies within your environment.</p><p>In this article, I&#8217;ll show you how to optimize your Python environment, especially for machine learning projects, using <strong>UV</strong>, the next-generation package manager. Managing dependencies in ML projects can often feel like a daunting task. We&#8217;ll also explore how to install <strong>CUDA</strong>-accelerated PyTorch in a virtual environment (uv) and run it seamlessly within a <em>Dockerfile</em>. Issues such as broken packages, version mismatches, and slow installations can significantly hinder your productivity during project development.</p><p>But don&#8217;t worry! We&#8217;ll explore how <strong>UV</strong> addresses these common challenges, ensuring faster, more reliable package management to keep your focus on building and innovating.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!2BKM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!2BKM!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!2BKM!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!2BKM!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!2BKM!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!2BKM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!2BKM!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!2BKM!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!2BKM!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!2BKM!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dd320d-d7b6-41f1-b591-23dd7d97ba96_1024x363.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">UV speed compared to&nbsp;other</figcaption></figure></div><h4>Installing UV</h4><p>This tutorial is based on my experience with <strong>Ubuntu 22.04</strong>, and it should work as of today. For the latest information and updates, please refer to the official documentation of Astral&nbsp;UV.</p><p>For macOS and&nbsp;Linux:</p><pre><code>curl -LsSf https://astral.sh/uv/install.sh | sh</code></pre><p>For Windows:</p><pre><code>powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"</code></pre><p>You can also use `pip` to install&nbsp;UV!!</p><pre><code>pip install uv</code></pre><p><em>(Ironically, the only time <strong>PIP</strong> is still useful is to install <strong>UV</strong>! Once set up, UV takes over, speeding up your package management for <strong>python </strong>projects.)</em></p><p>After installing uv, you can check that uv is available by running the uv&nbsp;command:</p><pre><code>uv</code></pre><p>You should see a help menu listing the available commands.</p><h4>Set up environment</h4><p>Once you&#8217;ve completed the basic UV installation, you can easily specify the Python version for your project. Unlike traditional PIP, UV allows you to streamline this process without extra tools or steps. In contrast, PIP doesn&#8217;t support direct installation of newer Python versions using a simple command. (If you know a workaround for this, feel free to share it in the comments&nbsp;below!)</p><p>By running,</p><pre><code>uv python install 3.12</code></pre><p>You can easily install Python 3.12 or even set up multiple Python versions for development. Simply run the following command:</p><pre><code>uv python install 3.11 3.12</code></pre><p>This command installs both Python versions on your system, allowing you to seamlessly switch between them for development. To see all present Python versions in your&nbsp;system:</p><pre><code>uv python list</code></pre><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!O14j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!O14j!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png 424w, /__u/substackcdn.com/image/fetch/$s_!O14j!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png 848w, /__u/substackcdn.com/image/fetch/$s_!O14j!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png 1272w, /__u/substackcdn.com/image/fetch/$s_!O14j!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!O14j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!O14j!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png 424w, /__u/substackcdn.com/image/fetch/$s_!O14j!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png 848w, /__u/substackcdn.com/image/fetch/$s_!O14j!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png 1272w, /__u/substackcdn.com/image/fetch/$s_!O14j!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a339bf5-7ce8-4548-858f-3270c5745e2b_1024x337.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Python versions from uv and my&nbsp;system</figcaption></figure></div><p>Now let's initialize the project and environment.</p><pre><code>uv init uv-sample</code></pre><p>The above command initializes the UV environment for your project, with <strong>&#8216;uv-sample&#8217;</strong> as the project name. Once executed, it generates several files within the project directory. But before exploring those files, let&#8217;s quickly set up a Python environment within the <strong>&#8216;uv-sample&#8217;</strong> directory.</p><pre><code>uv venv</code></pre><p>After creating the&nbsp;.venv environment in your project folder, it&#8217;s time to explore the files inside the directory.</p><h4>What UV offers&nbsp;you?</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!KLKD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!KLKD!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png 424w, /__u/substackcdn.com/image/fetch/$s_!KLKD!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png 848w, /__u/substackcdn.com/image/fetch/$s_!KLKD!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KLKD!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!KLKD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!KLKD!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png 424w, /__u/substackcdn.com/image/fetch/$s_!KLKD!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png 848w, /__u/substackcdn.com/image/fetch/$s_!KLKD!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KLKD!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e4032d5-b9d1-4d96-afdf-80ac800ceaa6_337x469.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Folder structure of&nbsp;UV</figcaption></figure></div><p>You&#8217;ll notice some familiar files like&nbsp;<strong>.gitignore</strong> and <strong>README.md</strong> (I&#8217;m sure you&#8217;re already familiar with their purpose!). Additionally, there are other files that are both intriguing and serve as the backbone of the UV environment, making it more efficient and&nbsp;faster.</p><ul><li><p>.python-version shows the current Python version of the project environment.</p></li><li><p>pyproject.toml file is a configuration file in Python projects that defines project metadata, dependencies, and build system requirements, ensuring streamlined project setup and compatibility.</p></li><li><p>The uv.lockfile records the exact versions of all dependencies in your project, ensuring consistent and reproducible environments across different setups. You will see this file after installing dependencies.</p></li></ul><h4>Install dependencies</h4><p>Let&#8217;s install some of the Python packages, libraries, or frameworks. For that, simply run the below command by defining their&nbsp;names.</p><pre><code>uv add fastapi uvicorn groq langchain-groq numpy requests</code></pre><p>The main reason to use UV over pip is its parallelism. UV installs all the required components simultaneously, significantly speeding up the installation process while reducing the likelihood of conflicts.</p><p>After installing these packages, you can find them in pyproject.toml&nbsp;.</p><pre><code>[project]
name = "uv-sample"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = "&gt;=3.12"
dependencies = [
    "fastapi&gt;=0.115.6",
    "groq&gt;=0.13.1",
    "langchain-groq&gt;=0.2.2",
    "numpy&gt;=2.2.1",
    "requests&gt;=2.32.3",
    "uvicorn&gt;=0.34.0",
]</code></pre><h4>Running Python&nbsp;file</h4><p>After running the&#8291; uv init &lt;project-name&gt; command, you will notice a hello.py file created by UV. As of today, this file contains some predefined content.</p><pre><code>def main():
    print("Hello from uv-sample!")


if __name__ == "__main__":
    main()</code></pre><p>Since the Python virtual environment is already activated, you can run the script using python hello.py. However, there's another way to execute the Python file using&nbsp;UV.</p><pre><code>uv run hello.py </code></pre><p>These are some basic setup steps for UV. For more detailed information, please refer to their <a href="https://docs.astral.sh/uv/">official documentation</a>.</p><h4>Create an&nbsp;API</h4><p>Now, let&#8217;s create a simple FastAPI application that takes a user query and generates a response using the <a href="https://console.groq.com/keys">Groq&nbsp;API</a>.</p><p>(I renamed hello.py to app.py&nbsp;)</p><pre><code>from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from langchain_groq import ChatGroq
import os 
import uvicorn

# Initialize FastAPI
app = FastAPI()

# Initialize ChatGroq LLM
llm = ChatGroq(
    model="mixtral-8x7b-32768",
    api_key='YOUR API KEY',
    temperature=0,
    max_tokens=None,
    timeout=None,
    max_retries=2,
    # Add additional parameters if necessary
)

# Define request schema
class ChatRequest(BaseModel):
    human_message: str

# Define response schema
class ChatResponse(BaseModel):
    response: str

@app.post("/chat", response_model=ChatResponse)
async def chat_endpoint(request: ChatRequest):
    """
    Handle user input and get a response from ChatGroq.
    """
    try:
        # Prepare messages
        messages = [
            (
                "system",
                "You are a helpful assistant. Response general questions from users.",
            ),
            ("human", request.human_message),
        ]
        
        # Call ChatGroq LLM
        ai_msg = llm.invoke(messages)
        
        # Return response
        return ChatResponse(response=ai_msg.content)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == '__main__':
    uvicorn.run(app, host="0.0.0.0", port=5500)</code></pre><p>To run the above code: open terminal, activate&nbsp;.venv and execute this&nbsp;command:</p><pre><code>uv run app.py</code></pre><p>You will see in the terminal that FastAPI is running on the server. Open a new terminal window and run the following command to&nbsp;test:</p><pre><code>curl -X POST \
  'http://0.0.0.0:5500/chat' \
  -H 'Content-Type: application/json' \
  -d '{
    "human_message": "Hello, how are you?"
  }'</code></pre><pre><code>{"response":"Hello! I'm an artificial intelligence and don't have feelings, but I'm here to help you. How can I assist you today? Is there a specific question you have in mind?"}</code></pre><p>That's how you can simply run the Python&nbsp;file.</p><h4>Create Dockerfile for&nbsp;UV</h4><pre><code>FROM python:3.12-slim-bookworm

# The installer requires curl (and certificates) to download the release archive
RUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends curl ca-certificates

# Download the latest installer
ADD https://astral.sh/uv/install.sh /uv-installer.sh

# Run the installer then remove it
RUN sh /uv-installer.sh &amp;&amp; rm /uv-installer.sh

# Ensure the installed binary is on the `PATH`
ENV PATH="/root/.local/bin/:$PATH"

# Copy the project into the image
ADD . /app

# Sync the project into a new environment, using the frozen lockfile
WORKDIR /app
RUN uv sync --frozen

# Export PORT
EXPOSE 5500

# Run file
CMD ["uv", "run", "app.py"]</code></pre><p>In the Dockerfile above, I use a basic template for a Python application and manually install uv using commands. This approach offers greater flexibility for future integrations and reduces potential conflicts. Alternatively, you can use the python-uv Docker image. For more information on this, refer to their Docker installation guide.</p><h4>Install PyTorch with&nbsp;CUDA</h4><p>If your operating system is GPU-accelerated or you have already installed CUDA on your system, you can simply install PyTorch. Let&#8217;s proceed with&nbsp;that.</p><pre><code>uv add torch torchvision</code></pre><p>By running this command, you can install PyTorch and its related packages. The real advantage, however, is that uv enables parallel downloading, which speeds up the installation process and automatically resolves package dependencies. See this screenshot:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!VGhA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!VGhA!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png 424w, /__u/substackcdn.com/image/fetch/$s_!VGhA!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png 848w, /__u/substackcdn.com/image/fetch/$s_!VGhA!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png 1272w, /__u/substackcdn.com/image/fetch/$s_!VGhA!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!VGhA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!VGhA!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png 424w, /__u/substackcdn.com/image/fetch/$s_!VGhA!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png 848w, /__u/substackcdn.com/image/fetch/$s_!VGhA!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png 1272w, /__u/substackcdn.com/image/fetch/$s_!VGhA!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e5f7672-cd0a-4be6-b01e-1b4bdef159a7_1024x373.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Parallel installation in&nbsp;uv</figcaption></figure></div><blockquote><p>Note: Installation pace depends on your internet&nbsp;speed.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!FT1X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!FT1X!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png 424w, /__u/substackcdn.com/image/fetch/$s_!FT1X!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png 848w, /__u/substackcdn.com/image/fetch/$s_!FT1X!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png 1272w, /__u/substackcdn.com/image/fetch/$s_!FT1X!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!FT1X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!FT1X!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png 424w, /__u/substackcdn.com/image/fetch/$s_!FT1X!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png 848w, /__u/substackcdn.com/image/fetch/$s_!FT1X!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png 1272w, /__u/substackcdn.com/image/fetch/$s_!FT1X!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F322f1f2f-9d21-4b36-ac76-e68a86a2882d_830x659.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">After installing torch and torchvision</figcaption></figure></div><p>On my device, the installation took around<em> 5 minutes</em>. You can try the same using pip install torch torchvision and compare the installation speed and conflict resolution capabilities of both&nbsp;methods.</p><p>After the installation, you can check the pyproject.toml file for the updated dependencies:</p><pre><code>[project]
name = "uv-sample"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = "&gt;=3.12"
dependencies = [
    "fastapi&gt;=0.115.6",
    "groq&gt;=0.13.1",
    "langchain-groq&gt;=0.2.2",
    "numpy&gt;=2.2.1",
    "requests&gt;=2.32.3",
    "torch&gt;=2.5.1",
    "torchvision&gt;=0.20.1",
    "uvicorn&gt;=0.34.0",
]</code></pre><h4>Magic of&nbsp;uv-sync</h4><p>The&#8291;uv sync command is my favorite feature of uv. In traditional Python projects, we typically create a requirements.txt file and list dependencies one by one, sometimes specifying versions. After pulling or cloning a repository from version control (e.g., GitHub, GitLab), installing dependencies can be a tedious process. It often involves version mismatches, differing Python package versions, or incompatible pip versions.</p><p>I&#8217;ve encountered these issues many times in production. Python projects, especially those involving ML packages like transformers, torch, tensorflow, pillow, and others, often require multiple sub-dependencies. When&#8291; pip attempts to install newer versions, it may uninstall older ones, leading to conflicts or broken package&nbsp;errors.</p><p>In such cases, uv is the perfect solution. If your source code is set up with uv, you simply need to create a virtual environment and run uv sync. This will quickly download all the dependencies, ensuring a smoother and conflict-free installation process.</p><h4>Final Thoughts</h4><p>I use uv in my latest ML projects, and it has significantly simplified my workflow. It allows me to focus more on the project itself rather than dealing with complex setup processes. I encourage you to try both the traditional pip method and the uv method, then decide which one suits your preferences better.</p><p>Remember, software engineering is a gray field&#8212;sometimes things work perfectly, and other times they don&#8217;t. While uv is a powerful tool, there might still be some cons or limitations you could encounter. For more details and updates, check their<a href="https://docs.astral.sh/uv/"> official website</a> or <a href="https://github.com/astral-sh/uv">GitHub repository</a> for the latest improvements.</p><p>That&#8217;s all for today! This year (2025), I&#8217;m planning to write more engaging blog posts&#8212;not just on Python, LLMs, and MLOps, but also on broader tech explorations from my learning journey. Don&#8217;t forget to check out my new Substack newsletter, <em><strong><a href="/__u/kmeanskaran.substack.com/">K-Means&nbsp;Karan</a></strong></em>.</p><p>If you enjoyed this blog, I&#8217;d love to hear your feedback in the comments. Give it an upvote and connect with me on <strong><a href="https://www.linkedin.com/in/karanshingde/">LinkedIn</a></strong><a href="https://www.linkedin.com/in/karanshingde/"> </a>or <strong><a href="https://x.com/kmeanskaran">X</a></strong>. Let&#8217;s grow and learn together!</p><div><hr></div><p><a href="https://levelup.gitconnected.com/boost-ml-projects-switch-from-pip-to-uv-14c4bdb04bb2">Boost ML Projects: Switch from PIP to UV</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Fine-Tuning Sentence Transformers for Embedding Search]]></title><description><![CDATA[Discover how to fine-tune and train a Sentence Transformers model for sentence similarity search by harnessing the power of vector embeddings.]]></description><link>https://kmeanskaran.substack.com/p/fine-tuning-sentence-transformers-for-embedding-search-4ee2030d6747</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/fine-tuning-sentence-transformers-for-embedding-search-4ee2030d6747</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Sat, 15 Jun 2024 07:19:53 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8913850b-ed90-4f3a-9692-b2e0210a9248_940x788.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Discover how to fine-tune and train a Sentence Transformers model for sentence similarity search by harnessing the power of <em><strong>vector embeddings.</strong></em></p><blockquote><p>This article is associated with team&nbsp;<a href="https://www.aihello.com/">AiHello</a>.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!558W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!558W!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png 424w, /__u/substackcdn.com/image/fetch/$s_!558W!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png 848w, /__u/substackcdn.com/image/fetch/$s_!558W!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png 1272w, /__u/substackcdn.com/image/fetch/$s_!558W!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!558W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!558W!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png 424w, /__u/substackcdn.com/image/fetch/$s_!558W!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png 848w, /__u/substackcdn.com/image/fetch/$s_!558W!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png 1272w, /__u/substackcdn.com/image/fetch/$s_!558W!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141a0a72-5657-4888-bf0e-510a279bf1d3_940x788.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Created by Karan&nbsp;Shingde</figcaption></figure></div><h4>Tables of Contents:</h4><ul><li><p><a href="#de35">Introduction</a></p></li><li><p><a href="#5310">Embedding for Similarity Search</a></p></li><li><p><a href="#0dd8">What is&nbsp;SBERT?</a></p></li><li><p><a href="#f582">Installation and&nbsp;setup</a></p></li><li><p><a href="#bfd4">Training SBERT</a></p></li><li><p><a href="#ce49">Various Methods for Training&nbsp;SBERT</a></p></li><li><p><a href="#e56a">Test the&nbsp;Model</a></p></li><li><p><a href="#d1cb">Conclusion</a></p></li><li><p><a href="#ae20">Resources</a></p></li></ul><h4><strong>Introduction</strong></h4><p>Sentence Transformers is a widely recognized Python module for training or fine-tuning state-of-the-art text embedding models. In the realm of large language models (LLMs), embedding plays a crucial role, as it significantly enhances the performance of tasks such as similarity search when tailored to specific datasets.</p><p>Recently, Hugging Face released version 3.0.0 of Sentence Transformers, which simplifies training, logging, and evaluation processes. In this article, we will explore how to train and fine-tune a Sentence Transformer model using our&nbsp;data.</p><h4>Embeddings for Similarity Search</h4><p>Embedding is the process of converting text into fixed-size vector representations (floating-point numbers) that capture the semantic meaning of the text in relation to other words. How can this be used for similarity search? In similarity search, we embed queries into a vector database. When a user submits a query, we need to find similar queries in the database.</p><p>First, convert all textual data into fixed-size vector embeddings and store them in a vector database. Next, accept a query from the user and convert it into an embedding as well. Then, find similar search terms or keywords from the user query within the vector database and retrieve those embeddings that are closest. Is it simple? Yes, but to search for the closest embeddings, we need to use distance-based algorithms such as Cosine Similarity, Manhattan Distance, or Euclidean Distance.</p><h4>What is&nbsp;SBERT?</h4><p>SBERT (Sentence-BERT) is a specialized type of sentence transformer model tailored for efficient sentence processing and comparison. It employs a Siamese network architecture, utilizing identical BERT models to process sentence pairs independently. Additionally, SBERT utilizes mean pooling on the final output layer to generate high-quality sentence embeddings. For a comprehensive understanding of SBERT, I recommend referring to the detailed&nbsp;<em><a href="https://towardsdatascience.com/sbert-deb3d4aef8a4">article</a></em>.</p><h4>Installation and&nbsp;setup</h4><p>You can either use online notebooks such as Google Colab. I have also covered how to execute training code from script. For Google Colab, set your runtime environment to T4 GPU hardware.</p><pre><code>!pip install -U "sentence-transformers[train]" accelerate datasets</code></pre><p>Import dependencies</p><pre><code>import os
import json
import torch
import datasets
import pandas as pd
from torch.utils.data import DataLoader
from sentence_transformers import (
    SentenceTransformer, models,
    losses, util,
    InputExample, evaluation,
    SentenceTransformerTrainingArguments, SentenceTransformerTrainer
)
from accelerate import Accelerator
from datasets import load_dataset</code></pre><p>For this blog post, I am using <a href="https://huggingface.co/datasets/SetFit/stsb">Glue STS-B</a> data and model <a href="https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2">sentence-transformers/all-MiniLM-L6-v2</a></p><pre><code>data = load_dataset('sentence-transformers/stsb')
train_data = data['train'].select(range(100))
val_data = data['validation'].select(range(100, 140))</code></pre><p>In the code block above, I&#8217;ve chosen samples of 100 for training and 40 for validation. This decision is due to the limited resources available in the free version of Colab. Feel free to adjust the range size or import the entire dataset as&nbsp;needed.</p><p>Let&#8217;s see random sample data from train&nbsp;data</p><pre><code># Example data from 5th record (taking randomly to just display)
print("Sentence 1: ", train_data['sentence1'][5], "\nSentence 2: ", train_data['sentence2'][5], "\nScore: ", train_data['score'][5])</code></pre><p>Output:</p><pre><code>Sentence 1:  Some men are fighting. 
Sentence 2:  Two men are fighting. 
Score:  0.85</code></pre><p>This will be the format of our data: &#8216;sentence1&#8217;, &#8216;sentence2&#8217;, and &#8216;score&#8217;. The &#8216;score&#8217; represents the degree of closeness or similarity between the two sentences. In cases where a label score is unavailable, you simply need to modify the loss function and evaluator accordingly.</p><h4>Training SBERT</h4><p>This is recommended way to train SBERT model form <a href="https://www.sbert.net/">SBERT official&nbsp;site.</a></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!NhJC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!NhJC!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png 424w, /__u/substackcdn.com/image/fetch/$s_!NhJC!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png 848w, /__u/substackcdn.com/image/fetch/$s_!NhJC!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png 1272w, /__u/substackcdn.com/image/fetch/$s_!NhJC!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!NhJC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!NhJC!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png 424w, /__u/substackcdn.com/image/fetch/$s_!NhJC!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png 848w, /__u/substackcdn.com/image/fetch/$s_!NhJC!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png 1272w, /__u/substackcdn.com/image/fetch/$s_!NhJC!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8aa3dc-4f7f-48c6-baeb-4229b2337338_1000x149.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Image from https://www.sbert.net/</figcaption></figure></div><blockquote><p>To train the SBERT model, you need to encapsulate the model building, evaluator, and training processes within the main() function. <a href="https://github.com/UKPLab/sentence-transformers/pull/2449">See this discussion.</a></p></blockquote><p>Training code:</p><pre><code>def main():
   
    # Get number of GPUs working
    accelerator = Accelerator()
    print(f"Using GPUs: {accelerator.num_processes}")

    # Sentence Transformer BERT Model
    word_embedding_model = models.Transformer('sentence-transformers/all-MiniLM-L6-v2')
    # Applying pooling on final layer
    pooling_model = models.Pooling(word_embedding_model.get_word_embedding_dimension())
    model = SentenceTransformer(modules=[word_embedding_model, pooling_model])

    # Define loss
    loss = losses.CoSENTLoss(model)

    # Define evaluator for evaluation
    evaluator = evaluation.EmbeddingSimilarityEvaluator(
        sentences1=val_data['sentence1'],
        sentences2=val_data['sentence2'],
        scores=val_data['score'],
        main_similarity=evaluation.SimilarityFunction.COSINE,
        name="sts-dev"
    )


    # Training arguments
    training_args = SentenceTransformerTrainingArguments(
        output_dir='./sbert-checkpoint', # Save checkpoints
        num_train_epochs=10,
        seed=33,
        per_device_train_batch_size=8,
        per_device_eval_batch_size=8,
        learning_rate=2e-5,
        fp16=True, # Loading model in mixed-precision
        warmup_ratio=0.1,
        evaluation_strategy="steps",
        eval_steps=2,
        save_total_limit=2,
        load_best_model_at_end=True,
        save_only_model=True,
        greater_is_better=True
    )


    # Train model
    trainer = SentenceTransformerTrainer(
        model=model,
        evaluator=evaluator,
        args=training_args,
        train_dataset=train_data,
        eval_dataset=val_data,
        loss=loss
    )
    trainer.train()

    # save the model
    model.save_pretrained("./sbert-model/")</code></pre><p>Now. let&#8217;s understand each component inside main() function step by&nbsp;step,</p><ul><li><p>Define the Accelerator() to determine the number of GPUs available on the current&nbsp;machine.</p></li><li><p>Load the Sentence Transformers model from the <a href="https://huggingface.co/sentence-transformers">HuggingFace repository</a> and extract the word embedding dimension using mean pooling. Add a mean pooling layer after the SBERT model as&nbsp;output.</p></li><li><p>Define the Loss function, such as CoSENTLoss(), to calculate the model&#8217;s loss based on float similarity scores. Choose the appropriate loss function from SBERT&#8217;s options based on your data and labels. Refer to the <a href="https://www.sbert.net/docs/sentence_transformer/loss_overview.html">Loss Overview</a> in the Sentence Transformers documentation.</p></li><li><p>Use the Evaluator() class provided by Sentence Transformers to calculate the evaluation loss during training and obtain specific metrics. Choose the appropriate evaluator, such as EmbeddingSimilarityEvaluator(), based on your data and use case. Refer to this <a href="https://www.sbert.net/docs/sentence_transformer/training_overview.html#evaluator">table</a> for available options.</p></li><li><p>Specify training arguments, such as the output directory for storing checkpoints, batch size per device (CPU/GPU), number of training epochs, learning rate, float16 precision for model loading, evaluation steps, etc., using the SentenceTransformerTrainer class which is indirectly inherited from transformers <a href="https://huggingface.co/docs/transformers/v4.26.1/en/main_classes/trainer#transformers.TrainingArguments">TrainingArguments</a>.</p></li><li><p>Train the model using the SentenceTransformerTrainer class by defining the training and validation data, optionally including an evaluator, specifying training arguments, and defining the loss function. Initiate training by calling the train() method. Perform training and save the model&nbsp;further.</p></li></ul><h4>Various Methods for Training&nbsp;SBERT</h4><p>After defining the main() function, simply call it to initiate the model training process. There are several ways to do&nbsp;this:</p><p>For Single&nbsp;GPU:</p><ul><li><p>If you are running code in Google Colab free version with T4 GPU then just create a new cell and call function: main()</p></li><li><p>If you are running your code in Python script, then just run a python command in the terminal: python&nbsp;main.py.</p></li></ul><p>For Multi-GPU:</p><p>HuggingFace transformer supports DistributedDataParallel (DDP) training to perform distributed parallel training on multiple GPU or in multiple machines. <a href="https://siboehm.com/articles/22/data-parallel-training">Read this article</a> to understand how DDP&nbsp;works.</p><ul><li><p>If you are running your code in colab or any notebook which contains multi-gpu, then:</p></li></ul><pre><code>from accelerator import notebook_launcher
notebook_launcher(main, num_processes=2)</code></pre><p>By running above code in a separate will run your code in multi-gpu.</p><ul><li><p>For Python&nbsp;Script:</p></li></ul><pre><code>accelerate launch &#8211;multi-gpu &#8211;num_processes=2 main.py</code></pre><p>These are some common ways to run a script or notebook for SBERT training.</p><h4>Test the&nbsp;Model</h4><p>After training the model, we can reload it and perform inference testing. For instance, if we have a list of product names and users input search terms, our goal is to identify the most similar product names along with a&nbsp;score.</p><p>Having trained our embedding model on sentence similarity data using similarity scores as labels, it will now improve the embeddings.</p><p>Here is the sample list of product name which we are using for embedding data:</p><pre><code># List of products
products = [
    "Apple iPhone 15 (256GB) | Silver",
    "Nike Air Max 2024 | Blue/White",
    "Samsung Galaxy S24 Ultra (512GB) | Phantom Black",
    "Sony PlayStation 5 Console | Digital Edition",
    "Dell XPS 13 Laptop | Intel i7, 16GB RAM, 512GB SSD",
    "Fitbit Charge 6 | Midnight Blue",
    "Bose QuietComfort 45 Headphones | Triple Black",
    "Canon EOS R6 Camera | 20.1 MP Mirrorless",
    "Microsoft Surface Pro 9 | Intel i5, 8GB RAM, 256GB SSD",
    "Adidas Ultraboost 21 Running Shoes | Core Black",
    "Amazon Kindle Paperwhite | 32GB, Waterproof",
    "LG OLED65C1PUB 65\" 4K Smart TV",
    "Garmin Forerunner 955 Smartwatch | Slate Grey",
    "Google Nest Thermostat | Charcoal",
    "KitchenAid Stand Mixer | 5-Quart, Empire Red",
    "Dyson V11 Torque Drive Cordless Vacuum",
    "JBL Charge 5 Portable Bluetooth Speaker | Squad",
    "Panasonic Lumix GH5 Camera | 20.3 MP, 4K Video",
    "Apple MacBook Pro 14\" | M1 Pro, 16GB RAM, 1TB SSD",
    "Under Armour HeatGear Compression Shirt | Black/Red"
]</code></pre><p>Next, load our fine-tuned SBERT model and convert product names into vector embeddings:</p><pre><code># Load fine-tuned model
model = SentenceTransformer('./sbert-model')</code></pre><p>To convert product names into embeddings, we&#8217;ll utilize the GPU and convert them into tensors. You can do so using the following code:</p><pre><code>product_data = model.encode(products, convert_to_tensor=True).to("cuda")</code></pre><p>By converting embeddings to CUDA, we leverage GPU computational support (dtype=torch.float32); otherwise, if CPU is selected, it defaults to (dtype=float32).</p><p>This product_data serves as our vector database, now stored in memory. Alternatively, you can utilize vector databases like Qdrant, Pinecone, Chroma,&nbsp;etc.</p><p>Lastly, create a function that accepts a user query from the terminal or as user input and returns the top products along with their Cosine-Similarity scores.</p><pre><code>def search():
    query = input("Enter Query:\n")
    query_embeddings = model.encode([query], convert_to_tensor=True).to("cuda")
    hits = util.semantic_search(query_embeddings, product_data,
                                score_function=util.cos_sim)
   
    for i in range(5):
        best_search_term_id, best_search_term_core = hits[0][i]['corpus_id'], hits[0][i]['score']
        print("\nTop result: ", products[best_search_term_id])
        print("Score: ", best_search_term_core)</code></pre><p>Test run:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!IfBB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!IfBB!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png 424w, /__u/substackcdn.com/image/fetch/$s_!IfBB!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png 848w, /__u/substackcdn.com/image/fetch/$s_!IfBB!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png 1272w, /__u/substackcdn.com/image/fetch/$s_!IfBB!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!IfBB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!IfBB!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png 424w, /__u/substackcdn.com/image/fetch/$s_!IfBB!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png 848w, /__u/substackcdn.com/image/fetch/$s_!IfBB!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png 1272w, /__u/substackcdn.com/image/fetch/$s_!IfBB!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cd07e4-5ef5-4022-97dd-fb399c43a6a9_1024x700.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Result from Google Colab&nbsp;run.</figcaption></figure></div><p>You can observe that our model is performing exceptionally well, with satisfactory scores. To further enhance result relevance, consider adding a threshold ratio of&nbsp;0.5.</p><h4>Conclusion</h4><p>Using SentenceTransformer 3.0.0 makes training or fine-tuning embedding models a breeze. The new version boasts support for multi-GPU utilization via the DDP method and introduces logging and experimentation features through Weights &amp; Biases. By encapsulating our code within a single main function and executing it with a single command, developers can streamline their workflow significantly.</p><p>The Evaluator functionality aids in evaluating models during the training phase, catering to defined tasks like Embedding Similarity Search in our scenario. Upon loading the model for inference, it delivers as anticipated, yielding a satisfactory similarity score.</p><p>This process harnesses the potential of vector embeddings to enhance search results, leveraging user queries and database interactions effectively.</p><h4>Resources</h4><p><a href="https://huggingface.co/blog/train-sentence-transformers">Training and Finetuning Embedding Models with Sentence Transformers v3 (huggingface.co)</a></p><p><a href="https://www.sbert.net/docs/sentence_transformer/training_overview.html">Training Overview&#8202;&#8212;&#8202;Sentence Transformers documentation (sbert.net</a>)</p><p>Thank you for reading the article. If you found it helpful, please consider giving it an upvote and sharing it. Connect me on <a href="https://www.linkedin.com/in/karanshingde/">LinkedIn</a> and&nbsp;<a href="https://x.com/kmeanskaran">X</a>.</p><p>Until next time, Signing&nbsp;off!</p><div><hr></div><p><a href="https://levelup.gitconnected.com/fine-tuning-sentence-transformers-for-embedding-search-4ee2030d6747">Fine-Tuning Sentence Transformers for Embedding Search</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[A Guide to Using Semantic Cache to Speed Up LLM Queries with Qdrant and Groq.]]></title><description><![CDATA[Introduction]]></description><link>https://kmeanskaran.substack.com/p/a-guide-to-using-semantic-cache-to-speed-up-llm-queries-with-qdrant-and-groq-dd29170c4804</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/a-guide-to-using-semantic-cache-to-speed-up-llm-queries-with-qdrant-and-groq-dd29170c4804</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Tue, 21 May 2024 16:20:58 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/253ff3b4-3827-4fd6-b8ee-c8809478fd5a_940x484.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!P5CK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!P5CK!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png 424w, /__u/substackcdn.com/image/fetch/$s_!P5CK!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png 848w, /__u/substackcdn.com/image/fetch/$s_!P5CK!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png 1272w, /__u/substackcdn.com/image/fetch/$s_!P5CK!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!P5CK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!P5CK!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png 424w, /__u/substackcdn.com/image/fetch/$s_!P5CK!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png 848w, /__u/substackcdn.com/image/fetch/$s_!P5CK!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png 1272w, /__u/substackcdn.com/image/fetch/$s_!P5CK!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b3ff2d-65a0-44a4-9aef-99939de1317f_940x484.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">by Karan&nbsp;Shingde</figcaption></figure></div><h4>Introduction</h4><p>Semantic caching is a method of retrieval optimization where frequent or similar queries are instantly fetched from the knowledge base by storing them in a cache. This concept is similar to caching in operating systems, where frequently accessed data is stored in a high-speed storage layer for quick retrieval.</p><p>In a <em><strong>Retrieval-Augmented Generation (RAG) system</strong></em>, users ask questions and receive results from a vector database. In a large-scale application with multiple users asking frequent questions, optimizing retrieval tasks by caching frequently accessed contexts can significantly improve the application&#8217;s performance.</p><p>In a simple RAG setup, the user&#8217;s query searches for related contexts in the database and returns them to the augmented prompt and Language Model (LLM). By introducing semantic caching, the system can quickly serve frequent queries from the cache, enhancing overall efficiency.</p><h3>How Does Semantic Cache&nbsp;Work?</h3><p>The simple retrieval process can be time-consuming because each search needs to find the context and retrieve the data, even when most queries have different semantics but the same context. This is where caching comes into&nbsp;play.</p><p>By storing frequently accessed contexts in cache memory, the need for repeated read-write operations is reduced, significantly improving efficiency. Caching ensures that the context is readily available for commonly asked questions, speeding up the retrieval process and enhancing overall performance.</p><p>See the&nbsp;diagram:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!XgSe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!XgSe!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!XgSe!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!XgSe!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!XgSe!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!XgSe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!XgSe!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!XgSe!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!XgSe!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!XgSe!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e67b107-4ac1-40ee-99b6-a28b75cddee9_1000x420.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: HuggingFace</figcaption></figure></div><p>Scenarios to use a semantic cache layer in the above&nbsp;diagram:</p><p>In the diagram, the semantic cache is placed between the vector database and the user query. This is the appropriate placement. When a user&#8217;s query is embedded and similar contexts are found from the database using distance metrics such as Cosine, Euclidean, etc., it fetches the data and stores it in another collection for the semantic cache. The results are then passed to the augmented prompt and the Language Model (LLM) to generate an answer for the&nbsp;user.</p><p>Another approach is to place the semantic cache after the text is generated by the augmented prompt and LLM. This will store answers from the LLM in the semantic cache, so users will receive answers in the generated text format. However, there is a caveat: if the user includes specific instructions in their query, this scenario may not be effective. For example, the queries &#8220;What is the Indus Valley?&#8221; and &#8220;I want to know about the Indus Valley civilization in 1000 words&#8221; have the same semantic context but different requirements. Since we are saving LLM answers in the cache, this approach would not fulfill the second query accurately.</p><p>The above scenarios are based on your requirements. So, choose wisely and implement by considering the pros and&nbsp;cons.</p><h4>Guide to Using Semantic Cache Using Qdrant, LangChain and Groq +&nbsp;Llama3</h4><p>Groq has released an LPU that can generate output with lightning speed, offering 10x performance at 1/10th the latency. Currently, Groq supports the Llama3 and Mixtral models as LLMs. It demonstrates impressive speed when it comes to the inference of LLM output&nbsp;tokens.</p><p>We have already seen how a semantic cache improves RAG performance in retrieval speed. Groq will be the cherry on top, accelerating application performance even&nbsp;further.</p><p>Let&#8217;s see an&nbsp;example:</p><p>First, install qdrant-client, langchain, langchain-groq, fastembed, and datasets using pip&nbsp;command.</p><pre><code>pip install qdrant-client langchain langchain-groq fastembed datasets</code></pre><p>Then create a Qdrant Cluster on <a href="https://qdrant.to/cloud">cloud</a> and collect the URL and API key. Visit <a href="https://console.groq.com/keys">GroqCloud</a> and create the API key to use Groq in LangChain.</p><p>Import dependencies and paste your credentials:</p><pre><code>import numpy as np
import pandas as pd
from datasets import load_dataset
from qdrant_client import QdrantClient
from qdrant_client.http import models


import uuid
import time
from typing import List
from fastembed import TextEmbedding
from qdrant_client.http.models import PointStruct, SearchParams

from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables.passthrough import RunnablePassthrough
from langchain_groq import ChatGroq


qdrant_uri = "Qdrant-URI"
qdrant_api = "Qdrant-API-Key"
groq_key = "Groq-API-key"</code></pre><p>Load the LLM model. We are using the Llama3&#8211;8B model; you can use the 70B parameter model&nbsp;also.</p><pre><code>llm = ChatGroq(groq_api_key=groq_key,
               model='llama3-8b-8192',
               temperature=0.2) # set temperature by your own</code></pre><p>Now, load the&nbsp;dataset.</p><pre><code>data = load_dataset("llamafactory/PubMedQA", split="train")
data = data.to_pandas()
data.head()</code></pre><p>Get the subset of the data to ingest in the&nbsp;database</p><pre><code>MAX_ROWS = 1000
OUTPUT = "output"
subset_data = data.head(MAX_ROWS)</code></pre><p>Create Qdrant DB Client collection and insert the document chunks into the database.</p><pre><code>client = QdrantClient(
    qdrant_uri,
    api_key=qdrant_api
)


chunks = subset_data[OUTPUT].to_list()

# Add data to defined collection
client.add(
   collection_name='PubMedQA',
   documents=chunks
)</code></pre><p>The above code block will add data in the collection name <strong>PudMedQA</strong>.</p><p>Now, we will see how retrieval works with and without semantic&nbsp;cache</p><ol><li><p>Without Semantic&nbsp;Cache</p></li></ol><pre><code>class QdrantVectorStore():
    def __init__(self):
        self.encoder = TextEmbedding(model_name="BAAI/bge-small-en-v1.5")
        self.client = QdrantClient()
        self.db_collection_name= "PubMedQA"
       
        self.db_client = QdrantClient(
            qdrant_uri,
            api_key=qdrant_api
        )
       
        self.euclidean_threshold = threshold
   
    def get_embedding(self, question):
        embedding = list(self.encoder.embed(question))[0]
        return embedding
   
    def query_database(self,query_text):
        result = self.db_client.query(
            query_text=query_text,
            limit=3,
            collection_name=self.db_collection_name
        )
        return result
   
    def query(self, question):
        start_time = time.time()
       
        db_results = self.query_database(question)
       
        if db_results:
            response_text = db_results[0].document
            print('Retrieval without cache.')
            elapsed_time = time.time() - start_time
            print(f"Time taken: {elapsed_time:.3f} seconds")
            return response_text
       
        print("No answer found in Database")
        elapsed_time = time.time() - start_time
        print(f"Time taken: {elapsed_time:.3f} seconds")
        return "No answer available"</code></pre><p>Create an object from the&nbsp;class.</p><pre><code>vector_db = QdrantVectorStore()</code></pre><p>Define augmented prompt and LLama3 model in LangChain Language Expression.</p><pre><code>def chat_query(question):
    context = vector_db.query(question)
   
    prompt_template = """Answer the question with given context as per requirement.
                {context}
           
                Question: {question}"""
    prompt = PromptTemplate.from_template(prompt_template)


    chain = prompt | llm | StrOutputParser()
   
    result = chain.invoke({"question":question, "context":context})
    print("\n\n")
    print(result)</code></pre><p>Ok, time to find out the performance. Here are questions I am using to compare performance with and without semantic&nbsp;cache.</p><pre><code>question_1 = "Does bacterial gastroenteritis predispose people to functional gastrointestinal disorders?"
question_2 = "Can bacterial gastroenteritis lead to functional gastrointestinal disorders?"</code></pre><pre><code>chat_query(question_1)</code></pre><pre><code>Retrieval without cache.
Time taken: 1.187 seconds

 
Yes, bacterial gastroenteritis predisposes people to functional gastrointestinal disorders, specifically Irritable Bowel Syndrome (IBS) and functional diarrhea.</code></pre><p>Let&#8217;s see similar question_2</p><pre><code>chat_query(question_2)</code></pre><pre><code>Retrieval without cache.
Time taken: 0.392 seconds


Yes, according to the given context, bacterial gastroenteritis can lead to functional gastrointestinal disorders, specifically Irritable Bowel Syndrome (IBS) and functional diarrhea.</code></pre><p>Here, we observe that even without a semantic cache, queries can perform quickly. However, let&#8217;s see what happens with a semantic&nbsp;cache.</p><p>2. With Semantic&nbsp;Cache</p><pre><code>class SemanticCache:
    def __init__(self, threshold=0.35):
        self.encoder = TextEmbedding(model_name="BAAI/bge-small-en-v1.5")
        self.cache_client = QdrantClient(":memory:")
        self.cache_collection_name = "PubMedQA-cache"


        self.cache_client.create_collection(
            collection_name=self.cache_collection_name,
            vectors_config=models.VectorParams(
                size=384,
                distance='Euclid'
            )
        )


        # Initialize Qdrant Client for external database
        self.db_client = QdrantClient(
            qdrant_uri,
            api_key=qdrant_api
        )
       
        self.db_collection_name = "PubMedQA"


        self.euclidean_threshold = threshold


    def get_embedding(self, question):
        embedding = list(self.encoder.embed(question))[0]
        return embedding


    def search_cache(self, embedding):
        search_result = self.cache_client.search(
            collection_name=self.cache_collection_name,
            query_vector=embedding,
            limit=1
        )
        return search_result


    def add_to_cache(self, question, response_text):
        # Create a unique ID for the new point
        point_id = str(uuid.uuid4())
        vector = self.get_embedding(question)
        # Create the point with payload
        point = PointStruct(id=point_id, vector=vector, payload={"response_text": response_text})
        # Upload the point to the cache
        self.cache_client.upload_points(
            collection_name=self.cache_collection_name,
            points=[point]
        )


    def query_database(self, query_text):
        results = self.db_client.query(
            query_text=query_text,
            limit=3,
            collection_name=self.db_collection_name
        )
        return results


    def ask(self, question):
        start_time = time.time()
        vector = self.get_embedding(question)
        search_result = self.search_cache(vector)
        print(search_result)
        if search_result:
            for s in search_result:
                if s.score &lt;= self.euclidean_threshold:
                    print('Answer recovered from Cache.')
                    print(f'Found cache with score {s.score:.3f}')
                    elapsed_time = time.time() - start_time
                    print(f"Time taken: {elapsed_time:.3f} seconds")
                    return s.payload['response_text']


        db_results = self.query_database(question)
        if db_results:
            response_text = db_results[0].document
            self.add_to_cache(question, response_text)
            print('Answer added to Cache.')
            elapsed_time = time.time() - start_time
            print(f"Time taken: {elapsed_time:.3f} seconds")
            return response_text


        # Fallback if no response is found
        print('No answer found in Cache or Database.')
        elapsed_time = time.time() - start_time
        print(f"Time taken: {elapsed_time:.3f} seconds")
        return "No answer available."</code></pre><p>In the above code, there is another Qdrant DB collection that holds the cached data for all unique contexts based on the&nbsp;queries.</p><pre><code>cache = SemanticCache()


def chat_cache(question):
    context = cache.ask(question)
   
    prompt_template = """Answer the question with given context as per requirement.
                {context}
           
                Question: {question}"""
    prompt = PromptTemplate.from_template(prompt_template)


    chain = prompt | llm | StrOutputParser()
   
    result = chain.invoke({"question":question, "context":context})
    print("\n\n")</code></pre><pre><code>chat_cache(question_1)</code></pre><pre><code>Answer added to Cache.
Time taken: 1.412 seconds

 
Yes, bacterial gastroenteritis predisposes people to functional gastrointestinal disorders, specifically Irritable Bowel Syndrome (IBS) and functional diarrhea.</code></pre><p>The first time a query is made, or for queries where the context is not present in the cache, simple retrieval is performed. However, the retrieved context is then stored in the&nbsp;cache.</p><p>Let&#8217;s ask question_2</p><pre><code>chat_cache(question_2)</code></pre><pre><code>Answer recovered from Cache.
Found cache with score 0.329
Time taken: 0.053 seconds

Yes, according to the given context, bacterial gastroenteritis can lead to functional gastrointestinal disorders, specifically Irritable Bowel Syndrome (IBS) and functional diarrhea. The study found that symptoms consistent with IBS and functional diarrhea occur more frequently in people after bacterial gastroenteritis compared to controls, even after excluding individuals with pre-existing functional gastrointestinal disorders.</code></pre><p>We successfully retrieved answers from the cache using a threshold score. For the threshold, we used a Euclidean distance-based score between the user query and the provided&nbsp;context.</p><h3>Benchmarks with and without Semantic&nbsp;Cache</h3><p><em>(All time stamps in this article are based on retrieval performance, not on Groq performance.)</em></p><p>We have seen that on question_1 and question_2 the two approaches have different results.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!KnXt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!KnXt!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png 424w, /__u/substackcdn.com/image/fetch/$s_!KnXt!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png 848w, /__u/substackcdn.com/image/fetch/$s_!KnXt!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KnXt!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!KnXt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!KnXt!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png 424w, /__u/substackcdn.com/image/fetch/$s_!KnXt!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png 848w, /__u/substackcdn.com/image/fetch/$s_!KnXt!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KnXt!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F957ab67c-5f80-4708-a004-c3528e6ed9bf_997x190.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Comparison on question_1 and question_2</figcaption></figure></div><p>Let&#8217;s compare on another set of questions:</p><p>Query 1:</p><pre><code>'Can we predict the duration of chemotherapy-induced neutropenia in febrile neutropenic patients, focusing on regimen-specific risk factors?'</code></pre><p>Query 2:</p><pre><code>'Can we predict the duration of chemotherapy-induced neutropenia in febrile neutropenic patients?'</code></pre><p>Here is the&nbsp;result:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!oWWy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!oWWy!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png 424w, /__u/substackcdn.com/image/fetch/$s_!oWWy!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png 848w, /__u/substackcdn.com/image/fetch/$s_!oWWy!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png 1272w, /__u/substackcdn.com/image/fetch/$s_!oWWy!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!oWWy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!oWWy!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png 424w, /__u/substackcdn.com/image/fetch/$s_!oWWy!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png 848w, /__u/substackcdn.com/image/fetch/$s_!oWWy!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png 1272w, /__u/substackcdn.com/image/fetch/$s_!oWWy!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F682d5dee-3ded-4ea3-97e7-480439c28aab_1024x199.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Comparison between query 1 and query&nbsp;2</figcaption></figure></div><p>Again, in both the examples, semantic cache performs way better when the same semantic query is asked a second&nbsp;time.</p><h3>Conclusion</h3><p>Semantic caching is an important technique to implement in any RAG-based system. It significantly reduces the retrieval time for frequently asked questions from the database. By placing the cache before the augmented prompt and LLM, answers can be tailored based on the given instructions in the&nbsp;query.</p><p>However, there are some drawbacks to consider. Semantic cache collections need to be managed differently. Additionally, as data and queries change over time, it&#8217;s important to periodically clear the semantic cache to keep it updated with only the most relevant data. Remember, the semantic cache should hold a limited amount of data; otherwise, it will take time to find answers from a large volume of&nbsp;data.</p><p>Finally, by implementing Groq and semantic caching, you will experience a significant increase in the speed of generating answers to user&nbsp;queries.</p><p>If you find this article useful, please upvote. Follow me on <a href="https://medium.com/@karanshingde">Medium</a> and <a href="https://www.linkedin.com/in/karanshingde/">LinkedIn</a>.</p><h3>References</h3><p><strong><a href="https://huggingface.co/learn/cookbook/semantic_cache_chroma_vector_database">Implementing semantic cache to improve a RAG system with FAISS.&#8202;&#8212;&#8202;Hugging Face Open-Source AI&nbsp;Cookbook</a></strong></p><p><strong><a href="https://qdrant.tech/blog/semantic-cache-ai-data-retrieval/">Semantic Cache: Accelerating AI with Lightning-Fast Data Retrieval&#8202;&#8212;&#8202;Qdrant</a></strong></p><div><hr></div><p><a href="https://blog.stackademic.com/a-guide-to-using-semantic-cache-to-speed-up-llm-queries-with-qdrant-and-groq-dd29170c4804">A Guide to Using Semantic Cache to Speed Up LLM Queries with Qdrant and Groq.</a> was originally published in <a href="https://blog.stackademic.com">Stackademic</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Building a Portuguese Language RAG Pipeline Using Sabia-7B, Qdrant, and LangChain.]]></title><description><![CDATA[Introduction:]]></description><link>https://kmeanskaran.substack.com/p/building-a-portuguese-language-rag-pipeline-using-sabia-7b-qdrant-and-langchain-f02eba404eb5</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/building-a-portuguese-language-rag-pipeline-using-sabia-7b-qdrant-and-langchain-f02eba404eb5</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Mon, 26 Feb 2024 11:40:04 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/332cb8bd-3963-41bb-9919-10bbae82b015_1024x538.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Introduction:</h3><p>Large language models (LLM) have significantly altered the landscape of technology. They&#8217;ve revolutionized natural language processing (NLP) capabilities, which has enabled advancements in machine translation, sentiment analysis, chatbots, and more. Most LLMs are trained on huge datasets from all over the internet. They are mostly known for their capabilities in the English language. Models like ChatGPT, Llama2, and Mistral are heavily trained on a large corpus of the English language. ChatGPT understands more than 50 languages, but when we talk about an open-source model, we are looking for a specialized model that focuses on one domain or language.</p><p>How can we build our LLM application specifically for the Portuguese language? Is there any model for that? Yes, the answer is &#8220;Sabia-7B&#8221;. This LLM is specially trained for the Portuguese language. In this article, we will see how to optimize the power of Sabia-7B to create a RAG application on our&nbsp;data.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!oPlb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!oPlb!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png 424w, /__u/substackcdn.com/image/fetch/$s_!oPlb!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png 848w, /__u/substackcdn.com/image/fetch/$s_!oPlb!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png 1272w, /__u/substackcdn.com/image/fetch/$s_!oPlb!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!oPlb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42244895-b107-4925-886a-1189386930dd_1024x538.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!oPlb!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png 424w, /__u/substackcdn.com/image/fetch/$s_!oPlb!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png 848w, /__u/substackcdn.com/image/fetch/$s_!oPlb!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png 1272w, /__u/substackcdn.com/image/fetch/$s_!oPlb!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42244895-b107-4925-886a-1189386930dd_1024x538.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Created by Karan&nbsp;Shingde</figcaption></figure></div><h3>Sabia-7B:</h3><p><a href="https://arxiv.org/pdf/2304.07880.pdf">Sabia: Portuguese Large Language Models</a> is an official research paper published by Maritaca AI. Sabia is a pre-trained model on GPT-J and LLaMA models on Portuguese texts. It is built upon Poeta, a suite of 14 Portuguese datasets. The researchers stated that their model outperforms English-centric and multilingual counterparts by a significant margin; Sabia-65B performs on par with GPT-3.5-turbo.</p><p>The model evaluated the dataset comprising texts created by native Brazilian Portuguese speakers, as well as the dataset translated into Portuguese. According to the Hugging Face model card, Sabia-7B is an auto-regressive model that uses the same architecture as LLaMA-1&#8211;7B and uses the same tokenizer as LLaMA-1&#8211;7B, with a maximum sequence length of 2048&nbsp;tokens.</p><p><a href="https://www.maritaca.ai/">Maritaca AI</a> is the organization behind building LLM for the Portuguese language. You can access the official API from their website, which is paid. In this article, we will explore how to use the Hugging Face model of Sabia-7B to build a RAG application.</p><h3>What is&nbsp;RAG:</h3><p>Retrieval Augmentation Generation (RAG) is a powerful technique for enhancing the capabilities of LLM. There are two main components:</p><ol><li><p><strong>Retriever</strong>: This model finds relevant information from a large corpus documents based on your query. Think of it like a super librarian who scours all the books in the library to find the ones most likely to have your&nbsp;answer.</p></li><li><p><strong>Generator</strong>: Once the retriever provides relevant context, the generator uses its language understanding and generation skills to produce a response tailored to your specific question.</p></li></ol><p><strong>Stages of RAG pipeline:</strong></p><ol><li><p><strong>Document Ingestion: </strong>The relevant documents are processed and converted into a format suitable for efficient retrieval. This often involves extracting key information and creating vector representations of the documents.</p></li></ol><p><strong>2. Indexing: </strong>These vector representations are stored in a specialized database called a &#8220;vector database&#8221; for faster retrieval during the online&nbsp;stage.</p><p><strong>3. Query Processing: </strong>Your query is received and encoded into a similar vector representation.</p><p><strong>4. Retrieval: </strong>The query vector is compared to the document vectors in the database. The most relevant documents are retrieved based on their similarity scores.</p><p><strong>5. Generation: </strong>The retrieved documents are prepended to your query as additional context. Then, the generator uses this contextualized query to generate a response that addresses your specific&nbsp;needs.</p><p>Now let&#8217;s build a simple chatbot application using the HuggingFace model: Sabia-7B.</p><h3>Steps to Build the Chatbot Application Using&nbsp;Sabia-7B</h3><h3>Collect the&nbsp;Data:</h3><p>Custom data is the base of a RAG application. So in this article, I have extracted the data from Wikipedia which is in Portuguese. There are two PDF files containing information about the famous Brazilian footballer Neymar Jr. and the Brazilian festival Carnival. While collecting this data, I changed Wikipedia language to Portuguese, copied the paragraphs, and pasted them into individual PDF&nbsp;files.</p><p>You can take any data you want, but it should be in Portuguese.</p><h3>Initial Setup:</h3><p>Before starting the coding part let&#8217;s install the necessary dependencies:</p><pre><code>!pip install transformers datasets peft bitsandbytes trl langchain accelerate huggingface_hub qdrant_client pypdf sentence-transformers</code></pre><p><strong>Note</strong>: I am using Google Colab&#8217;s free version for this explanation. Connect T4 GPU simply paste the above command in the first&nbsp;cell.</p><h3>Configure Vector Database:</h3><p>A vector database is a type of database that specializes in storing and querying high-dimensional vector data efficiently. In the vector database, we are storing your text data in a vector form using embeddings. If you don&#8217;t know what word embeddings are, or how they work, just read this article for a better understanding: <a href="https://www.datastax.com/guides/what-is-a-vector-embedding">What are Vector Embeddings? Applications, Use Cases &amp; More (datastax.com)</a></p><p>We are using Qdrant DB as our vector database for this&nbsp;article.</p><h3>QdrantDB:</h3><p>To begin with this stage, first set the Qdrant database for your application.</p><ol><li><p>Login to the&nbsp;<a href="https://qdrant.to/cloud">Qdrant</a><strong>.</strong></p></li><li><p>Get your API key (copy it and paste it on your side first, you can&#8217;t see the API key again after copying).</p></li><li><p>Copy the database URL with the key and save it locally&nbsp;first.</p></li></ol><p>Store your credentials along with dependencies. Like&nbsp;below:</p><pre><code>import os
import qdrant_client
from langchain_community.vectorstores import Qdrant
from langchain.embeddings import HuggingFaceEmbeddings
from langchain_community.document_loaders import PyPDFLoader, DirectoryLoader
from langchain.text_splitter import CharacterTextSplitter
import json
import re
from pprint import pprint
import pandas as pd
import torch
from qdrant_client import QdrantClient


QDRANT_URI = "YOUR-URI"
QDRANT_API_KEY = "YOUR-API-KEY"
HF_AUTH_KEY="HUGGINGFACE-TOKEN"


device = "cuda" if torch.cuda.is_available() else "cpu"</code></pre><blockquote><p>Also, to get your <strong>Hugging Face API</strong> key: Go to your <strong>Hugging Face profile</strong> &gt;&gt; <strong>Edit Profile </strong>&gt;&gt;<strong> Access Token</strong> &gt;&gt; <strong>New Token</strong> &gt;&gt; Give a name to the token, copy your key, and simply paste it into a variable.</p></blockquote><h3><strong>Select the Sabia-7B&nbsp;Model:</strong></h3><pre><code>embedding_model = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
model_name = "maritaca-ai/sabia-7b"


print(f"Device: {device}")
print(f"Embedding Model Name: {embedding_model}")
print(f"LLM Name: {model_name}")</code></pre><p>I have selected two models from HuggingFace. The first one is the embedding model which will be used to embed our textual data into a numerical representation. The second one is the large language model for our Portuguese language use case: Sabia-7B.</p><p>&#8220;sentence-transformers&#8221; provide embedding models for the English language and also multilingual languages. You can try with multiple versions of <a href="https://huggingface.co/sentence-transformers">sentence-transformers</a>.</p><h3>Chunk, Embed, and&nbsp;Store:</h3><p>We will start by chunking and breaking our text into pieces. Before that, let&#8217;s see how we can load our data from a directory and clean it using Langchain and Python&nbsp;Regex.</p><p>We will clean the text of PDFs, this is the simplest way you can do&nbsp;this:</p><pre><code># Function to clean the text
def clean_text(text):
  cleaned_text = text.strip()  # Remove leading/trailing whitespace
  cleaned_text = re.sub(r"\s+", " ", cleaned_text)  # Replace extra spaces with a single space
  cleaned_text = re.sub(r"[^\w\s]", "", cleaned_text)  # Remove non-alphanumeric characters
  return cleaned_text</code></pre><p>Langchain is a go-to library to deal with LLM projects using Simple Python language.</p><pre><code># Load document from data directory in .pdf format
def load_documents():
    loader = DirectoryLoader('data/', glob="*.pdf", loader_cls=PyPDFLoader)
    documents = loader.load()
    for doc in documents:
      cleaned_text = clean_text(doc.page_content)
      doc.page_content = cleaned_text
    return documents</code></pre><p>After this stage, the most critical step has to be performed which is converting numerical representations into embeddings:</p><p>Define the Qdrant&nbsp;Client</p><pre><code># Create a Qdrant Client
client = qdrant_client.QdrantClient(
    QDRANT_URI,
    api_key=QDRANT_API_KEY
)


# Create a collection
vectors_config = qdrant_client.http.models.VectorParams(
    size=384,
    distance=qdrant_client.http.models.Distance.COSINE
)


client.recreate_collection(
    collection_name="Brazilian-Portugeese",
    vectors_config=vectors_config
)</code></pre><p>There are three variables: <em><strong>client</strong></em> variables define the QdrantClient API so we can deal with Python. We can also define the configuration of our embeddings such as size and distance metrics, <em><strong>vectors_config </strong></em>does this work for us. Using <em><strong>client.recreate_collection() </strong></em>we can define a collection and store our&nbsp;data.</p><p>Let&#8217;s use our embedding algorithm from Hugging Face and perform our vector database ingestion task:</p><pre><code># Define Embeddings using HF
embeddings = HuggingFaceEmbeddings(
    model_name=embedding_model)
# Split texts
def get_chunks(text):
    text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size=300,
        chunk_overlap=50,
        length_function=len
    )
    chunks = text_splitter.split_documents(text)
    return chunks


cleaned_documents = load_documents()
text_chunks = get_chunks(cleaned_documents)</code></pre><p>Simply save text chunks by performing the above function.</p><p>In the last step push your data into your QdrantDB collection</p><pre><code>qdrant = Qdrant.from_documents(
    text_chunks,
    embeddings,
    url=QDRANT_URI,
    api_key=QDRANT_API_KEY,
    prefer_grpc=True,
    collection_name='Brazilian-Portugeese',
)</code></pre><h3>Build HF&nbsp;Model:</h3><p>Using open weights from Hugging Face transformers we developers can easily utilize them for our specific task. In this article, we will see a simple RAG application so we will start buildingour model with quantization, as the model is complex and large. There is another approach which is Fine-Tuning that we will see in another blog. For this application, let&#8217;s see how we can do this magic in simple lines of&nbsp;code.</p><pre><code>from torch import cuda, bfloat16
import transformers


bnb_config = transformers.BitsAndBytesConfig(
    load_in_4bit = True,
    bnb_4bit_quant_type='nf4',
    bnb_4bit_use_double_quant=True,
    bnb_4bit_compute_dtype=bfloat16
)


model_config = transformers.AutoConfig.from_pretrained(
    model_name,
    token=HF_AUTH_KEY
)</code></pre><p>This code snippet initializes a configuration object for running a Hugging Face Transformer model on a GPU with 4-bit weight quantization using the Bits And Bytes (BnB) technique. It imports necessary modules from PyTorch and the Hugging&nbsp;Face</p><p>Transformers library then configures the BnB parameters for low-memory computation while setting the compute data type to bfloat16. At last, it creates a configuration object specific to the chosen model architecture. Using this setup users are allowed to train or perform inferences with their desired model efficiently while reducing memory footprint through 4-bit quantization.</p><p>Now define the Causal Language Model to perform text generation operation:</p><pre><code>model = transformers.AutoModelForCausalLM.from_pretrained(
    model_name,
    trust_remote_code=True,
    config=model_config,
    quantization_config=bnb_config,
    device_map='auto',
    use_auth_token=HF_AUTH_KEY
)

model.eval()</code></pre><p>Using transformer architecture build your model using open weights based on the configuration provided.</p><p>Tokenizer is the essential part for LLMs to understand and process human-readable text. We will use a tokenizer of the same model as&nbsp;below:</p><pre><code>tokenizer = transformers.AutoTokenizer.from_pretrained(
    model_name,
    use_auth_token=HF_AUTH_KEY
)</code></pre><p>Create a transformer pipeline that generates text using a model and tokenizer combination.</p><pre><code>generate_text = transformers.pipeline(
    model=model, tokenizer=tokenizer,
    return_full_text=True,  # langchain expects the full text
    task='text-generation',
    # we pass model parameters here too
    temperature=0.2,  # 'randomness' of outputs, 0.0 is the min and 1.0 the max
    max_new_tokens=512,  # mex number of tokens to generate in the output
    repetition_penalty=1.1  # without this output begins repeating
)</code></pre><p>Creating a Transformer pipeline involves setting up a process for inputting text and generating output text, specifically for the purpose of text generation.</p><p>Using LangChain let&#8217;s convert the transformer pipeline into LLM using HuggingFacePipeline.</p><pre><code>from langchain.llms import HuggingFacePipeline
llm = HuggingFacePipeline(pipeline=generate_text)</code></pre><p>Use a vector store for retrieval generation. Let&#8217;s create a function for&nbsp;that:</p><pre><code>def get_vectore_store():

    client = qdrant_client.QdrantClient(
        QDRANT_URI,
        api_key=QDRANT_API_KEY
    )

    embeddings = HuggingFaceEmbeddings(
        model_name="sentence-transformers/all-MiniLM-L6-v2"
    )

    vectore_store = Qdrant(
        client=client,
        collection_name="Brazilian-Portugeese",
        embeddings=embeddings
    )

    return vectore_store</code></pre><p>Create RetrievalQA pipeline for RAG pipeline:</p><pre><code>from langchain.chains import RetrievalQA

vectore_store = get_vectore_store()
rag_pipeline = RetrievalQA.from_chain_type(
    llm=llm, chain_type='stuff',
    retriever=vectore_store.as_retriever()
)</code></pre><p>We will create <em><strong>rag_pipeline </strong></em>to generate text by passing&nbsp;text.</p><p>Let&#8217;s see examples in Portuguese language:</p><pre><code> rag_pipeline(&#8220;Carreira futebolistica de Neymar Jr&#8221;)</code></pre><pre><code>{'query': 'Carreira futebol&#237;stica de Neymar Jr',
 'result': '\n\nNeymar da Silva Santos J&#250;nior Mogi das Cruzes 5 de fevereiro de 1992 &#233; um futebolista brasileiro que atua como atacante Atualmente joga pelo AlHilal e pela Sele&#231;&#227;o Brasileira &#201; considerado o principal futebolista brasileiro da atualidade e um dos melhores do mundo11121314 sendo o maior artilheiro da Sele&#231;&#227;o Brasileira15 Revelado pelo Santos em 2009 Neymar ganhou diversos t&#237;tulos com o clube incluindo dois Campeonatos Paulistas seguidos uma Copa do Brasil e uma Libertadores com esse &#250;ltimo sendo o primeiro do Santos desde 1963 Ganhou por duas vezes seguidas o pr&#234;mio de melhor jogador sulamericano do ano em 2011 e 2012 e um pr&#234;mio Pusk&#225;s de gol mais bonito do ano em 201116 Em 2013 foi vendido ao Barcelona ap&#243;s ser protagonista da conquista da Copa das Confedera&#231;&#245;es de 2013 pela Sele&#231;&#227;o Brasileira Considerada a venda mais cara da hist&#243;ria do futebol brasileiro Neymar na sua segunda temporada pelo clube espanhol estrelando um trio de ataque ao lado de Lionel Messi e Luis Su&#225;rez conquistou a tr&#237;plice coroa de La Liga Copa del Rey e Liga dos Campe&#245;es da UEFA terminando como um dos artilheiros da &#250;ltima e se consagrando como um dos melhores futebolistas do mundo sendo finalista da Bola de Ouro da FIFA por suas atua&#231;&#245;es no mesmo ano Question: Carreira futebol&#237;stica de Neymar Jr\nHelpful Answer:\n\nNeymar da Silva Santos J&#250;nior Mogi das Cruzes 5 de fevereiro de 1992 &#233; um futebolista brasileiro que atua como atacante Atualmente joga pelo AlHilal e pela Sele&#231;&#227;o Brasileira &#201; considerado o principal futebolista brasileiro da atualidade e um dos melhores do mundo11121314 sendo o maior artilheiro da Sele&#231;&#227;o Brasileira15 Revelado pelo Santos em 2009 Neymar ganhou diversos t&#237;tulos com o clube incluindo dois Campeon'}</code></pre><p>We will create a simple chatbot that takes input queries and generates answers.</p><pre><code>def rag_chatbot():
  input_question = input("Pergunte qualquer coisa: ")
  print("\n")
  print("Resposta:\n")
  response = rag_pipeline(input_question)
  return response['result']</code></pre><pre><code>rag_chatbot()</code></pre><pre><code>Pergunte qualquer coisa: O que &#233; Festival de Carnaval no Brasil?


Resposta:


'\nO Carnaval brasileiro &#233; uma das festas mais famosas e vibrantes do mundo celebrada em todo o pa&#237;s com uma mistura de m&#250;sica dan&#231;a desfiles e tradi&#231;&#245;es culturais Originado de tradi&#231;&#245;es europeias africanas e ind&#237;genas o Carnaval no Brasil tornouse uma manifesta&#231;&#227;o &#250;nica e cheia de energia que reflete a diversidade e a criatividade do povo brasileiro A hist&#243;ria do Carnaval no Brasil remonta aos tempos coloniais quando os colonizadores portugueses trouxeram suas festas e tradi&#231;&#245;es religiosas como o Entrudo que envolvia jogos de &#225;gua e tinta Com o tempo essas celebra&#231;&#245;es foram influenciadas pelas tradi&#231;&#245;es africanas trazidas pelos escravos como o batuque e as dan&#231;as rituais No s&#233;culo 19 surgiram os primeiros blocos carnavalescos e cord&#245;es que reuniam pessoas para desfilarem pelas ruas ao som de m&#250;sicas e instrumentos improvisados Com o passar dos anos o Carnaval foi se tornando cada vez mais organizado com a cria&#231;&#227;o das escolas de samba e dos desfiles competitivos Hoje o Carnaval brasileiro &#233; conhecido por seus desfiles extravagantes especialmente no Rio de Janeiro e em S&#227;o Paulo onde as escolas de samba competem em uma verdadeira batalha pelo t&#237;tulo de campe&#227; do Carnaval Os desfiles apresentam carros aleg&#243;ricos elaborados fantasias deslumbrantes e performances emocionantes tudo ao som de samba enredo Al&#233;m dos desfiles o Carnaval tamb&#233;m &#233; celebrado com festas de rua bailes e blocos de Carnaval onde as pessoas se re&#250;nem para dan&#231;ar cantar e se divertir As festividades come&#231;am oficialmente na sextafeira antes da Quartafeira de Cinzas e continuam at&#233; a ter&#231;afeira seguinte conhecida como o dia do Carnaval Os desfiles s&#227;o realizados em v&#225;rios estados brasileiros como Rio de Janeiro S&#227;o Paulo Minas Gerais e Bahia Onde o Carnaval &#233; mais famoso e popularizado O Carnaval brasileiro &#233; uma mistura de cultura que reflete.&#8217;</code></pre><h3>Conclusion:</h3><p>This is the simplest way we can build a Portuguese language-based chatbot using an open-source LLM. You can use the Streamlit app for chatbot UI for interactive ways of chatting. Also, you can use more GPUs to train your model for higher accuracy. You can deploy your model to the endpoint on AWS so you will get faster and better inference time.</p><p>That&#8217;s it for today. Feel free to ask any questions in the comments section. If you found this blog valuable, do give an upvote and follow me on <a href="https://www.linkedin.com/in/karanshingde/">LinkedIn</a>.</p>]]></content:encoded></item><item><title><![CDATA[Build an Audio-Driven Speaker Recognition System Using Open-Source Technologies — Resemblyzer and…]]></title><description><![CDATA[Build an Audio-Driven Speaker Recognition System Using Open-Source Technologies &#8212; Resemblyzer and QdrantDB.]]></description><link>https://kmeanskaran.substack.com/p/build-an-audio-driven-speaker-recognition-system-using-open-source-technologies-resemblyzer-and-6499cf0246eb</link><guid isPermaLink="false">https://kmeanskaran.substack.com/p/build-an-audio-driven-speaker-recognition-system-using-open-source-technologies-resemblyzer-and-6499cf0246eb</guid><dc:creator><![CDATA[Karan Shingde]]></dc:creator><pubDate>Wed, 17 Jan 2024 11:26:30 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/d86c5208-6359-4ca3-8461-c462ba3a2a82_1024x538.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Build an Audio-Driven Speaker Recognition System Using Open-Source Technologies&#8202;&#8212;&#8202;Resemblyzer and QdrantDB.</h3><h3>Introduction</h3><p>In this article, we are going to explore how to match the voice of a speaker with an existing set of voices. You can think of it like a biometric system but using the human voice, unlike physical senses such as the thumb and the eye. To achieve this, we will use the magic of vector embeddings and open-source technologies.</p><p>This type of technology is used in Google Assistant or Siri. When you buy a new device, like an Android phone, while setting up Google on your system, it asks for your voice to capture its pattern, vocals, and so on, for security reasons. This is so that only you can access Google Assistant by saying &#8220;Ok,&nbsp;google&#8221;.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!_F0L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!_F0L!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png 424w, /__u/substackcdn.com/image/fetch/$s_!_F0L!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png 848w, /__u/substackcdn.com/image/fetch/$s_!_F0L!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png 1272w, /__u/substackcdn.com/image/fetch/$s_!_F0L!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_webp, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!_F0L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!_F0L!, /__u/kmeanskaran.substack.com/w_424, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png 424w, /__u/substackcdn.com/image/fetch/$s_!_F0L!, /__u/kmeanskaran.substack.com/w_848, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png 848w, /__u/substackcdn.com/image/fetch/$s_!_F0L!, /__u/kmeanskaran.substack.com/w_1272, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png 1272w, /__u/substackcdn.com/image/fetch/$s_!_F0L!, /__u/kmeanskaran.substack.com/w_1456, /__u/kmeanskaran.substack.com/c_limit, /__u/kmeanskaran.substack.com/f_auto, /__u/kmeanskaran.substack.com/q_auto:good, /__u/kmeanskaran.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42822e58-8e1a-4dab-9e49-920633252da6_1024x538.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Made by Karan&nbsp;Shingde</figcaption></figure></div><p>Before we get into the details, let&#8217;s understand first what vector embedding is and how it has been used for&nbsp;audio.</p><h3>Vector Embeddings for&nbsp;Audio</h3><p>Vector embeddings are a way to represent objects, such as words, sentences or, in our case, audio data, as vectors in a mathematical space. Audio data can be represented as vectors, where different aspects of the audio (features like frequency, amplitude, etc.) are mapped to specific positions in the&nbsp;vector.</p><p>In the context of audio data, machine learning models can be trained to learn these embeddings. The model analyzes the patterns and characteristics of the audio data to generate meaningful vector representations. Once the model is trained, it can encode audio data by transforming it into a vector representation. This vector now captures important information about the audio&#8217;s content and characteristics.</p><p>Audio content will have vectors that are close together in the embedding space. This allows for tasks like audio similarity comparison, where you can quickly identify how similar two audio clips are by measuring the distance between their respective embeddings. To generate vector embeddings, we will use an open-source tool called <em><strong>Resemblyzer</strong></em> and store those vectors in<em><strong> Qdrant&nbsp;DB.</strong></em></p><blockquote><p>We have a set of audio clips of some famous personalities: <em><strong>Cristiano Ronaldo, Donald Trump, and Homer Simpson</strong> </em>(yes, he is&nbsp;famous).</p></blockquote><h3>Resemblyzer: An&nbsp;Overview</h3><p>Resemblyzer allows us to derive high-level representation of voice through a deep learning model. It simplifies the life of developers by enabling them to convert audio clips into vectors with just a few lines of code, eliminating the need for neural networks. <em><a href="https://github.com/resemble-ai/Resemblyzer">See official github repository</a>.</em></p><p>Install Resemblyzer for Python&nbsp;(3.5+)</p><pre><code>pip install resemblyzer
</code></pre><blockquote><p>I&#8217;m using Google Colab with a free T4 GPU for this task. You can also use CPU, but it may take a long time. <a href="https://drive.google.com/drive/folders/1803t9CxJDiwtNvPif16S4chnLxkYZkEY?usp=sharing">Click here to get audio&nbsp;data</a>.</p></blockquote><p>Let&#8217;s begin with the coding&nbsp;part:</p><pre><code># import necessary libraries
from resemblyzer import preprocess_wav, VoiceEncoder
from  pathlib import Path 
from tqdm import tqdm 
import numpy as np 
from Ipython,display import Audio 
from itertools import groupby
import heapq

# run sample audio
audio_sample = Audio(&#8216;path-to-audio-folder/train/Trump.mp3&#8217;, autoplay=True)
display(audio_sample)</code></pre><p><strong>PLAY:</strong> <strong><a href="https://drive.google.com/file/d/1l40sD829Sr_ENSyMwKJjMqjAilLU0dBd/view?usp=drive_link">Trump.mp3</a></strong></p><p>Let&#8217;s fetch audio clips from the train&nbsp;folder.</p><pre><code># Get all the audio clips data file which is in ".mp3" format.
wav_fpaths = list(Path("path-to-audio-folder/train").rglob("*.mp3"))
speakers =list(map(lambda wav_fpath: wav_fpath.stem, wav_fpaths))
print(speakers)</code></pre><pre><code>['Ronaldo', 'Ronaldo2', 'Homer', 'Homer2', 'Trump']</code></pre><p>Now, the important part, we will unleash the power of Resemblyzer and convert audio clips into the vector embeddings with just a few lines of code. Preprocess the waves first for all audio&nbsp;clips.</p><pre><code>wavs = np.array(list(map(preprocess_wav, tqdm(wav_fpaths, &#8220;Preprocessing wavs&#8221;. len(wav_fpaths)))), dtype=object)
speaker_wavs = {speaker: wavs[list(indiices] for speaker, indices in groupby(range(len(wavs)), lambda i: speakers[i])}
print(speaker_wavs)</code></pre><pre><code>{'Ronaldo': array([array([ 0.00045622, -0.00088888,  0.00016845, ..., -0.00079568,
               -0.00718354, -0.01011641], dtype=float32)               ],
       dtype=object),
 'Ronaldo2': array([array([ 0.0025312 ,  0.00321749,  0.00460094, ..., -0.01093079,
               -0.01293177, -0.01618683], dtype=float32)               ],
       dtype=object),
 'Homer': array([array([0., 0., 0., ..., 0., 0., 0.], dtype=float32)], dtype=object),
 'Homer2': array([array([ 1.33051715e-14,  3.98843861e-14, -3.70518893e-15, ...,
                5.39025990e-04, -5.10490616e-04, -5.79551968e-04], dtype=float32)],
       dtype=object),
 'Trump': array([array([-0.0165875 ,  0.03297266, -0.01565401, ..., -0.03698713,
               -0.03372933, -0.02938525], dtype=float32)               ],
       dtype=object)}</code></pre><p>In the above code, we converted these sound waves into numerical representations with a few lines of code and without using any neural&nbsp;network.</p><p>Now, convert these numerical representations into embeddings.</p><pre><code># compute the embeddings
encoder = VoiceEncoder(&#8220;cuda&#8221;)
utterance_embeds = np.array(list(map(encoder.embed_utterance, 
print(utterance_embeds)</code></pre><pre><code>[[0.         0.         0.0173962  ... 0.         0.04333723 0.00142971]
 [0.         0.00967959 0.00503905 ... 0.04058945 0.09630667 0.0495304 ]
 [0.15830468 0.         0.01373593 ... 0.         0.         0.        ]
 [0.18647183 0.         0.11558624 ... 0.         0.         0.        ]
 [0.         0.11265804 0.         ... 0.         0.         0.14819394]]</code></pre><p>This vector contains a float object where each row represents each audio&nbsp;clip.</p><p>For this task we are using Qdrant DB as our primary vector database. So, for that, we need to convert this representation into a suitable format. Basically, we need a list of dictionaries where each dictionary contains key as id and vector as keys. Id will be an incremental numeral&nbsp;value.</p><p>To get similar vectors, a unique id must be assigned to the&nbsp;vectors.</p><pre><code># Create an empty list to hold the embeddings in the desired format
embeddings = []

# Iterate through each embedding in the array
for i, embedding in enumerate(utterance_embeds):
   # Create a dictionary with &#8220;id&#8221; and &#8220;vector&#8221; keys
   embedding_dict  = {&#8220;id&#8221;:i+1, &#8220;vector&#8221;:embedding.tolist()} # Start IDs from 1
   # Append the dictionary to the embeddings list
   embeddings.append(embedding_dict)
</code></pre><h3>QdrantDB: An&nbsp;Overview</h3><p>Qdrant DB is one of the most popular vector databases out there. Using Qdrant DB, web developers can store embeddings and retrieve them seamlessly. Here is the <a href="https://qdrant.tech/documentation/">official documentation</a>.</p><p>To start with Qdrant DB, <a href="https://qdrant.to/cloud">Sign up </a>on their Cloud Service to start with their free tier which has limits of up to 1GB per cluster. Get your API key (copy it locally and safely&#8202;&#8212;&#8202;you can&#8217;t see the API key again after copying).</p><p>For Python Qdrant DB has its own API <em><strong>qdrant_client </strong></em>which is very easy to use with fewer lines of code. Let&#8217;s set-up Qdrant&nbsp;DB.</p><p>Install <em><strong>qdrant_client</strong></em> via&nbsp;pip:</p><pre><code>pip install qdrant_client</code></pre><pre><code>import qdrant_client
qdrant_uri = 'paste-your-db-uri' # Paste your URI
qdrant_api_key = 'paste-your-api-key' # Paste your API KEY
</code></pre><p>Let&#8217;s create a collection in the database; here the meaning of collection is the same as MongoDB collection.</p><pre><code># Create a collection
vectors_config = qdrant_client.http.models.VectorParams(
  size=256, # requires for embeddings from resemblyzer
  distance=qdrant_client.http.models.Distance.COSINE
)</code></pre><p>Now, after initializing QdrantDB, we will upsert (or add) embeddings from Resemblyzer.</p><pre><code># Upsert embeddings
client.upsert('my-collection', embeddings)</code></pre><p>Till here we stored our audio samples in an encoded version in Qdrant DB. Now we will test this using a new voice, which has a record in the database.</p><h3>Speaker Recognition:</h3><p>To recognize the user with a new voice is all about finding a similarity between the new voice and the set of voices already stored. For example, take the new voice of Cristiano Ronaldo and check if it&#8217;s recognized or not. We already have Ronaldo&#8217;s voice in the database.</p><blockquote><p>I&#8217;m taking the iconic short speech by Ronaldo, which he gave after winning the&nbsp;UCL:</p></blockquote><blockquote><p>&#8220;<strong>Muchas gracias afici&#243;n esto para vosotros. Siuuuuuuuuu!&#8221;</strong></p></blockquote><p><strong>PLAY</strong>: <strong><a href="https://drive.google.com/file/d/1YTf-ImkbH7tVv8N-TL3eWheXrJiWIf_F/view?usp=drive_link">Siuu.mp3</a></strong></p><p>Convert the new voice into embeddings</p><pre><code>test_wav = preprocess_wav(&#8220;/content/drive/MyDrive/audio_data_colab/Siuu.mp3&#8221;)
# Create a voice encoder object
test_embeddings = encoder.embed_utterance(test_wav)

# Search related embeddings
results = client.search(&#8220;my-collection&#8221;, test_embeddings)
print(results)</code></pre><pre><code>[ScoredPoint(id=2, version=0, score=0.6956655, payload={}, vector=None, shard_key=None),
 ScoredPoint(id=1, version=0, score=0.6705738, payload={}, vector=None, shard_key=None),
 ScoredPoint(id=5, version=0, score=0.56731033, payload={}, vector=None, shard_key=None),
 ScoredPoint(id=3, version=0, score=0.535391, payload={}, vector=None, shard_key=None),
 ScoredPoint(id=4, version=0, score=0.42906034, payload={}, vector=None, shard_key=None)]</code></pre><p>By the above result you can see that the ids 1 and 2 are associated with the Ronaldo clip (we did this in the embedding code). The highest score is about 70%, which is fine because we have a very small amount of data. Also the length of the clips are 3&#8211;4 seconds on an average. You can add more data and try this&nbsp;out.</p><p>To get top 2 similar results, just run the following code (you can also do it for top 1 or top 3 and then decide based on mode in top 3&nbsp;case).</p><pre><code># Get the top two results based on scores, handling potential ties
top_two_results = heapq.nlargest(2, results, key=lambda result: result.score)

# Extract and align IDs, considering potential ties
top_two_ids = sorted({result.id - 1 for result in top_two_results}) # Remove duplicates

# Get corresponding names, checking for valid IDs
top_two_names = []
for aligned_id in top_two_ids:
 if 0 &lt;= aligned_id &lt; len(speakers):
  top_two_names.append(speakers[aligned_id])

 else:
  print(f&#8221;Invalid ID {aligned_id + 1} encountered.&#8221;)

print(&#8220;Top two speakers: &#8220;, top_two_names)</code></pre><pre><code>Top two speakers: ['Ronaldo', 'Ronaldo2']</code></pre><p>Yes! It&#8217;s a match. We have successfully verified the new voice with the existing set of&nbsp;voices.</p><h3>Conclusion</h3><p>In this article we implemented the audio-driven speaker recognition with just a few lines of code by using open-source technologies such as <strong>Resemblyzer</strong> and <strong>Qdrant DB</strong>. Resemblyzer is the easiest way to work on audio data and encode them into embeddings. There is no need for a neural network or transformer architecture. Qdrant DB, on other hand, provides an efficient way to store and retrieve embeddings.</p><p>Thanks for reading this article. Don&#8217;t forget to upvote, follow and subscribe my newsletter on&nbsp;Medium.</p><h3>References</h3><p><a href="https://qdrant.tech/documentation/">Qdrant Documentation&#8202;&#8212;&#8202;Qdrant</a></p><p><a href="https://github.com/resemble-ai/Resemblyzer">resemble-ai/Resemblyzer: A python package to analyze and compare voices with deep learning (github.com)</a></p>]]></content:encoded></item></channel></rss>