<?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[AI with Fafa]]></title><description><![CDATA[Everything AI from my lens]]></description><link>https://fafacodes.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!8uMu!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a78cf07-5725-4abe-8da0-4716cd500518_1280x1280.png</url><title>AI with Fafa</title><link>https://fafacodes.substack.com</link></image><generator>Substack</generator><lastBuildDate>Mon, 06 Apr 2026 01:12:44 GMT</lastBuildDate><atom:link href="https://fafacodes.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Fafa]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[fafacodes@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[fafacodes@substack.com]]></itunes:email><itunes:name><![CDATA[Fafa]]></itunes:name></itunes:owner><itunes:author><![CDATA[Fafa]]></itunes:author><googleplay:owner><![CDATA[fafacodes@substack.com]]></googleplay:owner><googleplay:email><![CDATA[fafacodes@substack.com]]></googleplay:email><googleplay:author><![CDATA[Fafa]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[How I Integrate Claude Code to my Dev Workflow]]></title><description><![CDATA[Using commands, context, modes, and MCP servers in Claude]]></description><link>https://fafacodes.substack.com/p/how-i-integrate-claude-code-to-my</link><guid isPermaLink="false">https://fafacodes.substack.com/p/how-i-integrate-claude-code-to-my</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Thu, 02 Apr 2026 15:43:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5f1247f9-714c-4cbe-983a-e7aa3524d1d0_3024x4032.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p style="text-align: justify;">Claude Code is arguably one of the best coding assistants right now. It allows you to use AI to execute tasks directly from your terminal. You give it a task, and it figures out what needs to be done to complete it. It decides the steps required, chooses the tools or models to use, and works with what is available within its context.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!S5ws!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!S5ws!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png 424w, https://substackcdn.com/image/fetch/$s_!S5ws!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png 848w, https://substackcdn.com/image/fetch/$s_!S5ws!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png 1272w, https://substackcdn.com/image/fetch/$s_!S5ws!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!S5ws!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png" width="1718" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:1718,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:73216,&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://fafacodes.substack.com/i/191562146?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c92a080-5104-4c4f-a715-cf2f2b76ed76_1718x480.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!S5ws!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png 424w, https://substackcdn.com/image/fetch/$s_!S5ws!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png 848w, https://substackcdn.com/image/fetch/$s_!S5ws!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.png 1272w, https://substackcdn.com/image/fetch/$s_!S5ws!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44e09d5f-2ae9-4259-b3eb-c37b593ff32e_1718x480.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 role="img" 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><title></title><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">Claude Code running on terminal with claude command after installation</figcaption></figure></div><p style="text-align: justify;">It can refer to other files, pull in instructions from different sources, and connect to other systems when needed. It operates beyond a simple prompt-response flow and acts more like a coding agent that can carry out a sequence of actions to get to an outcome.</p><p style="text-align: justify;">Honestly, it is a really useful tool to have in your developer workflow. Here are some of the things I found useful while using it.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><h3>Adding Context to a Project for Claude</h3><p style="text-align: justify;">When working on a project, giving Claude the right context is key. Providing too much information at once can actually reduce its performance. Claude works best when instructions are structured clearly and concisely.</p><p style="text-align: justify;">One way to set this up is by running the <code>/init</code> command in Claude on your project. This lets Claude analyse the entire codebase to understand the project&#8217;s purpose, architecture, important commands, critical files, coding patterns, and structure. After this analysis, Claude generates a summary and writes it to a <code>Claude.md</code> file, usually stored in the home directory of your project.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Mizh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Mizh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png 424w, https://substackcdn.com/image/fetch/$s_!Mizh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png 848w, https://substackcdn.com/image/fetch/$s_!Mizh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!Mizh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Mizh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png" width="1936" height="1000" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1000,&quot;width&quot;:1936,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:204717,&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;:false,&quot;internalRedirect&quot;:&quot;https://fafacodes.substack.com/i/191562146?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa14bac09-14df-46ab-8a91-b3dff88908d0_1936x1000.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Mizh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png 424w, https://substackcdn.com/image/fetch/$s_!Mizh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png 848w, https://substackcdn.com/image/fetch/$s_!Mizh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!Mizh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa23c486e-13af-4beb-bd4a-b065a54a124e_1936x1000.png 1456w" sizes="100vw"></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 role="img" 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><title></title><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">/init command run on Claude to generate a Claude.md file</figcaption></figure></div><p style="text-align: justify;">The <code>Claude.md</code> file serves two purposes. First, it guides Claude through the codebase by highlighting important aspects like coding style, architecture, and structure. Second, it allows you to include custom instructions for Claude. Every request you make to Claude automatically includes this file, acting like a persistent system prompt. Without it, you would need to repeat context in each prompt, which can be tedious.</p><p>The <code>Claude.md</code> file can exist in three locations:</p><ol><li><p style="text-align: justify;"><code>Claude.md</code> &#8211; Generated with the <code>/init</code> command, this version can be committed to version control and shared with other engineers.</p></li><li><p style="text-align: justify;"><code>Claude.local.md</code> &#8211; Contains personal or private instructions that should not be shared.</p></li><li><p style="text-align: justify;"><code>~/.claude/Claude.md</code> &#8211; Applies to all projects on your machine, providing global instructions that Claude should always follow.</p></li></ol><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/how-i-integrate-claude-code-to-my?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading AI with Fafa! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/how-i-integrate-claude-code-to-my?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://fafacodes.substack.com/p/how-i-integrate-claude-code-to-my?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p style="text-align: justify;">You can also add or edit instructions directly. Typing a hash (<code>#</code>) followed by a command, like <code># XYZ</code>, updates the appropriate section in your <code>Claude.md</code> file. To reference files in your project, you can use the at sign (<code>@</code>) to point Claude to a specific file, either in your codebase or within your <code>Claude.md</code> file.</p><p style="text-align: justify;">This system keeps Claude aligned with your project, ensures consistent behaviour, and allows for customisations without repeating instructions.</p><h3>Modes</h3><p>Two modes Claude can be used in are&nbsp;<strong>planning&nbsp;</strong>and&nbsp;<strong>thinking</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6Mh0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6Mh0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png 424w, https://substackcdn.com/image/fetch/$s_!6Mh0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png 848w, https://substackcdn.com/image/fetch/$s_!6Mh0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png 1272w, https://substackcdn.com/image/fetch/$s_!6Mh0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6Mh0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png" width="622" height="466" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:466,&quot;width&quot;:622,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:60741,&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://fafacodes.substack.com/i/191562146?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6Mh0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png 424w, https://substackcdn.com/image/fetch/$s_!6Mh0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png 848w, https://substackcdn.com/image/fetch/$s_!6Mh0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.png 1272w, https://substackcdn.com/image/fetch/$s_!6Mh0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc88d9196-593c-493f-ac9a-02b57fce1fc7_622x466.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 role="img" 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><title></title><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">Mode selection view from the Claude Code tool bar</figcaption></figure></div><p style="text-align: justify;"><strong>Planning mode</strong> is for reviewing what Claude intends to do before it actually executes a task. Instead of producing the implementation right away, it shows the steps it plans to take. This is especially useful for complex tasks that require extensive research across the codebase.</p><p style="text-align: justify;">To enable planning mode, press <strong>Shift</strong> and tap twice. This prevents Claude from starting implementation immediately, so you can approve its plan first. If you already have auto-accept edits enabled, pressing <strong>Shift + Tab</strong> once also puts you in planning mode.</p><p><strong>Thinking mode</strong> is for deeper analysis. It is triggered by keywords that control the depth of reasoning:</p><ul><li><p><code>think</code> &#8211; basic reasoning</p></li><li><p><code>think more</code> &#8211; extended reasoning</p></li><li><p><code>think a lot</code> &#8211; comprehensive reasoning</p></li><li><p><code>think longer</code> &#8211; extended time reasoning</p></li><li><p><code>ultra-think</code> &#8211; maximum reasoning capacity</p></li></ul><p style="text-align: justify;">Use the thinking mode when you want Claude to analyse a problem deeply before addressing it. Planning mode, in contrast, focuses on broader research across the project rather than deep analysis.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a coffee &#9749;&#65039;  &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a coffee &#9749;&#65039;  &#128176;</span></a></p><p>You can combine both modes to guide Claude more intentionally, but doing so consumes more tokens. This combination helps you be deliberate about what changes are made, when they happen, and what to expect from those changes.</p><h3>Managing Context with <code>/compact</code></h3><p>One command that becomes very useful for maintaining and controlling context in your conversations is the <code>/compact</code> command.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kAN_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kAN_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png 424w, https://substackcdn.com/image/fetch/$s_!kAN_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png 848w, https://substackcdn.com/image/fetch/$s_!kAN_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png 1272w, https://substackcdn.com/image/fetch/$s_!kAN_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kAN_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png" width="1306" height="416" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:416,&quot;width&quot;:1306,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:43751,&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://fafacodes.substack.com/i/191562146?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kAN_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png 424w, https://substackcdn.com/image/fetch/$s_!kAN_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png 848w, https://substackcdn.com/image/fetch/$s_!kAN_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.png 1272w, https://substackcdn.com/image/fetch/$s_!kAN_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29e72cf5-d4de-4d7a-9729-6d6dd60fccaa_1306x416.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 role="img" 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><title></title><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">Running the /compact command on Claude Code</figcaption></figure></div><p>When you are working on a task over a long conversation, the context can build up quickly. You may not want to start a new thread, but at the same time, you might be done with the existing context in that conversation.</p><p>The <code>/compact</code> command solves this by compressing the entire conversation history into a summary. This frees up more context while still preserving the key information from what has already been discussed.</p><p>It is a practical way to continue working in the same conversation or transition into a new one without losing the important context you have built up.</p><h3>Custom Commands</h3><p style="text-align: justify;">Claude comes with built-in commands that you can access by typing <code>/</code>. But you can also create your own custom commands.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d3Bq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d3Bq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png 424w, https://substackcdn.com/image/fetch/$s_!d3Bq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png 848w, https://substackcdn.com/image/fetch/$s_!d3Bq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png 1272w, https://substackcdn.com/image/fetch/$s_!d3Bq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d3Bq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png" width="1306" height="810" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/99136760-b136-4000-b50e-769daeb57300_1306x810.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:810,&quot;width&quot;:1306,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:91331,&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://fafacodes.substack.com/i/191562146?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!d3Bq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png 424w, https://substackcdn.com/image/fetch/$s_!d3Bq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png 848w, https://substackcdn.com/image/fetch/$s_!d3Bq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.png 1272w, https://substackcdn.com/image/fetch/$s_!d3Bq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99136760-b136-4000-b50e-769daeb57300_1306x810.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 role="img" 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><title></title><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">Viewing the list of available commands on Claude Code</figcaption></figure></div><p style="text-align: justify;">This is especially useful for repetitive tasks where you want to maintain consistency in how things are done. Instead of rewriting the same instructions every time, you can define a custom command once and reuse it.</p><p style="text-align: justify;">To set this up, you create a <code>.claude</code> folder in your project directory. Inside it, you create another folder called <code>commands</code>. For each custom command, you create a markdown file named after the command, for example <code>command-name.md</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xZP5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xZP5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png 424w, https://substackcdn.com/image/fetch/$s_!xZP5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png 848w, https://substackcdn.com/image/fetch/$s_!xZP5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png 1272w, https://substackcdn.com/image/fetch/$s_!xZP5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xZP5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png" width="1456" height="1725" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1725,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:586495,&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://fafacodes.substack.com/i/191562146?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xZP5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png 424w, https://substackcdn.com/image/fetch/$s_!xZP5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png 848w, https://substackcdn.com/image/fetch/$s_!xZP5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.png 1272w, https://substackcdn.com/image/fetch/$s_!xZP5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5571968-4345-40d0-9e35-f0e4831de3c5_1592x1886.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 role="img" 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><title></title><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">Creating a custom command on Claude Code</figcaption></figure></div><p>To use the command in Claude, you simply type <code>/command-name</code>.</p><p style="text-align: justify;">You can also make these commands more flexible by passing arguments to them, such as file paths, text, or numbers. This allows you to adapt the command to different situations while keeping the structure consistent.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0FSh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0FSh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png 424w, https://substackcdn.com/image/fetch/$s_!0FSh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png 848w, https://substackcdn.com/image/fetch/$s_!0FSh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png 1272w, https://substackcdn.com/image/fetch/$s_!0FSh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0FSh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png" width="1456" height="1324" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1324,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:157451,&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://fafacodes.substack.com/i/191562146?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0FSh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png 424w, https://substackcdn.com/image/fetch/$s_!0FSh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png 848w, https://substackcdn.com/image/fetch/$s_!0FSh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.png 1272w, https://substackcdn.com/image/fetch/$s_!0FSh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0460798d-ff89-4534-b3aa-dd6f8e34339f_1474x1340.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 role="img" 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><title></title><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">Running a custom command on Claude Code</figcaption></figure></div><p>This approach helps you standardise workflows and repeatedly provide specific instructions as part of your context.</p><h3>MCP Servers</h3><p style="text-align: justify;">MCP is a way to enhance the functionality of Claude Code and coding agents by giving them access to external software. Instead of figuring everything out on their own, they can leverage tools that already exist to perform specific tasks.</p><p style="text-align: justify;">For example, if you want to interact with a database, run tests on your application, integrate with a development tool, or perform operations on your file system, there is already software designed for these use cases. MCP allows AI to access that software through MCP servers, rather than trying to handle everything itself.</p><p style="text-align: justify;">To use an MCP server, you add it to your project using a command like <code>claude mcp add</code> followed by the server details. You can then manage permissions in the <code>.claude/settings.local.json</code> file, where you define what the server is allowed to do.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nRDq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nRDq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png 424w, https://substackcdn.com/image/fetch/$s_!nRDq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png 848w, https://substackcdn.com/image/fetch/$s_!nRDq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png 1272w, https://substackcdn.com/image/fetch/$s_!nRDq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nRDq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png" width="990" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/db7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:990,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:79502,&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://fafacodes.substack.com/i/191562146?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nRDq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png 424w, https://substackcdn.com/image/fetch/$s_!nRDq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png 848w, https://substackcdn.com/image/fetch/$s_!nRDq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.png 1272w, https://substackcdn.com/image/fetch/$s_!nRDq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7c76c5-e4c8-4d6a-8d35-d40cd20335db_990x400.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 role="img" 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><title></title><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">Setting up an MCP server with Claude Code</figcaption></figure></div><p style="text-align: justify;">Once connected, you can simply reference the capability in your prompt. For example, if an MCP server is available for working with databases, you can ask Claude to build or connect to a database, and it will use that server to carry out the task.</p><p>This makes it easier to extend what Claude can do by plugging into tools that are already built for those functions.</p><p style="text-align: justify;"></p>]]></content:encoded></item><item><title><![CDATA[Managing Python Dependencies to Prevent Project Deployment Issues]]></title><description><![CDATA[Understanding dependencies, lock files, and modern package management using uv]]></description><link>https://fafacodes.substack.com/p/managing-python-dependencies-so-prevent</link><guid isPermaLink="false">https://fafacodes.substack.com/p/managing-python-dependencies-so-prevent</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Wed, 11 Mar 2026 12:21:53 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6c8ce724-c841-4131-8da9-cb0414f66fd5.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Difference between packages, library and dependencies</h2><p>Before discussing package management and dependency handling in a Python project, it helps to understand the basic building blocks Python uses to organise and reuse code. The Python documentation clearly defines <strong>modules</strong>, <strong>packages</strong>, and <strong>imports</strong>, but it does not explicitly define <strong>libraries</strong> or <strong>dependencies</strong>, even though these terms are commonly used in everyday development discussions. Understanding how these ideas relate to one another makes it easier to reason about project structure and dependency management.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><h3>Modules</h3><p>A <strong>module</strong> is the simplest unit of organisation in Python. It is essentially a single Python file that contains code such as functions, classes, or variables.</p><p>Modules exist to organise code logically. Instead of writing everything in a single large file, you break your program into smaller files, with each module handling a specific responsibility.</p><p>Example:</p><pre><code># math_utils.py

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b</code></pre><p>This file is a module. Another Python file can use it by importing it.</p><pre><code>import math_utils

result = math_utils.add(2, 3)</code></pre><p>At the most basic level, modules are how Python organises code into manageable units.</p><div><hr></div><h3>Packages</h3><p>A <strong>package</strong> is a collection of modules grouped into a directory so they can be organised and reused as a single unit.</p><p>Packages make it easier to structure larger projects and to distribute code that performs a specific function. If modules are individual files, packages are folders that contain related modules.</p><p>The key idea behind a package is <strong>shareability and reuse</strong>. Packages allow code that implements a specific functionality to be packaged in a way that others can install and import into their own projects.</p><p>Example package structure:</p><pre><code>my_package/
    __init__.py
    math_utils.py
    string_utils.py</code></pre><p>You can then import from that package:</p><pre><code>from my_package import math_utils</code></pre><p>In practice, packages are how most third-party functionality is distributed in Python. When you install something using <code>pip</code>, you are usually installing a package.</p><p>Example:</p><pre><code>pip install django-debug-toolbar</code></pre><p>After installing it, you can import it into your project because the package is now available in your Python environment.</p><p>So a useful way to think about it is:</p><ul><li><p><strong>Modules</strong> organise code inside a file</p></li><li><p><strong>Packages</strong> organise modules into a reusable structure</p></li></ul><div><hr></div><h3>Libraries</h3><p>A <strong>library</strong> is generally a broader collection of packages and modules that provide related functionality.</p><p>Unlike the previous terms, &#8220;library&#8221; is not a strict technical construct defined by Python itself. It is more of a conceptual grouping used by developers to describe a large body of reusable code.</p><p>For example, Python ships with what is commonly called the <strong>standard library</strong>, which includes modules and packages that come pre-installed with Python.</p><p>Examples from the Python standard library include:</p><ul><li><p><code>datetime</code> for working with dates and times</p></li><li><p><code>json</code> for working with JSON data</p></li><li><p><code>os</code> for interacting with the operating system</p></li><li><p><code>math</code> for mathematical operations</p></li></ul><p>Example usage:</p><pre><code>import datetime

now = datetime.datetime.now()</code></pre><p>You do not need to install these because they come bundled with Python.</p><p>So in simple terms:</p><ul><li><p>A <strong>package</strong> is a structured unit of code distribution</p></li><li><p>A <strong>library</strong> is a broader collection of packages and modules that provide related capabilities</p></li></ul><p>Libraries often contain multiple packages.</p><div><hr></div><h3>Dependencies</h3><p>A <strong>dependency</strong> is anything a project relies on to run correctly.</p><p>This term is less about code structure and more about <strong>project requirements</strong>. When we say a project has dependencies, we are referring to external packages or libraries that must be present for the application to function.</p><p>For example, if a web application uses Django and requests, those packages must exist in the environment before the application can run.</p><p>Example dependency list:</p><pre><code>Django==4.2
requests==2.31.0
psycopg2==2.9.7</code></pre><p>These dependencies are often recorded in files such as:</p><ul><li><p><code>requirements.txt</code></p></li><li><p><code>pyproject.toml</code></p></li><li><p><code>Pipfile</code></p></li></ul><p>This allows other developers to recreate the same environment.</p><p>Example:</p><pre><code>pip install -r requirements.txt</code></pre><p>In that sense, <strong>dependency is a contextual term</strong>. It describes the relationship between your project and the external code it needs.</p><div><hr></div><h3>Putting It All Together</h3><p>These concepts are closely related but operate at different levels.</p><ul><li><p><strong>Module: </strong>A single Python file containing code.</p></li><li><p><strong>Package: </strong>A directory of modules organised so they can be reused and distributed.</p></li><li><p><strong>Library: </strong>A broader collection of packages and modules that provide related functionality.</p></li><li><p><strong>Dependency: </strong>Any external library or package that your project requires to run.</p></li></ul><p>So when working on a real Python project, the flow often looks like this:</p><ol><li><p>Developers write <strong>modules</strong>.</p></li><li><p>Modules are grouped into <strong>packages</strong>.</p></li><li><p>Packages may belong to a larger <strong>library</strong>.</p></li><li><p>When your project uses that library, it becomes a <strong>dependency</strong> of your project.</p></li></ol><h2>Managing your project packages efficiently</h2><p>What actually makes a <strong>good package management workflow in Python?</strong></p><p>There are many tools available today. Some are older and widely used, such as pip. Others are newer and attempt to solve problems that developers have historically struggled with. One of the most recent tools gaining attention is <strong>uv</strong>.</p><p>To reason about which tools are better, it helps to define the criteria that matter.</p><h3>1. Usability</h3><p>The first consideration is usability.</p><p>A good package management tool should be easy to understand and easy to use. The commands required to initialise a project, install dependencies, or update packages should not be overly complex.</p><p>Good documentation is also critical. Developers will inevitably run into issues such as dependency conflicts or installation errors. When that happens, clear documentation makes the difference between solving the issue quickly and spending hours debugging environment problems.</p><p>In practice, tools that require fewer steps and clearer commands tend to reduce friction in development workflows.</p><div><hr></div><h3>2. Virtual Environment Management</h3><p>Another important factor is how the tool handles <strong>virtual environments</strong>.</p><p>Virtual environments isolate project dependencies so that different projects can use different packages or versions without interfering with each other.</p><p>For many beginners, this is one of the first confusing parts of Python development. It is very common to see developers install packages globally without realising that different projects may require different versions of the same dependency.</p><p>Some tools expect the developer to create and manage virtual environments manually. Others automatically create and manage environments as part of their workflow.</p><p>Understanding how a tool handles this isolation is important because environment issues are one of the most common causes of broken Python setups.</p><div><hr></div><h3>3. Python Version Management</h3><p>Python version compatibility is another critical consideration.</p><p>Different packages support different Python versions. A dependency that works perfectly with Python 3.11 might not work with Python 3.8, and vice versa.</p><p>A good package management tool should allow a project to clearly define which Python versions it supports. This ensures that the environment used during development matches the environment used in production.</p><p>Without this control, it becomes very easy to accidentally create setups that work locally but fail when deployed elsewhere.</p><div><hr></div><h3>4. Dependency Management</h3><p>The core responsibility of a package management workflow is tracking dependencies.</p><p>A project should have a clear and easily readable definition of the packages it depends on and their versions.</p><p>Developers should be able to add, remove, and inspect dependencies without manually editing configuration files or trying to infer what was installed previously.</p><p>Historically, many Python projects used a <code>requirements.txt</code> file for this purpose. However, tools like uv now rely on <code>pyproject.toml</code>, which has become the modern standard for defining project metadata and dependencies.</p><div><hr></div><h3>5. Reproducibility</h3><p>Reproducibility is one of the most important properties of a production grade system.</p><p>When a developer clones a repository and installs its dependencies, the environment they create should behave exactly the same as the environment used by the original developers.</p><p>Without reproducibility, applications may work today but fail weeks or months later when dependency versions change.</p><p>This is where <strong>lock files</strong> become essential.</p><div><hr></div><h3>6. Collaboration</h3><p>Finally, package management workflows should make collaboration straightforward.</p><p>Developers working on different operating systems such as macOS, Linux, or Windows should all be able to recreate the same environment.</p><p>A well defined dependency configuration and lock file ensure that every collaborator installs the exact same dependency graph, preventing the classic &#8220;it works on my machine&#8221; problem.</p><div><hr></div><h2>Why Modern Tools Like uv Are Gaining Popularity</h2><p>Traditionally, Python developers relied on <strong>pip</strong> to install packages.</p><p>pip works well as a package installer, but it was never designed to manage an entire dependency workflow. As a result, developers often had to combine multiple tools together:</p><ul><li><p>pip for installing packages</p></li><li><p>venv for creating virtual environments</p></li><li><p>requirements.txt for tracking dependencies</p></li></ul><p>This workflow works, but it requires manual steps.</p><p>For example, when using pip, developers often regenerate the dependency list manually using:</p><pre><code>pip freeze &gt; requirements.txt</code></pre><p>This command captures the packages installed in the environment and writes them into the requirements file.</p><p>Modern tools like <strong>uv</strong> streamline this process.</p><p>uv integrates several pieces of functionality into a single workflow:</p><ul><li><p>installing packages</p></li><li><p>managing virtual environments</p></li><li><p>resolving dependencies</p></li><li><p>maintaining dependency definitions</p></li><li><p>generating lock files</p></li></ul><p>It also performs dependency resolution extremely quickly. Because uv is implemented in Rust, it can resolve dependencies dramatically faster than traditional Python based tooling, often by an order of magnitude.</p><p>Instead of manually updating dependency files, uv automatically records project dependencies in the <code>pyproject.toml</code> file when new packages are added.</p><p>For example:</p><pre><code>uv add fastapi</code></pre><p>This command both installs the dependency and updates the project&#8217;s dependency definition.</p><div><hr></div><h2>Why Lock Files Matter</h2><p>One of the most important features introduced by modern dependency managers is the <strong>lock file</strong>.</p><p>A dependency definition file such as <code>pyproject.toml</code> usually describes the <strong>acceptable versions</strong> of dependencies.</p><p>For example:</p><pre><code>fastapi &gt;=0.110</code></pre><p>This means any compatible version of FastAPI can be installed.</p><p>However, dependencies themselves have their own dependencies. Over time, newer versions of those packages may be released. This can lead to different combinations of packages being installed at different times.</p><p>A project that worked perfectly today might fail months later because one of the indirect dependencies has changed.</p><p>A lock file solves this problem.</p><p>Instead of describing acceptable ranges, the lock file records the <strong>exact versions of every dependency in the entire dependency graph</strong>, including transitive dependencies.</p><p>For example:</p><pre><code>fastapi 0.110.0
pydantic 2.6.1
typing_extensions 4.9.0</code></pre><p>Because these versions are pinned, every environment created from the lock file will install the exact same package versions.</p><p>This guarantees that the environment used by one developer will match the environment used by another developer, as well as the environment used in production.</p><p>In uv, this information is stored in the <code>uv.lock</code> file.</p><p>When this file is committed to version control, anyone working on the project can recreate the same environment deterministically.</p><p>This dramatically reduces environment related bugs and makes Python applications far more reliable to build and maintain.</p><h2>Actually Using uv in a Project</h2><p>After understanding why dependency management matters and why modern tools like <strong>uv</strong> are becoming popular, the next step is very simple: actually using it in a project.</p><p>One of the things I like about uv is that the workflow is straightforward. The commands are minimal, and the tool handles a lot of the environment and dependency management automatically.</p><h3>Initialising a Project</h3><p>The first step is to initialise uv inside your project directory.</p><pre><code>uv init</code></pre><p>Running this command sets up the project for dependency management. It creates the necessary project configuration so that uv can track dependencies and manage the environment for the project.</p><p>In most cases, this will create or configure the <code>pyproject.toml</code> file, which is where the project metadata and dependency definitions live.</p><div><hr></div><h3>Adding Dependencies</h3><p>Once the project is initialised, dependencies can be added using the <code>uv add</code> command.</p><pre><code>uv add fastapi</code></pre><p>This installs the package and automatically records the dependency in the project&#8217;s configuration.</p><p>At the same time, uv generates a <strong>lock file</strong> called:</p><pre><code>uv.lock</code></pre><p>This file captures the exact versions of all dependencies, including transitive dependencies. Because of this, the environment can be recreated exactly the same way across different machines.</p><p>Unlike older workflows where dependency files often needed to be manually updated, uv updates the project definition automatically when new packages are added.</p><div><hr></div><h3>Grouping Dependencies</h3><p>Another useful feature is <strong>dependency grouping</strong>.</p><p>Not all dependencies serve the same purpose. Some are required for running the application, while others are only needed for development tasks such as testing or linting.</p><p>uv allows dependencies to be grouped so that they are organised more clearly.</p><p>For example:</p><pre><code>uv add --group dev pytest</code></pre><p>This adds <code>pytest</code> to a development dependency group instead of the main runtime dependencies.</p><p>Structuring dependencies this way keeps the project configuration cleaner and makes it easier to understand which packages are required for which part of the workflow.</p><div><hr></div><h3>Running Commands with uv</h3><p>To run commands within the project&#8217;s managed environment, uv provides the <code>uv run</code> command.</p><pre><code>uv run python app.py</code></pre><p>This runs the command using the environment that uv manages for the project. All dependencies defined in the project configuration and lock file are available when the command executes.</p><p>This removes the need to manually activate virtual environments before running scripts. uv ensures the correct environment is used automatically.</p><div><hr></div><h3>Why This Workflow Works Well</h3><p>What stands out to me about uv is how it simplifies several steps that historically required multiple tools.</p><p>Instead of juggling environment creation, package installation, dependency tracking, and lock files separately, uv brings these pieces together into a single workflow.</p><p>The result is a setup that is easier to reason about, easier to reproduce, and much less prone to the environment issues that Python developers have traditionally struggled with.</p><p>For a production project where reproducibility and collaboration matter, that is a significant improvement.</p><h2>Glossary and Definitions</h2><p>Based on <a href="https://docs.python.org/3/glossary.html">Offical Python docs</a>. </p><p><strong>namespace: </strong>The place where a variable is stored. Namespaces are implemented as dictionaries. There are the local, global and built-in namespaces as well as nested namespaces in objects (in methods). Namespaces support modularity by preventing naming conflicts.</p><p><strong>importing: </strong>The process by which Python code in one module is made available to Python code in another module.</p>]]></content:encoded></item><item><title><![CDATA[Diagnosing and Fixing the N+1 Query Problem in Django APIs]]></title><description><![CDATA[Using Django Debug Toolbar to inspect database queries and reduce an API endpoint from 627 to 9 DB queries.]]></description><link>https://fafacodes.substack.com/p/diagnosing-and-fixing-the-n1-query</link><guid isPermaLink="false">https://fafacodes.substack.com/p/diagnosing-and-fixing-the-n1-query</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Thu, 05 Mar 2026 21:02:14 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/60332b60-6907-4ae5-9246-70dbbd018240.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you build APIs long enough, you eventually hit a moment that forces you to slow down and really inspect what your code is doing.</p><p>For me, that moment happened while working on an endpoint that generated a report. On the surface, the code looked perfectly fine. The endpoint returned a structured output assembled from several related models. It worked locally. It returned the correct data. Everything seemed normal.</p><p>Until I inspected the SQL queries.</p><p>That single API request triggered <strong>627 database queries</strong> to generate a report for just <strong>five experiment objects</strong>.</p><p>At that point, I realised something important. As backend engineers, it is not enough for an API to work. We also need to understand <strong>how it works at the database level</strong>.</p><p>This post walks through the exact thought process I used to investigate the problem and reduce those queries to <strong>9</strong>. If you build APIs with <a href="https://www.djangoproject.com/">Django</a>, you will eventually run into this pattern.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div><hr></div><h1>The Scenario</h1><p>Imagine we are building a research platform.</p><p>Researchers submit studies. Each study has experiments. Each experiment records observations. Observations can contain notes and references to datasets.</p><p>Now, imagine we want to generate a <strong>research report</strong> for a study.</p><p>The report needs to include:</p><ul><li><p>experiments</p></li><li><p>observations</p></li><li><p>notes</p></li><li><p>datasets referenced</p></li></ul><p>All nested under the study.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rU6K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rU6K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png 424w, https://substackcdn.com/image/fetch/$s_!rU6K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png 848w, https://substackcdn.com/image/fetch/$s_!rU6K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png 1272w, https://substackcdn.com/image/fetch/$s_!rU6K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rU6K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png" width="928" height="1152" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1152,&quot;width&quot;:928,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2083158,&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://fafacodes.substack.com/i/189985141?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rU6K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png 424w, https://substackcdn.com/image/fetch/$s_!rU6K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png 848w, https://substackcdn.com/image/fetch/$s_!rU6K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.png 1272w, https://substackcdn.com/image/fetch/$s_!rU6K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a5acbb-ef0b-44c4-847a-5c23fb44c154_928x1152.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 role="img" 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><title></title><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">Illustration od data model relationships generated using Gemini</figcaption></figure></div><div><hr></div><h1>Data Models</h1><p>Here is a simplified version of the models.</p><pre><code>class Study(models.Model):
    title = models.CharField(max_length=200)
    created_at = models.DateTimeField()


class Experiment(models.Model):
    study = models.ForeignKey(
        Study,
        related_name=&#8221;experiments&#8221;,
        on_delete=models.CASCADE
    )
    title = models.CharField(max_length=200)


class Observation(models.Model):
    experiment = models.ForeignKey(
        Experiment,
        related_name=&#8221;observations&#8221;,
        on_delete=models.CASCADE
    )
    description = models.TextField()


class Note(models.Model):
    observation = models.ForeignKey(
        Observation,
        related_name=&#8221;notes&#8221;,
        on_delete=models.CASCADE
    )
    text = models.TextField()


class DatasetReference(models.Model):
    observation = models.ForeignKey(
        Observation,
        related_name=&#8221;datasets&#8221;,
        on_delete=models.CASCADE
    )
    dataset_name = models.CharField(max_length=200)</code></pre><div><hr></div><h1>Entity Relationship Overview</h1><p>You can visualise the relationships like this:</p><pre><code>Study
  |
  &#9492;&#9472;&#9472; Experiment
        |
        &#9492;&#9472;&#9472; Observation
              |        \
              |         \
              |          \
            Note     DatasetReference</code></pre><p>This kind of hierarchy is very common in real systems.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a Coffee &#9749;&#65039;  &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a Coffee &#9749;&#65039;  &#128176;</span></a></p><h1>The Reporting Endpoint</h1><p>Now we build an API endpoint that generates a report for a study.</p><pre><code>class StudyReportView(APIView):

    def get(self, request, study_id):
        study = get_object_or_404(Study, id=study_id)

        report = []

        for experiment in study.experiments.all():
            for observation in experiment.observations.all():

                notes = [n.text for n in observation.notes.all()]
                datasets = [d.dataset_name for d in observation.datasets.all()]

                report.append({
                    &#8220;experiment&#8221;: experiment.title,
                    &#8220;observation&#8221;: observation.description,
                    &#8220;notes&#8221;: notes,
                    &#8220;datasets&#8221;: datasets
                })

        return Response(report)</code></pre><p>At first glance, this code is perfectly readable. Nothing seems obviously wrong.</p><p>But the problem is hidden in the loops.</p><p>Every <code>.all()</code> triggers a database query.</p><div><hr></div><h1>The Hidden N+1 Problem</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QxKk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QxKk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png 424w, https://substackcdn.com/image/fetch/$s_!QxKk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png 848w, https://substackcdn.com/image/fetch/$s_!QxKk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png 1272w, https://substackcdn.com/image/fetch/$s_!QxKk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QxKk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png" width="1018" height="427" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:427,&quot;width&quot;:1018,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:46872,&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://fafacodes.substack.com/i/189985141?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QxKk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png 424w, https://substackcdn.com/image/fetch/$s_!QxKk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png 848w, https://substackcdn.com/image/fetch/$s_!QxKk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.png 1272w, https://substackcdn.com/image/fetch/$s_!QxKk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F676a0097-dd10-4886-bea9-9801b3c04541_1018x427.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 role="img" 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><title></title><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">N+1 queries</figcaption></figure></div><p>Let&#8217;s assume this study contains:</p><ul><li><p>5 experiments</p></li><li><p>25 observations</p></li><li><p>75 notes</p></li><li><p>50 dataset references</p></li></ul><p>Without optimisation, Django performs queries like this:</p><pre><code>1 query &#8594; load experiments
5 queries &#8594; load observations for each experiment
25 queries &#8594; load notes
25 queries &#8594; load dataset references
75 queries &#8594; load related datasets
490 repeated nested queries from loops</code></pre><p>Total:</p><pre><code>627 queries</code></pre><p>And this grows quickly as the dataset grows.</p><p>In a real system, this can easily become <strong>hundreds or thousands of queries</strong>.</p><div><hr></div><h1>Detecting the Problem with Django Debug Toolbar</h1><p>The easiest way to inspect this is the <strong><a href="https://django-debug-toolbar.readthedocs.io/en/latest/">Django Debug Toolbar</a></strong>.</p><p>Install it:</p><pre><code>pip install django-debug-toolbar</code></pre><p>Add it to <code>INSTALLED_APPS</code> and middleware.</p><p>Then run your API locally and open the endpoint in your browser.</p><p>The toolbar appears on the right side of the page.</p><p>Click <strong>SQL</strong>.</p><p>You will see something like this:</p><pre><code>Total queries: 627
Duplicate queries: 598</code></pre><p>Scrolling through the queries usually reveals the pattern immediately.</p><pre><code>SELECT ... FROM observation WHERE experiment_id = 1
SELECT ... FROM observation WHERE experiment_id = 2
SELECT ... FROM observation WHERE experiment_id = 3
SELECT ... FROM observation WHERE experiment_id = 4
SELECT ... FROM observation WHERE experiment_id = 5</code></pre><p>That repetition is the classic <strong>N+1 query problem</strong>.</p><div><hr></div><h1>Why This Happens</h1><p>When Django encounters this line:</p><pre><code>experiment.observations.all()</code></pre><p>It runs a query.</p><p>If you do that inside a loop, Django runs the same query structure repeatedly.</p><pre><code>1 query for experiments
N queries for observations
N queries for notes
N queries for datasets</code></pre><p>The database is doing unnecessary work.</p><div><hr></div><h1>The Fix: Prefetch Related</h1><p>Django provides a built-in way to solve this.</p><p><code>prefetch_related</code></p><p>It tells Django to fetch all related objects <strong>in bulk</strong> before the loop runs.</p><p>Instead of querying one object at a time, Django loads everything into memory first.</p><div><hr></div><h1>Optimized Query</h1><p>Update the queryset like this:</p><pre><code>study = (
    Study.objects
    .prefetch_related(
        &#8220;experiments&#8221;,
        &#8220;experiments__observations&#8221;,
        &#8220;experiments__observations__notes&#8221;,
        &#8220;experiments__observations__datasets&#8221;
    )
    .get(id=study_id)
)</code></pre><p>Now Django runs a small number of queries.</p><pre><code>1 query -&gt; study
1 query -&gt; experiments
1 query -&gt; observations
1 query -&gt; notes
1 query -&gt; datasets</code></pre><p>Total:</p><pre><code>5 queries</code></pre><p>That is a massive reduction.</p><div><hr></div><h1>What Changed</h1><p>Instead of this pattern:</p><pre><code>Loop &#8594; Query
Loop &#8594; Query
Loop &#8594; Query</code></pre><p>Django now does this:</p><pre><code>Query everything once
Serve related objects from memory</code></pre><p>The loops remain the same. Only the queryset changed.</p><div><hr></div><h1>What to Look For During Debugging</h1><p>When debugging database performance in Django APIs, I now follow a simple checklist.</p><ol><li><p>Open the endpoint locally with Django Debug Toolbar.</p></li><li><p>Inspect the <strong>SQL panel</strong>.</p></li><li><p>Look for repeated queries.</p></li><li><p>Identify which relationship causes them.</p></li><li><p>Add <code>prefetch_related</code> or <code>select_related</code>.</p></li><li><p>Run the request again and compare query counts.</p></li></ol><p>A healthy endpoint usually executes <strong>single-digit queries</strong> for most operations.</p><div><hr></div><h1>The Result</h1><p>In the case that triggered this investigation, the numbers looked like this:</p><p>Before optimisation:</p><pre><code>627 queries</code></pre><p>After optimisation:</p><pre><code>9 queries</code></pre><p>Same endpoint. Same output. Just a better use of the ORM.</p><div><hr></div><h3><strong>A Habit I Now Follow Before Merging Backend Code</strong></h3><p>Before merging any endpoint that assembles nested data, I now do three things:</p><ol><li><p>Run the endpoint locally.</p></li><li><p>Inspect SQL queries with Django Debug Toolbar.</p></li><li><p>Confirm the query count is reasonable.</p></li></ol><p>This small habit has saved me from shipping inefficient endpoints more than once.</p><h1>Final Thoughts</h1><p>This experience reinforced something easy to forget when writing application code.</p><p>Code can look perfectly reasonable and still generate hundreds of unnecessary database queries.</p><p>The Django ORM is powerful, but it hides a lot of complexity. If you do not occasionally inspect what SQL is actually being executed, performance issues can slip in without you noticing.</p><p>The Django Debug Toolbar is one of the simplest tools you can add to your workflow. It gives immediate visibility into how your views interact with the database.</p><p>If you are building APIs, especially ones that assemble nested data structures, it is worth checking your query counts before merging your code.</p><p>Your future self and your database will thank you.</p>]]></content:encoded></item><item><title><![CDATA[I Wrote a Book to Help You Work with AI]]></title><description><![CDATA[Human + Machine: Practical Skills to Build, Ship, and Grow with AI]]></description><link>https://fafacodes.substack.com/p/i-wrote-a-book-to-help-you-work-with</link><guid isPermaLink="false">https://fafacodes.substack.com/p/i-wrote-a-book-to-help-you-work-with</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Fri, 20 Feb 2026 13:48:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/9517e60e-16d5-47f9-a6ef-6b79a5a63d92_6250x4683.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every week, I receive similar messages.</p><p><em>&#8220;What AI tools should I learn?&#8221;</em></p><p><em>&#8220;How do I actually build with AI?&#8221;</em></p><p><em>&#8220;Is it too late to get into this space?&#8221;</em></p><p><em>&#8220;What skills really matter anymore?&#8221;</em></p><p>That&#8217;s why I wrote&nbsp;<em><strong>_Human + Machine: Practical Skills to Build, Ship, and Grow with AI_</strong>. (discount codes to download for FREE at the end of this post)</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n3Wb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n3Wb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png 424w, https://substackcdn.com/image/fetch/$s_!n3Wb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png 848w, https://substackcdn.com/image/fetch/$s_!n3Wb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png 1272w, https://substackcdn.com/image/fetch/$s_!n3Wb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n3Wb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png" width="1456" height="1820" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1820,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7989179,&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://fafacodes.substack.com/i/188601955?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!n3Wb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png 424w, https://substackcdn.com/image/fetch/$s_!n3Wb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png 848w, https://substackcdn.com/image/fetch/$s_!n3Wb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.png 1272w, https://substackcdn.com/image/fetch/$s_!n3Wb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee499e-dc04-444f-a0a6-59aceb9cf6ba_3375x4219.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 role="img" 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><title></title><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>I kept noticing a gap between understanding AI agents, automation, and generative models and actually confidently using them. There&#8217;s also a gap between fear of being replaced and learning how to become more capable by leveraging AI.</p><p>Before anyone can build with AI, critique it, or contribute meaningfully to any AI discussion, they need solid foundational AI knowledge. This is where this book begins. We break down generative AI, agents, computer vision, speech systems, natural language processing, information extraction, and decision support in simple terms (what they are, how they&#8217;re used, and where they appear in real life).</p><p>For example, understanding how generative AI has transformed work (by allowing people to generate code, analyse data, draft technical documentation, and prototype ideas in hours instead of weeks) is just as important as knowing what these systems can&#8217;t reliably do. They can&#8217;t deeply understand context like humans do, take full responsibility, make complex architectural trade-offs with lived judgment, or navigate ambiguity with intuition.</p><p>That gap isn&#8217;t a weakness. It&#8217;s the point. It&#8217;s where humans still play a vital role.</p><p>That&#8217;s why this book exists. It enables individuals to navigate the current AI landscape as both consumers and builders, adopting it as a tool in new and emerging tech careers.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><h2>What&#8217;s Inside the Book</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2iBb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2iBb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png 424w, https://substackcdn.com/image/fetch/$s_!2iBb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png 848w, https://substackcdn.com/image/fetch/$s_!2iBb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png 1272w, https://substackcdn.com/image/fetch/$s_!2iBb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2iBb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png" width="1456" height="1091" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1091,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:18236126,&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://fafacodes.substack.com/i/188601955?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2iBb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png 424w, https://substackcdn.com/image/fetch/$s_!2iBb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png 848w, https://substackcdn.com/image/fetch/$s_!2iBb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.png 1272w, https://substackcdn.com/image/fetch/$s_!2iBb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87191d19-01b1-4230-8333-0c88eb2f5ffb_6250x4683.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 role="img" 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><title></title><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><strong>Staying Valuable in the Age of AI</strong></p><p>This chapter is about mindset and strategy. It answers the hard questions people are quietly asking about their careers. How do you stay relevant when AI can write code, draft documents, and automate tasks? What skills still matter?</p><p>We break down the human advantages that remain critical. Judgment. Context. Responsibility. Clear thinking. You will also learn practical strategies for working with AI in a way that improves your output without turning you into a copy-and-paste engineer. The focus is simple. Use AI to raise your standard, not lower it.</p><p><strong>Using AI to Improve Your Tech Skills</strong></p><p>Here, AI becomes a practical tool for growth. You will learn how to use it as a senior colleague who reviews your ideas, challenges your assumptions, and helps you learn faster. We cover communication, documentation, prototyping, feedback, and automation with clear examples of how to actually do it.</p><p>This chapter shows you how to structure prompts, refine your thinking, clean up your writing, and accelerate your learning. The goal is skill amplification, not dependency.</p><p><strong>Using AI to Build Software</strong></p><p>This section walks through the full journey from idea to shipped product. From defining a problem and writing clear specifications, to thinking through architecture and trade-offs, to implementing and reviewing code.</p><p>We also address vibe coding directly. When it works. When it fails. How to debug AI-generated code and avoid confidence errors. You will learn how to review outputs critically and maintain quality. We also introduce AI agents and integrations so you understand what they actually do and how to use them responsibly.</p><p><strong>Prompt Engineering</strong></p><p>If AI is a tool, prompting is the interface. This chapter focuses on how to give clear instructions, break complex tasks into smaller steps, iterate on responses, and evaluate results properly.</p><p>We cover practical techniques such as providing context, organising prompts, versioning them, and improving them over time. The emphasis is on clarity and control so you can consistently get useful results instead of random outputs.</p><p><strong>New Careers in the AI Era</strong></p><p>AI is not only changing tasks. It is reshaping roles. In this chapter, we map out emerging career paths such as AI engineer, AI agent systems engineer, AI creator, AI governance and policy specialist, and AI-focused founders.</p><p>For each path, we explain what the role involves, why it exists now, the skills that transition well, and how to become job-ready. You get a realistic view of what these careers look like and how to position yourself for them.</p><p><strong>What To Do Next</strong></p><p>The book closes with direction. How to learn AI professionally. How to practice intentionally. How to assess your own usage and improve it over time.</p><h2>How to Get the Book</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Gvpl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Gvpl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png 424w, https://substackcdn.com/image/fetch/$s_!Gvpl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png 848w, https://substackcdn.com/image/fetch/$s_!Gvpl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png 1272w, https://substackcdn.com/image/fetch/$s_!Gvpl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Gvpl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png" width="6250" height="4683" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:4683,&quot;width&quot;:6250,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12840885,&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://fafacodes.substack.com/i/188601955?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fbea8c8-439b-485e-8d45-ec036b6d96da_6250x4683.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Gvpl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png 424w, https://substackcdn.com/image/fetch/$s_!Gvpl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png 848w, https://substackcdn.com/image/fetch/$s_!Gvpl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.png 1272w, https://substackcdn.com/image/fetch/$s_!Gvpl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c3b2bd-4cf5-4171-82fb-7ee3be0c92cf_6250x4683.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 role="img" 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><title></title><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><strong>Human + Machine: Practical Skills to Build, Ship, and Grow with AI</strong> is available directly from my personal online shop. </p><p>If you purchase through my shop, you can use one of the discount codes below at checkout.</p><p>These are first-come, first-served:</p><ul><li><p><strong>AIWITHFAFA31</strong> &#8212; 100% off (25 copies available)</p></li><li><p><strong>AIWITHFAFA30</strong> &#8212; 75% off (50 copies available)</p></li><li><p><strong>AIWITHFAFA29</strong> &#8212; 50% off (75 copies available)</p></li><li><p><strong>AIWITHFAFA28</strong> &#8212; 25% off (100 copies available)</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://tr.ee/ThzP4pI4tq&quot;,&quot;text&quot;:&quot;Download for FREE &#127379;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://tr.ee/ThzP4pI4tq"><span>Download for FREE &#127379;</span></a></p><p>If a code does not work, it means all available uses have been claimed. Once the codes are gone, the book will return to its standard price of &#163;20 in my shop.</p><p>The book is also available on Amazon in both e-book and paperback formats. If you are subscribed to <a href="https://www.amazon.co.uk/kindle-dbs/hz/subscribe/ku?ref=abpmku_24_4_uk_psr_gs_r_mn_rbhab_rbw_lps_2wSOsEqcGS_rbro&amp;gad_source=1&amp;gad_campaignid=10025101115&amp;gbraid=0AAAAACYXwlzePbbsFoKwdwlerg1VIdHck&amp;gclid=Cj0KCQiAqeDMBhDcARIsAJEbU9RfEQ_ci5SS-LUWZoQRoW-vAv9d5SQVQLA4b8ySKauSiJNZngUwvi4aAh3BEALw_wcB">Kindle Unlimited</a>, you can read it for <strong>FREE</strong> as part of your subscription. If not, the Kindle edition and paperback are available worldwide for &#163;20. You can also download and read a <strong>FREE</strong> sample on Amazon to get a feel for the book before deciding to purchase.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://amzn.eu/d/05ByfpLP&quot;,&quot;text&quot;:&quot;Buy on Amazon &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://amzn.eu/d/05ByfpLP"><span>Buy on Amazon &#128176;</span></a></p><p>If you have any issues accessing the book in your region, send me an email, and I will help. And if cost is a barrier, reach out, and we can talk.</p><p>If you do read it, I would genuinely value your feedback. Leave a review, send a message, or reply to this post. I want this book to be useful, practical, and worth your time.</p><p>That&#8217;s it. If you&#8217;ve been thinking about taking AI seriously, this is a good place to start.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/i-wrote-a-book-to-help-you-work-with?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="https://fafacodes.substack.com/p/i-wrote-a-book-to-help-you-work-with?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[How I Used Spotify Artist Data to Understand RAG]]></title><description><![CDATA[Building a conversational search experience with Azure AI Search, vector data, and agentic retrieval]]></description><link>https://fafacodes.substack.com/p/how-i-used-spotify-artist-data-to</link><guid isPermaLink="false">https://fafacodes.substack.com/p/how-i-used-spotify-artist-data-to</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Tue, 27 Jan 2026 19:19:44 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7ec526e1-ac7d-45ee-b02f-0506f60102c2_3024x4032.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you&#8217;ve spent any real time in the AI engineering space, you&#8217;ve heard it probably more times than you can count:</p><p><strong>RAG. RAG. RAG.</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gnVD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gnVD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!gnVD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!gnVD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!gnVD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gnVD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1311500,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!gnVD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!gnVD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!gnVD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!gnVD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9365d61-32cc-4449-adfb-8e4604925c16_480x270.gif 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 role="img" 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><title></title><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>I&#8217;ve written about it before, and I&#8217;ll say it again: Retrieval-Augmented Generation (RAG) is everywhere right now. And honestly, you can&#8217;t really call yourself an AI engineer today if you don&#8217;t know how to connect your own data to an LLM. That&#8217;s the entire point of RAG.</p><p>At its core, RAG is about grounding LLM responses in <em>your</em> data. Not generic internet knowledge. Not hallucinated guesses. Actual, specific, proprietary context.</p><p>And that&#8217;s exactly what makes it so powerful and so unavoidable.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div><hr></div><h2>Why RAG Matters (Especially for Enterprises)</h2><p>A classic RAG use case is within enterprise organisations that want AI systems (chatbots, internal tools, or full-blown AI agents) to produce <strong>reliable, grounded answers</strong> from a defined data set.</p><p>That data might be:</p><ul><li><p>Internal documents (PDFs, text files)</p></li><li><p>Chat histories</p></li><li><p>Knowledge bases</p></li><li><p>Proprietary databases</p></li></ul><p>Large language models like ChatGPT or Claude are impressive, but they&#8217;re not tailored to your business out of the box. They don&#8217;t know your internal processes, your data definitions, or your source of truth.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UDRx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UDRx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!UDRx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!UDRx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!UDRx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UDRx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2609434,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!UDRx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!UDRx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!UDRx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!UDRx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb3419a4-0f0b-45c2-9b95-f1ea77b9d0a7_480x270.gif 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 role="img" 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><title></title><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 if you want context-aware responses that are <em>only</em> based on your data, you need RAG. More specifically, you need <strong>agentic retrieval</strong>, where the system decides <em>what</em> to retrieve, <em>when</em>, and <em>how</em> to use it to answer a query.</p><div><hr></div><h2>The Project: Conversational Search Over Spotify Artist Data</h2><p>To level up my hands-on experience with RAG, vector data, and agentic retrieval, I built a small but practical application: a <strong>conversational search experience over a knowledge base</strong>.</p><p>The idea was simple:</p><ul><li><p>Take a real dataset</p></li><li><p>Index it properly</p></li><li><p>Let users &#8220;chat&#8221; with the data using natural language</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qf_s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qf_s!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png 424w, https://substackcdn.com/image/fetch/$s_!Qf_s!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png 848w, https://substackcdn.com/image/fetch/$s_!Qf_s!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!Qf_s!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qf_s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png" width="1456" height="899" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:899,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:325595,&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://fafacodes.substack.com/i/184642523?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Qf_s!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png 424w, https://substackcdn.com/image/fetch/$s_!Qf_s!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png 848w, https://substackcdn.com/image/fetch/$s_!Qf_s!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!Qf_s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8990bb37-3d0d-46a5-830e-d43885eba27c_2238x1382.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 role="img" 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><title></title><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">Completed project running locally</figcaption></figure></div><h3>The Data</h3><p>I used a <a href="https://www.kaggle.com/datasets/serkantysz/550k-spotify-songs-audio-lyrics-and-genres/data">Spotify artists dataset from Kaggle</a>. It&#8217;s a CSV file containing information for over <strong>70,000 artists</strong>, including:</p><ul><li><p>Spotify ID</p></li><li><p>Artist name</p></li><li><p>Number of followers</p></li><li><p>Popularity score</p></li><li><p>Genres</p></li><li><p>Main genre</p></li></ul><p>The goal was to build a chatbot that could answer questions like:</p><blockquote><p>&#8220;Which artists in this genre have the most followers?&#8221;<br>&#8220;How popular is this artist compared to others?&#8221;</p></blockquote><p>All answers needed to come <strong>only</strong> from the dataset. No external knowledge.</p><div><hr></div><h2>The Stack: Azure AI Search + Microsoft Foundry </h2><p>This project uses Azure&#8217;s RAG-friendly tooling to wire everything together.</p><p>We&#8217;re building a conversational search experience powered by:</p><ul><li><p><strong><a href="https://learn.microsoft.com/en-us/azure/search/search-create-service-portal">Azure AI Search</a></strong> for indexing, vector search, and agentic retrieval</p></li><li><p><strong><a href="https://learn.microsoft.com/en-us/azure/ai-foundry/how-to/create-projects">Microsoft Foundry</a> </strong>for embeddings and LLM reasoning</p></li></ul><h3>What Is Azure AI Search?</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Jv_Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jv_Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png 424w, https://substackcdn.com/image/fetch/$s_!Jv_Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png 848w, https://substackcdn.com/image/fetch/$s_!Jv_Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png 1272w, https://substackcdn.com/image/fetch/$s_!Jv_Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Jv_Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png" width="2285" height="1448" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1448,&quot;width&quot;:2285,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:368575,&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://fafacodes.substack.com/i/184642523?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80705b0-1313-4907-9a91-ffc0637c3ce3_2342x1448.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Jv_Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png 424w, https://substackcdn.com/image/fetch/$s_!Jv_Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png 848w, https://substackcdn.com/image/fetch/$s_!Jv_Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.png 1272w, https://substackcdn.com/image/fetch/$s_!Jv_Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7a62287-3abb-454f-bd1c-c74bb88dcc08_2285x1448.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 role="img" 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><title></title><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">Azure AI Search resource dashboard on the Azure portal</figcaption></figure></div><p>Azure AI Search is a fully managed, cloud-hosted search service that supports both:</p><ul><li><p>Traditional keyword-based search</p></li><li><p>Vector and semantic search for LLM-assisted retrieval</p></li></ul><p>It handles a lot of the heavy lifting for RAG:</p><ul><li><p>Chunking</p></li><li><p>Vectorisation</p></li><li><p>Indexing</p></li><li><p>Semantic relevance</p></li></ul><div><hr></div><h2>Getting Started: Setup and Configuration</h2><p>Before writing any code, there&#8217;s a fair bit of setup involved.</p><h3>What You&#8217;ll Need</h3><ul><li><p>An Azure account</p></li><li><p>Azure AI Search service</p></li><li><p>A Microsoft Foundry project</p></li><li><p>Azure CLI</p></li><li><p>A programming IDE (I used PyCharm)</p></li></ul><p>When you create an Azure account, you get <strong>$200 in free credits</strong>, which is more than enough to experiment with a project like this. That&#8217;s exactly what I used.</p><h3>Configuration Steps</h3><p>At a high level, the setup looks like this:</p><ol><li><p>Create an Azure AI Search resource in the Azure Portal</p></li><li><p>Set up a Microsoft Foundry project</p></li><li><p>Install and authenticate Azure CLI locally</p></li><li><p>Ensure your CLI has permission to access both resources</p></li></ol><p>You&#8217;ll also need to grab the <strong>endpoints</strong> for:</p><ul><li><p>Azure AI Search</p></li><li><p>Microsoft Foundry</p></li></ul><p>These endpoints are unique URLs that provide network access to the services, and you&#8217;ll store them as environment variables in your project.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ux7R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ux7R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png 424w, https://substackcdn.com/image/fetch/$s_!ux7R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png 848w, https://substackcdn.com/image/fetch/$s_!ux7R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png 1272w, https://substackcdn.com/image/fetch/$s_!ux7R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ux7R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png" width="1456" height="925" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:925,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:252999,&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://fafacodes.substack.com/i/184642523?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ux7R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png 424w, https://substackcdn.com/image/fetch/$s_!ux7R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png 848w, https://substackcdn.com/image/fetch/$s_!ux7R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.png 1272w, https://substackcdn.com/image/fetch/$s_!ux7R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0634b435-f1db-4b3e-bfab-8e5f411cf61b_1486x944.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 role="img" 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><title></title><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">Microsoft Foundry home page</figcaption></figure></div><div><hr></div><h2>Models Used</h2><p>This project uses two models:</p><ul><li><p><strong>Embedding model</strong> for text-to-vector conversion</p><ul><li><p><code>text-embedding-3-large</code> (3072 dimensions)</p></li></ul></li><li><p><strong>LLM</strong> for query planning and answer generation</p><ul><li><p><code>GPT-5-mini</code> (though any supported Foundry model works)</p></li></ul></li></ul><p>The LLM serves two purposes:</p><ul><li><p>Planning the retrieval query</p></li><li><p>Generating the final answer</p></li></ul><div><hr></div><h2>Development Flow</h2><p>Once authenticated via <code>az login</code>, the actual development work begins.</p><h3>Dependencies</h3><p>The core libraries used are:</p><ul><li><p><code>azure-identity</code></p></li><li><p><code>azure-search-documents</code></p></li><li><p><code>langchain</code></p></li></ul><p>Additional Python dependencies are listed in the project&#8217;s <code>requirements.txt</code>.</p><div><hr></div><h2>Preparing the Data</h2><p>The Kaggle dataset is downloaded as a CSV file with 70k+ rows. Each row includes:</p><ul><li><p>ID</p></li><li><p>Artist name</p></li><li><p>Followers</p></li><li><p>Popularity</p></li><li><p>Genre</p></li><li><p>Main genre</p></li></ul><p>If you don&#8217;t want to work with the full dataset, you can easily subset it (e.g., first 100 rows) for faster iteration.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xVl4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xVl4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png 424w, https://substackcdn.com/image/fetch/$s_!xVl4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png 848w, https://substackcdn.com/image/fetch/$s_!xVl4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png 1272w, https://substackcdn.com/image/fetch/$s_!xVl4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xVl4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png" width="858" height="182" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:182,&quot;width&quot;:858,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65155,&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://fafacodes.substack.com/i/184642523?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xVl4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png 424w, https://substackcdn.com/image/fetch/$s_!xVl4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png 848w, https://substackcdn.com/image/fetch/$s_!xVl4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png 1272w, https://substackcdn.com/image/fetch/$s_!xVl4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94659eac-dc84-48b6-a8b5-5b3d8f610edc_858x182.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">7 out of 77K rows of my Spotify dataset from Kaggle</figcaption></figure></div><h3>CSV to JSON</h3><p>Before indexing, the CSV data is converted to JSON using a simple script. The JSON structure uses the CSV headers as field names:</p><ul><li><p><code>id</code></p></li><li><p><code>name</code></p></li><li><p><code>followers</code></p></li><li><p><code>popularity</code></p></li><li><p><code>genre</code></p></li><li><p><code>main_genre</code></p></li></ul><p>This format makes it easier to generate embeddings and upload documents.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wFh2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wFh2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png 424w, https://substackcdn.com/image/fetch/$s_!wFh2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png 848w, https://substackcdn.com/image/fetch/$s_!wFh2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png 1272w, https://substackcdn.com/image/fetch/$s_!wFh2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wFh2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png" width="858" height="249" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:249,&quot;width&quot;:858,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:42430,&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://fafacodes.substack.com/i/184642523?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wFh2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png 424w, https://substackcdn.com/image/fetch/$s_!wFh2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png 848w, https://substackcdn.com/image/fetch/$s_!wFh2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.png 1272w, https://substackcdn.com/image/fetch/$s_!wFh2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee849f2d-3ad7-474e-98a4-06500c14431f_858x249.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 role="img" 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><title></title><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">CSV to JSON converter code snippet</figcaption></figure></div><div><hr></div><h2>Indexing and Vector Search</h2><p>With the data ready, the next step is writing a Python script that can:</p><ul><li><p>Create a search index</p></li><li><p>Upload documents</p></li><li><p>Create a knowledge source</p></li><li><p>Create a knowledge base</p></li><li><p>Run the retrieval pipeline</p></li><li><p>Maintain conversational context</p></li></ul><h3>Creating the Search Index</h3><p>The search index defines both the <strong>fields</strong> and the <strong>search behaviour</strong>. It supports vector and semantic search.</p><p>Key fields include:</p><ul><li><p>ID</p></li><li><p>Artist text</p></li><li><p>Artist embedding (3072-dimensional vector)</p></li><li><p>Artist number</p></li></ul><h3>Uploading Documents</h3><p>For each artist, we construct a readable text representation by combining fields like:</p><ul><li><p>Name</p></li><li><p>Main genre</p></li><li><p>Follower count</p></li><li><p>Popularity</p></li><li><p>Additional genres</p></li></ul><p>This text becomes the basis for embeddings.</p><p>Embeddings are generated using LangChain&#8217;s <code>embed_query</code> method, producing a vector of floats for each artist. All of this (text, vectors, metadata) is uploaded into the search index.</p><p>From the Azure AI Search resource, we can search for information.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ibte!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ibte!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png 424w, https://substackcdn.com/image/fetch/$s_!ibte!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png 848w, https://substackcdn.com/image/fetch/$s_!ibte!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png 1272w, https://substackcdn.com/image/fetch/$s_!ibte!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ibte!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png" width="1059" height="879" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:879,&quot;width&quot;:1059,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:180636,&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://fafacodes.substack.com/i/184642523?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ibte!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png 424w, https://substackcdn.com/image/fetch/$s_!ibte!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png 848w, https://substackcdn.com/image/fetch/$s_!ibte!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.png 1272w, https://substackcdn.com/image/fetch/$s_!ibte!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e578a3-b71e-4d26-8631-ac7d7e1d5acd_1059x879.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 role="img" 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><title></title><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">search index with uploaded documents on the Azure portal</figcaption></figure></div><div><hr></div><h2>Knowledge Base and Agentic Retrieval</h2><p>Once indexing is complete:</p><ol><li><p>A <strong>knowledge source</strong> is created from the search index</p></li><li><p>A <strong>knowledge base</strong> is built on top of that source</p></li></ol><p>This knowledge base becomes the system&#8217;s source of truth.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7Qni!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7Qni!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png 424w, https://substackcdn.com/image/fetch/$s_!7Qni!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png 848w, https://substackcdn.com/image/fetch/$s_!7Qni!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png 1272w, https://substackcdn.com/image/fetch/$s_!7Qni!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7Qni!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png" width="992" height="427" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:427,&quot;width&quot;:992,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:89538,&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://fafacodes.substack.com/i/184642523?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7Qni!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png 424w, https://substackcdn.com/image/fetch/$s_!7Qni!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png 848w, https://substackcdn.com/image/fetch/$s_!7Qni!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.png 1272w, https://substackcdn.com/image/fetch/$s_!7Qni!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9c989a8-58f3-4ee5-be30-b58a2738b552_992x427.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 role="img" 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><title></title><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">Creating the knowledge source for the project</figcaption></figure></div><p>When a user asks a question, we use the <strong>Knowledge Base Retriever</strong> classes to ensure:</p><ul><li><p>Queries are grounded in the indexed data</p></li><li><p>Retrieval happens semantically, not just via keywords</p></li><li><p>The system responds <em>&#8220;I don&#8217;t know&#8221;</em> when no relevant data exists</p></li></ul><p>This is where embeddings really matter. Semantic similarity allows the system to match user intent to the most relevant indexed entries even when the wording isn&#8217;t exact.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uNNQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uNNQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png 424w, https://substackcdn.com/image/fetch/$s_!uNNQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png 848w, https://substackcdn.com/image/fetch/$s_!uNNQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png 1272w, https://substackcdn.com/image/fetch/$s_!uNNQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uNNQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png" width="1027" height="427" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:427,&quot;width&quot;:1027,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:106372,&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://fafacodes.substack.com/i/184642523?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uNNQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png 424w, https://substackcdn.com/image/fetch/$s_!uNNQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png 848w, https://substackcdn.com/image/fetch/$s_!uNNQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.png 1272w, https://substackcdn.com/image/fetch/$s_!uNNQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9b225f-f56b-40ce-bd78-32db0cf60578_1027x427.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 role="img" 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><title></title><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">Creating the knowledge source for the project</figcaption></figure></div><div><hr></div><h2>Wrapping Up</h2><p>The frontend for this project is built with <strong>Streamlit</strong>, which makes it easy to test and iterate on the conversational experience.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qAvF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qAvF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png 424w, https://substackcdn.com/image/fetch/$s_!qAvF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png 848w, https://substackcdn.com/image/fetch/$s_!qAvF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!qAvF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qAvF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png" width="2238" height="1382" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1382,&quot;width&quot;:2238,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:199831,&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://fafacodes.substack.com/i/184642523?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c1c614-9ac2-418b-9025-92842abe3a55_2238x1382.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qAvF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png 424w, https://substackcdn.com/image/fetch/$s_!qAvF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png 848w, https://substackcdn.com/image/fetch/$s_!qAvF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!qAvF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfd53a15-4d34-436e-87fd-bd86688d357f_2238x1382.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 role="img" 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><title></title><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">Streamlit UI for the project is loaded locally</figcaption></figure></div><p>That&#8217;s the full pipeline:</p><ul><li><p>Data &#8594; vectors &#8594; index</p></li><li><p>Index &#8594; knowledge base</p></li><li><p>Knowledge base &#8594; grounded conversational search</p></li></ul><p>If you want to try something similar, Azure&#8217;s <strong><a href="https://learn.microsoft.com/en-us/azure/search/search-get-started-agentic-retrieval?tabs=search&amp;pivots=programming-language-python">Quickstart documentation</a></strong> is genuinely helpful for understanding how agentic retrieval works end to end.</p><p>You can also view my full project code on <a href="https://github.com/UffaModey/azureAI-search-agentic-retrieval">GitHub</a> if you&#8217;d like to replicate this project.</p><p>RAG isn&#8217;t just a buzzword. It&#8217;s the backbone of practical, trustworthy AI systems. And once you&#8217;ve built one of these pipelines yourself, it becomes very clear why everyone keeps talking about it.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/how-i-used-spotify-artist-data-to?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading AI with Fafa! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/how-i-used-spotify-artist-data-to?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://fafacodes.substack.com/p/how-i-used-spotify-artist-data-to?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[Training an ML Model for Use in an App]]></title><description><![CDATA[How I used Google Trends data to build an ML MVP and what it taught me about simplicity, heuristics, and iteration]]></description><link>https://fafacodes.substack.com/p/training-an-ml-model-for-use-in-an</link><guid isPermaLink="false">https://fafacodes.substack.com/p/training-an-ml-model-for-use-in-an</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Tue, 13 Jan 2026 18:56:42 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/40709389-551c-4e4a-920a-d0d05d0c9d7e.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So apparently, training a machine learning model <strong>and</strong> using its predictions to power a web app isn&#8217;t as difficult as it sounds.</p><p>I know this because I just did it.</p><p>I built an end-to-end pipeline that takes text as input, runs it through a trained ML model, and returns a prediction through a web interface. No deep learning yet. Just a clean, working MVP that proved a point to myself: <em>this is doable</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!A2cu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!A2cu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png 424w, https://substackcdn.com/image/fetch/$s_!A2cu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png 848w, https://substackcdn.com/image/fetch/$s_!A2cu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!A2cu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!A2cu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png" width="1456" height="839" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:839,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:151361,&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://fafacodes.substack.com/i/184453238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!A2cu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png 424w, https://substackcdn.com/image/fetch/$s_!A2cu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png 848w, https://substackcdn.com/image/fetch/$s_!A2cu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!A2cu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc46b21b5-936c-4a64-8ff2-b57e37b5e3c0_1776x1024.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 role="img" 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><title></title><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">Screenshot of my app running locally with a WILL TREND prediction for the &#8220;Golden Globes&#8221;</figcaption></figure></div><div><hr></div><h2>The Tech Stack</h2><p>Here&#8217;s what I used to make it happen:</p><ul><li><p><strong>Backend:</strong> FastAPI + Uvicorn</p></li><li><p><strong>ML:</strong> Scikit-learn (TF-IDF + Logistic Regression), Joblib</p></li><li><p><strong>Frontend:</strong> HTML + Vanilla JS + Jinja2</p></li><li><p><strong>Data:</strong> <a href="https://trends.google.com/home?hl=en-US">Google Trends</a> CSV export (UK, last 7 days)</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div><hr></div><h2>The Idea: Can We Predict If a Topic Will Trend?</h2><p>While reviewing Google Trends data, I had a simple thought:</p><blockquote><p><em>What if I could build an app that predicts whether a given topic will trend or not?</em></p></blockquote><p>That&#8217;s it. That curiosity alone was enough to justify building a small experiment.</p><p>Now, a big caveat upfront:<br>This model <strong>still needs a ton of work</strong>.</p><ul><li><p>It was trained on ~1,800 rows of data</p></li><li><p>The labelling logic is based on a simple heuristic I came up with</p></li><li><p>The goal wasn&#8217;t perfection&#8212;it was learning</p></li></ul><p>This is very much an MVP. A baseline. Something to confirm assumptions quickly before investing more time and complexity.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dzXc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dzXc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!dzXc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!dzXc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!dzXc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dzXc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2261936,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!dzXc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!dzXc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!dzXc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!dzXc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdbd9ff4-63e1-4d1d-9ead-6e6273bf9afa_480x270.gif 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 role="img" 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><title></title><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>Understanding the Data</h2><p>From the Google Trends homepage, you can export trend data based on filters. I exported:</p><ul><li><p>Region: UK</p></li><li><p>Time range: Past 7 days</p></li><li><p>Category: All</p></li><li><p>Trends: All</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!G0qx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!G0qx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png 424w, https://substackcdn.com/image/fetch/$s_!G0qx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png 848w, https://substackcdn.com/image/fetch/$s_!G0qx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png 1272w, https://substackcdn.com/image/fetch/$s_!G0qx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!G0qx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png" width="1456" height="852" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:852,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:520000,&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://fafacodes.substack.com/i/184453238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!G0qx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png 424w, https://substackcdn.com/image/fetch/$s_!G0qx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png 848w, https://substackcdn.com/image/fetch/$s_!G0qx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.png 1272w, https://substackcdn.com/image/fetch/$s_!G0qx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a8e1c08-1ada-4845-b108-d50ed36d5ee8_2912x1704.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 role="img" 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><title></title><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">Good Trends for the past 7 days</figcaption></figure></div><p>This produced a CSV file with <strong>1,881 rows</strong> and the following columns:</p><ul><li><p><code>Trends</code></p></li><li><p><code>Search volume</code></p></li><li><p><code>Started</code></p></li><li><p><code>Ended</code></p></li><li><p><code>Trend breakdown</code></p></li><li><p><code>Explore link</code></p></li></ul><p>Is this enough data to build a production-grade system? Absolutely not.<br>Is it enough to test an end-to-end ML pipeline? Perfectly.</p><p>That&#8217;s the key distinction.</p><div><hr></div><h2>Defining &#8220;Trending&#8221;: Start Simple or Don&#8217;t Start at All</h2><p>Before touching the data, I had to answer an important question:</p><p><strong>How do we decide if a topic actually &#8220;trended&#8221;?</strong></p><p>For this first version, I used a very simple heuristic:</p><blockquote><p>If search volume is high, then the topic is trending.</p></blockquote><p>Why? Because if a lot of people are repeatedly searching for a phrase <strong>at a specific time</strong>, it&#8217;s clearly important <em>at that moment</em>.</p><p>Now, that &#8220;at that moment&#8221; part is crucial.<br>A more robust definition should factor in <strong>duration</strong>, <strong>velocity</strong>, and <strong>decay</strong>. But I intentionally ignored all of that for now.</p><p>Good ML practice isn&#8217;t about cramming every possible signal into v1. It&#8217;s about:</p><ul><li><p>Starting simple</p></li><li><p>Monitoring outputs</p></li><li><p>Iterating with intent</p></li></ul><p>Trying to build a &#8220;perfect&#8221; model from the start is a big no-no.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a Coffee &#9749;&#65039;  &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a Coffee &#9749;&#65039;  &#128176;</span></a></p><div><hr></div><h2>Step 1: Loading the Data</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AHEt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AHEt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif 424w, https://substackcdn.com/image/fetch/$s_!AHEt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif 848w, https://substackcdn.com/image/fetch/$s_!AHEt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif 1272w, https://substackcdn.com/image/fetch/$s_!AHEt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AHEt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif" width="500" height="281" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:281,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2269751,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!AHEt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif 424w, https://substackcdn.com/image/fetch/$s_!AHEt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif 848w, https://substackcdn.com/image/fetch/$s_!AHEt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif 1272w, https://substackcdn.com/image/fetch/$s_!AHEt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a3c29c-ae47-4a6f-8362-6974e481668f_500x281.gif 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 role="img" 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><title></title><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>First, I loaded the CSV into a Pandas DataFrame and did some basic sanity checks to make sure everything looked right.</p><pre><code><code># =========================================
# STEP 1: ROBUST CSV LOADING
# =========================================
script_dir = os.path.dirname(os.path.abspath(__file__))
csv_filename = 'trending_GB_7d_20260113-1342.csv'
csv_path = os.path.join(script_dir, csv_filename)

if not os.path.exists(csv_path):
    print(f"&#10060; {csv_filename} not found in {script_dir}")
    print("Available CSV files:")
    csv_files = [f for f in os.listdir(script_dir) if f.endswith('.csv')]
    print(csv_files)
    exit(1)

df = pd.read_csv(csv_path)
print(f"&#9989; Loaded {len(df)} rows from {csv_path}")
print("\nSample data:")
print(df[['Trends', 'Search volume']].head())
</code></code></pre><div><hr></div><h2>Step 2: Cleaning and Feature Engineering</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dq_S!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dq_S!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!dq_S!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!dq_S!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!dq_S!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dq_S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4064802,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!dq_S!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!dq_S!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!dq_S!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!dq_S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ffa5f97-b968-4ef7-a77d-34e5746df799_480x270.gif 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 role="img" 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><title></title><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>It&#8217;s never good practice to assume data is clean.</p><p>While reviewing the CSV, I noticed:</p><ul><li><p>Missing values</p></li><li><p>Non-English text</p></li><li><p>Inconsistent formatting</p></li></ul><p>This was manageable with ~1.8k rows, so just by visual inspection, I could see that the data needed to be cleaned.<br>Scale this to hundreds of thousands (or millions) and&#8230; yeah, <strong>bruh (I&#8217;m in danger).</strong></p><p>I cleaned and combined the main trend text with its top related terms:</p><pre><code><code># =========================================
# STEP 2: FEATURE ENGINEERING
# =========================================
def clean_trend(row):
    """Extract main trend + top 5 related terms"""
    trend = str(row['Trends']).strip('" ')
    breakdown = str(row['Trend breakdown']).strip('" ') if pd.notna(row['Trend breakdown']) else ''
    related_terms = re.split(r'[,\s]+', breakdown)
    related = ', '.join([t.strip().lower() for t in related_terms[:5] if t.strip()])
    return f"{trend.lower()} {related}".strip()

df['text'] = df.apply(clean_trend, axis=1)
</code></code></pre><div><hr></div><h2>Step 3: Labelling the Data (and Discovering Imbalance)</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vstD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vstD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif 424w, https://substackcdn.com/image/fetch/$s_!vstD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif 848w, https://substackcdn.com/image/fetch/$s_!vstD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif 1272w, https://substackcdn.com/image/fetch/$s_!vstD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vstD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif" width="480" height="362" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:362,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2805249,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!vstD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif 424w, https://substackcdn.com/image/fetch/$s_!vstD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif 848w, https://substackcdn.com/image/fetch/$s_!vstD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif 1272w, https://substackcdn.com/image/fetch/$s_!vstD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8578dce0-4150-4200-b49e-08c099695aa0_480x362.gif 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 role="img" 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><title></title><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>To train the model, I needed a target column: <code>trending</code>.</p><ul><li><p><code>1</code> &#8594; Trending</p></li><li><p><code>0</code> &#8594; Not trending</p></li></ul><p>I defined trending as search volumes of <strong>100K+ and above</strong>.</p><pre><code><code># =========================================
# STEP 3: TRUE TRENDING LABELS (100K+ ONLY)
# =========================================
def is_trending(vol):
    """1 = Viral (100K+), 0 = Not"""
    vol_str = str(vol).strip('" ').upper()
    high_volumes = ['100K+', '200K+', '500K+', '1M+']
    return 1 if any(hv in vol_str for hv in high_volumes) else 0

df['trending'] = df['Search volume'].apply(is_trending)

df = df[df['text'].str.len() &gt; 10].copy()
print(f"\n&#128202; After cleaning: {len(df)} rows")
print("Class distribution:")
print(df['trending'].value_counts())
print(f"Trending %: {df['trending'].mean():.1%}")
</code></code></pre><p>After cleaning, I had ~1.7k rows.</p><p>Here&#8217;s the interesting (and problematic) part:<br>Only <strong>~2.1%</strong> of the data was labelled as trending.</p><p>That means a na&#239;ve model could be &#8220;accurate&#8221; by predicting <em>Not Trending</em> every time and still be useless.</p><p>I didn&#8217;t solve this fully yet, but I accounted for it during training.</p><div><hr></div><h2>Step 4: Train/Test Split</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!A0_l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!A0_l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif 424w, https://substackcdn.com/image/fetch/$s_!A0_l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif 848w, https://substackcdn.com/image/fetch/$s_!A0_l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif 1272w, https://substackcdn.com/image/fetch/$s_!A0_l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!A0_l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif" width="630" height="354" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:354,&quot;width&quot;:630,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3570210,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!A0_l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif 424w, https://substackcdn.com/image/fetch/$s_!A0_l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif 848w, https://substackcdn.com/image/fetch/$s_!A0_l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif 1272w, https://substackcdn.com/image/fetch/$s_!A0_l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3abda41-7a70-445d-b772-6571d8fa128f_630x354.gif 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 role="img" 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><title></title><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>I separated inputs and labels and used <strong><a href="https://www.geeksforgeeks.org/machine-learning/stratified-sampling-in-machine-learning/">stratification</a></strong> to ensure both sets preserved the class imbalance.</p><pre><code><code># =========================================
# STEP 4: TRAIN/TEST SPLIT
# =========================================
X = df['text']
y = df['trending']

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42, stratify=y
)

print(f"\nTrain: {len(X_train)} | Test: {len(X_test)}")
</code></code></pre><div><hr></div><h2>Step 5: Training the Model</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FD1M!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FD1M!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!FD1M!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!FD1M!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!FD1M!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FD1M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:568616,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!FD1M!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!FD1M!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!FD1M!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!FD1M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8c240c4-9e87-47c8-a845-b1f11dd6a000_480x270.gif 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 role="img" 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><title></title><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><ul><li><p><strong>TF-IDF</strong> converts text into numerical vectors, removing common stop words</p></li><li><p><strong>Logistic Regression</strong> learns word weights associated with trending likelihood</p></li><li><p><code>class_weight='balanced'</code> prevents the model from defaulting to &#8220;Not Trending&#8221;</p></li></ul><pre><code><code># =========================================
# STEP 5: PRODUCTION PIPELINE
# =========================================
pipeline = Pipeline([
    ('tfidf', TfidfVectorizer(
        max_features=5000,
        stop_words='english',
        ngram_range=(1, 2),
        min_df=1
    )),
    ('clf', LogisticRegression(
        random_state=42,
        max_iter=3000,
        class_weight='balanced',
        C=1.5
    ))
])

print("\n&#128640; Training model...")
pipeline.fit(X_train, y_train)
</code></code></pre><div><hr></div><h2>Step 6: Evaluation</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ti2W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ti2W!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!ti2W!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!ti2W!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!ti2W!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ti2W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif" width="480" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1314927,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!ti2W!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!ti2W!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!ti2W!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!ti2W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fc80ab6-8a0a-48de-a21b-7087540d1652_480x480.gif 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 role="img" 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><title></title><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 model outputs:</p><ul><li><p>A hard prediction: <code>1</code> or <code>0</code></p></li><li><p>A probability score (confidence)</p></li></ul><pre><code><code># =========================================
# STEP 6: EVALUATION
# =========================================
y_pred = pipeline.predict(X_test)
y_proba = pipeline.predict_proba(X_test)[:, 1]

accuracy = accuracy_score(y_test, y_pred)
print(f"\n&#9989; Accuracy: {accuracy:.3f}")

print("\n&#128200; Classification Report:")
print(classification_report(y_test, y_pred, target_names=['Not Trending', 'Trending']))
</code></code></pre><div><hr></div><h2>Step 7: Saving the Model</h2><p>Using <code>joblib</code> I saved both the trained pipeline and some metadata for later use.</p><pre><code><code># =========================================
# STEP 7: SAVE MODEL
# =========================================
joblib.dump(pipeline, 'trend_model.joblib')

metadata = {
    'accuracy': accuracy,
    'classes': pipeline.classes_.tolist(),
    'n_features': len(pipeline.named_steps['tfidf'].get_feature_names_out()),
    'train_pos_ratio': y_train.mean()
}

joblib.dump(metadata, 'model_metadata.joblib')

print("\n&#128190; SAVED:")
print("  trend_model.joblib  &#9989;")
print("  model_metadata.joblib &#9989;")
</code></code></pre><div><hr></div><h2>Serving the Model with FastAPI</h2><p>The rest was fairly straightforward.</p><p>Using FastAPI, I created a simple backend with a <code>/predict</code> endpoint that loads the model and returns predictions.</p><pre><code><code># Load model
model = joblib.load('trend_model.joblib')

@app.get("/", response_class=HTMLResponse)
async def predict_form(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

@app.post("/predict", response_class=HTMLResponse)
async def predict(request: Request, text: str = Form(...)):
    prediction = model.predict([text.lower()])[0]
    prob = model.predict_proba([text.lower()])[0][1]

    result = "WILL trend" if prediction == 1 else "will NOT trend"
    confidence = f"{prob:.2%}"

    return templates.TemplateResponse("index.html", {
        "request": request,
        "prediction": result,
        "confidence": confidence,
        "input_text": text
    })
</code></code></pre><div><hr></div><h2>Trying It Out</h2><p>I built a very simple frontend where you can input any text and get a prediction.</p><p>Of course, the model&#8217;s outputs are entirely constrained by:</p><ul><li><p>Limited data</p></li><li><p>A narrow heuristic</p></li><li><p>Text-only features</p></li></ul><p>But that&#8217;s fine. That&#8217;s the point.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kVmS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kVmS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png 424w, https://substackcdn.com/image/fetch/$s_!kVmS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png 848w, https://substackcdn.com/image/fetch/$s_!kVmS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png 1272w, https://substackcdn.com/image/fetch/$s_!kVmS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kVmS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png" width="1456" height="811" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:811,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:149584,&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://fafacodes.substack.com/i/184453238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kVmS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png 424w, https://substackcdn.com/image/fetch/$s_!kVmS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png 848w, https://substackcdn.com/image/fetch/$s_!kVmS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.png 1272w, https://substackcdn.com/image/fetch/$s_!kVmS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1fbcc072-80ed-4b6a-9665-822e00305108_1752x976.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 role="img" 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><title></title><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">Prediction of &#8220;WILL Trend&#8221; for the search phrase &#8220;Liverpool vs Barnsley&#8221;</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1M3S!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1M3S!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png 424w, https://substackcdn.com/image/fetch/$s_!1M3S!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png 848w, https://substackcdn.com/image/fetch/$s_!1M3S!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png 1272w, https://substackcdn.com/image/fetch/$s_!1M3S!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1M3S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png" width="1456" height="811" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:811,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:143398,&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://fafacodes.substack.com/i/184453238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1M3S!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png 424w, https://substackcdn.com/image/fetch/$s_!1M3S!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png 848w, https://substackcdn.com/image/fetch/$s_!1M3S!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.png 1272w, https://substackcdn.com/image/fetch/$s_!1M3S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4d160fb-7e17-4c84-92a3-29e20dc579de_1752x976.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 role="img" 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><title></title><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">Prediction of &#8220;Will NOT Trend&#8221; for the search phrase &#8220;barbie&#8221;</figcaption></figure></div><div><hr></div><h2>Conclusion</h2><p>This project was a great experiment in building and deploying an <strong>end-to-end ML pipeline</strong>.</p><p>It doesn&#8217;t predict the future.<br>It doesn&#8217;t forecast growth.</p><p>What it <em>does</em> do is <strong>text-based trend classification</strong>, and for an MVP, that&#8217;s more than enough.</p><p>More importantly, it reinforced a key lesson for me:</p><blockquote><p>You don&#8217;t need a perfect model to start.<br>You need a working one.</p></blockquote><p><strong>View the full project code on <a href="https://github.com/UffaModey/predicting-google-search">GitHub</a>.</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/training-an-ml-model-for-use-in-an?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="https://fafacodes.substack.com/p/training-an-ml-model-for-use-in-an?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[I Built a Data Pipeline to Track Nigeria’s Trending Topics ]]></title><description><![CDATA[Sourcing, Storing, and Visualising Nigeria&#8217;s Online Conversations Using Reddit Data]]></description><link>https://fafacodes.substack.com/p/i-built-a-data-pipeline-to-track</link><guid isPermaLink="false">https://fafacodes.substack.com/p/i-built-a-data-pipeline-to-track</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Sun, 11 Jan 2026 19:31:47 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a077216e-37d6-4e24-b6a2-709c7af079c1_2316x3088.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Whoop whoop!! &#128588;</p><p>I just built a data pipeline and it&#8217;s publicly available for anyone who wants to explore it.</p><p>&#8220;Data is the new oil.&#8221;<br>&#8220;Knowledge is power.&#8221;</p><p>And if that&#8217;s true&#8230; then let me have my moment. (Yes, I am king &#128578;).</p><p>If you&#8217;ve ever wanted to know what Nigerians are talking about at any given time  (what&#8217;s trending, what&#8217;s controversial, what&#8217;s getting people <em>really</em> talking) I&#8217;ve got you covered.</p><p>This project pulls live data from <a href="https://www.reddit.com/?feed=home">Reddit</a> to surface trending topics in the Nigerian space, stores it in a database, and visualises it through a dashboard. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div><hr></div><h2><strong>The Idea: Why This Pipeline Exists</strong></h2><p>The core idea is:</p><blockquote><p>Collect first-hand signals about what Nigerians are discussing online and make that data accessible.</p></blockquote><p>I used:</p><ul><li><p><strong>API requests</strong></p></li><li><p><strong>Data analysis and visualisation</strong></p></li></ul><p>The goal is to make this information useful for businesses, organisations, institutions or anyone who needs insight into what&#8217;s happening or being discussed in Nigeria <em>right now.</em></p><p>The project is basically just clean data sourcing and collection with structure, and visibility.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LMdW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LMdW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png 424w, https://substackcdn.com/image/fetch/$s_!LMdW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png 848w, https://substackcdn.com/image/fetch/$s_!LMdW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!LMdW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LMdW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png" width="1456" height="827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:827,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:478745,&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://fafacodes.substack.com/i/184201469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LMdW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png 424w, https://substackcdn.com/image/fetch/$s_!LMdW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png 848w, https://substackcdn.com/image/fetch/$s_!LMdW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!LMdW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d3eec06-f91c-4e70-92dc-f189c69bb836_2816x1600.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 role="img" 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><title></title><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">Project Dashboard running locally and showcasing data pulled directly from the database</figcaption></figure></div><div><hr></div><h2><strong>The Database: Why I Chose Supabase</strong></h2><p>For storage, I used <strong><a href="https://supabase.com/">Supabase</a></strong> and honestly, it was a great choice.</p><p>Why?</p><ul><li><p>Cloud-based</p></li><li><p>Free tier</p></li><li><p>Easy to set up</p></li><li><p>PostgreSQL under the hood</p></li></ul><p>After creating a Supabase project, I set up a database and created a table called <code>reddit_posts</code> using SQL:</p><pre><code><code>CREATE TABLE IF NOT EXISTS reddit_posts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    subreddit TEXT NOT NULL,
    title TEXT NOT NULL,
    upvotes INTEGER,
    comments INTEGER,
    author TEXT,
    permalink TEXT UNIQUE,
    created_utc TIMESTAMP,
    collected_at TIMESTAMP DEFAULT NOW()
);
</code></code></pre><p>The schema mirrors the structure of Reddit&#8217;s response data.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uCSS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uCSS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png 424w, https://substackcdn.com/image/fetch/$s_!uCSS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png 848w, https://substackcdn.com/image/fetch/$s_!uCSS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png 1272w, https://substackcdn.com/image/fetch/$s_!uCSS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uCSS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png" width="1456" height="1143" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1143,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:660625,&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://fafacodes.substack.com/i/184201469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uCSS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png 424w, https://substackcdn.com/image/fetch/$s_!uCSS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png 848w, https://substackcdn.com/image/fetch/$s_!uCSS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.png 1272w, https://substackcdn.com/image/fetch/$s_!uCSS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44993d1b-8e78-40e7-8e52-dc8f8b2c09c2_2296x1802.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 role="img" 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><title></title><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">reddit_posts table view in my Supabase database</figcaption></figure></div><div><hr></div><h2><strong>Data Sourcing: Pulling Posts from Reddit</strong></h2><p>Fetching data from Reddit turned out to be surprisingly seamless.</p><p>Reddit allows access via HTTP requests using Python&#8217;s <code>requests</code> library. I targeted the <strong>Nigeria subreddit</strong> and pulled the<strong> posts for each day</strong>, capped at 100 posts per request.</p><p>Key settings:</p><ul><li><p>Subreddit: <code>nigeria</code></p></li><li><p>Time filter: <code>day</code></p></li><li><p>Limit: <code>100</code></p></li></ul><p>Here&#8217;s the core setup:</p><pre><code><code>SUBREDDIT = "nigeria"
TIME_FILTER = "day"
LIMIT = 100
REDDIT_USERNAME = os.getenv("REDDIT_USERNAME")

REDDIT_URL = f"https://www.reddit.com/r/{SUBREDDIT}/top/.json?t={TIME_FILTER}&amp;limit={LIMIT}"
HEADERS = {"User-Agent": f"trend-scraper/0.1 by {REDDIT_USERNAME}"}
</code></code></pre><p>And the fetch function:</p><pre><code><code>def fetch_reddit_posts():
    response = requests.get(REDDIT_URL, headers=HEADERS, timeout=10)
    response.raise_for_status()
    return response.json()["data"]["children"]
</code></code></pre><p>Each post is then inserted into the database using an <code>INSERT</code> statement with conflict handling on the permalink:</p><pre><code><code>INSERT INTO reddit_posts (
    subreddit, title, upvotes, comments, author, permalink, created_utc
)
VALUES (%s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (permalink) DO NOTHING;
</code></code></pre><p>This ensures we don&#8217;t store duplicates.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a Coffee &#9749;&#65039;  &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a Coffee &#9749;&#65039;  &#128176;</span></a></p><div><hr></div><h2><strong>Displaying the Data: Streamlit + Pandas</strong></h2><p>To make the data usable, I built a <strong>Streamlit dashboard</strong>.</p><p>Once connected to the database, I:</p><ul><li><p>Queried the <code>reddit_posts</code> table</p></li><li><p>Loaded the results into a Pandas DataFrame using SQLAlchemy</p></li></ul><p>From there, the fun began.</p><p>With the data in a DataFrame, I could:</p><ul><li><p>Show total number of posts collected</p></li><li><p>Calculate average upvotes</p></li><li><p>Calculate average number of comments<br><em>(These folks really be yapping.)</em></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UEVE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UEVE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png 424w, https://substackcdn.com/image/fetch/$s_!UEVE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png 848w, https://substackcdn.com/image/fetch/$s_!UEVE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png 1272w, https://substackcdn.com/image/fetch/$s_!UEVE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UEVE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png" width="1456" height="385" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:385,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:143307,&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://fafacodes.substack.com/i/184201469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UEVE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png 424w, https://substackcdn.com/image/fetch/$s_!UEVE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png 848w, https://substackcdn.com/image/fetch/$s_!UEVE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.png 1272w, https://substackcdn.com/image/fetch/$s_!UEVE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39f5d6e1-bdbf-4ff7-8d76-a04e341ae214_2286x604.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 role="img" 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><title></title><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">Dashboard showcasing the numberof posts and the average number of upvotes and comments based on the applied filters</figcaption></figure></div><pre><code>total_items = len(df_filtered)
avg_upvotes = int(df_filtered[&#8221;upvotes&#8221;].mean()) if total_items &gt; 0 else 0
avg_comments = int(df_filtered[&#8221;comments&#8221;].mean()) if total_items &gt; 0 else 0
col1.metric(&#8221;Total posts&#8221;, total_items)
col2.metric(&#8221;Avg upvotes&#8221;, avg_upvotes)
col3.metric(&#8221;Avg comments&#8221;, avg_comments)</code></pre><div><hr></div><h2><strong>Filtering and Exploring Trends</strong></h2><p>I added a filter that lets users select posts based on <strong>minimum upvotes</strong>. This makes it easier to focus on high-engagement content.</p><p>The UI displays:</p><ul><li><p>Post title</p></li><li><p>Upvotes</p></li><li><p>Comments</p></li><li><p>Author</p></li><li><p>Created date</p></li></ul><p>This allows users to inspect the raw data before jumping into charts.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eGi1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eGi1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png 424w, https://substackcdn.com/image/fetch/$s_!eGi1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png 848w, https://substackcdn.com/image/fetch/$s_!eGi1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png 1272w, https://substackcdn.com/image/fetch/$s_!eGi1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eGi1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png" width="1456" height="618" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:618,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:310642,&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://fafacodes.substack.com/i/184201469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eGi1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png 424w, https://substackcdn.com/image/fetch/$s_!eGi1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png 848w, https://substackcdn.com/image/fetch/$s_!eGi1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.png 1272w, https://substackcdn.com/image/fetch/$s_!eGi1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fc6b3a0-ab64-4295-ad06-7f7ea5d1970e_2286x970.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 role="img" 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><title></title><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">20 Items from the database displayed on the dashboard ordered by the number of upvotes</figcaption></figure></div><div><hr></div><h2><strong>Visualising the Data</strong></h2><p>I used <strong>Plotly</strong> for interactive charts.</p><h3>1. Upvotes Distribution</h3><p>A bar chart showing:</p><ul><li><p><strong>X-axis:</strong> Number of upvotes</p></li><li><p><strong>Y-axis:</strong> Number of posts</p></li></ul><p>This helps answer questions like:</p><blockquote><p>How many posts actually get significant engagement?</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v7BC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v7BC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png 424w, https://substackcdn.com/image/fetch/$s_!v7BC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png 848w, https://substackcdn.com/image/fetch/$s_!v7BC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!v7BC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v7BC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png" width="1456" height="879" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:879,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:190516,&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://fafacodes.substack.com/i/184201469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!v7BC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png 424w, https://substackcdn.com/image/fetch/$s_!v7BC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png 848w, https://substackcdn.com/image/fetch/$s_!v7BC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!v7BC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9eb0dc-4b07-4904-b2ef-ef6cfc5dd258_2286x1380.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 role="img" 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><title></title><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">Distribution charts of number of posts versus the upvotes received</figcaption></figure></div><h3>2. Posts Over Time</h3><p>Another chart groups posts by day using the <code>created_at</code> field:</p><ul><li><p><strong>X-axis:</strong> Date</p></li><li><p><strong>Y-axis:</strong> Number of posts</p></li></ul><p>This makes it easy to spot spikes or drops in activity over time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZpmP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZpmP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png 424w, https://substackcdn.com/image/fetch/$s_!ZpmP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png 848w, https://substackcdn.com/image/fetch/$s_!ZpmP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png 1272w, https://substackcdn.com/image/fetch/$s_!ZpmP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZpmP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png" width="1456" height="788" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:788,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:185947,&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://fafacodes.substack.com/i/184201469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZpmP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png 424w, https://substackcdn.com/image/fetch/$s_!ZpmP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png 848w, https://substackcdn.com/image/fetch/$s_!ZpmP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.png 1272w, https://substackcdn.com/image/fetch/$s_!ZpmP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cd9040-6256-4a83-9cbd-32b15d9c2fe2_2118x1146.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 role="img" 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><title></title><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">Chart showcasing the number of posts over time</figcaption></figure></div><div><hr></div><h2><strong>Exporting the Data</strong></h2><p>If someone wants the raw data, they can export it.</p><p>A download button:</p><ul><li><p>Takes the filtered DataFrame</p></li><li><p>Saves it as a CSV file</p></li><li><p>Uses the default name: <code>filtered_reddit_trends.csv</code></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d-UI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d-UI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png 424w, https://substackcdn.com/image/fetch/$s_!d-UI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png 848w, https://substackcdn.com/image/fetch/$s_!d-UI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!d-UI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d-UI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png" width="1456" height="871" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:871,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:702495,&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://fafacodes.substack.com/i/184201469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!d-UI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png 424w, https://substackcdn.com/image/fetch/$s_!d-UI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png 848w, https://substackcdn.com/image/fetch/$s_!d-UI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.png 1272w, https://substackcdn.com/image/fetch/$s_!d-UI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ebb2de7-255a-432a-9d2b-e26b34ccd3e2_2740x1640.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 role="img" 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><title></title><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">exported data from the database as a csv file</figcaption></figure></div><div><hr></div><h2><strong>Automation: Keeping the Data Fresh</strong></h2><p>A data pipeline isn&#8217;t much use if it goes stale.</p><p>To keep things updated, I set up a <strong>cron job</strong> on my local machine that runs the data-fetching script daily at a fixed time.</p><p>This ensures:</p><ul><li><p>The database is continuously populated</p></li><li><p>Charts update automatically as new data comes in</p></li><li><p>Trends evolve naturally over time</p></li></ul><div><hr></div><h2><strong>Next Steps: Making It More Robust</strong></h2><p>Running cron jobs on my personal laptop isn&#8217;t ideal.</p><p>What happens if:</p><ul><li><p>My PC is turned off?</p></li><li><p>I forget to run it?</p></li><li><p>Something crashes silently?</p></li></ul><p>A better solution:</p><ul><li><p>Convert the script into an <strong>AWS Lambda function</strong></p></li><li><p>Use <strong>AWS EventBridge</strong> to trigger it daily</p></li></ul><p>That would significantly reduce the risk of missed updates and make the pipeline more production-ready.</p><p><strong>However, ain&#8217;t nobody got money for this.</strong> &#129318;&#8205;&#9792;&#65039; </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TUAc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TUAc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif 424w, https://substackcdn.com/image/fetch/$s_!TUAc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif 848w, https://substackcdn.com/image/fetch/$s_!TUAc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif 1272w, https://substackcdn.com/image/fetch/$s_!TUAc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TUAc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif" width="480" height="268" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:268,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:971852,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!TUAc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif 424w, https://substackcdn.com/image/fetch/$s_!TUAc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif 848w, https://substackcdn.com/image/fetch/$s_!TUAc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif 1272w, https://substackcdn.com/image/fetch/$s_!TUAc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5a56da5-923a-4bc7-ad57-c1a4b4e8b0b4_480x268.gif 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 role="img" 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><title></title><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><strong>Conclusion</strong></h2><p>So, there we have it.</p><p>I built a <strong>free, end-to-end data pipeline</strong> that:</p><ul><li><p>Collects trending topics in the Nigerian space using Reddit data</p></li><li><p>Stores them in a structured database</p></li><li><p>Automates ingestion over time</p></li><li><p>Visualises trends through a Streamlit dashboard</p></li><li><p>Allows data export for further analysis</p></li></ul><p>Core Python and Data libraties used are;</p><ul><li><p><code>os</code> - Environment variables</p></li><li><p><code>requests</code> - HTTP API calls to Reddit JSON endpoint</p></li><li><p><code>psycopg2</code> - PostgreSQL database connection</p></li><li><p><code>datetime</code> - Timestamp handling</p></li><li><p><code>dotenv</code> - Load <code>.env</code> files</p></li><li><p><code>pathlib</code> - File path resolution</p></li><li><p><code>streamlit</code> - Web dashboard framework (<code>st</code>, <code>@st.cache_data</code>)</p></li><li><p><code>pandas</code> - Data processing (<code>pd.read_sql</code>, DataFrames)</p></li><li><p><code>matplotlib.pyplot</code> - Charts (<code>plt.subplots</code>, <code>st.pyplot</code>)</p></li><li><p><code>sqlalchemy</code> - Database ORM (<code>create_engine</code>)</p></li></ul><p>This project helped me to connect a lot of dots from database design, to data ingestion, to automation and to visualisation.</p><p>Would you like access to the data or the project code?<br>Let me know in the comments, and I&#8217;ll make it available.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/i-built-a-data-pipeline-to-track?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="https://fafacodes.substack.com/p/i-built-a-data-pipeline-to-track?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Before You Build the Model, Define the Win]]></title><description><![CDATA[Why metrics, scope, and simple prototypes matter in ML projects]]></description><link>https://fafacodes.substack.com/p/before-you-build-the-model-define</link><guid isPermaLink="false">https://fafacodes.substack.com/p/before-you-build-the-model-define</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Fri, 09 Jan 2026 14:41:32 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5f2bde84-19cd-4107-a014-4479cef1c043.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you&#8217;re building an ML model, one simple question should come first:</p><p><strong>How do I know this model will actually solve the problem in the product I&#8217;m building?</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aeJA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aeJA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif 424w, https://substackcdn.com/image/fetch/$s_!aeJA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif 848w, https://substackcdn.com/image/fetch/$s_!aeJA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif 1272w, https://substackcdn.com/image/fetch/$s_!aeJA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aeJA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif" width="477" height="355" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:355,&quot;width&quot;:477,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:149758,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!aeJA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif 424w, https://substackcdn.com/image/fetch/$s_!aeJA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif 848w, https://substackcdn.com/image/fetch/$s_!aeJA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif 1272w, https://substackcdn.com/image/fetch/$s_!aeJA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48a5ea05-d9e6-4640-b9f1-14c9059d3590_477x355.gif 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 role="img" 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><title></title><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>This is where many ML projects quietly fail. Not because the model is bad, but because <em>&#8220;success&#8221;</em> was never clearly defined. That&#8217;s why metrics and planning are the foundation of any useful ML system and not just bureaucratic overhead.</p><p>Before writing a single line of training code, you need to decide how you&#8217;ll judge whether the model is doing a good job.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div><hr></div><h2>Defining What &#8220;Good&#8221; Means in an ML Product</h2><p>Before you start building, ask yourself:</p><blockquote><p><em>What metrics will I use to decide if my model is producing good results?</em></p></blockquote><p>Broadly, four categories of performance determine whether an ML model is actually useful in a product.</p><div><hr></div><h3>1. Business Performance: Does the Model Make the Product Better?</h3><p>If the problem your model is solving is clearly defined, then business metrics often tell you whether the model is succeeding.</p><p>For example, imagine building a recommender system for an entertainment app like Netflix or Spotify. The real question to judge model accuracy becomes:</p><ul><li><p>How often do users click on recommendations?</p></li><li><p>How frequently do they skip them?</p></li><li><p>Do recommendations increase watch time, listens, or retention?</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g9z2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g9z2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!g9z2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!g9z2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!g9z2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g9z2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif" width="480" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:42941,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!g9z2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!g9z2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!g9z2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!g9z2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58edba3f-ba2b-45e7-b238-914145f89ad3_480x480.gif 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 role="img" 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><title></title><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>To measure this, the product itself needs to capture user interactions. The UI has to log whether recommendations are accepted or ignored. Without this feedback loop, you can&#8217;t connect model outputs to real-world impact.</p><p>Business performance is usually something you only see <em>after</em> deployment, but that doesn&#8217;t make it optional.</p><div><hr></div><h3>2. Model Performance: Do the Predictions Make Sense?</h3><p>Unlike business metrics, model performance can (and should) be evaluated <em>before</em> launch. These are often called <strong>offline metrics</strong>.</p><p>After training, you test your model on held-out data to assess its accuracy and reasonableness.</p><p>For example:</p><ul><li><p>A classifier that predicts whether an image shows a traffic offence can be tested on labelled traffic images before it&#8217;s ever used in production.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0ebR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0ebR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!0ebR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!0ebR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!0ebR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0ebR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif" width="480" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4536353,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!0ebR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!0ebR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!0ebR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!0ebR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd792388f-ac6a-46da-81b5-0e997ba454ef_480x480.gif 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 role="img" 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><title></title><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>But there&#8217;s an important caveat here:</p><blockquote><p>A model is only as good as the data it was trained on.</p></blockquote><p>If that traffic offence model was trained mostly on daytime images in clear weather, its performance may degrade badly when tested on:</p><ul><li><p>Nighttime images</p></li><li><p>Poor weather conditions</p></li><li><p>Different camera angles or environments</p></li></ul><div><hr></div><h3>3. Freshness and Distribution Shift: Will It Still Work Tomorrow?</h3><p>Supervised models usually perform best when production data looks like training data. When that assumption breaks, things get interesting, and often ugly.</p><p>Consider a model trained to predict someone&#8217;s age from passport photos:</p><ul><li><p>If it were trained mostly on images of men, it may perform poorly on women.</p></li><li><p>If cosmetic procedures become more common, people may look significantly younger than their chronological age.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CiXP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CiXP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif 424w, https://substackcdn.com/image/fetch/$s_!CiXP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif 848w, https://substackcdn.com/image/fetch/$s_!CiXP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif 1272w, https://substackcdn.com/image/fetch/$s_!CiXP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CiXP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif" width="480" height="360" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:360,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2232432,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!CiXP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif 424w, https://substackcdn.com/image/fetch/$s_!CiXP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif 848w, https://substackcdn.com/image/fetch/$s_!CiXP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif 1272w, https://substackcdn.com/image/fetch/$s_!CiXP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c09457-4e56-4fd1-9c65-c5b3833c5bb4_480x360.gif 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 role="img" 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><title></title><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>Over time, real-world data changes. This is known as a <strong>distribution shift</strong>.</p><p>If you don&#8217;t plan for this, your model&#8217;s outputs slowly become obsolete. That&#8217;s why it&#8217;s critical to think ahead:</p><ul><li><p>How will you monitor changes in input data?</p></li><li><p>How often will the model be retrained?</p></li><li><p>What signals will tell you that performance is degrading?</p></li></ul><p>Freshness is not a &#8220;nice to have.&#8221; It&#8217;s essential for long-lived ML systems.</p><div><hr></div><h3>4. Speed: How Fast Is Fast Enough?</h3><p>Performance is also about latency.</p><p>How quickly does your model need to return a result?</p><p>That depends entirely on the product:</p><ul><li><p>A writing assistant needs to predict the next word in fractions of a second.</p></li><li><p>An image generator can take several seconds without harming the user experience.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YUPZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YUPZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif 424w, https://substackcdn.com/image/fetch/$s_!YUPZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif 848w, https://substackcdn.com/image/fetch/$s_!YUPZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif 1272w, https://substackcdn.com/image/fetch/$s_!YUPZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YUPZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif" width="450" height="450" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:450,&quot;width&quot;:450,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4260792,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!YUPZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif 424w, https://substackcdn.com/image/fetch/$s_!YUPZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif 848w, https://substackcdn.com/image/fetch/$s_!YUPZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif 1272w, https://substackcdn.com/image/fetch/$s_!YUPZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92abf3f2-57aa-4e44-903c-7ead30e5bf57_450x450.gif 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 role="img" 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><title></title><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>Speed requirements should be explicit. Otherwise, you risk building a model that works perfectly&#8230; but too slowly to be useful.</p><div><hr></div><h2>Scoping the Project and Anticipating Challenges</h2><p>Once you know <em>how</em> you&#8217;ll measure success, the next step is understanding the scope of what you&#8217;re building and the challenges you&#8217;re likely to face.</p><p>Two approaches help a lot here.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a Coffee &#9749;&#65039;  &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a Coffee &#9749;&#65039;  &#128176;</span></a></p><div><hr></div><h3>Leverage Domain Expertise</h3><p>For each performance metric, you should be able to answer a simple question:</p><blockquote><p><em>How do I check whether this result is actually good?</em></p></blockquote><p>Domain experts are invaluable for this. Often, a short conversation reveals how people in that field intuitively judge quality.</p><p>If you don&#8217;t have access to domain experts, your next best option is the data itself:</p><ul><li><p>Examine examples of successful outcomes.</p></li><li><p>Look for simple, interpretable patterns.</p></li></ul><p>For example, if you&#8217;re building a model that predicts whether an Instagram post will go viral, you might start by analysing viral posts and looking for common trends:</p><ul><li><p>Time or date of posting</p></li><li><p>Topic or content type</p></li><li><p>Follower count of the creator</p></li></ul><p>You&#8217;re basically trying to understand the problem first before building the perfect model. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JCvj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JCvj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!JCvj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!JCvj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!JCvj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JCvj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1383147,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!JCvj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!JCvj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!JCvj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!JCvj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e663788-9727-4503-bef4-ad50f7a4571f_480x270.gif 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 role="img" 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><title></title><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>Stand on the Shoulders of Giants</h3><p>Reinventing the wheel is rarely a good idea in ML.</p><p>Before working in isolation, ask:</p><ul><li><p>Do similar models already exist?</p></li><li><p>Are there public datasets relevant to this problem?</p></li><li><p>Is there open-source code I can learn from or adapt?</p></li></ul><p>Common sources of public data include:</p><ul><li><p>Reddit</p></li><li><p>Kaggle</p></li><li><p>Common Crawl</p></li><li><p>Wikipedia</p></li><li><p>The Internet Archive</p></li></ul><p>Leveraging existing work doesn&#8217;t make your solution more realistic.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l9vj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l9vj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png 424w, https://substackcdn.com/image/fetch/$s_!l9vj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png 848w, https://substackcdn.com/image/fetch/$s_!l9vj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png 1272w, https://substackcdn.com/image/fetch/$s_!l9vj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l9vj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png" width="1456" height="1214" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1214,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:891273,&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://fafacodes.substack.com/i/184013388?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!l9vj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png 424w, https://substackcdn.com/image/fetch/$s_!l9vj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png 848w, https://substackcdn.com/image/fetch/$s_!l9vj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.png 1272w, https://substackcdn.com/image/fetch/$s_!l9vj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa618e3e3-2130-4b2c-ac11-32859c450f6d_2242x1870.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 role="img" 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><title></title><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">Kaggle Datasets page showcasing trending Datasets</figcaption></figure></div><div><hr></div><h2>Build a Simple Prototype (Seriously)</h2><p>Once you&#8217;ve defined metrics, explored the problem space, and identified data sources, the next step is surprisingly simple:</p><p><strong>Build a basic prototype.</strong></p><p>At this stage, your goal is <em>not</em> perfection. It&#8217;s to see how your model behaves with:</p><ul><li><p>The data you have</p></li><li><p>The code you&#8217;ve written</p></li></ul><p>You should expect the model to be rough. That&#8217;s fine. The aim is incremental improvement, not a one-shot masterpiece.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AJWc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AJWc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!AJWc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!AJWc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!AJWc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AJWc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4788033,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!AJWc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!AJWc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!AJWc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!AJWc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c17e8f1-8a23-4fb3-a091-b4215bf6051d_480x270.gif 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 role="img" 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><title></title><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>A Minimal ML Pipeline</h3><p>At the very least, your project should have two pipelines:</p><h4>Training</h4><p>This is where you teach the model to make predictions. You iterate on data and code until the outputs start to make sense according to your defined metrics.</p><h4>Inference</h4><p>This is how the trained model is actually used. In production, inference usually involves:</p><ul><li><p>Receiving new data</p></li><li><p>Preprocessing it</p></li><li><p>Running it through the model</p></li><li><p>Returning a prediction</p></li></ul><p>Keeping these pipelines conceptually separate helps you reason clearly about your system.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kYvZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kYvZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png 424w, https://substackcdn.com/image/fetch/$s_!kYvZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png 848w, https://substackcdn.com/image/fetch/$s_!kYvZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png 1272w, https://substackcdn.com/image/fetch/$s_!kYvZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kYvZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png" width="1082" height="378" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:378,&quot;width&quot;:1082,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:67023,&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://fafacodes.substack.com/i/184013388?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kYvZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png 424w, https://substackcdn.com/image/fetch/$s_!kYvZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png 848w, https://substackcdn.com/image/fetch/$s_!kYvZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.png 1272w, https://substackcdn.com/image/fetch/$s_!kYvZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F637629b4-9f29-4f92-9aaf-f278b75d91eb_1082x378.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 role="img" 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><title></title><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">Complementary Training and Inference pipelines, as illustrated in Building Machine Learning Powered Applications by Emmanuel Ameisen</figcaption></figure></div><div><hr></div><h2>Conclusion: Start Small, Measure Clearly</h2><p>Defining core metrics <em>before</em> building your model is one of the most important steps in any ML project. It gives you a clear way to judge effectiveness early on and keeps your work grounded in reality.</p><p>Once metrics are defined:</p><ol><li><p>Build a simple training and inference pipeline.</p></li><li><p>Observe how the model performs.</p></li><li><p>Improve it iteratively.</p></li></ol><p>It&#8217;s far better to start small and refine your way toward your goals than to aim for a &#8220;perfect&#8221; model from the outset and miss the mark entirely.</p><p>In ML, clarity beats cleverness every time.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/before-you-build-the-model-define?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="https://fafacodes.substack.com/p/before-you-build-the-model-define?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[To ML or Not to ML?]]></title><description><![CDATA[How AI Engineers Decide When Machine Learning Can Be Applied to Software and When It Cannot Be]]></description><link>https://fafacodes.substack.com/p/to-ml-or-not-to-ml</link><guid isPermaLink="false">https://fafacodes.substack.com/p/to-ml-or-not-to-ml</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Wed, 07 Jan 2026 14:16:33 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a54478bf-808b-4a15-a81e-10650bf2f91e.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A major part of being an AI Engineer is <strong>building machine learning (ML) features that truly enhance software applications</strong>.</p><p>But before jumping straight in, one critical question must come first:</p><blockquote><p><strong>Is machine learning actually the right solution for this problem?</strong></p></blockquote><p>And if it is, <strong>what kind of ML model makes sense?</strong></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><p>Think about recommender systems on Amazon, Spotify, or Netflix; features like &#8220;Jobs You May Be Interested In&#8221; on LinkedIn, &#8220;People You May Know&#8221; on Instagram; or even writing suggestions in Grammarly. These are real-world examples of ML improving functionality and user experience.</p><p>In this post, I&#8217;ll discuss how AI Engineers evaluate whether ML should be applied, by considering the <strong>project goal</strong>, the <strong>data available</strong>, and the <strong>existence of suitable models</strong> to decide whether machine learning is the right tool, or if an alternative approach makes more sense.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6Cz0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6Cz0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!6Cz0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!6Cz0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!6Cz0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6Cz0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:956574,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!6Cz0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!6Cz0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!6Cz0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!6Cz0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3737ca-ee25-4134-af13-3a94b5bc9834_480x270.gif 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 role="img" 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><title></title><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><strong>Why Not Just Solve It With Code?</strong></h2><p>Let&#8217;s assume you have a clearly defined problem or a new feature you want to build.</p><p>For example:<br>A <strong>dog grooming app</strong> requires users to upload images of their dogs. You want to ensure that the uploaded image actually contains a dog.</p><p>Using traditional programming, you might try to write a series of rules and conditions:</p><ul><li><p>Does it have four legs?</p></li><li><p>Does it have a tail?</p></li><li><p>Are there whiskers?</p></li><li><p>Does it have pointy ears?</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!h1O4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!h1O4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png 424w, https://substackcdn.com/image/fetch/$s_!h1O4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png 848w, https://substackcdn.com/image/fetch/$s_!h1O4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png 1272w, https://substackcdn.com/image/fetch/$s_!h1O4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!h1O4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png" width="1176" height="462" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:462,&quot;width&quot;:1176,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:286659,&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://fafacodes.substack.com/i/183779198?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!h1O4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png 424w, https://substackcdn.com/image/fetch/$s_!h1O4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png 848w, https://substackcdn.com/image/fetch/$s_!h1O4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.png 1272w, https://substackcdn.com/image/fetch/$s_!h1O4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278ff1d3-a7cd-49a4-99a9-76af3576d0c1_1176x462.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 role="img" 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><title></title><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 from Building Machine Learning Powered Applications by Emmanuel Ameisen</figcaption></figure></div><p>If you&#8217;ve written code before, you can already see the problem.</p><p>This approach quickly turns into a <strong>maintenance nightmare</strong> full of loopholes and edge cases. What about dogs with cropped ears? Dogs lying down? Dogs partially out of frame? Wolves? Foxes? Stuffed toys?</p><p>Now compare that to a machine learning approach.</p><p>With ML, you can train an <strong>image classification model</strong> that learns patterns from thousands of labeled images and confidently determines whether an uploaded image contains a dog or not.</p><p>This is why a <strong>core skill for AI Engineers</strong> is knowing <strong>which problems are better solved with machine learning</strong> and identifying the <strong>appropriate ML approach</strong> to use.</p><div><hr></div><h2><strong>Evaluating Whether Machine Learning Is Feasible</strong></h2><p>To decide if machine learning is a viable solution, two fundamental questions must be answered:</p><ol><li><p><strong>What data is required for this task?</strong></p></li><li><p><strong>What machine learning models can be applied using that data?</strong></p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QiTd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QiTd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!QiTd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!QiTd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!QiTd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QiTd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43d588ca-2696-4086-8d91-da17152d2392_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2547552,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!QiTd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!QiTd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!QiTd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!QiTd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d588ca-2696-4086-8d91-da17152d2392_480x270.gif 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 role="img" 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><title></title><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>Let&#8217;s break these down.</p><div><hr></div><h3><strong>Data: The Foundation of Machine Learning</strong></h3><p>Data is one of the most valuable commodities of the 21st century (and for good reason).</p><p>Machine learning systems learn from data. That means <strong>AI is only as good as the data it was trained on</strong>.</p><p>For example, voice assistants trained primarily on accents from a limited geographic region will perform poorly for users outside that group. Imagine my grandmother, with her thick Igbo accent, trying to use Alexa or Siri.</p><p>(<em>internal screaming</em>)</p><p>Even I have to <strong>code-switch</strong> when speaking to AI systems. And honestly, having to do that unconsciously after finally unlearning it in human conversations is wild.</p><p>When evaluating data for machine learning, two key factors matter:</p><ul><li><p><strong>The type of data required</strong></p></li><li><p><strong>The availability of that data</strong></p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a Coffee &#9749;&#65039;  &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a Coffee &#9749;&#65039;  &#128176;</span></a></p><div><hr></div><h4><strong>Data Type: What Exactly Do You Need?</strong></h4><p>You cannot determine the type of data you need unless you are <strong>crystal clear about the problem you&#8217;re solving</strong>.</p><p>Some examples:</p><ul><li><p>A dog grooming app &#8594; <strong>images of dogs</strong></p></li><li><p>A writing assistant &#8594; <strong>text samples with excellent grammar</strong></p></li><li><p>A sales forecasting system &#8594; <strong>historical sales data</strong></p></li><li><p>A recommendation system &#8594; <strong>user behavior and interaction data</strong></p></li></ul><p>The problem definition always comes first. The data follows.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KL9e!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KL9e!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif 424w, https://substackcdn.com/image/fetch/$s_!KL9e!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif 848w, https://substackcdn.com/image/fetch/$s_!KL9e!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif 1272w, https://substackcdn.com/image/fetch/$s_!KL9e!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KL9e!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif" width="480" height="344" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:344,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7902417,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!KL9e!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif 424w, https://substackcdn.com/image/fetch/$s_!KL9e!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif 848w, https://substackcdn.com/image/fetch/$s_!KL9e!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif 1272w, https://substackcdn.com/image/fetch/$s_!KL9e!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85df600f-185a-4c2a-97e6-5f447fbd2b22_480x344.gif 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 role="img" 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><title></title><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><h4><strong>Data Availability: Where Will the Data Come From?</strong></h4><p>This is often the hardest part of the evaluation.</p><p>Where will your data come from?</p><ul><li><p>Web scraping</p></li><li><p>Organizational or internal data</p></li><li><p>Open-source or public datasets</p></li><li><p>Synthetic data</p></li></ul><p>The type of machine learning model you choose also determines the kind of data you&#8217;ll need.</p><ul><li><p><strong>Labeled data</strong> is essential for supervised learning tasks like classification. For example, a pet classifier requires images labeled as <em>dog</em>, <em>cat</em>, <em>not a pet</em>, etc.</p></li><li><p><strong>Weakly labeled data</strong> can be inferred from user behavior. For example, Spotify may interpret skipping a song early as a signal that the user didn&#8217;t enjoy it and adjust future recommendations accordingly.</p></li><li><p><strong>Unlabeled data</strong> is useful for discovering hidden patterns or trends that aren&#8217;t immediately obvious to humans.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div><hr></div><h3><strong>Choosing the Right Machine Learning Model</strong></h3><p>Once you understand your data, the next step is identifying the appropriate ML model for your problem.</p><p>Here are some common categories of machine learning models used in real-world applications.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GDyY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GDyY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!GDyY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!GDyY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!GDyY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GDyY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif" width="480" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2719996,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!GDyY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!GDyY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!GDyY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!GDyY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F053db4fc-a310-4703-9a9b-0bed16c50f95_480x480.gif 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 role="img" 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><title></title><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><h4><strong>Classification and Regression</strong></h4><ul><li><p><strong>Classification</strong> assigns data to predefined categories.<br>Examples include spam detection, fraud detection, or determining whether an image contains a dog.</p></li><li><p><strong>Regression</strong> focuses on prediction.<br>For example: predicting house prices, future sales, or economic trends.</p></li></ul><p>Will Nigeria win the next World Cup?</p><p>(<em>I hate that I don&#8217;t need AI to answer this question &#128557;</em>)</p><div><hr></div><h4><strong>Knowledge Extraction</strong></h4><p>Knowledge extraction models transform <strong>unstructured data into structured insights</strong>.</p><p>Examples include:</p><ul><li><p>Analyzing customer reviews to identify popular product features</p></li><li><p>Examining airport traffic data to uncover common travel routes or preferred airlines</p></li></ul><div><hr></div><h4><strong>Catalog Organization and Recommendation Systems</strong></h4><p>These models learn from <strong>past user behavior</strong> to make future recommendations.</p><p>Examples:</p><ul><li><p>&#8220;People You May Know&#8221; on Facebook</p></li><li><p>Product recommendations on Amazon</p></li><li><p>Content suggestions on Netflix</p></li></ul><p>(<em>Yes, I viewed her profile. No, I did not follow her. Please stop suggesting her before I accidentally send a friend request &#128557;</em>)</p><div><hr></div><h4><strong>Generative Models</strong></h4><p>Generative models focus on <strong>creating new data</strong> eg, text, images, audio, or video.</p><p>This is currently the most popular application of AI. However, because outputs are open-ended, evaluating their reliability and safety in production environments becomes a challenge of its own.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bGG6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bGG6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!bGG6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!bGG6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!bGG6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bGG6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif" width="480" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:931605,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!bGG6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!bGG6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!bGG6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!bGG6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e7c7b62-1ec8-4c97-8b67-e6a9445d8d9b_480x480.gif 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 role="img" 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><title></title><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><strong>Conclusion: When Machine Learning Makes Sense</strong></h2><p>Before committing to machine learning as a feature in your application, an AI Engineer must evaluate:</p><ul><li><p><strong>The problem being solved</strong></p></li><li><p><strong>The type and availability of data required</strong></p></li><li><p><strong>The appropriate machine learning model</strong></p></li></ul><p>Once these pieces are clear, you can confidently move forward with training models, validating results, and integrating ML into production systems.</p><p>Easy peasy. Lemon squeezy.</p><p>(<em>&#8230;or not &#128520;</em>)</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/to-ml-or-not-to-ml?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="https://fafacodes.substack.com/p/to-ml-or-not-to-ml?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[MCP: The USB-C Moment for AI Applications]]></title><description><![CDATA[How Model Context Protocol is solving AI&#8217;s biggest interoperability problem and why it matters for real-world, mission-driven tools]]></description><link>https://fafacodes.substack.com/p/mcp-the-usb-c-moment-for-ai-applications</link><guid isPermaLink="false">https://fafacodes.substack.com/p/mcp-the-usb-c-moment-for-ai-applications</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Sun, 04 Jan 2026 20:13:49 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f3ed97a4-8967-4688-8154-d12d1c06a671.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Model Context Protocol (MCP), often described as the <strong>&#8220;USB-C for AI applications,&#8221;</strong> is emerging as a foundational standard for how AI models connect to external capabilities.</p><p>The analogy is intentional.</p><p>Just as USB-C created a universal way for devices to connect to power, data, and peripherals, <strong>MCP creates a standard interface for AI models to connect to external tools, data sources, and environments</strong>. This simple idea unlocks something powerful: <strong>interoperability across the AI ecosystem</strong>.</p><p>At its core, MCP extends what AI models can do by allowing them to safely and consistently access more information and capabilities without custom, brittle integrations.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l-jq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l-jq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif 424w, https://substackcdn.com/image/fetch/$s_!l-jq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif 848w, https://substackcdn.com/image/fetch/$s_!l-jq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif 1272w, https://substackcdn.com/image/fetch/$s_!l-jq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l-jq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif" width="443" height="312" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:312,&quot;width&quot;:443,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2315953,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!l-jq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif 424w, https://substackcdn.com/image/fetch/$s_!l-jq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif 848w, https://substackcdn.com/image/fetch/$s_!l-jq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif 1272w, https://substackcdn.com/image/fetch/$s_!l-jq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7347e951-a279-439e-a6c0-c0e3a473a887_443x312.gif 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 role="img" 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><title></title><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>Why MCP Matters: Solving the M&#215;N Problem</h2><p>Before MCP, developers who wanted their AI application to interact with external tools faced a familiar engineering challenge: the <strong>M&#215;N problem</strong>.</p><ul><li><p><strong>M AI applications</strong></p></li><li><p><strong>N external tools or data sources</strong></p></li><li><p>Result: <strong>M &#215; N unique integrations</strong></p></li></ul><p>Each new tool required a custom implementation for each AI app. This approach does not scale.</p><p>MCP changes this entirely.</p><p>With MCP:</p><ul><li><p>Each <strong>AI application implements the client side once</strong></p></li><li><p>Each <strong>tool or data source implements the server side once</strong></p></li></ul><p>This transforms the problem from <strong>M&#215;N to M+N</strong>.</p><p>The result is a <strong>standardised, interoperable AI ecosystem</strong>, where tools become reusable, composable, and accessible across applications.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KNzZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KNzZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!KNzZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!KNzZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!KNzZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KNzZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1842296,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!KNzZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!KNzZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!KNzZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!KNzZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a7910b7-ee6f-43b9-80e1-e747a374d423_480x270.gif 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 role="img" 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><title></title><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>Core MCP Concepts </h2><p>To understand how MCP works, it helps to clarify its key components:</p><ul><li><p><strong>Host: </strong>The AI application the user interacts with directly<br><em>Example: Anthropic&#8217;s Claude Desktop</em></p></li><li><p><strong>Client: </strong>An intermediary between the Host and a specific MCP Server</p></li><li><p><strong>Server: </strong>A program or service that exposes capabilities via the MCP protocol</p></li><li><p><strong>Tool: </strong>A function the AI model can call to perform a task</p></li><li><p><strong>Resources: </strong>Read-only data sources exposed to the model</p></li><li><p><strong>Prompts: </strong>Structured communication between users, models, and available capabilities</p></li><li><p><strong>Sampling: </strong>Server-initiated requests that ask the Host/Client to perform LLM interactions</p></li></ul><p>Together, these components create a clean, predictable way for AI systems to interact with the outside world.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div><hr></div><h2>A Practical Example: CivicShield MCP</h2><p>To make this concrete, let&#8217;s look at a real project.</p><p><strong>CivicShield MCP</strong> is an <strong>AI-powered Digital Rights Risk Analyzer for Activists</strong>.</p><p>View project code on <a href="https://github.com/UffaModey/civic-shield-mcp#">GitHub</a>.</p><p>Digital rights activists are often required to engage with documents such as:</p><ul><li><p>Platform Terms of Service</p></li><li><p>Donor agreements</p></li><li><p>Data protection laws</p></li><li><p>Surveillance and security policies</p></li></ul><p>These documents are:</p><ul><li><p>Legally complex</p></li><li><p>Written for corporations, not communities</p></li><li><p>Potentially harmful if misunderstood</p></li></ul><p><strong>CivicShield MCP helps activists understand risk </strong><em><strong>before</strong></em><strong> harm happens.</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a Coffee &#9749;&#65039;  &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a Coffee &#9749;&#65039;  &#128176;</span></a></p><div><hr></div><h2>Core Technology Stack</h2><p>For this project, I used:</p><ul><li><p><strong>FastMCP: </strong>To orchestrate tools, handle routing, and expose an MCP-compatible API</p></li><li><p><strong>Gradio: </strong>To serve a lightweight, frictionless frontend for the application</p></li></ul><p>This combination allows me to focus on functionality while keeping the user experience simple and accessible.</p><div><hr></div><h2>How the Application Works</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L6eg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L6eg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png 424w, https://substackcdn.com/image/fetch/$s_!L6eg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png 848w, https://substackcdn.com/image/fetch/$s_!L6eg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png 1272w, https://substackcdn.com/image/fetch/$s_!L6eg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L6eg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png" width="1456" height="1015" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1015,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:180728,&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://fafacodes.substack.com/i/183365094?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L6eg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png 424w, https://substackcdn.com/image/fetch/$s_!L6eg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png 848w, https://substackcdn.com/image/fetch/$s_!L6eg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.png 1272w, https://substackcdn.com/image/fetch/$s_!L6eg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b81915-58d5-4f1c-aa35-4ee3336e053b_2454x1710.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 role="img" 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><title></title><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">Deployed app running locally on http://127.0.0.1:7888/</figcaption></figure></div><p>The project begins with an <code>app.py</code><a href="https://github.com/UffaModey/civic-shield-mcp/blob/main/app.py"> file</a>.</p><p>When the virtual environment is activated and the app is run using:</p><pre><code><code>python app.py
</code></code></pre><p>The application launches locally and opens in the browser, displaying the landing page.</p><p>From there, the user can upload a <strong>PDF document</strong> for analysis.</p><div><hr></div><h2>MCP in Action: Tool-Based Analysis</h2><p>When the user clicks <strong>&#8220;Analyse Document&#8221;</strong>, the application calls <strong>four tools</strong> defined in the <code>server.py</code> file using FastMCP:</p><ul><li><p><code>analyze_risks</code></p></li><li><p><code>extract_clauses</code></p></li><li><p><code>simplify_text</code></p></li><li><p><code>recommend_actions</code></p></li></ul><p>Each tool internally calls the <strong>OpenAI Chat Completions API</strong>, using carefully designed prompts to generate its response.</p><p>The key point here is architectural:</p><blockquote><p>The application does not need to know <em>how</em> the OpenAI API works, it only knows <em>which tools to call</em>.</p></blockquote><pre><code>from mcp.server.fastmcp import FastMCP
from api_tool import chat_completions

# -------------------------------
# MCP Server Setup
# -------------------------------
mcp = FastMCP("CivicShield MCP")

model = "gpt-4o"


@mcp.tool()
async def analyze_risks(text: str, context: dict) -&gt; str:
    """
    Analyze a document to identify digital rights risks for activists in a given
    region and activism context.
    """
    prompt = f""" ... """
    return chat_completions(model, prompt)


@mcp.tool()
async def extract_clauses(text: str) -&gt; str:
    """
    Identify and explain clauses in a document that could pose risks to activists.
    """
    prompt = f""" ... """
    return chat_completions(model, prompt)


@mcp.tool()
async def simplify_text(text: str, audience: str) -&gt; str:
    """
    Rewrite complex legal or policy text in plain language for a specific audience.
    """
    prompt = f""" ... """
    return chat_completions(model, prompt)


@mcp.tool()
async def recommend_actions(text: str, context: dict) -&gt; str:
    """
    Suggest practical safety and advocacy actions based on identified risks and context.
    """
    prompt = f""" ... """
    return chat_completions(model, prompt)
</code></pre><div><hr></div><h2>Why This Is the Magic of MCP</h2><p>If I deploy my MCP server, <strong>any other application</strong> can immediately call these tools without re-implementing logic or understanding the OpenAI API at all.</p><p>This is where MCP truly shines.</p><ul><li><p>Tools become reusable services</p></li><li><p>AI capabilities become modular</p></li><li><p>Developers can integrate powerful AI functionality without deep LLM expertise</p></li></ul><p>Yes, I <em>could</em> hard-code OpenAI API calls directly inside <code>app.py</code>, and the application would still work perfectly.</p><p>But that approach:</p><ul><li><p>Tightly couples AI logic to the app</p></li><li><p>Requires every developer to understand OpenAI&#8217;s API</p></li><li><p>Does not scale well as integrations grow</p></li></ul><p>Now imagine adding <strong>multiple AI providers</strong>, <strong>new data sources</strong>, or <strong>entirely different capabilities</strong>.</p><p>Without MCP, complexity grows fast.</p><p>With MCP, integration stays clean.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IQ97!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IQ97!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!IQ97!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!IQ97!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!IQ97!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IQ97!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:908786,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!IQ97!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!IQ97!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!IQ97!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!IQ97!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31433411-d144-4e42-94c6-56c162b9fb9d_480x270.gif 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 role="img" 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><title></title><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>Final Thoughts</h2><p>For me, this is the real power of Model Context Protocol.</p><p><strong>MCP lowers the barrier to building AI-powered applications</strong>, encourages reuse, and moves us closer to an open, interoperable AI ecosystem where tools can be shared, extended, and composed across projects.</p><p>That&#8217;s really good engineering.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/mcp-the-usb-c-moment-for-ai-applications?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="https://fafacodes.substack.com/p/mcp-the-usb-c-moment-for-ai-applications?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[PDFs to Answers: A RAG-Based Search Bot with LangChain]]></title><description><![CDATA[How I built a grounded AI search bot for answering questions over sensitive internal documents using RAG.]]></description><link>https://fafacodes.substack.com/p/building-an-ai-powered-internal-search</link><guid isPermaLink="false">https://fafacodes.substack.com/p/building-an-ai-powered-internal-search</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Fri, 02 Jan 2026 19:43:20 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/d6781c05-f63d-45ab-9f5a-892476ae28e8.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last month at work, we had a mini hackathon. Although I didn&#8217;t win (smiles in pain &#128522; ), I was genuinely intrigued by the task itself and by the solutions my extremely talented colleagues came up with. To be honest, I expected nothing less from them.</p><p>Still, the use case really resonated with me, so I decided to take some personal time to try out the task myself.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Diyw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Diyw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!Diyw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!Diyw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!Diyw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Diyw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif" width="480" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:945218,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!Diyw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!Diyw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!Diyw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!Diyw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c6fab5-87f3-40ab-819a-aad55aaf746d_480x480.gif 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 role="img" 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><title></title><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 challenge was simple:</p><blockquote><p><strong>Build a prototype of an AI-powered search bot that can look through a &#8220;data lake&#8221; of company PDFs (policy guides, handbooks, etc.) and return clear, human-readable answers to employee questions.</strong></p></blockquote><p><strong>Example Use</strong></p><p><strong>Input:</strong><br>A query around a particular policy or area in the app<br><em>e.g. &#8220;How many days of annual leave do I get at HHL?&#8221;</em></p><p><strong>Output:</strong><br>A clear, human-readable answer pulled from internal documents<br><em>e.g. &#8220;You get 28 days of annual leave.&#8221;</em></p><div><hr></div><h2>Solution Overview</h2><p>I took a stab at solving this using <strong><a href="https://www.langchain.com/">LangChain</a></strong>, and at a high level, what we&#8217;re building is a <strong><a href="https://docs.langchain.com/oss/python/langchain/rag#build-a-rag-agent-with-langchain">Retrieval-Augmented Generation (RAG)</a></strong><a href="https://docs.langchain.com/oss/python/langchain/rag#build-a-rag-agent-with-langchain"> application</a>.</p><p>View project repo on <a href="https://github.com/UffaModey/rag-search-bot">GitHub</a>.</p><p>In simple terms, this search bot:</p><ul><li><p>Searches internal documents using semantic similarity</p></li><li><p>Retrieves the most relevant content</p></li><li><p>Uses an LLM to generate a grounded, human-readable response</p></li><li><p>Restricts answers strictly to the provided documents</p></li></ul><p>The goal is to simulate <strong>conversational interactions</strong> with employees via text, while ensuring that responses are accurate, explainable, and sourced from internal documentation.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div><hr></div><h2>What Are We Doing, Simply?</h2><p>At its core, this is a <strong>question-answering system over private data</strong> using RAG.</p><p>Our solution uses a RAG agent that makes a <strong>single LLM call per query</strong>, performing contextual search over embedded documents and generating an answer based only on retrieved context.</p><p>This approach is particularly useful for organisations that:</p><ul><li><p>Have sensitive internal documents</p></li><li><p>Cannot expose sensitive internal documents to public-facing AI systems.</p></li><li><p>Still want to apply AI meaningfully to internal workflows</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8Lj7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8Lj7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif 424w, https://substackcdn.com/image/fetch/$s_!8Lj7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif 848w, https://substackcdn.com/image/fetch/$s_!8Lj7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif 1272w, https://substackcdn.com/image/fetch/$s_!8Lj7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8Lj7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif" width="400" height="203" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:203,&quot;width&quot;:400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:553769,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!8Lj7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif 424w, https://substackcdn.com/image/fetch/$s_!8Lj7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif 848w, https://substackcdn.com/image/fetch/$s_!8Lj7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif 1272w, https://substackcdn.com/image/fetch/$s_!8Lj7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c65cb83-d07d-4633-95c9-77c191763399_400x203.gif 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h2>Core Concepts (Quick Overview)</h2><p>Before diving into the build, let&#8217;s briefly cover the core concepts involved. If you&#8217;re already familiar with RAG, feel free to skip ahead to the implementation section.</p><div><hr></div><h3>Embeddings</h3><p>Embeddings are numerical representations of content that allow machines to process and understand text. They convert text into vectors that capture semantic meaning while discarding irrelevant detail.</p><p>The distance between two embeddings indicates how semantically similar they are. In LangChain:</p><ul><li><p><code>embed_query()</code> is used to generate embeddings for a single query</p></li><li><p><code>embed_documents()</code> is used to generate embeddings for multiple documents</p></li></ul><p>Below is a simple example that demonstrates how embeddings capture semantic similarity between words.</p><pre><code><code>import getpass
import os
from dotenv import load_dotenv
from scipy.spatial.distance import pdist, squareform
import numpy as np
import pandas as pd
from langchain_openai import OpenAIEmbeddings

load_dotenv()

if not os.getenv("OPENAI_API_KEY"):
    os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter your OpenAI API key: ")

os.environ["LANGSMITH_TRACING"] = "true"

if not os.getenv("LANGSMITH_API_KEY"):
    os.environ["LANGSMITH_API_KEY"] = getpass.getpass("Enter your LangSmith API key: ")

embeddings = OpenAIEmbeddings(
    model="text-embedding-3-large"
)

words = ["cat", "dog", "computer", "animal"]
doc_vectors = embeddings.embed_documents(words)

X = np.array(doc_vectors)
dists = squareform(pdist(X))

df = pd.DataFrame(data=dists, index=words, columns=words)
styled = df.style.background_gradient(cmap="coolwarm")
styled.to_html("embedding_distances.html")
</code></code></pre><p>Running this script generates a table showing the Euclidean distances between embeddings for the words <em>cat</em>, <em>dog</em>, <em>computer</em>, and <em>animal</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gDrT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gDrT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png 424w, https://substackcdn.com/image/fetch/$s_!gDrT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png 848w, https://substackcdn.com/image/fetch/$s_!gDrT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png 1272w, https://substackcdn.com/image/fetch/$s_!gDrT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gDrT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png" width="982" height="398" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/84704871-6602-42ec-aba5-8400b12b794b_982x398.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:398,&quot;width&quot;:982,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83954,&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://fafacodes.substack.com/i/183226508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gDrT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png 424w, https://substackcdn.com/image/fetch/$s_!gDrT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png 848w, https://substackcdn.com/image/fetch/$s_!gDrT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.png 1272w, https://substackcdn.com/image/fetch/$s_!gDrT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84704871-6602-42ec-aba5-8400b12b794b_982x398.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 role="img" 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><title></title><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">Embedding distances for 4 words: cat, dog, computer, animal</figcaption></figure></div><p>As expected, <strong>cat&#8211;animal</strong> and <strong>cat&#8211;dog</strong> are much closer semantically than <strong>cat&#8211;computer</strong>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a Coffee &#9749;&#65039;  &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a Coffee &#9749;&#65039;  &#128176;</span></a></p><div><hr></div><h3>Vector Storage</h3><p>Vector storage refers to how embeddings are stored and retrieved. There are three important concepts here:</p><ol><li><p><strong>Vector indexing:</strong> Organising vectors so similar ones are stored close together</p></li><li><p><strong>Vector libraries:</strong> Tools that perform vector operations and similarity search</p></li><li><p><strong>Vector databases:</strong> Systems for storing, managing, and querying large sets of vectors</p></li></ol><div><hr></div><h4>Vector Indexing</h4><p>Vector indexing structures embeddings so that similar vectors can be retrieved efficiently. Common algorithms include:</p><ul><li><p>Product Quantization (PQ)</p></li><li><p>Locality-Sensitive Hashing (LSH)</p></li><li><p>Hierarchical Navigable Small World (HNSW)</p></li></ul><p>The choice of indexing algorithm depends on trade-offs between search speed, accuracy, and memory usage.</p><div><hr></div><h4>Vector Libraries</h4><p>Vector libraries allow us to store embeddings and perform similarity search using Approximate Nearest Neighbour (ANN) algorithms.</p><p>Examples include:</p><ul><li><p><strong>FAISS</strong> (Facebook AI Similarity Search)</p></li><li><p><strong>Annoy</strong> (by Spotify)</p></li></ul><p>FAISS supports indexing algorithms such as PQ, LSH, and HNSW and is commonly used for similarity search and clustering over dense vectors.</p><div><hr></div><h4>Vector Databases</h4><p>Vector databases manage and query vector data at scale. Their primary application is <strong>semantic search</strong>.</p><p>Popular options include:</p><ul><li><p>Chroma</p></li><li><p>Qdrant</p></li><li><p>Milvus</p></li><li><p>Pinecone</p></li></ul><div><hr></div><h2>Prototype Development</h2><p>Now that we&#8217;ve covered the core concepts, let&#8217;s move on to the build.</p><p>The prototype follows two main phases:</p><ol><li><p><strong>Indexing</strong></p></li><li><p><strong>Retrieval and generation</strong></p></li></ol><div><hr></div><h2>Indexing</h2><h3>Document Loading</h3><p>We use LangChain&#8217;s <code>DirectoryLoader</code> to load all PDFs from a directory. This folder acts as the knowledge base for the search bot.</p><pre><code><code>loader = DirectoryLoader(documents_dir, glob="*.pdf", loader_cls=PyPDFLoader)
status_text.text("Loading PDF documents...")
progress_bar.progress(20)

try:
    docs = loader.load()
    status_text.text(f"Loaded {len(docs)} pages from {len(pdf_files)} files.")
    progress_bar.progress(40)
except Exception as e:
    st.error(f"&#10060; Error loading PDFs: {str(e)}")
    return None
</code></code></pre><div><hr></div><h3>Text Splitting</h3><p>Large documents are split into smaller chunks to improve retrieval quality. Here, we use 1,000-character chunks with a 200-character overlap to preserve context and metadata.</p><pre><code><code>splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
)

status_text.text("Splitting documents into chunks...")
progress_bar.progress(60)

chunks = splitter.split_documents(docs)
status_text.text(f"Created {len(chunks)} text chunks.")
progress_bar.progress(80)
</code></code></pre><div><hr></div><h3>FAISS Vector Store</h3><p>We then generate embeddings for each chunk and store them in a FAISS vector index.</p><pre><code><code>embedding_dim = len(embeddings.embed_query("test"))
index = faiss.IndexFlatL2(embedding_dim)

vector_store = FAISS(
    embedding_function=embeddings,
    index=index,
    docstore=InMemoryDocstore({}),
    index_to_docstore_id={},
)

status_text.text("Generating embeddings and indexing...")
vector_store.add_documents(chunks)
progress_bar.progress(100)
status_text.text("&#9989; Vector store ready!")
</code></code></pre><div><hr></div><h2>Retrieval and Generation</h2><h3>Retrieval</h3><p>When a user submits a query, we perform a similarity search over the vector store to retrieve the most relevant document chunks.</p><pre><code><code>retrieved_docs = vector_store.similarity_search(query, k=3)
</code></code></pre><div><hr></div><h3>Context Building and Prompting</h3><p>We then construct a context from the retrieved documents and explicitly instruct the LLM to use <strong>only</strong> that context when answering.</p><pre><code><code>context = "\n\n".join(
    f"Source: {doc.metadata.get('source', 'Unknown')} (Page {doc.metadata.get('page', 'N/A')})\n{doc.page_content}"
    for doc in retrieved_docs
)

prompt = f"""
You are an internal HR policy assistant.

Answer the user&#8217;s question using ONLY the information provided in the context.
If the answer is not present, say:
&#8220;I couldn&#8217;t find this information in the available documents.&#8221;
Always cite the source file and page after relevant facts.

Context:
{context}

Question:
{query}

Answer:
"""
</code></code></pre><div><hr></div><h3>Generation</h3><p>We invoke the LLM to generate a response grounded in the retrieved context.</p><pre><code><code>@st.cache_resource
def load_models():
    llm = ChatOpenAI(model="gpt-4o", temperature=0)
    embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
    return llm, embeddings

response = llm.invoke(prompt)
</code></code></pre><p>The UI then displays the answer, with an expandable section showing source metadata such as filenames and page numbers.</p><pre><code><code>with st.expander(f"&#128218; Sources ({len(retrieved_docs)} documents)", expanded=False):
    for i, doc in enumerate(retrieved_docs, 1):
        st.markdown(
            f"**Source {i}:** `{os.path.basename(doc.metadata.get('source', 'Unknown'))}`"
        )
        st.markdown(f"**Page:** {doc.metadata.get('page', 'N/A')}")
        st.markdown("**Content:**")
        st.write(
            doc.page_content[:500] + "..."
            if len(doc.page_content) &gt; 500
            else doc.page_content
        )</code></code></pre><h2>Demo</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2t_w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2t_w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png 424w, https://substackcdn.com/image/fetch/$s_!2t_w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png 848w, https://substackcdn.com/image/fetch/$s_!2t_w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png 1272w, https://substackcdn.com/image/fetch/$s_!2t_w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2t_w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png" width="812" height="866" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:866,&quot;width&quot;:812,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:155688,&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://fafacodes.substack.com/i/183226508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2t_w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png 424w, https://substackcdn.com/image/fetch/$s_!2t_w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png 848w, https://substackcdn.com/image/fetch/$s_!2t_w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.png 1272w, https://substackcdn.com/image/fetch/$s_!2t_w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdefaba5-5fe2-4404-98c0-bfd4bc61f181_812x866.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 role="img" 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><title></title><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">My project file set up showcasing the PDFs I loaded to my app</figcaption></figure></div><p>To run the app locally, activate your virtual environment, install the dependencies, and run:</p><pre><code> python -m streamlit run app.py</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uAxF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uAxF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png 424w, https://substackcdn.com/image/fetch/$s_!uAxF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png 848w, https://substackcdn.com/image/fetch/$s_!uAxF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png 1272w, https://substackcdn.com/image/fetch/$s_!uAxF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uAxF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png" width="1456" height="597" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:597,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:153769,&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://fafacodes.substack.com/i/183226508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uAxF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png 424w, https://substackcdn.com/image/fetch/$s_!uAxF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png 848w, https://substackcdn.com/image/fetch/$s_!uAxF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.png 1272w, https://substackcdn.com/image/fetch/$s_!uAxF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0f3d8ce-9479-452f-8027-8868079838a0_1994x818.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 role="img" 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><title></title><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">The app successfully loaded, running locally and opened in my web browser</figcaption></figure></div><p>You can then ask any question that may (or may not) be contained in the PDFs and view the generated responses along with their sources.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!39WT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!39WT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png 424w, https://substackcdn.com/image/fetch/$s_!39WT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png 848w, https://substackcdn.com/image/fetch/$s_!39WT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png 1272w, https://substackcdn.com/image/fetch/$s_!39WT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!39WT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png" width="1456" height="1132" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1132,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:327511,&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://fafacodes.substack.com/i/183226508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!39WT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png 424w, https://substackcdn.com/image/fetch/$s_!39WT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png 848w, https://substackcdn.com/image/fetch/$s_!39WT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.png 1272w, https://substackcdn.com/image/fetch/$s_!39WT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbedb9407-26fc-40ab-9b21-0172164994d0_1994x1550.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 role="img" 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><title></title><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">Demo 1 of a question asked of the app and its successful response</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1sbS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1sbS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png 424w, https://substackcdn.com/image/fetch/$s_!1sbS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png 848w, https://substackcdn.com/image/fetch/$s_!1sbS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png 1272w, https://substackcdn.com/image/fetch/$s_!1sbS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1sbS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png" width="1456" height="1132" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1132,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:319833,&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://fafacodes.substack.com/i/183226508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1sbS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png 424w, https://substackcdn.com/image/fetch/$s_!1sbS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png 848w, https://substackcdn.com/image/fetch/$s_!1sbS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.png 1272w, https://substackcdn.com/image/fetch/$s_!1sbS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9058b1a2-5f2e-4989-bbb7-19a89697774c_1994x1550.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 role="img" 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><title></title><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">Demo 2 of a question asked of the app and its successful response</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mrqv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mrqv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png 424w, https://substackcdn.com/image/fetch/$s_!mrqv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png 848w, https://substackcdn.com/image/fetch/$s_!mrqv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png 1272w, https://substackcdn.com/image/fetch/$s_!mrqv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mrqv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png" width="1456" height="847" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:847,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:263962,&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://fafacodes.substack.com/i/183226508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mrqv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png 424w, https://substackcdn.com/image/fetch/$s_!mrqv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png 848w, https://substackcdn.com/image/fetch/$s_!mrqv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.png 1272w, https://substackcdn.com/image/fetch/$s_!mrqv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12eb45c5-392e-4b63-ab25-e4be8d794c72_2206x1284.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 role="img" 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><title></title><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">Demo 3 of a question asked of the app and its successful response</figcaption></figure></div><h2>Conclusion</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-QfK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-QfK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-QfK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-QfK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-QfK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-QfK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg" width="3024" height="2326" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2326,&quot;width&quot;:3024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2121748,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://fafacodes.substack.com/i/183226508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd456851-2720-43e2-bee8-924923a10fbb.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-QfK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-QfK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-QfK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-QfK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8a51f5-0e4a-42cd-8050-a01374dacdf2_3024x2326.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 role="img" 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><title></title><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>I genuinely enjoyed building this app. Not just because it worked, but because of how much I learned revisiting core concepts like embeddings, vector databases, and indexing.</p><p>The RAG use case is particularly ingenious. Many organisations have sensitive internal documents that should not be exposed publicly, yet still need AI applied to them in a safe and controlled way. RAG offers a powerful solution to that problem.</p><p>I&#8217;m looking forward to doing more with RAG and exploring how it can be applied as a core capability when building other applications.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/building-an-ai-powered-internal-search?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading AI with Fafa! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/building-an-ai-powered-internal-search?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://fafacodes.substack.com/p/building-an-ai-powered-internal-search?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><p></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[How I Get AI to Do Exactly What I Want; Nothing more, Nothing Less]]></title><description><![CDATA[A practical reflection on why AI misunderstands us, how bad prompts sabotage good models, and best practices for prompt engineering]]></description><link>https://fafacodes.substack.com/p/how-i-get-ai-to-do-exactly-what-i</link><guid isPermaLink="false">https://fafacodes.substack.com/p/how-i-get-ai-to-do-exactly-what-i</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Tue, 30 Dec 2025 23:22:02 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7d9e1c13-1a46-416a-a43e-1b975c3d9eaa.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let&#8217;s be honest: communicating with a fully grown adult with fully formed frontal lobes can be a chore sometimes. Whether it&#8217;s through texting, phone calls, face-to-face conversations, letters, interviews, or blog posts, you sometimes realize that there are people who find a way to twist your words, derive an entirely new narrative from your statements, or completely miss your point altogether.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Agda!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Agda!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif 424w, https://substackcdn.com/image/fetch/$s_!Agda!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif 848w, https://substackcdn.com/image/fetch/$s_!Agda!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif 1272w, https://substackcdn.com/image/fetch/$s_!Agda!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Agda!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif" width="499" height="499" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:499,&quot;width&quot;:499,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3476647,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!Agda!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif 424w, https://substackcdn.com/image/fetch/$s_!Agda!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif 848w, https://substackcdn.com/image/fetch/$s_!Agda!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif 1272w, https://substackcdn.com/image/fetch/$s_!Agda!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36ade7b7-a7df-427a-ae70-13c2ed7318b3_499x499.gif 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 role="img" 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><title></title><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>Bruhhh&#8230; have you ever tried to place an order, pour your heart out in a relationship, delegate a task, or narrate an experience to someone, only for them to totally misunderstand you? Almost like speaking to a brick wall sometimes. Or maybe the misunderstanding arises from your poor communication skills. There are scenarios where you don&#8217;t even want to try to express yourself directly, so you hire an expert or bring in a third party to communicate on your behalf. Just so nothing gets lost in translation or taken out of context.</p><p>And this is while communicating with fellow humans &#128516;<br>What happens when we have to communicate with machines?<br><em>Smiles in confusion.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div><hr></div><h4>How can you get a foundation AI model to do exactly what you want?</h4><p>Nothing more. Nothing less.</p><p>This is commonly known as <strong>prompt engineering</strong>. It is the process of crafting instructions that guide a model to generate the desired outcome.</p><div><hr></div><h2>Prompting AI</h2><p>Depending on your use case, you can give prompts to foundation AI models using different styles. Some people talk to AI the same way they would talk to a friend or fellow human. But after a while, you may realise that you&#8217;re not very satisfied with the responses the model generates.</p><p>This could be caused by several factors:</p><ul><li><p>Very open-ended prompts where you assume the AI knows what you&#8217;re referring to, the same way a human would, but of course, it doesn&#8217;t.</p></li><li><p>Not clearly stating what you want, or including typos and grammatical errors that completely change the meaning of your request.</p></li><li><p>Not providing explicit boundaries for the depth or scope of the response.</p></li><li><p>The level of &#8220;intelligence&#8221; of the model with respect to completing the specified task.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zWln!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zWln!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif 424w, https://substackcdn.com/image/fetch/$s_!zWln!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif 848w, https://substackcdn.com/image/fetch/$s_!zWln!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif 1272w, https://substackcdn.com/image/fetch/$s_!zWln!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zWln!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif" width="480" height="269" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:269,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3397470,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!zWln!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif 424w, https://substackcdn.com/image/fetch/$s_!zWln!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif 848w, https://substackcdn.com/image/fetch/$s_!zWln!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif 1272w, https://substackcdn.com/image/fetch/$s_!zWln!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3c8da22-92ca-463d-9d02-153a5920f3ea_480x269.gif 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 role="img" 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><title></title><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>Giving a model a good prompt is directly related to the quality of the response it generates. It&#8217;s basically a <em>garbage-in, garbage-out</em> scenario. If you give AI a rubbish prompt, you&#8217;ll most likely get a rubbish response &#129299;.</p><p>I feel compelled to share that in my not-so-finest moments, I have gotten very frustrated with ChatGPT&#8217;s responses and spiralled while prompting, causing the entire chat to turn into one big back-and-forth that eventually resulted in model hallucinations.<br>(<em>Bows head in shame and commits to doing better.</em>)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!b660!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b660!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png 424w, https://substackcdn.com/image/fetch/$s_!b660!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png 848w, https://substackcdn.com/image/fetch/$s_!b660!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png 1272w, https://substackcdn.com/image/fetch/$s_!b660!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b660!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png" width="1179" height="826" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:826,&quot;width&quot;:1179,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:97059,&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://fafacodes.substack.com/i/182990817?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!b660!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png 424w, https://substackcdn.com/image/fetch/$s_!b660!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png 848w, https://substackcdn.com/image/fetch/$s_!b660!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.png 1272w, https://substackcdn.com/image/fetch/$s_!b660!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F877f84cf-62fa-4442-bd38-588c8b7122d7_1179x826.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 role="img" 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><title></title><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">I asked ChatGPT to generate trivia questions for game night, and it did a very poor job, mainly because of my provided prompts. <a href="https://chatgpt.com/share/69545c44-081c-800a-aee5-e339180d8fdf">See the full chat here for additional context</a></figcaption></figure></div><div><hr></div><p>So whether you&#8217;re using system prompts, user prompts, or leveraging the model&#8217;s context window, you need to think critically about:</p><ul><li><p>The outcomes you require from the model</p></li><li><p>How your instructions might be misinterpreted</p></li><li><p>What the model should use as a source of truth</p></li><li><p>How clearly all of this is communicated</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a Coffee &#9749;&#65039;  &#128176;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a Coffee &#9749;&#65039;  &#128176;</span></a></p><div><hr></div><h2>Best Practices for Prompt Engineering</h2><p>I believe that how a model understands information in a prompt largely depends on the quality of the model itself. However, beyond model-specific prompting techniques, there are general guidelines you should follow to communicate clearly and get the desired results.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!H2CJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!H2CJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!H2CJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!H2CJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!H2CJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!H2CJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif" width="480" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3008437,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!H2CJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!H2CJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!H2CJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!H2CJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c58c42-41f0-47c2-821f-c4df6abc72d9_480x480.gif 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 role="img" 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><title></title><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>Write clear and explicit instructions</h3><p>Some tips for writing clear instructions for AI models include:</p><ul><li><p>Explaining unambiguously what you want the model to do</p></li><li><p>Asking the model to adopt a specific persona</p></li><li><p>Providing examples</p></li><li><p>Specifying the desired output format</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!70zR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!70zR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png 424w, https://substackcdn.com/image/fetch/$s_!70zR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png 848w, https://substackcdn.com/image/fetch/$s_!70zR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png 1272w, https://substackcdn.com/image/fetch/$s_!70zR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!70zR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png" width="1456" height="643" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f311f20b-5301-4789-b35f-305402f71e70_1462x646.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:643,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:117486,&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://fafacodes.substack.com/i/182990817?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!70zR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png 424w, https://substackcdn.com/image/fetch/$s_!70zR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png 848w, https://substackcdn.com/image/fetch/$s_!70zR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.png 1272w, https://substackcdn.com/image/fetch/$s_!70zR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff311f20b-5301-4789-b35f-305402f71e70_1462x646.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 role="img" 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><title></title><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">An example of clear instructions for a task given to an AI model</figcaption></figure></div><div><hr></div><h3>Provide sufficient context</h3><p>Context helps the model understand where to gather information from. For example, you might specify that the model should reference a particular document or web link when generating its response.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ki_K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ki_K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png 424w, https://substackcdn.com/image/fetch/$s_!ki_K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png 848w, https://substackcdn.com/image/fetch/$s_!ki_K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png 1272w, https://substackcdn.com/image/fetch/$s_!ki_K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ki_K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png" width="1456" height="643" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:643,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:125614,&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://fafacodes.substack.com/i/182990817?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ki_K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png 424w, https://substackcdn.com/image/fetch/$s_!ki_K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png 848w, https://substackcdn.com/image/fetch/$s_!ki_K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.png 1272w, https://substackcdn.com/image/fetch/$s_!ki_K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c3de685-4d1e-494e-9fab-826f1b6cc649_1462x646.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 role="img" 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><title></title><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">An example of giving sufficient context in an AI model prompt</figcaption></figure></div><div><hr></div><h3>Break complex tasks into simpler subtasks</h3><p>Instead of writing one very large, complex prompt, break it down into smaller subtasks. This helps the model understand the task better.</p><p>For example, in a ChatGPT session involving a large task like a code review, you can start by explaining the overall goal and then provide separate prompts for each individual step.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FUp6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FUp6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png 424w, https://substackcdn.com/image/fetch/$s_!FUp6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png 848w, https://substackcdn.com/image/fetch/$s_!FUp6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png 1272w, https://substackcdn.com/image/fetch/$s_!FUp6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FUp6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png" width="1456" height="906" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/acd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:906,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:152775,&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://fafacodes.substack.com/i/182990817?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FUp6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png 424w, https://substackcdn.com/image/fetch/$s_!FUp6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png 848w, https://substackcdn.com/image/fetch/$s_!FUp6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.png 1272w, https://substackcdn.com/image/fetch/$s_!FUp6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd71144-625c-4a08-8dc4-d7c1619210d9_1462x910.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 role="img" 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><title></title><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">An example of providing subtasks in a prompt to an AI model</figcaption></figure></div><div><hr></div><h3>Give the model time to think</h3><p>Chain-of-thought prompting enables the model to critique itself. This is especially helpful when you&#8217;re unsure what a &#8220;good&#8221; response should look like.</p><p>Personally, when I&#8217;m uncertain about a response, I ask the model to &#8220;explain its reasoning&#8221; or provide a step-by-step breakdown of how it arrived at the answer.</p><div><hr></div><h3>Iterate on your prompts</h3><p>Sometimes you need to experiment. Try different ways of asking the model to perform the same task and observe how the responses change.</p><p>This requires a lot of out-of-the-box thinking, but it helps you better understand how the model processes information.</p><div><hr></div><h3>Evaluate prompt engineering tools</h3><p>There are tools designed to help generate effective prompts for specific tasks, such as OpenPrompt, DSPy, DeepMind&#8217;s PromptBreeder, and Stanford&#8217;s TextGrad.</p><p>One thing I personally like doing is asking AI to generate a suitable prompt for me. For example, when vibe-coding with Lovable or Goose, I use ChatGPT to generate a prompt for a feature I want to build, then copy and paste it into the vibe-coding platform.</p><p>That said, sometimes a hiccup arises in <em>how</em> to prompt ChatGPT to generate the right prompt for the vibe-coding tool.<br>(<em>Screams internally.</em>)</p><p>The chicken-and-egg problem: who came first? &#128520;<br>Do I now use a prompt engineering tool to generate a prompt that I&#8217;ll use to generate another prompt for vibe coding? Bruh.</p><div><hr></div><h3>Organise and version your prompts</h3><p>When working with a model API, maintaining code quality is important. For readability, testing, and collaboration, you should keep prompts in separate files and import them into your code as needed.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Y5Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Y5Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png 424w, https://substackcdn.com/image/fetch/$s_!0Y5Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png 848w, https://substackcdn.com/image/fetch/$s_!0Y5Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png 1272w, https://substackcdn.com/image/fetch/$s_!0Y5Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Y5Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png" width="982" height="398" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:398,&quot;width&quot;:982,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:80929,&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://fafacodes.substack.com/i/182990817?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0Y5Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png 424w, https://substackcdn.com/image/fetch/$s_!0Y5Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png 848w, https://substackcdn.com/image/fetch/$s_!0Y5Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.png 1272w, https://substackcdn.com/image/fetch/$s_!0Y5Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27efb7d2-6718-4ac1-b223-0e47e0ab0db2_982x398.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 role="img" 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><title></title><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">An example of importing a prompt from a file within code from AI Engineering by Huyen</figcaption></figure></div><div><hr></div><h2>Conclusion</h2><p>Prompt engineering is a very big deal. At this point, it&#8217;s essentially the ability to get AI to do <em>anything</em> within its constraints.</p><p>There are strict limits in place to prevent harmful use of AI and that&#8217;s a topic we can explore in another post. But generally speaking, AI isn&#8217;t inherently &#8220;smart.&#8221; A lot of effort is required to ensure it generates the results you want.</p><p>Nothing more. Nothing less.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/how-i-get-ai-to-do-exactly-what-i?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="https://fafacodes.substack.com/p/how-i-get-ai-to-do-exactly-what-i?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[ChatGPT vs Claude vs Gemini: Who Really Gives the “Best” AI Responses?]]></title><description><![CDATA[Why evaluating AI outputs is subjective, what trade-offs matter most, and how to decide which model fits your use case.]]></description><link>https://fafacodes.substack.com/p/chatgpt-vs-claude-vs-gemini-who-really</link><guid isPermaLink="false">https://fafacodes.substack.com/p/chatgpt-vs-claude-vs-gemini-who-really</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Mon, 29 Dec 2025 22:06:08 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e2b9263f-69c0-4b47-a32b-e264cbea857c_3024x4032.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p><strong>Which Foundation AI Model Gives the Best Responses?</strong></p></blockquote><p>I&#8217;ve been thinking about this lately. Ever since the growing popularity and adoption of foundation AI models, what is the real benchmark for saying that a model gives <em>very good</em> responses?</p><p>Foundation models like ChatGPT, Claude, and Gemini now support a wide range of use cases, both for personal use and for building AI-based software.</p><p>But how can we properly evaluate the responses from these models?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UqPH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UqPH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif 424w, https://substackcdn.com/image/fetch/$s_!UqPH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif 848w, https://substackcdn.com/image/fetch/$s_!UqPH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif 1272w, https://substackcdn.com/image/fetch/$s_!UqPH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UqPH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif" width="450" height="253" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:253,&quot;width&quot;:450,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:557272,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!UqPH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif 424w, https://substackcdn.com/image/fetch/$s_!UqPH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif 848w, https://substackcdn.com/image/fetch/$s_!UqPH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif 1272w, https://substackcdn.com/image/fetch/$s_!UqPH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ab914c8-6e97-4d4f-ba3d-8884dafa2b0b_450x253.gif 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 role="img" 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><title></title><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>Other AI models, such as classifier models, are quite binary in their use. For example, with a model trained to detect spam emails, it is very easy to determine whether the model works optimally or not. You can test it on 10,000 sampled emails and immediately see which ones are spam and which are not. Easy peasy, lemon squeezy.</p><p>From those results, you can determine how efficient the model is: how many emails it correctly classified as spam and how many it wrongly classified.</p><p>However, when using foundation models like ChatGPT, Gemini, or Claude for personal use, it becomes much harder to determine whether a response is satisfactory or not.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zFvs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zFvs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!zFvs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!zFvs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!zFvs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zFvs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/967eb516-e200-4836-b07b-56db003140a9_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:850899,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="" srcset="https://substackcdn.com/image/fetch/$s_!zFvs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!zFvs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!zFvs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!zFvs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F967eb516-e200-4836-b07b-56db003140a9_480x270.gif 1456w" sizes="100vw"></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 role="img" 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><title></title><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>Let&#8217;s do a quick experiment. I&#8217;ll give the same prompt to three foundation models and evaluate their responses. Imagine I want to create an AI-based service for generating poems, and I want to use an AI model for this feature.</p><p>Here is the prompt:</p><blockquote><p><em>&#8220;Write a short poem for me.&#8221;</em></p></blockquote><p>Below are the responses from OpenAI&#8217;s ChatGPT, Anthropic&#8217;s Claude, and Google&#8217;s Gemini.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n4cX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n4cX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png 424w, https://substackcdn.com/image/fetch/$s_!n4cX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png 848w, https://substackcdn.com/image/fetch/$s_!n4cX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png 1272w, https://substackcdn.com/image/fetch/$s_!n4cX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n4cX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png" width="1456" height="1010" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1010,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:155522,&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://fafacodes.substack.com/i/182852962?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!n4cX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png 424w, https://substackcdn.com/image/fetch/$s_!n4cX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png 848w, https://substackcdn.com/image/fetch/$s_!n4cX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.png 1272w, https://substackcdn.com/image/fetch/$s_!n4cX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee25459c-52e7-4b77-8c4d-4d189cb4cee9_1568x1088.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 role="img" 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><title></title><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 class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uWJa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uWJa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png 424w, https://substackcdn.com/image/fetch/$s_!uWJa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png 848w, https://substackcdn.com/image/fetch/$s_!uWJa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png 1272w, https://substackcdn.com/image/fetch/$s_!uWJa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uWJa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png" width="1456" height="1203" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1203,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:234285,&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://fafacodes.substack.com/i/182852962?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uWJa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png 424w, https://substackcdn.com/image/fetch/$s_!uWJa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png 848w, https://substackcdn.com/image/fetch/$s_!uWJa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.png 1272w, https://substackcdn.com/image/fetch/$s_!uWJa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa77e43f4-aa17-4196-bb96-9125a70aef61_1724x1424.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 role="img" 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><title></title><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 class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lpOg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lpOg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png 424w, https://substackcdn.com/image/fetch/$s_!lpOg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png 848w, https://substackcdn.com/image/fetch/$s_!lpOg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png 1272w, https://substackcdn.com/image/fetch/$s_!lpOg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lpOg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png" width="1456" height="799" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:799,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:165097,&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://fafacodes.substack.com/i/182852962?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lpOg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png 424w, https://substackcdn.com/image/fetch/$s_!lpOg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png 848w, https://substackcdn.com/image/fetch/$s_!lpOg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.png 1272w, https://substackcdn.com/image/fetch/$s_!lpOg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58ab9851-cc34-4a1f-a4aa-05143341cd7a_1724x946.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 role="img" 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><title></title><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>To be honest, I&#8217;m not really a poet, but here are my thoughts on the three responses:</p><ul><li><p><strong>ChatGPT: </strong>It knows my name. <em>shy &#128584;</em><br>Maybe because this is my most-used foundation AI model, the poem honestly feels very personalised. It is almost like it reflects a stage in my life that I&#8217;m currently going through. In my opinion, the response is <em>too</em> personalised. Maybe I&#8217;m the only one who can tell, because I&#8217;m the only one who knows what I&#8217;ve discussed previously on the platform.<br>For context, I&#8217;m logged into my personal account for all of these experiments. However, remember that the idea here is to build an AI-based product that generates poems (not necessarily poems for <em>me</em> personally).</p></li><li><p><strong>Claude: </strong>Not bad at all, per se.</p></li><li><p><strong>Gemini: </strong>If I needed an AI-generated poem, I would definitely choose Claude&#8217;s response over Gemini&#8217;s.</p></li></ul><p>Now, this works because we are able to give feedback on the responses. We already have some idea of what a &#8220;good&#8221; poem might look like.</p><p>Let&#8217;s take it up a notch.</p><p>What if we want an AI response for a task where we <em>don&#8217;t</em> know what a good response should look like? What if we need a model to summarise a large body of text that we haven&#8217;t already read?</p><p>How do we know if it has done a good job?</p><p><em>Da dauuumm&#8230;</em><br>These are the real issues.</p><p>So how can we say which model provides the best response for a specific task? How do we know which model to adopt for personal use or for embedding AI features into applications via APIs?</p><p>The truth is that responses from foundation models are currently very subjective. There is no direct or easy method to assess their output quality universally.</p><p>However, there <em>are</em> metrics that individuals and developers can apply when deciding which model to adopt for a specific task.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buy.stripe.com/cNi28t42s7dj15u0VC33W00&quot;,&quot;text&quot;:&quot;Buy Fafa a Coffee &#128181;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buy.stripe.com/cNi28t42s7dj15u0VC33W00"><span>Buy Fafa a Coffee &#128181;</span></a></p><h3>1. Data Privacy</h3><p>Any information you provide to a model via a prompt can potentially become part of the model&#8217;s knowledge base. This can lead to severe data leaks in use cases where privacy is critical.</p><p>Think about this from both national security and proprietary business perspectives. Before using a model, you need to understand where the model hosts its data. Are you comfortable with your data being hosted outside your national servers? What is the model&#8217;s policy on using prompt data for training and improvement?</p><h3>2. Data Lineage and Copyright</h3><p>Although IP laws around AI are still evolving, understanding a model&#8217;s training data sources is crucial (especially for commercial use). If a model is trained on copyrighted data and you use it to generate a digital product, can you fully defend your product&#8217;s intellectual property?</p><h3>3. Performance</h3><p>It has become obvious that many foundation models perform better when you pay for them (<em>internal screaming</em>). Open-source models often do not yet match proprietary ones in performance. Sad but true.</p><p>That said, history shows us that open-source software eventually catches up. At some point, open-source foundation models will likely reach parity with proprietary models.</p><h3>4. Functionality</h3><p>For me, this should be the defining factor.</p><p>Instead of asking which model is &#8220;the best,&#8221; we should ask how well a model performs <em>the specific task we care about</em>. Reviewing response quality for your particular use case is often the most practical way to decide.</p><p>In my earlier example, the experiment was inconclusive because the prompt itself wasn&#8217;t well-suited to the use case. I didn&#8217;t specify that the poem should be generic enough for something like an electronic billboard in a city centre. Expecting the model to infer that was unrealistic.</p><h3>5. Control</h3><p>When ChatGPT launched in 2022, people built entire SaaS products around its API. Wild times.</p><p>But what happens when a model is deprecated, its API changes, or access is restricted entirely? There&#8217;s a real risk in tightly coupling your product to a single external model. This needs to be considered before committing long-term.</p><h3>6. Cost</h3><p>Depending on pricing, rate limits, and SLAs, building your own model can sometimes be the better option.</p><p>Okay, calm down. I&#8217;m not screaming <em>&#8220;build your own foundation model&#8221;</em> like it&#8217;s a sponge cake. But when you factor in cost per API call and long-term scalability for commercial applications, it&#8217;s at least worth considering.</p><div><hr></div><h3>Conclusion</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1WeK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1WeK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif 424w, https://substackcdn.com/image/fetch/$s_!1WeK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif 848w, https://substackcdn.com/image/fetch/$s_!1WeK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif 1272w, https://substackcdn.com/image/fetch/$s_!1WeK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1WeK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif" width="800" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:889635,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!1WeK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif 424w, https://substackcdn.com/image/fetch/$s_!1WeK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif 848w, https://substackcdn.com/image/fetch/$s_!1WeK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif 1272w, https://substackcdn.com/image/fetch/$s_!1WeK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87fa106d-99dd-4e96-97d6-3143dcdc613a_800x800.gif 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 role="img" 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><title></title><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>Selecting the appropriate foundation model is still a subjective process. It depends on factors such as cost, training data, privacy requirements, control, and most importantly, whether you&#8217;re satisfied with the responses for your use case.</p><p>I encourage everyone, especially application developers embedding AI features, to include a clear model-evaluation plan before committing to a foundation model. Being able to critically justify <em>why</em> you chose a particular model is now a best practice, not a nice-to-have.</p><p>Let me know in the comments what issues you&#8217;ve faced when using foundation models and whether switching models could have mitigated those problems.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/chatgpt-vs-claude-vs-gemini-who-really?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading AI with Fafa! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/chatgpt-vs-claude-vs-gemini-who-really?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://fafacodes.substack.com/p/chatgpt-vs-claude-vs-gemini-who-really?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[AI Can Write Code. That Doesn’t Mean It Can Build Software.]]></title><description><![CDATA[What I've learned about AI, trust, and the future of software engineering ... so far]]></description><link>https://fafacodes.substack.com/p/ai-can-write-code-that-doesnt-mean</link><guid isPermaLink="false">https://fafacodes.substack.com/p/ai-can-write-code-that-doesnt-mean</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Fri, 19 Dec 2025 13:31:49 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/4ffb8c9c-c816-495f-b7ec-6d9d86ab05c3.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#8220;AI is going to replace software engineers.&#8221;<br>&#8221;Software engineering as a career will soon be obsolete.&#8221;<br>&#8221;AI is going to replace junior developers.&#8221;<br><em>Yapper, yapper, yaaaapper.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Fepm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Fepm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif 424w, https://substackcdn.com/image/fetch/$s_!Fepm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif 848w, https://substackcdn.com/image/fetch/$s_!Fepm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif 1272w, https://substackcdn.com/image/fetch/$s_!Fepm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Fepm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif" width="500" height="359" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:359,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:469981,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!Fepm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif 424w, https://substackcdn.com/image/fetch/$s_!Fepm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif 848w, https://substackcdn.com/image/fetch/$s_!Fepm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif 1272w, https://substackcdn.com/image/fetch/$s_!Fepm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba012aaa-fcd1-4db5-9403-7aa4f7cf2f95_500x359.gif 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 role="img" 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><title></title><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 all statements we&#8217;ve heard repeatedly over the last two years, following the rapid innovations and developments in the AI sector. And to a large extent, I actually believed them.</p><p>I remember the first time I saw AI generate code. I thought, <em>&#8220;OMG, I&#8217;m screwed. AI is going to replace me.&#8221;</em></p><p>Anyway, fast forward to today. If you&#8217;ve been paying attention to the industry, you&#8217;ll realise that AI has not done such a good job of <em>&#8220;replacing&#8221;</em> software engineers across all levels.</p><p>Let&#8217;s take a quick look at a few shockers we&#8217;ve witnessed in recent years:</p><ul><li><p><strong>Replit&#8217;s AI coding assistant</strong> deleting an entire production database</p></li><li><p><strong>McDonald&#8217;s hiring chatbot</strong> exposing data of 64 million applicants (password: <em>123456</em>)</p></li><li><p><strong>A biased lending AI</strong> that cost a bank $2.5 million in fines</p></li><li><p><strong>The ChatGPT diet</strong> that landed a man in the hospital</p></li></ul><p>What these incidents reveal is that, although AI is disruptive, it may be <em>too</em> disruptive in its current state.</p><p>It&#8217;s not ready. At least not 100% yet.</p><p>There are still too many edge cases and scenarios that make deploying AI without multiple layers of human intervention extremely risky.</p><div><hr></div><h3>How does this relate to software engineering jobs?</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rOHp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rOHp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif 424w, https://substackcdn.com/image/fetch/$s_!rOHp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif 848w, https://substackcdn.com/image/fetch/$s_!rOHp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif 1272w, https://substackcdn.com/image/fetch/$s_!rOHp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rOHp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif" width="512" height="512" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:512,&quot;width&quot;:512,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1952440,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!rOHp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif 424w, https://substackcdn.com/image/fetch/$s_!rOHp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif 848w, https://substackcdn.com/image/fetch/$s_!rOHp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif 1272w, https://substackcdn.com/image/fetch/$s_!rOHp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8f489d-73f3-4871-b63b-c4c6835c813e_512x512.gif 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 role="img" 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><title></title><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>All of the incidents above demonstrate one thing:&nbsp;<strong>AI in 2025 could not be fully trusted.</strong></p><p>Humans (software engineers) are still critically needed to ensure AI systems don&#8217;t embarrass companies, violate regulations, or cause real-world harm. The cost of failure is simply too high, both for tech companies and for organisations outside the tech sector.</p><div><hr></div><h3>Can we really vibe-code a SaaS in 30 minutes?</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dvPu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dvPu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!dvPu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!dvPu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!dvPu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dvPu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:96672,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!dvPu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!dvPu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!dvPu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!dvPu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0624fe6f-b6db-4142-a429-34e82625196c_480x270.gif 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 role="img" 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><title></title><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>Another popular belief this year is <em>vibe coding</em>.</p><p>Don&#8217;t get me wrong, I&#8217;m not against vibe coding. But I do think the term, at face value, made non-technical folks believe they could build the next Facebook using only natural language.</p><p><em>Internal screaming.</em></p><p>I think this belief is what many people were referring to when they claimed AI would eliminate software engineering jobs.</p><p>So, can we vibe-code a SaaS in 30 minutes?</p><p>The honest answer is: <strong>it depends</strong>.</p><h4>1. The scale of the application</h4><p>The more complex the app (in terms of features, expected users, geographic distribution, and security requirements), the harder it becomes to vibe-code.</p><p>A simple one-page app? Absolutely doable.</p><p>The next Facebook in 30 minutes?<br>For lack of better words&#8230; <em>crazy</em>.</p><h4>2. The experience level of the developer</h4><p>This is the biggest factor.</p><p>I wouldn&#8217;t bet on someone who&#8217;s watched three Python videos on YouTube to vibe-code Facebook. But I <em>would</em> put money on a seasoned engineer/CTO/senior/founding engineer/PhD/MSc/BSc (I&#8217;ve run out of titles and qualifications, but you get the point).</p><p>Vibe coding works best when you already know <em>what</em> to do, but you&#8217;re just too lazy, too busy, or too time-constrained to do it manually.</p><p>AI-generated code still needs to be thoroughly inspected to ensure it&#8217;s correct, optimised, secure, and production-ready.</p><h4>3. The AI tools being used</h4><p>Some LLMs are better at generating code than others. Some integrate deeply with terminals, IDEs, and deployment pipelines, making semi-autonomous development possible.</p><p>Vibe coding requires knowing <strong>which tools to use, how to combine them, and where their limits are</strong>.</p><div><hr></div><h3>Why humans still matter</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MLhf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MLhf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!MLhf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!MLhf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!MLhf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MLhf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif" width="480" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4104731,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!MLhf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif 424w, https://substackcdn.com/image/fetch/$s_!MLhf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif 848w, https://substackcdn.com/image/fetch/$s_!MLhf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!MLhf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763b62b3-a2a0-4288-8e1c-9b6880a18480_480x480.gif 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 role="img" 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><title></title><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><em>Human-in-the-loop</em> is one of the most practical approaches to AI-assisted software engineering today.</p><p>It means using AI to build software while keeping critical decision-making in human hands.</p><p>Right now, a human developer should always be responsible for deciding:</p><ul><li><p>How the software actually solves user problems</p></li><li><p>What security risks exist, and how they&#8217;re mitigated</p></li><li><p>Which architectural decisions are appropriate</p></li><li><p>What criteria must be met before real users can access the system</p></li></ul><p>These are not decisions we should hand over entirely to AI.</p><div><hr></div><h3>What&#8217;s next for software developers?</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!M1nI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!M1nI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!M1nI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!M1nI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!M1nI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!M1nI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1235485,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!M1nI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!M1nI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!M1nI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!M1nI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23c8cf76-e144-432f-bd9b-6278f6e8abf2_480x270.gif 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 role="img" 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><title></title><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>AI is not going to replace software engineers, but it <em>will</em> change how we work.</p><p>It introduces a new set of skills developers must adopt to work effectively with AI agents.</p><h4>Prompt engineering</h4><p>At one point, people thought this would become a standalone career.</p><p>While that may not be the case, <strong>clear communication with AI is now a core skill</strong>:<br>writing structured prompts, using markdown, defining constraints, understanding context windows, and being explicit about what the AI should and should not do.</p><h4>System design</h4><p>If you&#8217;ve tried to vibe-code an app, you&#8217;ll quickly realise that dumping one massive prompt doesn&#8217;t work.</p><p>System design remains the developer&#8217;s responsibility. You must break complex problems into smaller, well-defined tasks for AI agents and sub-agents.</p><p>This is not something we can outsource to AI.</p><h4>Quality assurance</h4><p>From my perspective, QA is one of the safest roles in the AI era.</p><p>Do we really expect AI to reliably test AI?<br><em>More internal screaming.</em></p><p>Being able to validate, test, and reason about AI-generated code is now a critical skill for all developers.</p><h4>Integration</h4><p>Modern applications depend on multiple external services and APIs. These integrations must be designed carefully and not left open-ended for AI to guess.</p><div><hr></div><h3>Conclusion</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Rm8a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Rm8a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif 424w, https://substackcdn.com/image/fetch/$s_!Rm8a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif 848w, https://substackcdn.com/image/fetch/$s_!Rm8a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!Rm8a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Rm8a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif" width="326" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:326,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1050999,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&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="https://substackcdn.com/image/fetch/$s_!Rm8a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif 424w, https://substackcdn.com/image/fetch/$s_!Rm8a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif 848w, https://substackcdn.com/image/fetch/$s_!Rm8a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif 1272w, https://substackcdn.com/image/fetch/$s_!Rm8a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fd58e0a-e18f-460a-b306-9a110399605f_326x480.gif 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 role="img" 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><title></title><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>AI won&#8217;t replace software engineers, but engineers who refuse to adapt may struggle.</p><p>If you&#8217;re already a developer, learn how to use AI to <strong>increase your productivity</strong>, not replace your thinking.</p><p>If you&#8217;re just starting, focus on building strong foundations while recognising that the industry has shifted. Don&#8217;t get stuck learning things that AI can already do effortlessly. Instead, learn <em>why</em> things work, then apply AI to build faster and better.</p><p>Understand the shift.<br>Join the wave.</p><p>That&#8217;s all for now.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 AI with Fafa! 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><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/ai-can-write-code-that-doesnt-mean?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">This post is public, so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.substack.com/p/ai-can-write-code-that-doesnt-mean?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://fafacodes.substack.com/p/ai-can-write-code-that-doesnt-mean?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[2026 Free Resources for Learning AI Engineering]]></title><description><![CDATA[My recommendations for improving AI Engineering skills on a budget]]></description><link>https://fafacodes.substack.com/p/2026-free-resources-for-learning</link><guid isPermaLink="false">https://fafacodes.substack.com/p/2026-free-resources-for-learning</guid><dc:creator><![CDATA[Fafa]]></dc:creator><pubDate>Thu, 18 Dec 2025 05:51:40 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/41861372-159e-4b1f-ab60-042c4c322801_1920x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Your AI Engineering skills will definitely improve in 2026 if you check out these 3 free resources.</strong></p><p><strong>Number one</strong> is the Stanford Online YouTube channel. This contains extremely high-quality lectures on building LLMs, deep learning and agentic AI.</p><p><a href="https://www.youtube.com/@stanfordonline/videos">https://www.youtube.com/@stanfordonline/videos</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6q_g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6q_g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png 424w, https://substackcdn.com/image/fetch/$s_!6q_g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png 848w, https://substackcdn.com/image/fetch/$s_!6q_g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png 1272w, https://substackcdn.com/image/fetch/$s_!6q_g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6q_g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png" width="1456" height="978" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:978,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3145902,&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://fafacodes.substack.com/i/181958890?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6q_g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png 424w, https://substackcdn.com/image/fetch/$s_!6q_g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png 848w, https://substackcdn.com/image/fetch/$s_!6q_g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.png 1272w, https://substackcdn.com/image/fetch/$s_!6q_g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd92790a7-dcfd-4c73-8bde-6e84c8e35ea8_2660x1786.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 role="img" 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><title></title><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>For <strong>number two</strong>, we have the Learn AI Engineering repo on GitHub. This repo is a well-curated guide on a range of core AI topics, including math foundations for AI, ML frameworks, and  generative AI, and it is updated frequently.</p><p><a href="https://github.com/ashishps1/learn-ai-engineering">https://github.com/ashishps1/learn-ai-engineering</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!47Ji!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!47Ji!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png 424w, https://substackcdn.com/image/fetch/$s_!47Ji!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png 848w, https://substackcdn.com/image/fetch/$s_!47Ji!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png 1272w, https://substackcdn.com/image/fetch/$s_!47Ji!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!47Ji!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png" width="1456" height="978" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:978,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:566027,&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;:false,&quot;internalRedirect&quot;:&quot;https://fafacodes.substack.com/i/181958890?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!47Ji!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png 424w, https://substackcdn.com/image/fetch/$s_!47Ji!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png 848w, https://substackcdn.com/image/fetch/$s_!47Ji!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png 1272w, https://substackcdn.com/image/fetch/$s_!47Ji!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2149e22-83d5-444d-8055-45115b86b3a7_2660x1786.png 1456w" sizes="100vw"></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 role="img" 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><title></title><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>And finally, on <strong>number three</strong>, the Learn Machine Learning community on Reddit released a Google Drive with free ML, AI, and deep learning books, mostly from O&#8217;Reilly, that would typically cost an arm and a leg to purchase on Amazon.</p><p><a href="https://www.reddit.com/r/learnmachinelearning/comments/1i443cm/free_ml_ai_and_dl_books_google_drive_link/">https://www.reddit.com/r/learnmachinelearning/comments/1i443cm/free_ml_ai_and_dl_books_google_drive_link/</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XKDM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XKDM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!XKDM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!XKDM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!XKDM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XKDM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9b7e22f-3383-4c0a-b16f-755fca94cb42_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;:511647,&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://fafacodes.substack.com/i/181958890?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XKDM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!XKDM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!XKDM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!XKDM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9b7e22f-3383-4c0a-b16f-755fca94cb42_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 role="img" 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><title></title><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>That&#8217;s all.</p><p>Have fun. Cheers.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://fafacodes.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 Fafa's Substack! 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></channel></rss>