<?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[The Adaptive Engineer]]></title><description><![CDATA[Welcome to "The Adaptive Engineer," a weekly newsletter that provides insights, guidance, and resources for software engineers and architects who want to improve their design skills and create more effective, efficient, and scalable systems.
]]></description><link>https://newsletter.adaptiveengineer.com</link><image><url>https://substackcdn.com/image/fetch/$s_!c_sk!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa76522ad-7641-4568-90b0-a3ef4b06523f_250x250.png</url><title>The Adaptive Engineer</title><link>https://newsletter.adaptiveengineer.com</link></image><generator>Substack</generator><lastBuildDate>Sun, 12 Apr 2026 08:29:46 GMT</lastBuildDate><atom:link href="https://newsletter.adaptiveengineer.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Zahiruddin Tavargere]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[theadaptiveengineer@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[theadaptiveengineer@substack.com]]></itunes:email><itunes:name><![CDATA[Zahiruddin Tavargere]]></itunes:name></itunes:owner><itunes:author><![CDATA[Zahiruddin Tavargere]]></itunes:author><googleplay:owner><![CDATA[theadaptiveengineer@substack.com]]></googleplay:owner><googleplay:email><![CDATA[theadaptiveengineer@substack.com]]></googleplay:email><googleplay:author><![CDATA[Zahiruddin Tavargere]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[How to Monitor Your Brand on ChatGPT & Perplexity — Full Tutorial]]></title><description><![CDATA[Why Your Brand Needs to Show Up on Answer Engines (and How to Monitor It)]]></description><link>https://newsletter.adaptiveengineer.com/p/how-to-monitor-your-brand-on-chatgpt</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/how-to-monitor-your-brand-on-chatgpt</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Sat, 29 Nov 2025 15:33:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!RPg2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RPg2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RPg2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png 424w, https://substackcdn.com/image/fetch/$s_!RPg2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png 848w, https://substackcdn.com/image/fetch/$s_!RPg2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png 1272w, https://substackcdn.com/image/fetch/$s_!RPg2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RPg2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png" width="1456" height="791" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:791,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:306456,&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://newsletter.adaptiveengineer.com/i/180233159?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.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_!RPg2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png 424w, https://substackcdn.com/image/fetch/$s_!RPg2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png 848w, https://substackcdn.com/image/fetch/$s_!RPg2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.png 1272w, https://substackcdn.com/image/fetch/$s_!RPg2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3ae5362-3961-42ba-98f0-4ee8c11a7ee9_2755x1497.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></p><h2><strong>Why Your Brand Needs to Show Up on Answer Engines (and How to Monitor It)</strong></h2><p>Over the past twenty years, we&#8217;ve all been conditioned to think in <strong>search-first workflows</strong>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>You type a query into Google, skim ten blue links, and decide whom to trust.</p><p>That mental model is disappearing&#8212;quietly, but fast.</p><p>Today, more users are skipping the &#8220;search &#8594; compare &#8594; decide&#8221; loop entirely and going straight to <strong>answer engines</strong> like ChatGPT, Perplexity, and Claude. These systems don&#8217;t present links; they present conclusions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://www.mckinsey.com/capabilities/growth-marketing-and-sales/our-insights/new-front-door-to-the-internet-winning-in-the-age-of-ai-search" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rMrJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png 424w, https://substackcdn.com/image/fetch/$s_!rMrJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png 848w, https://substackcdn.com/image/fetch/$s_!rMrJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png 1272w, https://substackcdn.com/image/fetch/$s_!rMrJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rMrJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png" width="1280" height="1210" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1210,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:281258,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://www.mckinsey.com/capabilities/growth-marketing-and-sales/our-insights/new-front-door-to-the-internet-winning-in-the-age-of-ai-search&quot;,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.adaptiveengineer.com/i/180233159?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!rMrJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png 424w, https://substackcdn.com/image/fetch/$s_!rMrJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png 848w, https://substackcdn.com/image/fetch/$s_!rMrJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.png 1272w, https://substackcdn.com/image/fetch/$s_!rMrJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf25e9ee-d8b0-4125-9b7b-4e71ce85ae4b_1280x1210.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 that shift has enormous implications for brands.</p><h3><strong>The Rise of Answer-Led Discovery</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mIm9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mIm9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png 424w, https://substackcdn.com/image/fetch/$s_!mIm9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png 848w, https://substackcdn.com/image/fetch/$s_!mIm9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png 1272w, https://substackcdn.com/image/fetch/$s_!mIm9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mIm9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png" width="1265" height="1395" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1395,&quot;width&quot;:1265,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:218361,&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://newsletter.adaptiveengineer.com/i/180233159?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.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_!mIm9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png 424w, https://substackcdn.com/image/fetch/$s_!mIm9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png 848w, https://substackcdn.com/image/fetch/$s_!mIm9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.png 1272w, https://substackcdn.com/image/fetch/$s_!mIm9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833c0dec-b1b5-4fcf-8cb1-9f93aa9df285_1265x1395.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></p><p>According to data from multiple generative-AI usage studies, nearly <strong>45&#8211;60% of new users now start with an AI assistant</strong> when exploring a product or service category for the first time. In fact, Perplexity itself claims a <strong>20&#8211;30% month-over-month rise</strong> in &#8220;shopping and services queries.&#8221;</p><p>That means the customer&#8217;s first impression is no longer shaped by your homepage or your Google ranking. It&#8217;s shaped by whatever an LLM decides to say about you.</p><p>If your brand shows up in that answer, fantastic&#8212;you&#8217;ve just inherited <em>pre-trained trust</em>.<br>If it doesn&#8217;t, you&#8217;ve silently lost a high-intent customer without ever knowing they existed.</p><h3><strong>A Simple Visual Thought Experiment</strong></h3><p>Imagine this scenario:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IDt7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IDt7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!IDt7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!IDt7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!IDt7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IDt7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;https://www.rivalsee.com/images/blog/local-business-ai-seo-strategy.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="https://www.rivalsee.com/images/blog/local-business-ai-seo-strategy.png" title="https://www.rivalsee.com/images/blog/local-business-ai-seo-strategy.png" srcset="https://substackcdn.com/image/fetch/$s_!IDt7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!IDt7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!IDt7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!IDt7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0844fccf-6f94-4792-b0e3-de545a95b9de_1536x1024.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>A user asks:</p><blockquote><p><em>&#8220;Who are the top curtain repair services near me?&#8221;</em></p></blockquote><p>The LLM responds confidently, naming three providers.<br>Your brand is either:</p><ul><li><p><strong>In the answer &#8594;</strong> instant credibility</p></li><li><p><strong>Not mentioned &#8594;</strong> invisible</p></li><li><p><strong>Misrepresented &#8594;</strong> losing trust without knowing why</p></li></ul><p>This is the new discovery funnel.<br>And right now, most brands aren&#8217;t even aware it exists.</p><h3><strong>Why Monitoring Your Brand on ChatGPT &amp; Perplexity Is No Longer Optional</strong></h3><p>Here&#8217;s the uncomfortable truth:<br>LLMs don&#8217;t pull answers from a single database&#8212;they synthesize information from various sources: review sites, listicles, Reddit threads, local directories, news mentions, and your own content (if it exists and is structured well enough to be recognized).</p><p>If they aren&#8217;t citing you, it&#8217;s usually because:</p><ul><li><p>Your content isn&#8217;t tuned for answer-engine style queries</p></li><li><p>Your competitors have better-structured or more recent content</p></li><li><p>Third-party sites describe your category better than you do</p></li><li><p>Your brand simply isn&#8217;t &#8220;on the radar&#8221; of the model yet</p></li></ul><p>In every case, the fix starts with <strong>monitoring</strong>.</p><h3><strong>What Monitoring Actually Gives You</strong></h3><p>By actively tracking your brand visibility across multiple queries, you begin to see:</p><ul><li><p><strong>How often ChatGPT or Perplexity cite you</strong></p></li><li><p><strong>Which sources they rely on</strong></p></li><li><p><strong>Which competitors consistently show up</strong></p></li><li><p><strong>What real customer queries in your category look like</strong></p></li><li><p><strong>Which themes or topics you&#8217;re missing in your content</strong></p></li></ul><h3><strong>In Today&#8217;s Episode</strong></h3><p>In the video, I&#8217;ll walk you through a <strong>LangGraph agent</strong> that:</p><ul><li><p>Scrapes your website</p></li><li><p>Identifies your domain, location, and service themes</p></li><li><p>Generates likely customer queries</p></li><li><p>Tests those queries against answer engines</p></li><li><p>Monitors citations, competitor presence, and content gaps</p></li></ul><p>So instead of guessing how answer engines perceive your brand, you&#8217;ll have a real-time dashboard telling you <strong>where you stand and how to improve</strong>.</p><div id="youtube2-5JMrLX9gFaI" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;5JMrLX9gFaI&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/5JMrLX9gFaI?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h3>Code</h3><p><a href="https://github.com/zahere-dev/agentexpert-labs/tree/main/business_use_cases/brand_monitoring">https://github.com/zahere-dev/agentexpert-labs/tree/main/business_use_cases/brand_monitoring</a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[This is The Powerful Pattern Behind Top AI Agents]]></title><description><![CDATA[Hey everyone!]]></description><link>https://newsletter.adaptiveengineer.com/p/this-is-the-powerful-pattern-behind</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/this-is-the-powerful-pattern-behind</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Tue, 11 Nov 2025 11:13:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!E5Ww!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E5Ww!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E5Ww!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png 424w, https://substackcdn.com/image/fetch/$s_!E5Ww!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png 848w, https://substackcdn.com/image/fetch/$s_!E5Ww!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png 1272w, https://substackcdn.com/image/fetch/$s_!E5Ww!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E5Ww!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png" width="1456" height="846" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:846,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!E5Ww!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png 424w, https://substackcdn.com/image/fetch/$s_!E5Ww!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png 848w, https://substackcdn.com/image/fetch/$s_!E5Ww!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.png 1272w, https://substackcdn.com/image/fetch/$s_!E5Ww!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39c8aad1-c4e8-4b85-bcec-890b11df6ff1_1488x865.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>Hey everyone!</p><p>Have you ever wondered how AI agents like Claude, Anthropic&#8217;s Computer Use agent, Gemini&#8217;s CLI tools, or LangChain agents handle complex tasks so effectively?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>There&#8217;s a powerful design pattern that all these top agents share - and today, I&#8217;m going to break it down for you.</p><p>It&#8217;s called <strong>write_todos</strong> or Todo Tool, and once you understand it, you&#8217;ll never build AI agents the same way again.</p><div><hr></div><p>Full walkthrough of the custom write_todo implementation in Customer Service Agent.</p><div id="youtube2-hlwxIIXZEbI" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;hlwxIIXZEbI&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/hlwxIIXZEbI?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xUz-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xUz-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png 424w, https://substackcdn.com/image/fetch/$s_!xUz-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png 848w, https://substackcdn.com/image/fetch/$s_!xUz-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png 1272w, https://substackcdn.com/image/fetch/$s_!xUz-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xUz-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png" width="1456" height="814" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:814,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:275467,&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://newsletter.adaptiveengineer.com/i/178582417?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.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_!xUz-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png 424w, https://substackcdn.com/image/fetch/$s_!xUz-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png 848w, https://substackcdn.com/image/fetch/$s_!xUz-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.png 1272w, https://substackcdn.com/image/fetch/$s_!xUz-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f9654f-e6c4-427c-aa56-8081d642de99_2400x1342.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>In many AI agents, write_todos is used to create and manage <strong>TODO lists</strong> that help the agent stay organized and focused during long or complex tasks.</p><p>For example, Claude Code uses a feature called <strong>plan mode</strong> to generate a structured list of steps before starting any work. This is done using a tool called <strong>TodoWrite</strong>, which is based on a special prompt.</p><p>Each TODO item includes:</p><ul><li><p>A short, clear description of the task</p></li><li><p>A status: <strong>pending</strong>, <strong>in progress</strong>, or <strong>completed</strong></p></li></ul><p>As tasks grow in size&#8212;sometimes involving 50 or more tool calls&#8212;it becomes harder for the agent to remember everything. This can lead to <strong>context rot</strong>, where the agent forgets earlier goals or drifts off-topic.</p><p>To prevent this, agents like <strong>Manus</strong> regularly rewrite and update their TODO lists. This helps them stay on track by constantly reminding themselves of their goals, reducing the risk of losing focus or deviating from the task.</p><p>There are 2 parts</p><p><strong>Phase 1: Planning</strong> The agent receives a complex task and uses an LLM to decompose it into smaller, actionable subtasks. Think of it like a project manager breaking down a big project.</p><p><strong>[Show example: &#8220;Handle customer complaint about delayed order&#8221;]</strong> The agent might plan:</p><ul><li><p>Todo 1: Search knowledge base for refund policy</p></li><li><p>Todo 2: Look up similar past tickets</p></li><li><p>Todo 3: Check shipping status</p></li><li><p>Todo 4: Draft response with options</p></li></ul><p><strong>Phase 2: Writing (The Critical Part)</strong> <strong>[Highlight this]</strong></p><p>Here&#8217;s the key difference: <strong>The agent writes these todos down</strong> - typically to a file, database, or persistent storage.</p><h2>Why use &#8216;write_todos&#8217;?</h2><h3>Reason #1: Transparency and Debuggability</h3><p>When your agent writes its plan to a file, you as a developer - or even the user - can see exactly what it&#8217;s planning to do BEFORE it does it.</p><h3>Reason #2: Fault Tolerance and Recovery</h3><p>Here&#8217;s where it gets really powerful. If your agent crashes halfway through a task, what happens?</p><p>Without write-todos: Everything is lost. Start over. With write-todos: Read the file, see what&#8217;s completed, continue where you left off.</p><h3>Reason #3: Human-in-the-Loop Workflows</h3><p>Sometimes you want human approval before execution. With write-todos:</p><ol><li><p>Agent creates plan and writes it</p></li><li><p>Human reviews and approves (or modifies)</p></li><li><p>Agent reads the (potentially modified) plan and executes</p></li></ol><h2>When to use &#8216;write_todos&#8217;?</h2><h3>Multi-step tasks (3+ steps) </h3><p>If your task naturally breaks down into multiple sequential or parallel steps, write-todos will help.</p><ul><li><p>Research and analysis</p></li><li><p>Customer support workflows</p></li><li><p>Data processing pipelines</p></li><li><p>Code generation and deployment</p></li><li><p>Content creation workflows</p></li></ul><h3><strong>Long-running operations (minutes to hours)</strong></h3><p>Anything that takes significant time benefits from fault tolerance and observability.</p><h3>High-stakes operations</h3><p>Financial transactions, data deletion, production deployments - anything where you want a review before action.</p><h3>Collaborative agent-human workflows</h3><p>When humans need to be in the loop at any</p><h2><strong>&#10060; Don&#8217;t use write-todos when:</strong></h2><p><strong>1. Simple, single-step tasks</strong> &#8220;What&#8217;s the weather?&#8221; - No need for todos.</p><p><strong>2. Real-time, low-latency requirements</strong> File I/O adds overhead. If you need sub-second responses, keep it in memory.</p><p><strong>3. Stateless, idempotent operations</strong> If the operation can be safely retried from scratch, the crash recovery benefit is less valuable.</p><h2>The ToDo Methods in our Agent</h2><p>Below is a simple implementation of the Todo tools for our Customer Service Agent.</p><p><a href="https://github.com/zahere-dev/agentexpert-labs/tree/main/core_concepts/todos">Full source code here.</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_!j4r1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j4r1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png 424w, https://substackcdn.com/image/fetch/$s_!j4r1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png 848w, https://substackcdn.com/image/fetch/$s_!j4r1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png 1272w, https://substackcdn.com/image/fetch/$s_!j4r1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j4r1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png" width="1327" height="1500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1500,&quot;width&quot;:1327,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:221639,&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://newsletter.adaptiveengineer.com/i/178582417?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.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_!j4r1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png 424w, https://substackcdn.com/image/fetch/$s_!j4r1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png 848w, https://substackcdn.com/image/fetch/$s_!j4r1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.png 1272w, https://substackcdn.com/image/fetch/$s_!j4r1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c62d287-466b-4d78-89f8-371cc52b89a3_1327x1500.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>The generated Todo file</p><p><code>{</code></p><p><code>  &#8220;created_at&#8221;: &#8220;2025-11-11T01:26:18.171559&#8221;,</code></p><p><code>&#8220;todos&#8221;: [</code></p><p><code>    {</code></p><p><code>&#8220;id&#8221;: 1,</code></p><p><code>&#8220;task&#8221;: &#8220;Search knowledge base for \&#8221;refund policy\&#8221; to understand the guidelines for processing refunds.&#8221;,</code></p><p><code>&#8220;status&#8221;: &#8220;completed&#8221;,</code></p><p><code>&#8220;result&#8221;: &#8220;No relevant article found in knowledge base.&#8221;</code></p><p><code>    },</code></p><p><code>    {</code></p><p><code>&#8220;id&#8221;: 2,</code></p><p><code>&#8220;task&#8221;: &#8220;Look up the customer&#8217;s order status in the system to determine if the product has shipped or if there are any delays.&#8221;,</code></p><p><code>&#8220;status&#8221;: &#8220;completed&#8221;,</code></p><p><code>&#8220;result&#8221;: &#8220;Found 2 similar past tickets:\n- Ticket TICKET-2024-089: Order delayed - carrier issue\n  Customer reported order stuck in transit for 8 days. Root cause: Holiday shipping backlog. Resolution: Expedited replacement sent, original order refu...\n  Resolved in: 2 days\n- Ticket TICKET-2024-112: Package not delivered after 10 days\n  Order placed 10 days ago, tracking shows &#8216;in transit&#8217; with no updates. Customer requested refund. Resolution: Refund processed, new order sent with ex...\n  Resolved in: 1 day\n&#8221;</code></p><p><code>    },</code></p><p><code>    {</code></p><p><code>&#8220;id&#8221;: 3,</code></p><p><code>&#8220;task&#8221;: &#8220;Check recent similar tickets or issues to see if other customers are experiencing similar delays with the same product.&#8221;,</code></p><p><code>&#8220;status&#8221;: &#8220;completed&#8221;,</code></p><p><code>&#8220;result&#8221;: &#8220;Found 2 similar past tickets:\n- Ticket TICKET-2024-089: Order delayed - carrier issue\n  Customer reported order stuck in transit for 8 days. Root cause: Holiday shipping backlog. Resolution: Expedited replacement sent, original order refu...\n  Resolved in: 2 days\n- Ticket TICKET-2024-112: Package not delivered after 10 days\n  Order placed 10 days ago, tracking shows &#8216;in transit&#8217; with no updates. Customer requested refund. Resolution: Refund processed, new order sent with ex...\n  Resolved in: 1 day\n&#8221;</code></p><p><code>    },</code></p><p><code>    {</code></p><p><code>&#8220;id&#8221;: 4,</code></p><p><code>&#8220;task&#8221;: &#8220;Review current refund processing times to inform the customer about how long it may take to receive their refund if approved.&#8221;,</code></p><p><code>&#8220;status&#8221;: &#8220;completed&#8221;,</code></p><p><code>&#8220;result&#8221;: &#8220;Completed: Review current refund processing times to inform the customer about how long it may take to receive their refund if approved.&#8221;</code></p><p><code>    }</code></p><p><code>  ]</code></p><p><code>}</code></p><p>I strongly recommend you go through the video or the code to full understand this pattern.</p><p>So there you have it - the write-todos pattern that powers some of the most sophisticated AI agents in production today.</p><p>To recap:</p><ul><li><p><strong>What it is:</strong> Externalize the agent&#8217;s plan by writing it to persistent storage</p></li><li><p><strong>Why use it:</strong> Transparency, fault tolerance, human-in-the-loop, better planning, and testability</p></li><li><p><strong>When to use it:</strong> Multi-step tasks, long-running operations, high-stakes work, collaborative workflows</p><p></p></li></ul><p>The complete code for this example is in the description below. I encourage you to:</p><ol><li><p>Clone it and run it yourself</p></li><li><p>Modify it to handle different support scenarios</p></li><li><p>Try adding a &#8220;human approval&#8221; step before execution</p></li><li><p>Build your own agent using this pattern</p></li></ol><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[I've Been Teaching MCP Wrong for 6 Months!]]></title><description><![CDATA[The Wake-Up Call]]></description><link>https://newsletter.adaptiveengineer.com/p/ive-been-teaching-mcp-wrong-for-6</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/ive-been-teaching-mcp-wrong-for-6</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Mon, 20 Oct 2025 15:35:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/19rH1GiJxUU" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>The Wake-Up Call</h2><p>Alright. So at work, I&#8217;ve been consulting a few teams to design MCP servers.</p><p>I have a solution in prod and some teams were interested to learn from my experience. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>All my experiments on my blog, YouTube channel, and the solution at work were based on SSE&#8212;meaning the transport layer of my MCP servers was Server-Sent Events.</p><p>However, recently when one of the devs I was consulting told me that they read SSE transport was deprecated and only STDIO and Streamable HTTP were the only choices, I strongly denied such updates and told them there&#8217;s no way I would miss such an update.</p><p>They shared the link with me and I just couldn&#8217;t believe I had missed that update. An update that had come in late March 2025.</p><p>I felt embarrassed as I was recommending SSE transport for all our projects.</p><p>Luckily, the change to streamable_http wasn&#8217;t big and we could easily get on with the changes.</p><p>But I realized <strong>staying current with rapidly evolving AI protocols isn&#8217;t optional&#8212;it&#8217;s critical</strong>.</p><p>Missing a single protocol update can mean building on deprecated foundations, giving outdated advice, and potentially creating scalability issues that won&#8217;t surface until production load hits.</p><p>I know I&#8217;m a bit late here&#8212;but let&#8217;s understand why SSE was deprecated and learn how to build MCP servers with Streamable HTTP transport.</p><div><hr></div><h2>Why SSE Was Deprecated</h2><p>The SSE (Server-Sent Events) transport was part of the original MCP specification, but it had fundamental architectural problems that became apparent at scale:</p><h3>1. <strong>Two-Endpoint Architecture</strong></h3><p>SSE required maintaining <strong>two separate endpoints</strong>:</p><ul><li><p>GET <code>/sse</code> for server-to-client streaming</p></li><li><p>POST <code>/messages</code> for client-to-server requests</p></li></ul><p>This split architecture created complexity in connection management and made deployment harder.</p><h3>2. <strong>Connection Limit Hell</strong></h3><p>SSE connections are <strong>long-lived HTTP connections</strong>. Under load, servers quickly hit OS-level file descriptor limits (~1024 on most systems). Performance testing showed:</p><ul><li><p>1000+ concurrent TCP connections with SSE</p></li><li><p>Execution times 4x slower than Streamable HTTP</p></li><li><p>Success rates dropping sharply after ~1024 concurrent users</p></li></ul><h3>3. <strong>No Resumability</strong></h3><p>If an SSE connection dropped, there was no way to resume from where you left off. The entire operation had to restart.</p><h3>4. <strong>One-Way Communication</strong></h3><p>SSE only supports server-to-client streaming. Client-to-server communication required separate HTTP POST requests, creating an asymmetric architecture.</p><h3>5. <strong>Cloud Deployment Nightmare</strong></h3><p>Long-lived connections don&#8217;t play well with:</p><ul><li><p>Serverless functions (AWS Lambda, Cloud Run)</p></li><li><p>Load balancers with connection timeouts</p></li><li><p>Auto-scaling infrastructure</p></li><li><p>Container orchestration platforms</p></li></ul><div><hr></div><h2>Enter Streamable HTTP</h2><p><strong>Streamable HTTP</strong> was introduced in protocol version 2025-03-26 and addresses all of SSE&#8217;s limitations. Here&#8217;s what makes it better:</p><h3>Single Endpoint Architecture</h3><p>Everything goes through <strong>one endpoint</strong>: <code>/mcp</code></p><h3>Connection Reuse</h3><p>Instead of 1000 concurrent SSE connections, Streamable HTTP reuses TCP connections, keeping the count to just ~50 even under high load.</p><h3>Flexible Response Format</h3><p>The server chooses the response type based on the operation:</p><ul><li><p><strong>Quick operations</strong> &#8594; Instant JSON response</p></li><li><p><strong>Long operations</strong> &#8594; SSE stream with progress updates</p></li></ul><h3>Stateless Mode</h3><p>Perfect for cloud deployments&#8212;no session state to maintain, works beautifully with serverless and auto-scaling.</p><div><hr></div><h2>Migration from SSE to Streamable HTTP</h2><p>The migration is surprisingly simple:</p><h3>Python</h3><pre><code><code># Old (SSE)
mcp.run(transport=&#8221;sse&#8221;)

# New (Streamable HTTP)
mcp.run(transport=&#8221;streamable-http&#8221;)
</code></code></pre><h3>Client Code</h3><pre><code><code># Old
from mcp.client.sse import sse_client
async with sse_client(url) as (read, write):
    # ...

# New
from mcp.client.streamable_http import streamablehttp_client
async with streamablehttp_client(url) as (read, write, _):
    # ...
</code></code></pre><p>That&#8217;s it. The tool definitions, resources, and prompts remain unchanged.</p><div><hr></div><h2>Key Takeaways</h2><ol><li><p><strong>SSE is deprecated</strong> since protocol 2025-03-26 (March 26, 2025)</p></li><li><p><strong>Streamable HTTP is the standard</strong> for production deployments</p></li><li><p><strong>Migration is straightforward</strong> - mostly just changing transport configuration</p></li><li><p><strong>Performance is significantly better</strong> - 4x faster with better scalability</p></li><li><p><strong>Cloud-friendly</strong> - Works seamlessly with serverless and auto-scaling</p></li></ol><div><hr></div><h2>Here&#8217;s the video of the week</h2><div id="youtube2-19rH1GiJxUU" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;19rH1GiJxUU&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/19rH1GiJxUU?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Stop Writing Alt Tags Manually: I Built an AI Solution That Does It in Minutes]]></title><description><![CDATA[Hey everyone,]]></description><link>https://newsletter.adaptiveengineer.com/p/stop-writing-alt-tags-manually-i</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/stop-writing-alt-tags-manually-i</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Sun, 12 Oct 2025 20:11:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/VXhh2FdIsdE" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey everyone,</p><p>If you manage a website (or several), you know the pain of alt tags.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>They&#8217;re essential for accessibility and SEO, but writing hundreds of them manually? </p><p>Soul-crushing work.</p><p>And let&#8217;s be honest: when we DO write them, half the time they end up as generic descriptions like &#8220;image-123.jpg&#8221; that help exactly no one.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QwIG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QwIG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png 424w, https://substackcdn.com/image/fetch/$s_!QwIG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png 848w, https://substackcdn.com/image/fetch/$s_!QwIG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png 1272w, https://substackcdn.com/image/fetch/$s_!QwIG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QwIG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png" width="1456" height="244" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:244,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:107350,&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://newsletter.adaptiveengineer.com/i/175980221?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.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_!QwIG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png 424w, https://substackcdn.com/image/fetch/$s_!QwIG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png 848w, https://substackcdn.com/image/fetch/$s_!QwIG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png 1272w, https://substackcdn.com/image/fetch/$s_!QwIG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f1c8661-c403-4686-98be-0181ec2191f5_1739x291.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><h2>How It Actually Works</h2><p>The workflow is surprisingly elegant. You feed it any URL, and it:</p><ol><li><p><strong>Scrapes the page</strong> and finds every image missing an alt tag</p></li><li><p><strong>Extracts rich context</strong> &#8211; page titles, nearby text, headings, captions, everything around that image</p></li><li><p><strong>Sends both the image URL and context to GPT-4o-mini</strong> &#8211; this is key: the AI actually LOOKS at the image while understanding where it appears on the page</p></li><li><p><strong>Generates perfect alt tags</strong> following Google&#8217;s accessibility guidelines</p></li><li><p><strong>Stores everything in a database</strong> ready for your CMS</p></li></ol><p>The magic is in the context. Most alt tag generators just describe what they see. This workflow understands PURPOSE. A photo of a laptop gets described differently on a tech news site versus an e-commerce product page versus a workspace inspiration blog.</p><h2>Who This Is For</h2><p>This is perfect if you&#8217;re:</p><ul><li><p>A developer managing multiple client sites</p></li><li><p>An SEO specialist optimizing for image search</p></li><li><p>A content manager drowning in accessibility backlog</p></li><li><p>An agency that needs to scale accessibility services</p></li><li><p>Anyone who cares about making the web more accessible</p></li></ul><h2>The Technical Bits</h2><p>Don&#8217;t worry if you&#8217;re not an n8n expert &#8211; I walk through every single node in detail. You&#8217;ll learn:</p><ul><li><p>How to scrape websites properly</p></li><li><p>JavaScript for HTML parsing (regex-based, no external libraries)</p></li><li><p>How to structure prompts for vision AI</p></li><li><p>Loop automation techniques</p></li><li><p>Database integration basics</p></li></ul><p>Even if you&#8217;ve never used n8n before, you&#8217;ll have a working automation by the end.</p><h2>Watch It Here</h2><div id="youtube2-VXhh2FdIsdE" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;VXhh2FdIsdE&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/VXhh2FdIsdE?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[My Journey with n8n: Why This No-Code Automation Tool Blew Me Away]]></title><description><![CDATA[For the past few months, I&#8217;ve been watching a lot of YouTube videos about how n8n is one of the hottest no-code agentic solutions.]]></description><link>https://newsletter.adaptiveengineer.com/p/my-journey-with-n8n-why-this-no-code</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/my-journey-with-n8n-why-this-no-code</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Mon, 29 Sep 2025 00:36:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/skV5MLs1j7w" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For the past few months, I&#8217;ve been watching a lot of YouTube videos about how n8n is one of the hottest no-code agentic solutions.</p><p>Today, I decided to take it for a spin.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>Here&#8217;s my experience.</p><p>n8n is everything the &#8220;influencers&#8221; claim it to be.</p><p>It&#8217;s intuitive, powerful, and packed with over 400 integrations, a drag-and-drop interface, and custom code options that make complex automations feel effortless.</p><p>From the ease of setting it up on my 12-year-old Mac Mini to developing a solution in just 30 minutes (thanks to its impressive documentation), I must say, I&#8217;m a fan</p><p>As someone who spent a decade building enterprise automation, I can see how n8n solves so many process-related challenges, like streamlining data flows and reducing manual errors.</p><h2>Is it RPA?</h2><p>Tools like Power Automate, Automation Anywhere, UiPath, and others do similar things&#8212;but deploying and scaling them at an enterprise level requires dedicated teams, hefty infrastructure, and ongoing vendor support.</p><p>In contrast, n8n stands out as open-source and self-hostable, with no vendor lock-in or per-bot licensing fees.</p><p>It&#8217;s API-focused for seamless app integrations rather than UI-based bot mimicry, making it lighter, more flexible, and cost-effective for modern workflows without sacrificing power.</p><h2>So what did I build with this?</h2><div id="youtube2-skV5MLs1j7w" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;skV5MLs1j7w&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/skV5MLs1j7w?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>A production-ready n8n workflow that automatically analyzes thousands of customer reviews using AI and generates actionable business insights, such as sentiment trends, key pain points, and improvement recommendations.</p><h2>My verdict</h2><p>n8n is a game-changer for efficient, scalable automation. It&#8217;s developer-friendly yet accessible to non-coders, and its community-driven updates keep it evolving. If you&#8217;re tired of bloated tools, give n8n a try&#8212;you won&#8217;t regret it.</p><h2>Why should you learn it?</h2><p>In today&#8217;s fast-paced digital world, automation skills are essential for boosting productivity and staying competitive.</p><p>n8n empowers you to connect disparate tools&#8212;like APIs, databases, and AI services&#8212;without deep coding expertise, saving hours on repetitive tasks.</p><p>It&#8217;s future-proof: as no-code/low-code platforms rise, mastering n8n opens doors to freelance gigs, startup roles, or internal efficiencies at big companies.</p><p>Plus, its active open-source community means constant improvements, free resources, and real-world applications in marketing, data analysis, e-commerce, and more. </p><p>Whether you&#8217;re a solo entrepreneur automating lead gen or a team lead optimizing operations, learning n8n builds versatile problem-solving skills that pay off immediately and scale with your career.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[How to Build an Agent Driven Content Audit System with LangGraph]]></title><description><![CDATA[How to Build an Agent-Driven Content Audit System with LangGraph]]></description><link>https://newsletter.adaptiveengineer.com/p/how-to-build-an-agent-driven-content</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/how-to-build-an-agent-driven-content</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Mon, 22 Sep 2025 18:47:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ij_C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are unnoticed flaws in your digital assets silently eroding your B2B revenue?</p><p>Your websites, landing pages, and digital content are critical revenue drivers.</p><p>But when mismanaged, they leak profits.</p><p>As content scales, manual audits fall short, inviting brand inconsistency and compliance risks.</p><p>Discover how AI Agents can streamline content audits across thousands of pages.</p><h2>The Agent-Driven Content Audit System</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ij_C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ij_C!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png 424w, https://substackcdn.com/image/fetch/$s_!ij_C!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png 848w, https://substackcdn.com/image/fetch/$s_!ij_C!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png 1272w, https://substackcdn.com/image/fetch/$s_!ij_C!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ij_C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png" width="1456" height="925" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.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;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ij_C!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png 424w, https://substackcdn.com/image/fetch/$s_!ij_C!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png 848w, https://substackcdn.com/image/fetch/$s_!ij_C!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.png 1272w, https://substackcdn.com/image/fetch/$s_!ij_C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6ad1c5b-8892-4011-b361-ad7844836781_1600x1016.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>Let me walk you through the high-level design.</p><p>The first step is content ingestion&#8212;gathering all URLs and asset metadata from various sources like crawler lists, CSVs, or CMS integrations. This ensures complete, real-time coverage across your content footprint.</p><p>Next, the orchestrator prioritizes assets using AI and historical data, focusing audits on high-impact pages first. This guarantees critical content gets the right attention every time.</p><p>Multiple audit engines then run in parallel: checking readability, SEO, accessibility, compliance, and post-launch monitoring. They use both third-party tools and custom code for thorough reviews.</p><p>All results feed into secure databases that connect content to revenue and risk metrics. Finally, the prioritization engine turns data into business impact scores, triggering automated tickets and alerts so stakeholders can make fast, informed decisions.</p><p>I&#8217;ve done full walk-through of the code in this video.</p><div id="youtube2-0pt4fNAVWnM" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;0pt4fNAVWnM&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/0pt4fNAVWnM?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Mastering the Routing Pattern: 4 Essential Techniques for Building Intelligent AI Agents]]></title><description><![CDATA[The Four Pillars of Intelligent Routing]]></description><link>https://newsletter.adaptiveengineer.com/p/mastering-the-routing-pattern-4-essential</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/mastering-the-routing-pattern-4-essential</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Sun, 07 Sep 2025 18:29:18 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/2Gz0T6JS4B8" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div id="youtube2-2Gz0T6JS4B8" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;2Gz0T6JS4B8&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/2Gz0T6JS4B8?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h2></h2><h2>The Four Pillars of Intelligent Routing</h2><p>After analyzing hundreds of production agent systems, four distinct routing approaches have emerged as the foundation of modern agentic architectures. Each represents a different trade-off between accuracy, speed, cost, and implementation 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_!LoCE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LoCE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png 424w, https://substackcdn.com/image/fetch/$s_!LoCE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png 848w, https://substackcdn.com/image/fetch/$s_!LoCE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png 1272w, https://substackcdn.com/image/fetch/$s_!LoCE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LoCE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png" width="1456" height="1397" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1397,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:796229,&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://newsletter.adaptiveengineer.com/i/173019923?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.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_!LoCE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png 424w, https://substackcdn.com/image/fetch/$s_!LoCE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png 848w, https://substackcdn.com/image/fetch/$s_!LoCE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.png 1272w, https://substackcdn.com/image/fetch/$s_!LoCE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfe6a6b6-af44-4337-b3b4-ab7f7d8c8e5c_1828x1754.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><h3>1. LLM-Based Routing: The Universal Translator</h3><p>LLM-based routing leverages the same language understanding capabilities that make modern AI so impressive. Instead of trying to predict every possible user intent, you simply ask the language model to analyze the input and make the routing decision.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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><strong>The core mechanism</strong> is elegantly simple: present the LLM with the user's input and a carefully crafted prompt that defines your routing categories. The LLM analyzes the semantic meaning, context, and intent, then outputs a structured decision about where to route the request.</p><p><strong>Where it shines:</strong></p><ul><li><p><strong>Handling ambiguous inputs</strong> that don't fit neat patterns</p></li><li><p><strong>Understanding complex, multi-part requests</strong> that span multiple categories</p></li><li><p><strong>Adapting to new types of queries</strong> without retraining or rule updates</p></li><li><p><strong>Processing context-dependent routing</strong> that considers conversation history</p></li></ul><p><strong>The architectural trade-off:</strong> Maximum flexibility comes at the cost of latency and API expenses. Each routing decision requires a full LLM inference, which can add 1-3 seconds and $0.001-0.01 per request. For high-throughput systems, these costs compound quickly.</p><p><strong>Production pattern:</strong> Many sophisticated systems use LLM routing as a fallback for edge cases or as the primary router for high-value, low-volume interactions where accuracy matters more than speed.</p><h3>2. Embedding-Based Routing: The Semantic Compass</h3><p>Embedding-based routing transforms the routing problem into a mathematical similarity search. By converting both user inputs and routing destinations into high-dimensional vectors, the system can make routing decisions based on semantic similarity rather than surface-level pattern matching.</p><p><strong>The mechanism</strong> involves pre-computing embeddings for each possible route (or representative examples of each route), then computing the embedding for each incoming request and finding the closest match using cosine similarity or other distance metrics.</p><p><strong>Where it excels:</strong></p><ul><li><p><strong>Semantic understanding</strong> that goes beyond keyword matching</p></li><li><p><strong>Multi-language support</strong> since embeddings capture meaning across languages</p></li><li><p><strong>Consistent performance</strong> with sub-second routing decisions</p></li><li><p><strong>Handling synonyms and paraphrasing</strong> naturally</p></li></ul><p><strong>The sweet spot:</strong> Embedding routing offers the best balance of semantic understanding and computational efficiency for most production systems. Once the embeddings are computed, routing decisions happen in milliseconds with no API calls.</p><p><strong>Implementation insight:</strong> The quality of your route embeddings determines everything. Spend time crafting comprehensive descriptions of each route's purpose and scope&#8212;these become the foundation for accurate similarity matching.</p><h3>3. Rule-Based Routing: The Deterministic Workhorse</h3><p>Rule-based routing might seem primitive compared to AI-powered alternatives, but it remains the backbone of many production systems for good reason. Using predefined patterns, keyword matching, and logical conditions, rule-based routing provides predictable, lightning-fast decisions.</p><p><strong>The approach</strong> relies on explicit logic: if the input contains certain keywords, matches specific patterns, or triggers particular conditions, route to the designated handler. Complex decision trees can be built by combining multiple rules and conditions.</p><p><strong>Where it dominates:</strong></p><ul><li><p><strong>High-throughput systems</strong> where microsecond response times matter</p></li><li><p><strong>Compliance-sensitive applications</strong> requiring auditable, deterministic routing</p></li><li><p><strong>Well-defined use cases</strong> with predictable input patterns</p></li><li><p><strong>Resource-constrained environments</strong> with minimal computational overhead</p></li></ul><p><strong>The reliability factor:</strong> Rule-based routing never has an "off day." It makes identical decisions for identical inputs, making it perfect for systems that require absolute consistency and predictability.</p><p><strong>Modern evolution:</strong> Today's rule-based systems often incorporate regular expressions, fuzzy matching, and hierarchical decision trees, making them far more sophisticated than simple keyword matching.</p><h3>4. ML Model-Based Routing: The Learning Specialist</h3><p>Machine learning model-based routing represents a middle ground between the flexibility of LLM routing and the efficiency of rule-based systems. A specialized classification model is trained on labeled examples of correct routing decisions, creating a dedicated routing function optimized for your specific use case.</p><p><strong>The core difference</strong> from LLM routing is crucial: instead of using a general-purpose language model prompted to make routing decisions, you train a discriminative model specifically for routing. The routing logic becomes encoded in the model's learned weights rather than expressed through prompts.</p><p><strong>Where it excels:</strong></p><ul><li><p><strong>Domain-specific accuracy</strong> that improves with more training data</p></li><li><p><strong>Cost-effective operation</strong> with no ongoing API expenses</p></li><li><p><strong>Fast inference</strong> comparable to rule-based systems</p></li><li><p><strong>Continuous improvement</strong> through retraining on new examples</p></li></ul><p><strong>The training advantage:</strong> Unlike embeddings, which rely on general-purpose representations, ML routing models learn patterns specific to your application. They can discover subtle correlations between input features and routing decisions that human-designed rules might miss.</p><p><strong>Implementation strategy:</strong> The most effective ML routing implementations combine traditional ML features (TF-IDF, n-grams) with modern embedding representations, creating hybrid models that capture both statistical and semantic patterns.</p><div><hr></div><h3>code: <a href="https://github.com/zahere-dev/agentexpert-labs/tree/main/core_concepts/routing">https://github.com/zahere-dev/agentexpert-labs</a></h3><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[How to Add OAuth2 Authentication to Your MCP SSE Server | Step-by-step Tutorial]]></title><description><![CDATA[Video Authentication Flow]]></description><link>https://newsletter.adaptiveengineer.com/p/how-to-add-oauth2-authentication</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/how-to-add-oauth2-authentication</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Sun, 31 Aug 2025 03:10:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/9sGAslxJ4xs" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Video</h2><div id="youtube2-9sGAslxJ4xs" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;9sGAslxJ4xs&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/9sGAslxJ4xs?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h2>Authentication Flow</h2><p>Before looking at the code, let&#8217;s see how the authentication flow works:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uG2K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uG2K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png 424w, https://substackcdn.com/image/fetch/$s_!uG2K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png 848w, https://substackcdn.com/image/fetch/$s_!uG2K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png 1272w, https://substackcdn.com/image/fetch/$s_!uG2K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uG2K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png" width="1456" height="941" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:941,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:210489,&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://newsletter.adaptiveengineer.com/i/172377466?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.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_!uG2K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png 424w, https://substackcdn.com/image/fetch/$s_!uG2K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png 848w, https://substackcdn.com/image/fetch/$s_!uG2K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.png 1272w, https://substackcdn.com/image/fetch/$s_!uG2K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F116fcdb4-27e8-4ca3-8aa6-54ab45e3d991_2050x1325.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><strong>Key points from the flow</strong>:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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><ul><li><p>Clients log in via <strong>Auth0</strong> and receive a <strong>JWT access token</strong>.</p></li><li><p>The server uses Auth0&#8217;s <strong>JWKS (JSON Web Key Set)</strong> to validate token signatures.</p></li><li><p>Requests without a valid token are rejected with <strong>401 Unauthorized</strong>.</p></li></ul><h2>Create Auth0 Service (Or any other OAuth provider)</h2><ul><li><p>**We are using Auth0 as it is free**</p></li><li><p>Use your github/google account to signup to Auth0 service</p></li><li><p>Create a Machine-to-Machine app and generate your domain, client id and secret.</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_!YZrj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YZrj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png 424w, https://substackcdn.com/image/fetch/$s_!YZrj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png 848w, https://substackcdn.com/image/fetch/$s_!YZrj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png 1272w, https://substackcdn.com/image/fetch/$s_!YZrj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YZrj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png" width="910" height="620" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:620,&quot;width&quot;:910,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40539,&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://newsletter.adaptiveengineer.com/i/172377466?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.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_!YZrj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png 424w, https://substackcdn.com/image/fetch/$s_!YZrj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png 848w, https://substackcdn.com/image/fetch/$s_!YZrj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.png 1272w, https://substackcdn.com/image/fetch/$s_!YZrj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67383888-8c7b-43e3-abf5-6748e05174f2_910x620.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></p><h2>Imports and Setup</h2><pre><code>import datetime
import os
from zoneinfo import ZoneInfo
from fastapi import Depends, FastAPI, HTTPException, status, Request
from fastapi.responses import JSONResponse
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import jwt
import requests
from jwt.algorithms import RSAAlgorithm
from starlette.applications import Starlette
from starlette.routing import Route, Mount
import logging

from mcp.server.fastmcp import FastMCP
from mcp.server.sse import SseServerTransport
from dotenv import load_dotenv

load_dotenv()
</code></pre><ul><li><p><strong>FastAPI / Starlette</strong>: Provide the ASGI framework and request/response tools.</p></li><li><p><strong>jwt &amp; RSAAlgorithm</strong>: For decoding and verifying <strong>JWTs signed with RS256</strong>.</p></li><li><p><strong>HTTPBearer</strong>: A security utility to parse <code>Authorization: Bearer &lt;token&gt;</code> headers.</p></li><li><p><strong>dotenv</strong>: Loads environment variables (e.g., API keys).</p></li><li><p><strong>logging</strong>: For server-side logging.</p></li><li><p><strong>MCP modules</strong>: <code>FastMCP</code> and <code>SseServerTransport</code> enable MCP over SSE.</p></li></ul><h2>Auth0 Configuration</h2><pre><code>
AUTH0_DOMAIN = "zahere-dev.us.auth0.com"
API_AUDIENCE = "https://zahere-dev.us.auth0.com/api/v2/"
ALGORITHMS = ["RS256"]

# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("mcp-server")

# Fetch JWKS keys once at startup
jwks_url = f"https://{AUTH0_DOMAIN}/.well-known/jwks.json"
jwks = requests.get(jwks_url, verify=False).json()
</code></pre><ul><li><p><strong>AUTH0_DOMAIN</strong>: Your Auth0 tenant domain.</p></li><li><p><strong>API_AUDIENCE</strong>: The intended audience claim of the JWT (ensures tokens are meant for your API).</p></li><li><p><strong>ALGORITHMS</strong>: We only accept <code>RS256</code> (RSA signature with SHA-256).</p></li><li><p><strong>JWKS Fetch</strong>: At startup, the server downloads Auth0&#8217;s <strong>public signing keys</strong>. These are later used to validate incoming tokens.</p></li></ul><h2>JWT Verification Logic</h2><pre><code># Auth setup
security = HTTPBearer()

def verify_jwt(token: str):
    try:
        header = jwt.get_unverified_header(token)
        kid = header["kid"]

        # Find matching JWK
        key = next((k for k in jwks["keys"] if k["kid"] == kid), None)
        if not key:
            raise HTTPException(status_code=401, detail="Invalid auth key")

        public_key = RSAAlgorithm.from_jwk(key)

        payload = jwt.decode(
            token,
            public_key,
            algorithms=ALGORITHMS,
            audience=API_AUDIENCE,
            issuer=f"https://{AUTH0_DOMAIN}/"
        )
        return payload
    except Exception as e:
        logger.error(f"JWT validation error: {str(e)}")
        raise HTTPException(status_code=401, detail="Invalid or expired token")
</code></pre><ul><li><p><strong>Extract header &amp; KID</strong>: Each JWT contains a <code>kid</code> (key ID). This tells us which public key was used to sign it.</p></li><li><p><strong>Find JWK</strong>: Match the <code>kid</code> against Auth0&#8217;s JWKS set.</p></li><li><p><strong>RSAAlgorithm.from_jwk</strong>: Convert the JWK to a usable RSA public key.</p></li><li><p><strong>jwt.decode</strong>: Validate the token signature, audience, issuer, and expiry.</p></li><li><p>If anything fails, raise a <strong>401 Unauthorized</strong> error.</p></li></ul><h2>MCP Server &amp; Tools (Minimal)</h2><pre><code># ======================
# MCP Server Setup
# ======================
mcp = FastMCP(name="Weather and Time SSE Server")

@mcp.tool()
def TimeTool(input_timezone: str = None):
    current_time = datetime.datetime.now()
    if input_timezone:
        current_time = current_time.astimezone(ZoneInfo(input_timezone))
    return f"The current time is {current_time}."

transport = SseServerTransport("/messages/")

@mcp.tool()
def weather_tool(location: str):
    api_key = os.getenv("OPENWEATHERMAP_API_KEY")
    url = f"http://api.openweathermap.org/data/2.5/weather?q={location}&amp;appid={api_key}&amp;units=metric"
    response = requests.get(url)
    data = response.json()
    if data.get("cod") == 200:
        temp = data["main"]["temp"]
        description = data["weather"][0]["description"]
        return f"The weather in {location} is {description} with {temp}&#176;C."
    return f"Couldn't fetch weather for {location}."
</code></pre><ul><li><p>A simple implementation of the MCP server tools</p></li></ul><h2>FastAPI App &amp; Endpoints</h2><pre><code>app = FastAPI()

@app.get("/sse")
async def handle_sse(request: Request):
    auth_hdr = request.headers.get("authorization")
    token = None
    if auth_hdr and auth_hdr.lower().startswith("bearer "):
        token = auth_hdr.split(" ", 1)[1]
    else:
        token = request.query_params.get("access_token")

    if not token:
        raise HTTPException(status_code=401, detail="Missing token")

    verify_jwt(token)

    async with transport.connect_sse(request.scope, request.receive, request._send) as (in_stream, out_stream):
        await mcp._mcp_server.run(in_stream, out_stream, mcp._mcp_server.create_initialization_options())

</code></pre><ul><li><p>Supports <strong>two auth methods</strong>:</p><ol><li><p>Standard <code>Authorization: Bearer &lt;token&gt;</code> header.</p></li><li><p>Query parameter <code>?access_token=...</code> (useful for browser <code>EventSource</code>).</p></li></ol></li><li><p>Token is verified, then SSE connection is established.</p></li></ul><h2>Protecting the ASGI Transport</h2><pre><code>def auth_asgi_wrapper(asgi_app):
    async def app(scope, receive, send):
        if scope["type"] == "http":
            headers = {k.decode().lower(): v.decode() for k, v in scope.get("headers", [])}
            auth_hdr = headers.get("authorization")
            if not auth_hdr or not auth_hdr.lower().startswith("bearer "):
                resp = JSONResponse({"detail": "Not authenticated"}, status_code=401)
                await resp(scope, receive, send)
                return
            token = auth_hdr.split(" ", 1)[1]
            try:
                verify_jwt(token)
            except HTTPException as he:
                resp = JSONResponse({"detail": he.detail}, status_code=he.status_code)
                await resp(scope, receive, send)
                return
            except Exception:
                resp = JSONResponse({"detail": "Invalid or expired token"}, status_code=401)
                await resp(scope, receive, send)
                return
        await asgi_app(scope, receive, send)
    return app
</code></pre><ul><li><p>This wrapper protects the <code>/messages/</code> endpoint. It intercepts requests, checks for a Bearer token, and validates it before passing control to the MCP transport.</p></li></ul><h2>Mount Messages Route</h2><pre><code>app.mount("/messages/", auth_asgi_wrapper(transport.handle_post_message))
</code></pre><ul><li><p>This makes sure POST requests to <code>/messages/</code> are also protected by our wrapper</p></li></ul><h2>Run the Server</h2><pre><code>if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8100)
</code></pre><h2>The Client</h2><p>**Below is only part of the client code**. Full code is available in repo.</p><pre><code>def get_token():
    import http.client

    conn = http.client.HTTPSConnection(os.getenv("AUTH0_DOMAIN"))
    
    payload = {"client_id":os.getenv("CLIENT_ID"), "client_secret":os.getenv("CLIENT_SECRET"),"audience":os.getenv("AUTH_AUDIENCE"),"grant_type":"client_credentials"}

    headers = { 'content-type': "application/json" }

    conn.request("POST", "/oauth/token", json.dumps(payload), headers)

    res = conn.getresponse()
    data = json.loads(res.read())
    return data["access_token"]


async def main(queries: list[str]):
    sse_url = "http://localhost:8100/sse"
    logger.info(f"Generating Bearer token for authentication")
    auth_token = get_token()
    #auth_token = "12124234"
    logger.info(f"Token generated {auth_token[:20]} ")
    headers = {"Authorization": f"Bearer {auth_token}"}    
    try:
        logger.info("Connecting to MCP Server with token")
        # 1) Open SSE &#8594; yields (in_stream, out_stream)
        async with sse_client(url=sse_url, headers=headers) as (in_stream, out_stream):
            # 2) Create an MCP session over those streams
            logger.info("Connected to MCP Server")
            async with ClientSession(in_stream, out_stream) as session:
                
                # 3) Initialize
                info = await session.initialize()
                logger.info(f"Connected to {info.serverInfo.name} v{info.serverInfo.version}")

                # 4) List tools
                tools = (await session.list_tools())
                logger.info(tools)            
                
                ### Run the queries
                
                for query in queries:                
                
                    prompt = get_prompt_to_identify_tool_and_arguements(query,tools)
                    logger.info(f"Printing Prompt \n {prompt}")
                    
                    response = llm_client(prompt)
                    print(response)
                    
                    tool_call = json.loads(response)
                                
                    result = await session.call_tool(tool_call["tool"], arguments=tool_call["arguments"])
                    logger.success(f"User query: {query}, Tool Response: {result.content[0].text}")
    except httpx.HTTPStatusError as http_e:
        logger.exception(f"HTTP Error: {http_e}")
    except Exception as e:
        logger.exception(f"Error: {e}")
            

if __name__ == "__main__":
    queries = ["What is the time in Bengaluru?", "What is the weather like right now in Dubai?"]    
    asyncio.run(main(queries))
</code></pre><ul><li><p>Use the client_id and secret to connect with Auth0 and request for access token</p></li><li><p>Send the token to the MCP Server as a header with &#8220;Authorization&#8221; key.</p></li><li><p>If connection is established, you will see the message below, else 401 Unauthorized error</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jKOK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jKOK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png 424w, https://substackcdn.com/image/fetch/$s_!jKOK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png 848w, https://substackcdn.com/image/fetch/$s_!jKOK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png 1272w, https://substackcdn.com/image/fetch/$s_!jKOK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jKOK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png" width="1456" height="36" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:36,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19950,&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://newsletter.adaptiveengineer.com/i/172377466?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.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_!jKOK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png 424w, https://substackcdn.com/image/fetch/$s_!jKOK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png 848w, https://substackcdn.com/image/fetch/$s_!jKOK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png 1272w, https://substackcdn.com/image/fetch/$s_!jKOK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26ebc1ed-86d7-4347-9531-d5d9a1b02260_2745x67.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Tools‑First Approach to Building Reliable AI Agents]]></title><description><![CDATA[Why deterministic tools, not just prompts, are the foundation for scalable GenAI systems]]></description><link>https://newsletter.adaptiveengineer.com/p/the-toolsfirst-approach-to-building</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/the-toolsfirst-approach-to-building</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Sun, 27 Jul 2025 12:50:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/ZeKUwLohdv8" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Why deterministic tools, not just prompts, are the foundation for scalable GenAI systems</strong></p><h2>TL;DR</h2><blockquote><p><em><strong>LLM agents become robust, scalable, and debuggable only when you build, test, and orchestrate deterministic tools first&#8212;before prompt crafting. Tools, not prompts, should encode business logic, connect to APIs, and manage data. Start With Tools Not Tasks</strong></em></p></blockquote><p></p><h2>Video</h2><div id="youtube2-ZeKUwLohdv8" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;ZeKUwLohdv8&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/ZeKUwLohdv8?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p></p><h2>Context</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-yIs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-yIs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png 424w, https://substackcdn.com/image/fetch/$s_!-yIs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png 848w, https://substackcdn.com/image/fetch/$s_!-yIs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png 1272w, https://substackcdn.com/image/fetch/$s_!-yIs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-yIs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png" width="1456" height="789" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:789,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-yIs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png 424w, https://substackcdn.com/image/fetch/$s_!-yIs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png 848w, https://substackcdn.com/image/fetch/$s_!-yIs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.png 1272w, https://substackcdn.com/image/fetch/$s_!-yIs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7856873a-a71c-4364-92a0-412877b7b303_2640x1430.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>Let&#8217;s say you were given a task to build an <strong>Email Processing Agent</strong> that is capable of parsing incoming emails, understanding the intent, and executing the relevant tasks (like routing, calling downstream tools, and/or responding to the sender).</p><p>Below is how you would commonly approach these use cases with agent frameworks like CrewAI/LangGraph?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HtI3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HtI3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png 424w, https://substackcdn.com/image/fetch/$s_!HtI3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png 848w, https://substackcdn.com/image/fetch/$s_!HtI3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png 1272w, https://substackcdn.com/image/fetch/$s_!HtI3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HtI3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png" width="1456" height="745" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:745,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!HtI3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png 424w, https://substackcdn.com/image/fetch/$s_!HtI3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png 848w, https://substackcdn.com/image/fetch/$s_!HtI3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.png 1272w, https://substackcdn.com/image/fetch/$s_!HtI3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fcaec71-f2cb-4a99-bd09-6dece1670ad5_2555x1307.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>But should you start with Flow Methods, Nodes and Edges or should you start with the tool?</p><p>Most frameworks for building AI agents advise:</p><blockquote><p><em><strong>&#8220;Effective task definition is often more important than model selection.&#8221;</strong></em></p></blockquote><p>This is a great start, but <strong>I challenge this orthodoxy</strong>. In my experience, when deploying LLM agents for enterprise automation, this advice still puts you at risk of invisible failures and brittle systems.</p><blockquote><p><em><strong>My premise:<br>Don&#8217;t start with the task. Start with your tool design. Only then define the task and choose the model.</strong></em></p></blockquote><p>Why? Suppose your tools, the deterministic, testable modules that wrap core business logic and external APIs, aren&#8217;t designed and hardened up front. In that case, both task definition and model selection become sources of confusion and fragility.</p><p>In the case of the Email Parser Agent, the following can happen</p><ul><li><p><strong>Increased Risk of System-Wide Failures</strong>: Untested tools like the Email Classifier or Support Ticket API can cause cascading errors across workflows, disrupting tasks like invoicing or meeting scheduling.</p></li><li><p><strong>Unreliable Tool Behavior</strong>: Unvalidated tools, such as the Calendar API, may mishandle edge cases (e.g., invalid time zones), leading to incorrect workflow outcomes.</p></li><li><p><strong>Complex Debugging and Maintenance</strong>: Building workflows first obscures whether errors stem from tools, LLMs, or orchestration, complicating debugging in CrewAI or LangGraph.</p></li><li><p><strong>Poor Handling of Edge Cases</strong>: Untested tools like the Email Classifier may fail on ambiguous inputs, breaking workflows like Technical Support Queries.</p></li><li><p><strong>Over-Reliance on LLMs</strong>: Without tools like the Invite Parser, workflows rely on unpredictable LLMs for deterministic tasks, reducing reliability.</p></li><li><p><strong>Scalability Challenges</strong>: Unoptimized tools (e.g., Support Ticket API) may fail under high load, causing bottlenecks in high-volume email processing.</p></li></ul><p><strong>Prompts can impress, effective tasks may clarify, but only robust tools make agents truly reliable.</strong></p><p><strong>So:</strong><br>Start by designing and hardening your tools. Make each unit deterministic, observable, and testable.<br><strong>Then:</strong><br>Define the agent&#8217;s task in terms of tool orchestration&#8212;not raw prompting. Only at this point does model selection add real value.</p><blockquote><p><em><strong>&#8220;Build your tools first. Then the task. Then the prompt. That&#8217;s where scalable, production-ready AI starts.&#8221;</strong></em></p></blockquote><p>This guide provides you with a practical blueprint:</p><ul><li><p><strong>Why &#8220;tools-first&#8221;? How does it differ from standard &#8220;task-first&#8221; or &#8220;prompt-first&#8221; wisdom?</strong></p></li><li><p><strong>What, exactly, is a tool&#8212;and why is it the most controllable, reliable artifact in your stack?</strong></p></li><li><p><strong>How do you design, validate, and orchestrate tools for enterprise-ready agents?</strong></p></li></ul><h2>Let&#8217;s Start with Why! Why a Tools-First Approach?</h2><p>Tools are the deterministic components of an AI agent&#8217;s architecture.</p><p>Unlike LLMs, which generate responses based on probabilities, tools are explicitly coded to perform specific tasks, such as fetching data from APIs, performing calculations, or interacting with databases.</p><p>By prioritizing tool development, you create a solid foundation for your AI agent, ensuring that the most predictable parts of your system are reliable before introducing the variability of LLMs.</p><p>Benefits of the Tools-First Approach</p><ol><li><p><strong>Deterministic Behavior</strong>: Tools execute predefined logic, making their behavior predictable and testable.</p></li><li><p><strong>Modularity</strong>: Well-designed tools are reusable across multiple agents or workflows.</p></li><li><p><strong>Debugging Simplicity</strong>: Isolating tools from LLMs allows you to test and debug them independently, reducing complexity.</p></li><li><p><strong>Reliability</strong>: Thoroughly tested tools minimize runtime errors when integrated with LLMs.</p></li><li><p><strong>Scalability</strong>: Robust tools can handle edge cases and scale with increased usage.</p></li><li><p><strong>Security</strong>: Keeps critical validation logic out of fragile prompts, reducing prompt injection risks.</p></li><li><p><strong>Faster Iteration</strong>: Tools can be developed, tested, and deployed independently.</p></li></ol><p>Common Pitfalls of Skipping Tool Development</p><ul><li><p>Over-Reliance on LLMs: Developers sometimes use LLMs to handle tasks better suited for deterministic tools, leading to inconsistent results.</p></li><li><p>Untested Tools: Rushing to integrate untested tools with LLMs can cause cascading failures.</p></li><li><p>Poor Error Handling: Without proper tool validation, errors propagate through the agent, making debugging difficult.</p></li></ul><h2>What Is the &#8220;Tools-First&#8221; Approach?</h2><h3>Definition</h3><p>A <strong>tool</strong> in agent systems is a deterministic, testable unit of logic encapsulating business operations, integrations, or API calls. Think:</p><ul><li><p>API connectors (CRM, weather, finance)</p></li><li><p>Business logic/calculators</p></li><li><p>Document parsers</p></li><li><p>Database queries</p></li><li><p>Integration wrappers (Slack, Jira)</p></li></ul><blockquote><p><em><strong>A tool is deterministic code. Same input, same output; wrapping real business logic or external actions, callable by the agent.</strong></em></p></blockquote><h3>LLM-First vs Tools-First</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!o7hp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!o7hp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png 424w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png 848w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png 1272w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!o7hp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png" width="1456" height="375" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:375,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:71069,&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://newsletter.adaptiveengineer.com/i/169368884?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.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_!o7hp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png 424w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png 848w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.png 1272w, https://substackcdn.com/image/fetch/$s_!o7hp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F073dc09f-c5b0-435f-a218-f1b0ea5bb4a2_2045x527.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></p><h3>Core Tool Properties</h3><ul><li><p><strong>Deterministic:</strong> Same input &#8594; same output</p></li><li><p><strong>Composable:</strong> Reusable across agents and workflows</p></li><li><p><strong>Testable:</strong> Unit tests and mocks are doable in isolation</p></li></ul><h3>Key Principle</h3><p><strong>Write, test, and harden your tools first. Only then orchestrate with LLMs.</strong></p><h2>Best Practices for Tool Development</h2><p>To maximize the effectiveness of the Tools-First Approach, follow these best practices when designing, writing, and testing tools:</p><ol><li><p><strong>Define Clear Specifications</strong>: Document the tool&#8217;s purpose, inputs, outputs, and error conditions. Use type hints (e.g., Python&#8217;s typing module) to enforce input/output contracts.</p></li><li><p><strong>Implement Comprehensive Logging</strong>: Use structured logging to capture tool execution details, inputs, outputs, and errors for debugging and monitoring.</p></li><li><p><strong>Enable Tracing</strong>: Integrate tracing (e.g., OpenTelemetry, Langfuse) to track tool execution in distributed systems, especially when tools interact with external services.</p></li><li><p><strong>Handle Errors Gracefully</strong>: Anticipate edge cases and implement robust error handling with meaningful error messages.</p></li><li><p><strong>Write Unit Tests</strong>: Achieve near-100% test coverage to ensure the tool behaves correctly under all conditions.</p></li><li><p><strong>Validate Inputs and Outputs</strong>: Use schemas (e.g., Pydantic) to validate data entering and leaving the tool.</p></li><li><p><strong>Optimize Performance</strong>: Profile the tool to ensure it performs efficiently, especially for high-frequency tasks.</p></li><li><p><strong>Document the Tool</strong>: Provide clear documentation for other developers or agents to understand and use the tool.</p></li><li><p><strong>Version Control</strong>: Use semantic versioning for tools to manage updates and dependencies.</p></li></ol><h3>Implementation</h3><p>Below is the complete implementation of the Weather API Tool, incorporating best practices.</p><pre><code><code>import requests
from typing import Dict, Any
from pydantic import BaseModel, Field, ValidationError
import structlog
from opentelemetry import trace
from opentelemetry.trace import Span
import os
from requests.exceptions import RequestException
from http import HTTPStatus

# Initialize structured logger
logger = structlog.get_logger()

# Initialize OpenTelemetry tracer
tracer = trace.get_tracer(__name__)

# Input schema
class WeatherInput(BaseModel):
    city: str = Field(..., min_length=1, description="Name of the city")
    api_key: str = Field(..., min_length=1, description="OpenWeatherMap API key")

# Output schema
class WeatherOutput(BaseModel):
    temperature: float = Field(..., description="Temperature in Celsius")
    condition: str = Field(..., description="Weather condition (e.g., Clear)")
    humidity: int = Field(..., ge=0, le=100, description="Humidity percentage")

class WeatherAPIError(Exception):
    """Custom exception for Weather API errors."""
    pass

class WeatherTool:
    """A tool to fetch current weather data for a given city."""

    def __init__(self, base_url: str = "http://api.openweathermap.org/data/2.5/weather"):
        self.base_url = base_url

    @tracer.start_as_current_span("fetch_weather")
    def fetch_weather(self, input_data: WeatherInput) -&gt; WeatherOutput:
        """
        Fetch weather data for the specified city.

        Args:
            input_data: WeatherInput object containing city and API key.

        Returns:
            WeatherOutput object with temperature, condition, and humidity.

        Raises:
            WeatherAPIError: If the API request fails or returns invalid data.
        """
        span: Span = trace.get_current_span()
        span.set_attribute("city", input_data.city)

        logger.info("Fetching weather data", city=input_data.city)

        try:
            # Make API request
            params = {
                "q": input_data.city,
                "appid": input_data.api_key,
                "units": "metric"  # Use Celsius
            }
            response = requests.get(self.base_url, params=params, timeout=5)
            span.set_attribute("http.status_code", response.status_code)

            # Check for HTTP errors
            if response.status_code != HTTPStatus.OK:
                error_msg = f"API request failed: {response.status_code} - {response.text}"
                logger.error(error_msg)
                raise WeatherAPIError(error_msg)

            # Parse response
            data = response.json()
            weather_data = self._parse_weather_data(data)

            logger.info("Weather data fetched successfully", city=input_data.city)
            return weather_data

        except RequestException as e:
            error_msg = f"Network error: {str(e)}"
            logger.error(error_msg, exc_info=True)
            span.record_exception(e)
            raise WeatherAPIError(error_msg)
        except ValidationError as e:
            error_msg = f"Invalid response data: {str(e)}"
            logger.error(error_msg, exc_info=True)
            span.record_exception(e)
            raise WeatherAPIError(error_msg)
        except Exception as e:
            error_msg = f"Unexpected error: {str(e)}"
            logger.error(error_msg, exc_info=True)
            span.record_exception(e)
            raise WeatherAPIError(error_msg)

    def _parse_weather_data(self, data: Dict[str, Any]) -&gt; WeatherOutput:
        """
        Parse raw API response into WeatherOutput schema.

        Args:
            data: Raw JSON response from the API.

        Returns:
            WeatherOutput object.

        Raises:
            ValidationError: If the response data is invalid.
        """
        return WeatherOutput(
            temperature=data["main"]["temp"],
            condition=data["weather"][0]["main"],
            humidity=data["main"]["humidity"]
        )</code></code></pre><pre><code><code>
import asyncio
from pydantic import BaseModel
from agents import Agent, Runner, function_tool
from tools import WeatherTool, WeatherInput, WeatherOutput
from dotenv import load_dotenv

load_dotenv()

@function_tool
def get_weather(weather_input: WeatherInput) -&gt; WeatherOutput:
    print("[debug] get_weather called")
    weather_tool = WeatherTool()
    return weather_tool.fetch_weather(weather_input)

agent = Agent(
    name="Hello world",
    instructions="You are a helpful agent.",
    tools=[get_weather],
)

async def main():
    result = await Runner.run(agent, input="What's the weather in Tokyo?")
    print(result.final_output)
    # The weather in Tokyo is sunny.

if __name__ == "__main__":
    asyncio.run(main())</code></code></pre><pre><code><code>{
  "name": "fetch_weather",
  "trace_id": "9a3a1ee00e4151e3c9e49a2127f8baab",
  "span_id": "1b66ffcf7ab68586",
  "attributes": {
    "city": "Tokyo",
    "http.status_code": 401
  },
  "status": "ERROR",
  "start_time": "2025-07-27T12:46:40.463738Z",
  "end_time": "2025-07-27T12:46:40.527270Z",
  "events": [
    {
      "name": "exception",
      "timestamp": "2025-07-27T12:46:40.521267Z",
      "attributes": {
        "exception.type": "tools.WeatherAPIError",
        "exception.message": "API request failed: 401 - {\"cod\":401, \"message\": \"Invalid API key. Please see https://openweathermap.org/faq#error401 for more info.\"}",
        "exception.stacktrace": "Traceback (most recent call last):\n  File \"C:\\Users\\Zahiruddin_T\\Documents\\LocalDriveProjects\\ToolFirstApproachForAgents\\src\\tools.py\", line 85, in fetch_weather\n    raise WeatherAPIError(error_msg)\ntools.WeatherAPIError: API request failed: 401 - {\"cod\":401, \"message\": \"Invalid API key. Please see https://openweathermap.org/faq#error401 for more info.\"}\n",
        "exception.escaped": "False"
      }
    },
    {
      "name": "exception",
      "timestamp": "2025-07-27T12:46:40.527270Z",
      "attributes": {
        "exception.type": "tools.WeatherAPIError",
        "exception.message": "Unexpected error: API request failed: 401 - {\"cod\":401, \"message\": \"Invalid API key. Please see https://openweathermap.org/faq#error401 for more info.\"}",
        "exception.stacktrace": "Traceback (most recent call last):\n  File \"C:\\Users\\Zahiruddin_T\\Documents\\LocalDriveProjects\\ToolFirstApproachForAgents\\src\\tools.py\", line 85, in fetch_weather\n    raise WeatherAPIError(error_msg)\ntools.WeatherAPIError: API request failed: 401 - {\"cod\":401, \"message\": \"Invalid API key. Please see https://openweathermap.org/faq#error401 for more info.\"}\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"c:\\Users\\Zahiruddin_T\\Documents\\LocalDriveProjects\\ToolFirstApproachForAgents\\.venv\\Lib\\site-packages\\opentelemetry\\trace\\__init__.py\", line 589, in use_span\n    yield span\n  File \"c:\\Users\\Zahiruddin_T\\Documents\\LocalDriveProjects\\ToolFirstApproachForAgents\\.venv\\Lib\\site-packages\\opentelemetry\\sdk\\trace\\__init__.py\", line 1105, in start_as_current_span\n    yield span\n  File \"C:\\Python3127\\Lib\\contextlib.py\", line 81, in inner\n    return func(*args, **kwds)\n           ^^^^^^^^^^^^^^^^^^^\n  File \"C:\\Users\\Zahiruddin_T\\Documents\\LocalDriveProjects\\ToolFirstApproachForAgents\\src\\tools.py\", line 109, in fetch_weather\n    raise WeatherAPIError(error_msg)\ntools.WeatherAPIError: Unexpected error: API request failed: 401 - {\"cod\":401, \"message\": \"Invalid API key. Please see https://openweathermap.org/faq#error401 for more info.\"}\n",
        "exception.escaped": "False"
      }
    }
  ]
}
</code></code></pre><h3>Full Code</h3><p><a href="https://github.com/zahere-dev/tool-first-approach-to-building-agents">https://github.com/zahere-dev/tool-first-approach-to-building-agents </a></p><h2>Summary: Think Like a Systems Engineer</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Pvpg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Pvpg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.png 424w, https://substackcdn.com/image/fetch/$s_!Pvpg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.png 848w, https://substackcdn.com/image/fetch/$s_!Pvpg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.png 1272w, https://substackcdn.com/image/fetch/$s_!Pvpg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Pvpg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.png" width="1456" height="384" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/06260113-e310-42ee-9a90-f78735c93167_2045x540.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:384,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:78095,&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://newsletter.adaptiveengineer.com/i/169368884?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.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_!Pvpg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.png 424w, https://substackcdn.com/image/fetch/$s_!Pvpg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.png 848w, https://substackcdn.com/image/fetch/$s_!Pvpg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.png 1272w, https://substackcdn.com/image/fetch/$s_!Pvpg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06260113-e310-42ee-9a90-f78735c93167_2045x540.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><h2>References &amp; Further Reading</h2><p><strong>Beginner:</strong></p><ul><li><p><a href="https://python.langchain.com/docs/modules/agents/tools/">LangChain Tools &amp; Decorators</a></p></li><li><p><a href="https://swagger.io/docs/specification/about/">OpenAPI &amp; Microservices Basics</a></p></li></ul><p><strong>Intermediate:</strong></p><ul><li><p><a href="https://tenacity.readthedocs.io/">Tenacity Retry Library</a></p></li><li><p><a href="https://langgraph.org/tutorial/">LangGraph Node Design</a></p></li></ul><p><strong>Advanced:</strong></p><ul><li><p><a href="https://www.anthropic.com/research/model-context-protocol">Anthropic&#8217;s Model Context Protocol Whitepapers &amp; SDK</a></p></li></ul><h1>Bottom Line</h1><blockquote><p><em><strong>In modern AI agent systems, tools are code, LLMs are orchestration glue. Harden your tools first. Let LLMs coordinate. That&#8217;s how you build agents that scale, adapt, and never leave you debugging in the dark.</strong></em></p></blockquote>]]></content:encoded></item><item><title><![CDATA[How To Create a FastAPI MCP SSE Server with JWT Auth & Custom Client]]></title><description><![CDATA[&#128214; Introduction]]></description><link>https://newsletter.adaptiveengineer.com/p/how-to-create-a-fastapi-mcp-sse-server</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/how-to-create-a-fastapi-mcp-sse-server</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Sun, 18 May 2025 19:39:01 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/D-m5J4rTGN8" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>&#128214; Introduction</strong></h2><p>In modern AI applications, communication between clients and tools isn&#8217;t always as simple as calling an API. The <strong>Model Context Protocol (MCP)</strong> provides a standardized way for clients to exchange information, invoke tools, and maintain shared context over persistent connections &#8212; typically via <strong>Server-Sent Events (SSE)</strong>.</p><p>In this post, I&#8217;ll walk you through:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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><ul><li><p>Building an MCP SSE server using <strong>FastAPI</strong></p></li><li><p>Securing it with <strong>JWT authentication</strong></p></li><li><p>Implementing a <strong>custom Python client</strong> to connect, authenticate, and use MCP tools<br>We&#8217;ll also build a simple <code>BMI Calculator</code> tool to demo tool calling through MCP.</p></li></ul><h2><strong>&#127899;&#65039; Project Overview</strong></h2><p>We&#8217;ll build:</p><ul><li><p>A <strong>FastAPI server</strong> that exposes an MCP-compliant SSE endpoint</p></li><li><p>A <strong>token-based auth system</strong></p></li><li><p>Simple tools to get weather and time for a given location</p></li><li><p>A <strong>Python client</strong> that authenticates, connects via SSE, and invokes the tool dynamically</p></li></ul><div><hr></div><div id="youtube2-D-m5J4rTGN8" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;D-m5J4rTGN8&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/D-m5J4rTGN8?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div><hr></div><h2><strong>&#128230; Tech Stack</strong></h2><ul><li><p>Python 3.11+</p></li><li><p>Python MCP SDK</p></li><li><p>FastAPI</p></li><li><p>aiohttp</p></li><li><p>PyJWT</p></li><li><p>Pydantic</p></li><li><p>loguru (for clean logs)</p></li></ul><h2><strong>Setting up the MCP SSE Server (<a href="http://server.py/">server.py</a>)</strong></h2><p>Let&#8217;s first import the relevant libraries and get credentials and keys from env variables</p><pre><code><code>import datetime
import os
from zoneinfo import ZoneInfo
from fastapi import  FastAPI, HTTPException, Request
from pydantic import BaseModel
import requests
from starlette.applications import Starlette
from starlette.routing import Route, Mount
import jwt
from mcp.server.fastmcp import FastMCP
from mcp.server.sse import SseServerTransport
from loguru import logger

from dotenv import load_dotenv

load_dotenv()
</code></code></pre><p>Let&#8217;s initialize the MCP server and setup the tools</p><pre><code><code># Initialize the MCP server with your tools
mcp = FastMCP(
    name="Weather and Time SSE Server"
)


@mcp.tool()
def TimeTool(input_timezone):
    "Provides the current time for a given city's timezone like Asia/Kolkata, America/New_York etc. If no timezone is provided, it returns the local time."
    format = "%Y-%m-%d %H:%M:%S %Z%z"
    current_time = datetime.datetime.now()    
    if input_timezone:
        print("TimeZone", input_timezone)
        current_time =  current_time.astimezone(ZoneInfo(input_timezone))
    return f"The current time is {current_time}."

transport = SseServerTransport("/messages/")


@mcp.tool()
def weather_tool(location: str):
    """Provides weather information for a given location"""        
    api_key = os.getenv("OPENWEATHERMAP_API_KEY")
    url = f"http://api.openweathermap.org/data/2.5/weather?q={location}&amp;appid={api_key}&amp;units=metric"
    response = requests.get(url)
    data = response.json()
    if data["cod"] == 200:
        temp = data["main"]["temp"]
        description = data["weather"][0]["description"]
        return f"The weather in {location} is currently {description} with a temperature of {temp}&#176;C."
    else:
        return f"Sorry, I couldn't find weather information for {location}."
</code></code></pre><p>We will now setup the JWT auth system and use the starlette routes to essentially expose the app to the clients.</p><pre><code><code>
SECRET_KEY = "my_super_secret_key"
ALGORITHM = "HS256"     
def check_auth(request: Request):
    auth = request.headers.get("authorization", "")        
    if auth.startswith("Bearer "):
        token = auth.split(" ", 1)[1]
        try:
            payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
            return True
        except jwt.ExpiredSignatureError:
            raise HTTPException(status_code=401, detail="Token expired")
        except jwt.InvalidTokenError:
            raise HTTPException(status_code=401, detail="Invalid token")

    raise HTTPException(status_code=401, detail="Unauthorized")

async def handle_sse(request):
    check_auth(request=request)
    # Prepare bidirectional streams over SSE
    async with transport.connect_sse(
        request.scope,
        request.receive,
        request._send
    ) as (in_stream, out_stream):
        # Run the MCP server: read JSON-RPC from in_stream, write replies to out_stream
        await mcp._mcp_server.run(
            in_stream,
            out_stream,
            mcp._mcp_server.create_initialization_options()
        )


#Build a small Starlette app for the two MCP endpoints
sse_app = Starlette(
    routes=[
        Route("/sse", handle_sse, methods=["GET"]),
        # Note the trailing slash to avoid 307 redirects
        Mount("/messages/", app=transport.handle_post_message)
    ]
)
</code></code></pre><p>Now let&#8217;s setup a FastAPI app and add a route for the clients to create a token. We will create a mock client store to simulate credential manager.</p><pre><code><code>app = FastAPI()

# Mock client store
CLIENTS = {
    "test_client": "secret_1234"
}


class TokenRequest(BaseModel):
    client_id: str
    client_secret: str


@app.post("/token")
def generate_token(request: TokenRequest):
    if request.client_id in CLIENTS and CLIENTS[request.client_id] == request.client_secret:
        payload = {
            "sub": request.client_id,
            "exp": datetime.datetime.now() + datetime.timedelta(minutes=60)
        }
        token = jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
        return {"access_token": token}
    else:
        raise HTTPException(status_code=401, detail="Invalid credentials")
</code></code></pre><p>Mount the starlette app to FastAPI and setup gunicorn server to run the app.</p><pre><code><code>app.mount("/", sse_app)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8100)
</code></code></pre><h2><strong>&#128274; Why JWT-Based Auth?</strong></h2><p>Using <strong>client_id</strong> / <strong>client_secret</strong> via POST is scalable:</p><ul><li><p>You can rotate credentials</p></li><li><p>Enforce expiration</p></li><li><p>Integrate external OAuth2/OIDC providers</p></li><li><p>Track session-level auth</p></li></ul><h2><strong>Setting up the MCP SSE Client (<a href="http://client.py/">client.py</a>)</strong></h2><p>Setting up client is similar to what we have seen previously in this series. The only change being we generate the token and pass that as headers in the SSE Client.</p><pre><code><code>import asyncio
import json
from typing import Optional
from mcp import ClientSession
from mcp.client.sse import sse_client
from openai import OpenAI
import mcp.client.sse as _sse_mod
from httpx import AsyncClient as _BaseAsyncClient
from loguru import logger
import aiohttp

from dotenv import load_dotenv

load_dotenv()  # load environment variables from .env

import httpx
_orig_request = httpx.AsyncClient.request

async def _patched_request(self, method, url, *args, **kwargs):
    # ensure follow_redirects is set so 307 &#8594; /messages/ works
    kwargs.setdefault("follow_redirects", True)
    return await _orig_request(self, method, url, *args, **kwargs)

httpx.AsyncClient.request = _patched_request
def llm_client(message: str):
    client = OpenAI()

    completion = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "You are an intelligent Assistant. You will execute tasks as instructed"},
            {
                "role": "user",
                "content": message,
            },
        ],
    )

    result = completion.choices[0].message.content
    return result



def get_prompt_to_identify_tool_and_arguements(query, tools):
    tools_description = "\n".join([f"{tool.name}: {tool.description}, {tool.inputSchema}" for tool in tools.tools])
    return  ("You are a helpful assistant with access to these tools:\n\n"
                f"{tools_description}\n"
                "Choose the appropriate tool based on the user's question. \n"
                f"User's Question: {query}\n"                
                "If no tool is needed, reply directly.\n\n"
                "IMPORTANT: When you need to use a tool, you must ONLY respond with "                
                "the exact JSON object format below, nothing else:\n"
                "Keep the values in str "
                "{\n"
                '    "tool": "tool-name",\n'
                '    "arguments": {\n'
                '        "argument-name": "value"\n'
                "    }\n"
                "}\n\n")




TOKEN_URL = "http://localhost:8100/token"
SSE_URL = "http://localhost:8100/sse"

async def get_token():
    payload = {"client_id": "test_client", "client_secret": "secret_1234"}
    async with aiohttp.ClientSession() as session:
        async with session.post(TOKEN_URL, json=payload) as resp:
            if resp.status != 200:
                logger.error(f"Failed to get token: {resp.status}")
                raise Exception("Unable to authenticate. Ensure you are using valid credentials")
            data = await resp.json()
            logger.info("Successfully generated token")
            return data["access_token"]

async def main(query:str):        
    try:
        auth_token = await get_token()    
        headers = {"Authorization": f"Bearer {auth_token}"}
        async with sse_client(url=SSE_URL,headers=headers) as (in_stream, out_stream):
            # 2) Create an MCP session over those streams
            async with ClientSession(in_stream, out_stream) as session:
                # 3) Initialize
                info = await session.initialize()
                logger.info(f"Connected to {info.serverInfo.name} v{info.serverInfo.version}")

                # 4) List tools
                tools = (await session.list_tools())
                logger.info(tools)            

                prompt = get_prompt_to_identify_tool_and_arguements(query,tools)
                logger.info(f"Printing Prompt \n {prompt}")

                response = llm_client(prompt)
                print(response)

                tool_call = json.loads(response)

                result = await session.call_tool(tool_call["tool"], arguments=tool_call["arguments"])
                logger.success(f"User query: {query}, Tool Response: {result.content[0].text}")
    except Exception as e:
        print(f"Encountered error: {e}")



if __name__ == "__main__":

    queries = ["What is the time in Bengaluru?", "What is the weather like right now in Dubai?"]
    for query in queries:
        asyncio.run(main(query))
</code></code></pre><p>Response when the client is run.</p><pre><code><code>2025-05-18 18:00:48.230 | SUCCESS  | __main__:main:103 - User query: What is the weather like right now in Dubai?, Tool Response: The weather in Dubai is currently clear sky with a temperature of 30.37&#176;C.
</code></code></pre><div><hr></div><p><strong><a href="https://github.com/zahere-dev/mcp-labs">GitHub - zahere-dev/mcp-labs: Repository of my experiments with MCP</a></strong></p><p><strong><a href="https://github.com/zahere-dev/mcp-labs">Repository of my experiments with MCP. Contribute to zahere-dev/mcp-labs development by creating an account on GitHub.</a></strong></p><p><strong><a href="https://github.com/zahere-dev/mcp-labs">github.com</a></strong></p><div id="youtube2-0KJ2oBRtUbs" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;0KJ2oBRtUbs&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/0KJ2oBRtUbs?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h3></h3><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Build a Custom MCP Client and Server from Scratch Using Python]]></title><description><![CDATA[If you&#8217;re curious about how to build an intelligent agent using Model Context Protocol (MCP), you&#8217;re in the right place.]]></description><link>https://newsletter.adaptiveengineer.com/p/build-a-custom-mcp-client-and-server</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/build-a-custom-mcp-client-and-server</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Mon, 07 Apr 2025 04:24:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/hMHYhRcd_Uo" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you&#8217;re curious about how to build an intelligent agent using <strong>Model Context Protocol (MCP)</strong>, you&#8217;re in the right place.</p><p>In this post, I&#8217;ll walk you through how to:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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><ul><li><p>Create an <strong>MCP Server</strong> using FastMCP</p></li><li><p>Expose a tool that calculates <strong>BMI</strong></p></li><li><p>Build a Client that communicates with this server via <strong>stdio</strong></p></li><li><p>Use <strong>OpenAI&#8217;s GPT model</strong> to decide which tool to call and how to call it</p></li></ul><p>Let&#8217;s break this down line by line &#8212; code and concept.</p><div><hr></div><div id="youtube2-hMHYhRcd_Uo" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;hMHYhRcd_Uo&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/hMHYhRcd_Uo?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div><hr></div><h2><strong>What is MCP?</strong></h2><p>Before diving into code, let&#8217;s understand what MCP is.</p><p>MCP (Model Context Protocol) is an <strong>open protocol</strong> developed by <strong><a href="https://www.anthropic.com/">Anthropic</a></strong> to <strong>standardize how LLMs interact with tools</strong>. Think of it as the <strong>USB-C of AI apps</strong> &#8212; a universal way to connect and interact with tools, APIs, and services without writing tons of custom glue code.</p><p>Here&#8217;s a simple analogy:</p><ul><li><p><strong>USB-C Port</strong>: One port to rule them all &#8212; display, power, storage.</p></li><li><p><strong>MCP</strong>: One protocol to access tools &#8212; calculators, search, databases, or any custom service.</p></li></ul><p>By adopting MCP, we avoid the pain of writing one-off integration code for every LLM interaction. Instead, we define tools once and let the LLM figure out how to use them.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Aldt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Aldt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!Aldt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!Aldt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!Aldt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Aldt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bef5f890-a86f-49db-9eda-4eade8c4d55d_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;:null,&quot;alt&quot;:&quot;What is MCP?&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="What is MCP?" title="What is MCP?" srcset="https://substackcdn.com/image/fetch/$s_!Aldt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!Aldt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!Aldt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!Aldt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbef5f890-a86f-49db-9eda-4eade8c4d55d_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><em>Courtesy:</em> <em><strong><a href="https://norahsakal.com/">norahsakal.com</a></strong></em></p><div><hr></div><h2><strong>&#128736;&#65039; Project Overview</strong></h2><p>We&#8217;ll build two things:</p><ol><li><p><strong>An MCP Server</strong> that exposes a simple tool to calculate BMI.</p></li><li><p><strong>An MCP Client</strong> that communicates with the server via an LLM (like OpenAI GPT) and invokes the tool.</p></li></ol><p>Let&#8217;s get started.</p><h2><strong>MCP Server</strong></h2><p>There are just 2 dependencies we need to install.</p><pre><code><code>pip install "mcp[cli]"
pip install openai
</code></code></pre><p>Let&#8217;s create a file called <code>bmi_server.py</code>.</p><pre><code><code>from mcp.server.fastmcp import FastMCP

mcp = FastMCP("BMI Server")

print(f"Starting server {mcp.name}")

@mcp.tool()
def calculate_bmi(weight_kg:float, height_m:float) -&gt; float:
    """
    Calculate BMI given weight in kg and height in meters.
    """
    if height_m &lt;= 0:
        raise ValueError("Height must be greater than zero.")
    return weight_kg / (height_m ** 2)


if __name__ == "__main__":
    mcp.run(transport="stdio")
</code></code></pre><p><strong>What&#8217;s happening here?</strong></p><ul><li><p>We use the FastMCP class to create the MCP server</p></li><li><p>We create a BMI tool using the <code>@mcp.tool()</code>decorator.</p></li><li><p>It takes weight and height and returns BMI.</p></li><li><p>The server exposes this tool using standard input/output transport.</p></li><li><p>We want this file to be run independently and not as a module</p></li></ul><p>Obviously, this is a fundamental MCP server, but this should get us started on building our own MCP client.</p><h2><strong>MCP Client</strong></h2><p>Now, let&#8217;s create the client in a file named <code>bmi_client.py</code>.</p><p>Import all the dependencies. The key ones here being ClientSession, StdioServerParameters and stdio_client from the mcp package and OpenAI class to communicate with the LLM.</p><pre><code><code>import asyncio
from openai import OpenAI
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import os
import json
</code></code></pre><p>We need to now establish a way to communicate with the server we just wrote. Let&#8217;s use the StdioServerParameters class from the mcp package to do that.</p><pre><code><code>server_params = StdioServerParameters(command="python", args=["bmi-server.py"])
</code></code></pre><p>Essentially, we are telling the client what command to run and how to use the server file.</p><p>Let&#8217;s write a generic method that to communicate with an LLM API. This should simply take a prompt and return a response.</p><pre><code><code>def llm_client(message:str):
    """
    Send a message to the LLM and return the response.
    """
    # Initialize the OpenAI client
    openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

    # Send the message to the LLM
    response = openai_client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role":"system",
                    "content":"You are an intelligent assistant. You will execute tasks as prompted",
                    "role": "user", "content": message}],
        max_tokens=250,
        temperature=0.2
    )

    # Extract and return the response content
    return response.choices[0].message.content.strip()
</code></code></pre><p>We need to write a prompt that does 2 things</p><p>1. Share the context with the LLM about the tools it has at its disposal<br>2. Instruct a structured output so that we can execute the tool the LLM selected</p><pre><code><code>def get_prompt_to_identify_tool_and_arguments(query,tools):
    tools_description = "\n".join([f"- {tool.name}, {tool.description}, {tool.inputSchema} " for tool in tools])
    return  ("You are a helpful assistant with access to these tools:\n\n"
                f"{tools_description}\n"
                "Choose the appropriate tool based on the user's question. \n"
                f"User's Question: {query}\n"                
                "If no tool is needed, reply directly.\n\n"
                "IMPORTANT: When you need to use a tool, you must ONLY respond with "                
                "the exact JSON object format below, nothing else:\n"
                "Keep the values in str "
                "{\n"
                '    "tool": "tool-name",\n'
                '    "arguments": {\n'
                '        "argument-name": "value"\n'
                "    }\n"
                "}\n\n")
</code></code></pre><p>We are passing two arguments - the original query from the user and the list of tools from the server(s). Let&#8217;s now see how get the list of tools from the server.</p><pre><code><code>
async def run(query: str):
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read,write) as session:

            await session.initialize()

            # Get the list of available tools
            tools = await session.list_tools()

            print(f"Available tools: {tools}")

            prompt = get_prompt_to_identify_tool_and_arguments(query,tools.tools)

            llm_response = llm_client(prompt)
            print(f"LLM Response: {llm_response}")

            tool_call = json.loads(llm_response)

            result = await session.call_tool(tool_call["tool"], arguments=tool_call["arguments"])

            print(f"BMI for weight {tool_call["arguments"]["weight_kg"]}kg and height {tool_call["arguments"]["height_m"]}m is {result.content[0].text}")
</code></code></pre><p><strong>Key things happening here:</strong></p><ul><li><p>We start the BMI Server process using <code>stdio_client</code>, and get access to its read and write streams</p></li><li><p>Next, we create a session and initialize it. This sets up the communication between our client and the server.</p></li><li><p>We then ask the server for a list of all available tools. In our case, it will return the <code>calculate_bmi</code> function we exposed earlier.</p></li><li><p>&#8220;We prepare a detailed prompt using the earlier function, passing in the user's query and available tools. This prompt helps the language model figure out what tool to call and what arguments to pass.</p></li><li><p>We parse the JSON response, extract the tool name and arguments, and then call the tool using <code>session.call_tool</code>.</p></li><li><p>Finally, we return the output from the tool call &#8212; in this case, the calculated BMI.</p></li></ul><p>To make all of the above work, we will add an entry point. When this script is run, it sets the user query &#8212; here we ask to calculate BMI &#8212; and runs the <code>run()</code> function using <code>asyncio</code>. The final result is printed on screen!</p><pre><code><code>if __name__ == "__main__":
    import asyncio
    query = "Calculate BMI for height 5ft 10inches and weight 80kg"
    print(f"Sending query: {query}")
    result = asyncio.run(run(query))
    print(f"Result: {result}")
</code></code></pre><div><hr></div><p><strong><a href="https://github.com/zahere-dev/mcp-labs">GitHub - zahere-dev/mcp-labs: Repository of my experiments with MCP</a></strong></p><p><strong><a href="https://github.com/zahere-dev/mcp-labs">Repository of my experiments with MCP. Contribute to zahere-dev/mcp-labs development by creating an account on GitHub.</a></strong></p><p><strong><a href="https://github.com/zahere-dev/mcp-labs">github.com</a></strong></p><div><hr></div><p>And that&#8217;s how you build an intelligent MCP client that can call tools dynamically using OpenAI and a BMI server. The magic lies in combining tool discovery, LLM prompting, and tool invocation &#8212; all within a simple and elegant flow.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[My Favorite OpenAI Agents SDK Feature (And The Most Understated!)]]></title><description><![CDATA[In our previous tutorial, we built a restaurant customer support chatbot using OpenAI's Agents SDK.]]></description><link>https://newsletter.adaptiveengineer.com/p/my-favorite-openai-agents-sdk-feature</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/my-favorite-openai-agents-sdk-feature</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Mon, 24 Mar 2025 01:56:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!FV_E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In our <a href="https://newsletter.adaptiveengineer.com/p/building-a-multi-agent-system-with">previous tutorial, we built a restaurant customer support chatbot</a> using OpenAI's Agents SDK. In this follow-up, we&#8217;ll explore <strong>guardrails</strong>&#8212;a critical feature that enhances AI chatbot safety and reliability.</p><h3>What Are Guardrails in AI Agents?</h3><p>Guardrails act as a <strong>safety net</strong> for AI agents, ensuring they operate within predefined boundaries and preventing misuse.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>They work alongside agents, validating user inputs and outputs to safeguard against errors and inappropriate responses.</p><p>There are two types of guardrails:</p><ul><li><p><strong>Input Guardrails</strong>: Validate user inputs before processing.</p></li><li><p><strong>Output Guardrails</strong>: Ensure the final response is appropriate before delivering it to the user.</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_!FV_E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FV_E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png 424w, https://substackcdn.com/image/fetch/$s_!FV_E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png 848w, https://substackcdn.com/image/fetch/$s_!FV_E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png 1272w, https://substackcdn.com/image/fetch/$s_!FV_E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FV_E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png" width="1456" height="612" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:612,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:199600,&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://newsletter.adaptiveengineer.com/i/159716233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.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_!FV_E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png 424w, https://substackcdn.com/image/fetch/$s_!FV_E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png 848w, https://substackcdn.com/image/fetch/$s_!FV_E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.png 1272w, https://substackcdn.com/image/fetch/$s_!FV_E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8fe4d90-98ff-4bab-845c-3606f61490e9_2665x1120.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></p><p>Let&#8217;s see them in action!</p><div id="youtube2-yKqMAsaKI5A" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;yKqMAsaKI5A&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/yKqMAsaKI5A?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h2>Input Guardrails</h2><ul><li><p>These validate initial user inputs before passing them to expensive models.</p></li><li><p>They operate in three steps: receiving input, running validation functions, and triggering errors if misuse is detected.</p></li></ul><p>Input guardrails are mechanisms put in place to validate, sanitize, and preprocess user inputs before they reach an AI model. These safeguards help in preventing:</p><ul><li><p>Malicious injections (e.g., prompt injection attacks)</p></li><li><p>Profanity, hate speech, and harmful language</p></li><li><p>Unstructured or irrelevant input that reduces model efficiency</p></li><li><p>Bias amplification</p></li></ul><p>By implementing input guardrails, developers can ensure that AI models receive well-structured and appropriate input, leading to better and safer outputs.</p><h3><strong>Why Are Input Guardrails Important?</strong></h3><ol><li><p><strong>Security</strong>: Prevents prompt injections, SQL injections, and adversarial attacks.</p></li><li><p><strong>Quality Assurance</strong>: Filters out irrelevant or poorly structured queries.</p></li><li><p><strong>Bias Mitigation</strong>: Helps remove explicit bias in prompts.</p></li><li><p><strong>User Experience</strong>: Ensures clear and understandable input for meaningful responses.</p></li><li><p><strong>Compliance</strong>: Adheres to ethical AI principles and regulatory requirements.</p></li></ol><h3><strong>How to Implement Input Guardrails</strong></h3><p>Create the guardrail agent as below. Use the @input_guardrail decorator for the guardrail method.</p><p>More here in the <a href="https://openai.github.io/openai-agents-python/guardrails/">documentation</a>.</p><p>Input guardrails run in 3 steps:</p><ol><li><p>First, the guardrail receives the same input passed to the agent.</p></li><li><p>Next, the guardrail function runs to produce a <code>GuardrailFunctionOutput</code>, which is then wrapped in an <code>InputGuardrailResult</code></p></li><li><p>Finally, we check if <code>.tripwire_triggered</code> is true. If true, an <code>InputGuardrailTripwireTriggered</code> exception is raised, so you can appropriately respond to the user or handle the exception.</p></li></ol><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QinM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QinM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png 424w, https://substackcdn.com/image/fetch/$s_!QinM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png 848w, https://substackcdn.com/image/fetch/$s_!QinM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png 1272w, https://substackcdn.com/image/fetch/$s_!QinM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QinM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png" width="1456" height="962" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:962,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:182070,&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://newsletter.adaptiveengineer.com/i/159716233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.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_!QinM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png 424w, https://substackcdn.com/image/fetch/$s_!QinM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png 848w, https://substackcdn.com/image/fetch/$s_!QinM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.png 1272w, https://substackcdn.com/image/fetch/$s_!QinM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43849546-663f-4fd3-9c96-a6b5ee456070_1687x1115.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>Pass the guardrail as an argument to the triage agent.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zzVC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zzVC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png 424w, https://substackcdn.com/image/fetch/$s_!zzVC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png 848w, https://substackcdn.com/image/fetch/$s_!zzVC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png 1272w, https://substackcdn.com/image/fetch/$s_!zzVC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zzVC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png" width="1222" height="307" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:307,&quot;width&quot;:1222,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:53152,&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://newsletter.adaptiveengineer.com/i/159716233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.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_!zzVC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png 424w, https://substackcdn.com/image/fetch/$s_!zzVC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png 848w, https://substackcdn.com/image/fetch/$s_!zzVC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.png 1272w, https://substackcdn.com/image/fetch/$s_!zzVC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065268de-2a29-4489-98cf-6622ce6f4821_1222x307.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>Handle the <code>InputGuardrailTripwireTriggered exception.</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_!C7Hb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!C7Hb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png 424w, https://substackcdn.com/image/fetch/$s_!C7Hb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png 848w, https://substackcdn.com/image/fetch/$s_!C7Hb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png 1272w, https://substackcdn.com/image/fetch/$s_!C7Hb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!C7Hb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png" width="1456" height="861" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:861,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:226897,&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://newsletter.adaptiveengineer.com/i/159716233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.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_!C7Hb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png 424w, https://substackcdn.com/image/fetch/$s_!C7Hb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png 848w, https://substackcdn.com/image/fetch/$s_!C7Hb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.png 1272w, https://substackcdn.com/image/fetch/$s_!C7Hb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd304c0ec-edd5-4bf6-b425-c66c83cecf1f_1897x1122.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>Exception raised when the input is &#8220;Why is my order delayed? You guys are pathetic&#8220;</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qv4e!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qv4e!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png 424w, https://substackcdn.com/image/fetch/$s_!qv4e!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png 848w, https://substackcdn.com/image/fetch/$s_!qv4e!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png 1272w, https://substackcdn.com/image/fetch/$s_!qv4e!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qv4e!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png" width="1456" height="70" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:70,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65463,&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://newsletter.adaptiveengineer.com/i/159716233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.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_!qv4e!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png 424w, https://substackcdn.com/image/fetch/$s_!qv4e!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png 848w, https://substackcdn.com/image/fetch/$s_!qv4e!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png 1272w, https://substackcdn.com/image/fetch/$s_!qv4e!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f088748-229c-4d11-ab0c-14cc4fc6b076_3140x150.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>Output Guardrails</h2><ul><li><p>These validate the final outputs generated by agents before they are delivered to users.</p></li><li><p>They operate similarly to input guardrails but focus on the output stage to ensure accuracy and safety.</p></li></ul><p>Output guardrails run in 3 steps:</p><ol><li><p>First, the guardrail receives the same input passed to the agent.</p></li><li><p>Next, the guardrail function runs to produce a <code>GuardrailFunctionOutput</code>, which is then wrapped in an <code>OutputGuardrailResult</code></p></li><li><p>Finally, we check if <code>.tripwire_triggered</code> is true. If true, an <code>OutputGuardrailTripwireTriggered</code> exception is raised, so you can appropriately respond to the user or handle the exception.</p></li></ol><p></p><p>In the example below - we want to check for the &#8220;card&#8221; in the response of the order_agent and raise an exception accordingly.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SPQC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SPQC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png 424w, https://substackcdn.com/image/fetch/$s_!SPQC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png 848w, https://substackcdn.com/image/fetch/$s_!SPQC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png 1272w, https://substackcdn.com/image/fetch/$s_!SPQC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SPQC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png" width="1456" height="790" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:790,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:152318,&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://newsletter.adaptiveengineer.com/i/159716233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.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_!SPQC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png 424w, https://substackcdn.com/image/fetch/$s_!SPQC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png 848w, https://substackcdn.com/image/fetch/$s_!SPQC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.png 1272w, https://substackcdn.com/image/fetch/$s_!SPQC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97ddf2a-3011-4d0b-9ded-8c254ee07e0f_1575x855.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>Add the output guardrail as the argument to the final agent in the workflow.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6mWU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6mWU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png 424w, https://substackcdn.com/image/fetch/$s_!6mWU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png 848w, https://substackcdn.com/image/fetch/$s_!6mWU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png 1272w, https://substackcdn.com/image/fetch/$s_!6mWU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6mWU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png" width="1456" height="163" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4910aa32-8630-4118-a845-1e03d332b916_2905x325.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:163,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:64905,&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://newsletter.adaptiveengineer.com/i/159716233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.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_!6mWU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png 424w, https://substackcdn.com/image/fetch/$s_!6mWU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png 848w, https://substackcdn.com/image/fetch/$s_!6mWU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png 1272w, https://substackcdn.com/image/fetch/$s_!6mWU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4910aa32-8630-4118-a845-1e03d332b916_2905x325.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>We simulated the response of the order_agent for order 12346 to contain the word &#8220;card&#8221; and this is how the exception is caught.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8k3d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8k3d!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png 424w, https://substackcdn.com/image/fetch/$s_!8k3d!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png 848w, https://substackcdn.com/image/fetch/$s_!8k3d!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png 1272w, https://substackcdn.com/image/fetch/$s_!8k3d!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8k3d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png" width="1456" height="65" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:65,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:23924,&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://newsletter.adaptiveengineer.com/i/159716233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.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_!8k3d!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png 424w, https://substackcdn.com/image/fetch/$s_!8k3d!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png 848w, https://substackcdn.com/image/fetch/$s_!8k3d!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png 1272w, https://substackcdn.com/image/fetch/$s_!8k3d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff197c0bb-2593-4893-b0bc-02c4dfc5fb75_1780x80.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>Code</h2><p>https://github.com/zahere-dev/openai-agents-sdk-tutorial</p><h2><strong>Conclusion:</strong></h2><ul><li><p>Guardrails are vital components of AI agent systems, ensuring they operate safely and efficiently.</p></li><li><p>By implementing guardrails, developers can enhance user trust and prevent misuse scenarios effectively.<br></p></li></ul><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Building a Multi-Agent System with OpenAI Agents SDK - Part 1]]></title><description><![CDATA[OpenAI recently released their Agents SDK, a lightweight yet powerful framework for building multi-agent workflows.]]></description><link>https://newsletter.adaptiveengineer.com/p/building-a-multi-agent-system-with</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/building-a-multi-agent-system-with</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Sun, 16 Mar 2025 06:54:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/FAxAxiR4s-A" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>OpenAI recently released their Agents SDK, a lightweight yet powerful framework for building multi-agent workflows. Unlike the experimental OpenAI Swarm released last year, <a href="https://github.com/openai/openai-agents-python">this SDK</a> is production-ready and offers one of the most straightforward implementations of multi-agent orchestration currently available.</p><div id="youtube2-FAxAxiR4s-A" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;FAxAxiR4s-A&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/FAxAxiR4s-A?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>In this tutorial, we'll build a Restaurant Customer Support system using multiple specialized agents that can handle different types of customer queries automatically.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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_!Jrxj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jrxj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png 424w, https://substackcdn.com/image/fetch/$s_!Jrxj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png 848w, https://substackcdn.com/image/fetch/$s_!Jrxj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png 1272w, https://substackcdn.com/image/fetch/$s_!Jrxj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Jrxj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png" width="1456" height="815" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:815,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:191577,&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://newsletter.adaptiveengineer.com/i/159166248?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.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_!Jrxj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png 424w, https://substackcdn.com/image/fetch/$s_!Jrxj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png 848w, https://substackcdn.com/image/fetch/$s_!Jrxj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.png 1272w, https://substackcdn.com/image/fetch/$s_!Jrxj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F847df106-e2db-44c0-9d66-f076ffbf6d65_2510x1405.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></p><h2>What is OpenAI Agent SDK?</h2><p>The OpenAI Agent SDK provides a framework for creating multi-agent systems where specialized agents handle specific tasks. The core concepts include:</p><ul><li><p><strong>Agents</strong>: The fundamental building blocks powered by language models and configured with specific instructions and tools</p></li><li><p><strong>Handoffs</strong>: The ability for agents to delegate tasks to other specialized agents</p></li><li><p><strong>Guardrails</strong>: Concurrent checks and validations that ensure interactions adhere to predefined criteria</p></li><li><p><strong>Tools</strong>: Functions or methods that agents can use to retrieve or manipulate data</p></li></ul><h2>Building a Restaurant Support System</h2><p>Let's create a customer support system for a restaurant that can:</p><ul><li><p>Check order status</p></li><li><p>Answer FAQs</p></li><li><p>Handle complaints</p></li><li><p>Manage table reservations</p></li></ul><h3>Setting Up the Environment</h3><p>First, install the required package - that is all you need:</p><p><code>pip install openai-agents</code></p><h3>Creating Our Agents</h3><h4>The Classifier (Triage) Agent</h4><p>This agent serves as the entry point, determining the intent of customer queries and routing them to specialized agents.</p><p>The handoffs parameter is the key here - it takes a list of specialised agents as arguments.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vC4E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vC4E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png 424w, https://substackcdn.com/image/fetch/$s_!vC4E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png 848w, https://substackcdn.com/image/fetch/$s_!vC4E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png 1272w, https://substackcdn.com/image/fetch/$s_!vC4E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vC4E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png" width="1050" height="220" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/69439957-b6ea-42a2-8580-2d116e904678_1050x220.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:220,&quot;width&quot;:1050,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:35438,&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://newsletter.adaptiveengineer.com/i/159166248?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.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_!vC4E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png 424w, https://substackcdn.com/image/fetch/$s_!vC4E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png 848w, https://substackcdn.com/image/fetch/$s_!vC4E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png 1272w, https://substackcdn.com/image/fetch/$s_!vC4E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69439957-b6ea-42a2-8580-2d116e904678_1050x220.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The rest of agents look like below. Instead of handoffs we pass the tool/method the agent can use to process the task/ user query.</p><p>For example - in the case of order_agent, I have oversimplified the check_order_status tool that it uses to check the status of an order.</p><p>In a real use case, this function could be making an API call, or fetching the order status from a database.</p><p>We use @function_tool decorator to denote a method as a tool for an agent. This function can be used with an agent. It just needs be passed as an argument to the tools parameter in the Agent class.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0h_L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0h_L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png 424w, https://substackcdn.com/image/fetch/$s_!0h_L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png 848w, https://substackcdn.com/image/fetch/$s_!0h_L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png 1272w, https://substackcdn.com/image/fetch/$s_!0h_L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0h_L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png" width="1456" height="511" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:511,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105622,&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://newsletter.adaptiveengineer.com/i/159166248?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.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_!0h_L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png 424w, https://substackcdn.com/image/fetch/$s_!0h_L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png 848w, https://substackcdn.com/image/fetch/$s_!0h_L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.png 1272w, https://substackcdn.com/image/fetch/$s_!0h_L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08726bbb-53c4-4a0a-81a3-c9190b84336b_1552x545.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>FAQAgent, ComplaintAgent and ReservationAgent are also setup as above with their own relevant functions.</p><h3>Running the Multi-Agent System</h3><p>To create an interactive chat interface, the most important entity is to establish context or conversation history.<br><br>We can simple add &#8220;response.to_input_list()&#8221; which has the context from previous query added. </p><p>This makes it a very efficient chat interface.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9vE2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9vE2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.png 424w, https://substackcdn.com/image/fetch/$s_!9vE2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.png 848w, https://substackcdn.com/image/fetch/$s_!9vE2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.png 1272w, https://substackcdn.com/image/fetch/$s_!9vE2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9vE2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.png" width="1315" height="782" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/817be183-e77c-48f7-8531-60067e589f77_1315x782.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:782,&quot;width&quot;:1315,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:110328,&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://newsletter.adaptiveengineer.com/i/159166248?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.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_!9vE2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.png 424w, https://substackcdn.com/image/fetch/$s_!9vE2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.png 848w, https://substackcdn.com/image/fetch/$s_!9vE2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.png 1272w, https://substackcdn.com/image/fetch/$s_!9vE2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F817be183-e77c-48f7-8531-60067e589f77_1315x782.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><h2>Testing the System</h2><p>Let's test our multi-agent system with various queries:</p><p>You will see that the agent can easily identify the intents and route them to specialised agents for processing.<br><br>All agents are easily able to extract relevant arguments for their tools and execute the functions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g9Cd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g9Cd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png 424w, https://substackcdn.com/image/fetch/$s_!g9Cd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png 848w, https://substackcdn.com/image/fetch/$s_!g9Cd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png 1272w, https://substackcdn.com/image/fetch/$s_!g9Cd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g9Cd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png" width="1456" height="547" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:547,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:636067,&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://newsletter.adaptiveengineer.com/i/159166248?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.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_!g9Cd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png 424w, https://substackcdn.com/image/fetch/$s_!g9Cd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png 848w, https://substackcdn.com/image/fetch/$s_!g9Cd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.png 1272w, https://substackcdn.com/image/fetch/$s_!g9Cd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1385348-0b8c-4e11-93ee-de86a6ebe801_1457x547.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><h2>Benefits of This Approach</h2><ol><li><p><strong>Modularity</strong>: Each agent handles a specific domain, making code organization cleaner</p></li><li><p><strong>Specialized Knowledge</strong>: Agents can be optimized for particular tasks</p></li><li><p><strong>Maintainability</strong>: Add or modify agents without affecting the entire system</p></li><li><p><strong>Contextual Understanding</strong>: The system maintains conversation context between interactions</p></li></ol><h2>Conclusion</h2><p>The OpenAI Agent SDK provides a streamlined way to build powerful multi-agent systems. In this tutorial, we built a restaurant customer support system using specialized agents that can handle different types of queries. This approach provides a clean, modular architecture that can be extended to handle more complex use cases.</p><p>In a future tutorial, we'll explore more advanced features like guardrails and tracing to enhance the robustness and debuggability of our multi-agent system.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Why I'm Going Back to Basics]]></title><description><![CDATA[Video As an engineer in the rapidly evolving field of AI, I don't just want to leverage GenAI APIs and build agents.]]></description><link>https://newsletter.adaptiveengineer.com/p/why-im-going-back-to-basics</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/why-im-going-back-to-basics</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Sun, 02 Feb 2025 18:07:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/EHOF50C2p_E" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Video</h2><div id="youtube2-EHOF50C2p_E" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;EHOF50C2p_E&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/EHOF50C2p_E?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>As an engineer in the rapidly evolving field of AI, I don't just want to leverage GenAI APIs and build agents.</p><h2>The Catalyst: DeepSeek's Innovation</h2><p>Recently, the AI community has been abuzz with the groundbreaking innovations from DeepSeek.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>This Chinese startup has developed a new AI model, R1, which matches or even surpasses the performance of leading models like ChatGPT, but at a fraction of the cost.</p><p>DeepSeek's approach has highlighted the importance of efficiency and deep understanding of AI fundamentals, particularly in mathematics.</p><p>This has inspired me to reset my learning and focus on building a strong mathematical foundation.</p><p>I believe having a solid math foundation will serve me well for a long and successful career. </p><p>So here&#8217;s what I am doing about it.</p><h2>Quarterly Goals and Tracking</h2><p>For the past year, I've been setting quarterly goals and tracking them using a tracker board that I have right above my monitor.</p><p>This board helps me visualize my progress and stay consistent.</p><p>Over the last six months, I've been able to post weekly videos and newsletters by setting clear goals. My previous quarterly goals included creating 12 videos, writing 12 news articles, losing 5 kilos, and working on specific content.</p><h2>The 12-Week Plan</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l9V8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l9V8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png 424w, https://substackcdn.com/image/fetch/$s_!l9V8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png 848w, https://substackcdn.com/image/fetch/$s_!l9V8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png 1272w, https://substackcdn.com/image/fetch/$s_!l9V8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l9V8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png" width="1456" height="808" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:808,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:155512,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!l9V8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png 424w, https://substackcdn.com/image/fetch/$s_!l9V8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png 848w, https://substackcdn.com/image/fetch/$s_!l9V8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.png 1272w, https://substackcdn.com/image/fetch/$s_!l9V8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31173b01-fff1-4d54-9138-8e320f1e813a_2497x1385.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></p><p>For this quarter, I've divided my 12-week plan into three tracks:</p><ol><li><p><strong>Work Track</strong>: This track takes up 80-90% of my time, roughly 40-50 hours per week. It includes my regular job responsibilities and tasks. The learning in these hours is immense as well, as I read code, documentation of the systems and tools I use, and of course the internet/Google to execute my day-to-day tasks.</p></li><li><p><strong>Latest Trends Track</strong>: I dedicate 4-5 hours per week to stay updated with the latest trends in ML, DL, and GenAI. This involves reading new research papers, exploring new frameworks, and learning about new techniques. I spread this time throughout the week or focus on it during weekends.</p></li><li><p><strong>Learning Track</strong>: This quarter, I'm focusing on resetting my learning by diving deep into the mathematics behind AI. After spending two years in this field, I've realized the importance of understanding the mathematical foundations of algorithms. This knowledge will help me optimize, fine-tune, and (hopefully) conduct deep research in ML and AI.</p></li></ol><h2>Learning Mathematics for AI: 12-Week Plan</h2><p>To build a strong foundation in  Math for AI, I've structured my learning track into a simple 12-week plan. Here's the simple breakdown:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qDHj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qDHj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png 424w, https://substackcdn.com/image/fetch/$s_!qDHj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png 848w, https://substackcdn.com/image/fetch/$s_!qDHj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png 1272w, https://substackcdn.com/image/fetch/$s_!qDHj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qDHj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png" width="1456" height="687" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:687,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:136061,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qDHj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png 424w, https://substackcdn.com/image/fetch/$s_!qDHj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png 848w, https://substackcdn.com/image/fetch/$s_!qDHj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.png 1272w, https://substackcdn.com/image/fetch/$s_!qDHj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53471d98-e367-4cbe-a4cb-a4df0f7862c0_2622x1237.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>Three core topics - Linear Algebra, Calculus, and Probability &amp; Statistics are spread over 12 weeks - with 4 weeks/40 hours dedicated to each.</p><p>Will this make me an expert in Math? </p><p>Definitely not!</p><p>Will I be better at Math than I am today?</p><p>ABSOLUTELY! </p><p>I will share my learnings here every week. Subscribe to the newsletter, if you haven&#8217;t already, to tag along with me.</p><h2>Conclusion</h2><p>This 12-week plan is designed to help me balance my work, stay updated with the latest trends, and deepen my understanding of AI. </p><p>Thank you for joining me on this journey. Stay tuned for updates on my progress and feel free to share your own learning plans in the comments!</p><p>If you have any questions or need further assistance, feel free to ask!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[How Uber Saved 140,000 Hours Monthly Using Generative AI Agents]]></title><description><![CDATA[Video The Problem at Hand]]></description><link>https://newsletter.adaptiveengineer.com/p/how-uber-saved-140000-hours-monthly</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/how-uber-saved-140000-hours-monthly</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Tue, 14 Jan 2025 07:20:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/UPBMkFSJdBI" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Video</h2><div id="youtube2-UPBMkFSJdBI" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;UPBMkFSJdBI&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/UPBMkFSJdBI?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div><hr></div><h2><strong>The Problem at Hand</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Sd22!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Sd22!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Sd22!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Sd22!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Sd22!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Sd22!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg" width="1105" height="520" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:520,&quot;width&quot;:1105,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Sd22!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Sd22!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Sd22!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Sd22!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1131d751-55de-465b-bb12-c0b74cf921e0_1105x520.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg 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>Uber's data platform processes approximately <strong>1.2 million interactive queries monthly</strong>, with 36% of these coming from the operations organization. This group&#8212;comprising engineers, data scientists, and operations professionals&#8212;analyzes data from hundreds of thousands of tables across various domains to derive actionable insights.</p><p>However, the process of composing and executing queries was a bottleneck:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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><ul><li><p><strong>10 minutes per query</strong>: Each actor spent an average of 10 minutes composing a query.</p></li><li><p><strong>Inefficiency Loop</strong>: Users would sift through datasets, run queries, and validate results in a repetitive cycle.</p></li><li><p><strong>Wasted Time</strong>: The cumulative effect of this inefficiency led to significant lost productivity.</p></li></ul><p>This challenge is not unique to Uber. It resonates across industries, from e-commerce to customer support, where operations teams grapple with similar inefficiencies.</p><div><hr></div><h2><strong>Enter QueryGPT: The Hackathon Solution</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4S6y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4S6y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4S6y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4S6y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4S6y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4S6y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg" width="1145" height="492" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:492,&quot;width&quot;:1145,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4S6y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4S6y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4S6y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4S6y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88ef92b8-2fdc-49f3-85dd-389854a2abbe_1145x492.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>In 2023, a team at Uber's hackathon introduced <strong>QueryGPT</strong>, a prototype designed to streamline the query-generation process. Here's how it worked:</p><ol><li><p><strong>Metadata-Driven Query Generation</strong>:</p><ul><li><p>Stored 20 SQL queries with metadata (table and schema information).</p></li><li><p>Mapped natural language prompts to these queries.</p></li></ul></li><li><p><strong>Few-Shot Prompting</strong>:</p><ul><li><p>Used a Retrieval-Augmented Generation (RAG) technique to fetch relevant queries.</p></li><li><p>Generated SQL queries in response to user prompts.</p></li></ul></li><li><p><strong>Initial Results</strong>:</p><ul><li><p>Reduced query composition time from 10 minutes to 3 minutes.</p></li><li><p>Achieved an <strong>18% productivity gain</strong>.</p></li></ul></li></ol><p>While this was a promising start, the prototype faced scalability and technical challenges, necessitating further iterations.</p><div><hr></div><h2><strong>Challenges and Iterative Solutions</strong></h2><h3><strong>Key Challenges</strong></h3><ol><li><p><strong>Prompt-to-Schema Mismatch</strong>:</p><ul><li><p>The system struggled to align user prompts with relevant schemas.</p></li></ul></li><li><p><strong>Token Limitations</strong>:</p><ul><li><p>Some schemas had over 200 columns, leading to token counts exceeding GPT-4's 32k limit.</p></li></ul></li></ol><div><hr></div><h2><strong>The Final Architecture</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5P1L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5P1L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg 424w, https://substackcdn.com/image/fetch/$s_!5P1L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg 848w, https://substackcdn.com/image/fetch/$s_!5P1L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!5P1L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5P1L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg" width="1165" height="580" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:580,&quot;width&quot;:1165,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5P1L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg 424w, https://substackcdn.com/image/fetch/$s_!5P1L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg 848w, https://substackcdn.com/image/fetch/$s_!5P1L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!5P1L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85d6835e-f86b-4b23-beab-2b4dadbf4a81_1165x580.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>The refined system, powered by <strong>Azure OpenAI and GPT-4</strong>, demonstrated remarkable efficiency:</p><ul><li><p><strong>Context Optimization</strong>: Leveraged a context window of 128k tokens to handle large schemas.</p></li><li><p><strong>Human Validation</strong>: Ensured precision through user acknowledgment of suggested tables.</p></li><li><p><strong>Scalable Design</strong>: Addressed the challenge of querying across hundreds of thousands of datasets.</p></li></ul><p>Uber's engineering team implemented a robust architecture combining <strong>SQL, RAG, agents, and custom configurations</strong>. Here's a breakdown:</p><ol><li><p><strong>Domain-Specific Curation</strong>:</p><ul><li><p>Decomposed datasets into <strong>business domains/workflows</strong> (e.g., mobility, trips, support).</p></li><li><p>Allowed the system to focus on smaller, relevant subsets of data.</p></li></ul></li><li><p><strong>Intent Agent</strong>:</p><ul><li><p>Classified user prompts to map them to the appropriate domain or workspace.</p></li><li><p>Likely employed a vector-store-based intent classifier for high accuracy.</p></li></ul></li><li><p><strong>Table Agent</strong>:</p><ul><li><p>Retrieved domain-specific tables and displayed them in a user-friendly interface.</p></li><li><p>Enabled human-in-the-loop validation to ensure table relevance.</p></li></ul></li><li><p><strong>Enhanced RAG Pipeline</strong>:</p><ul><li><p>Generated few-shot prompts tailored to the specific domain.</p></li><li><p>Sent refined prompts to GPT-4 for SQL query generation.</p></li></ul></li></ol><h3><strong>Real-World Impact</strong></h3><p>By the 20th iteration, Uber's Query GPT achieved a staggering <strong>140,000 hours saved monthly</strong> across its operations organization. This success underscores the value of combining AI, domain-specific curation, and user-centric design.</p><div><hr></div><h2><strong>Key Takeaways for Your Business</strong></h2><p>Uber's solution offers valuable insights for tackling similar challenges in other industries:</p><ol><li><p><strong>Break Down Data Silos</strong>:</p><ul><li><p>Organize datasets by business domains to streamline data retrieval.</p></li></ul></li><li><p><strong>Implement Intent Detection</strong>:</p><ul><li><p>Use AI-driven agents to map user queries to relevant datasets or workspaces.</p></li></ul></li><li><p><strong>Leverage Human-in-the-Loop Systems</strong>:</p><ul><li><p>Involve users in validating AI-generated outputs for enhanced accuracy.</p></li></ul></li><li><p><strong>Iterate for Scalability</strong>:</p><ul><li><p>Start small, learn from challenges, and scale iteratively.</p></li></ul></li></ol><div><hr></div><h2><strong>The Future of AI in Operations</strong></h2><p>Uber's journey with QueryGPT exemplifies the transformative potential of generative AI in operational analytics. By reducing manual effort and empowering teams with intelligent tools, businesses can unlock unprecedented productivity gains.</p><p>Whether you're in e-commerce, customer support, or any data-intensive field, the principles behind Uber's success can guide your own AI-driven innovations.</p><p>Want to delve deeper into the technical details? Check out Uber's engineering blog <strong><a href="https://www.uber.com/en-TW/blog/query-gpt/">here</a></strong> for the full story.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[A Deep Dive into Google's "Agents" White Paper: Hype or Revolution?]]></title><description><![CDATA[Video Google's recent white paper on "Agents" has created quite a buzz.]]></description><link>https://newsletter.adaptiveengineer.com/p/a-deep-dive-into-googles-agents-white</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/a-deep-dive-into-googles-agents-white</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Fri, 10 Jan 2025 07:42:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/FgRGwnpd2HY" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Video</h2><div id="youtube2-FgRGwnpd2HY" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;FgRGwnpd2HY&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/FgRGwnpd2HY?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Google's recent white paper on "Agents" has created quite a buzz.</p><p>The paper explores the concept of AI agents and delves into their architecture and potential. Let's break down what this white paper offers, its key takeaways, and some areas where it could improve.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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><strong>The Marketing Angle: A Platform-Centric View?</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ciNL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ciNL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ciNL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ciNL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ciNL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ciNL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg" width="1456" height="912" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:912,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ciNL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ciNL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ciNL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ciNL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e2ac0b6-b96a-4a3d-9054-fcf74beb01d4_2577x1615.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg 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>At first glance, the white paper feels like a marketing tool for Google's <strong>Vertex AI</strong>. And that's perfectly fine&#8212;after all, companies often use such publications to showcase their platforms.</p><p>However, adopting a more <strong>platform-agnostic</strong> approach could have made the paper more universally applicable.</p><p>For instance, many examples in the white paper are tied to <strong>Vertex AI-specific features</strong>, which might be unfamiliar to those using other agentic frameworks.</p><p>Additionally, certain concepts, like extensions, are introduced but not elaborated on in sufficient detail, leaving room for better documentation and clarity.</p><p>Despite these limitations, the paper provides a solid starting point for understanding agents. Let&#8217;s dive into the key concepts.</p><div><hr></div><h2><strong>What is an Agent?</strong></h2><p>Google defines an agent as:</p><blockquote><p><em><strong>"An application that attempts to achieve a goal by observing the world and acting upon it using the tools at its disposal."</strong></em></p></blockquote><p>This definition is both simple and powerful. It captures the essence of what an agent is without overcomplicating things. While many experts on platforms like LinkedIn and YouTube often layer terms like reasoning, context awareness, and more onto the definition, the core idea remains straightforward.</p><p>Interestingly, my personal favorite definition comes from Hugging Face, which describes AI agents as:</p><blockquote><p><em><strong>"Programs where LLM outputs control the workflows."</strong></em></p></blockquote><p>This succinctly highlights the operational dynamics of agents, especially when integrated with language models.</p><div><hr></div><h2><strong>The Agentic Architecture: Core Components</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0AJO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0AJO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0AJO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0AJO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0AJO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0AJO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg" width="1456" height="937" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:937,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0AJO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0AJO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0AJO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0AJO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8cecfbb9-32cb-408d-b7c6-7a144a54da96_2330x1500.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>The white paper also details the architecture of agents, a topic I&#8217;ve previously discussed on my channel. Here's a simplified breakdown of the <strong>three primary components</strong> that define an agentic system:</p><h3><strong>1. The Model</strong></h3><p>At the heart of any agent lies a <strong>language model</strong>. This serves as the foundation for the agent's intelligence and capabilities. Trained on extensive datasets, the model enables the agent to comprehend language, process instructions, and provide knowledge.</p><p>In an agentic framework, the model is not just a passive responder. Its capabilities drive the decision-making processes within the orchestration layer.</p><h3><strong>2. The Tools</strong></h3><p>Tools are what set agents apart from simple LLM calls. Since LLMs are inherently limited&#8212;they can&#8217;t interact with external systems or access real-time information&#8212;tools extend their capabilities.</p><p>Agents use tools to interact with the external world, making them more dynamic and useful. Frameworks like <strong>LangChain</strong> and <strong>LlamaIndex</strong> exemplify how tools can augment the performance of agentic systems, enabling them to achieve their goals effectively.</p><h3><strong>3. The Orchestration Layer</strong></h3><p>Often referred to as the <strong>reasoning loop</strong>, this layer governs the agent's ability to:</p><ul><li><p><strong>Plan</strong>: Decide the next steps in a workflow.</p></li><li><p><strong>Reason</strong>: Analyze the gathered information.</p></li><li><p><strong>Execute</strong>: Take action based on the plan.</p></li></ul><p>This iterative process is the backbone of an agent&#8217;s functionality, ensuring it can adapt and respond intelligently to various scenarios.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!S2FR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!S2FR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg 424w, https://substackcdn.com/image/fetch/$s_!S2FR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg 848w, https://substackcdn.com/image/fetch/$s_!S2FR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!S2FR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!S2FR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg" width="1456" height="871" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg&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;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!S2FR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg 424w, https://substackcdn.com/image/fetch/$s_!S2FR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg 848w, https://substackcdn.com/image/fetch/$s_!S2FR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!S2FR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd96a4ed0-acfa-4819-85d8-fb0003cfaa49_2660x1592.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><h2><strong>Tools (Key Takeaways)</strong></h2><ol><li><p><strong>Extensions</strong></p><ul><li><p><strong>Definition</strong>: Extensions are interfaces that bridge the gap between APIs and agents. They allow for seamless API execution by teaching agents how to use APIs via examples.</p></li><li><p><strong>Use Case</strong>: Extensions are ideal for scenarios where the agent needs to dynamically interact with APIs like booking flights or fetching weather data. They reduce ambiguity in API calls by guiding the agent with context and examples.</p></li><li><p><strong>Your Example</strong>: Your custom tool implementation fits here because it defines tools with a name and description, guiding the LLM to invoke the correct tool and arguments based on context.</p></li></ul></li><li><p><strong>Functions</strong></p><ul><li><p><strong>Definition</strong>: Functions are reusable logic modules that allow developers to define behavior and handle specific tasks.</p></li><li><p><strong>Difference</strong>: Unlike extensions, functions offload API execution to client-side logic or middleware, especially in cases where security or authentication constraints prevent direct calls from the LLM.</p></li><li><p><strong>Your Observations</strong>: Google's distinction clarifies that functions give developers fine-grained control and decouple execution from the agent, making iteration easier without redeploying infrastructure.</p></li></ul></li></ol><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Master These Skills to Dominate 2025]]></title><description><![CDATA[Today I want to share something I deeply believe will shape the future of software engineering.]]></description><link>https://newsletter.adaptiveengineer.com/p/master-these-skills-to-dominate-2025</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/master-these-skills-to-dominate-2025</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Tue, 31 Dec 2024 05:05:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/6e0U8i3bGz8" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today I want to share something I deeply believe will shape the future of software engineering.</p><p>As we approach 2025, there are rapid advancements in technology that we, as engineers, cannot afford to ignore. Whether you&#8217;re looking to add value to your organization, grow your skillset, or simply future-proof your career, there are certain core skills that will set you apart.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>Let&#8217;s dive right in.</p><div><hr></div><h2>Video</h2><div id="youtube2-6e0U8i3bGz8" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;6e0U8i3bGz8&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/6e0U8i3bGz8?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div><hr></div><h2><strong>The New Baseline: AI and Business Context Understanding</strong></h2><p>Gone are the days when being a full-stack engineer meant just knowing how to develop and deploy applications. Today, understanding the "why" behind what you&#8217;re building is just as important as the "how."</p><p>If you find yourself working on user stories without knowing the business context or understanding the decisions made by your engineering or product managers, it&#8217;s time to rethink your approach.</p><p>Business understanding is what differentiates an average engineer from a great one.</p><p>And as AI continues to integrate into every facet of technology, this understanding will become even more critical.</p><p>Here&#8217;s my take on the essential skills every full-stack engineer should master to thrive in this new era.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mPpc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mPpc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mPpc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mPpc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mPpc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mPpc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg" width="1456" height="734" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:734,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mPpc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mPpc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mPpc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mPpc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6095552-c0e4-46da-b457-604d3bdd9840_2717x1370.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><h2><strong>1. Core AI/ML Engineering Skills</strong></h2><h3><strong>Large Language Models (LLMs)</strong></h3><p>By now, you&#8217;ve probably experimented with tools like ChatGPT or integrated APIs into your projects. But to truly excel, you need to:</p><ul><li><p>Understand how LLMs work at a deeper level.</p></li><li><p>Learn about fine-tuning models for specific use cases.</p></li><li><p>Master <strong>prompt engineering</strong> &#8211; arranging instructions in ways that yield the best results.</p></li></ul><h4><strong>Retrieval-Augmented Generation (RAG)</strong></h4><p>RAG will remain indispensable for enterprise applications, even as LLMs handle increasingly large context windows. Why? Because RAG ensures that only the most relevant data is fed into the model, optimizing performance and cost. Gaining expertise in designing RAG pipelines and integrating them with business workflows is a must.</p><h4><strong>AI Agents</strong></h4><p>The buzzword for 2025 is "agents." Multi-agent frameworks and systems are set to revolutionize how we build solutions. Understanding how to design and orchestrate these systems will keep you ahead of the curve.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Xd9T!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Xd9T!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Xd9T!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Xd9T!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Xd9T!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Xd9T!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg" width="1456" height="703" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:703,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Xd9T!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Xd9T!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Xd9T!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Xd9T!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7fe0ca8-d817-479f-b457-a1f45d35ce3d_2717x1312.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><h3><strong>2. Technical Stack Mastery</strong></h3><h4><strong>Python: The Go-To Language</strong></h4><p>Python&#8217;s ecosystem for AI and ML is unparalleled. From frameworks like PyTorch and scikit-learn to tools like LangChain and LlamaIndex, Python should be in every engineer&#8217;s toolkit. If you&#8217;re new to the space, start experimenting with these frameworks.</p><h4><strong>Cloud Platforms and Vector Databases</strong></h4><ul><li><p>Familiarize yourself with cloud platforms like AWS, Azure, or GCP, and tools like VMware Tanzu.</p></li><li><p>Learn about vector databases, such as PGVector, which allow efficient storage and retrieval of embeddings. Even spinning up a simple Docker instance can give you hands-on experience.</p></li></ul><h4><strong>API Development</strong></h4><p>Frameworks like FastAPI and Flask make it easier to create and deploy AI-powered web applications. Combine this with an understanding of socket programming for real-time communication tools like chatbots, and you&#8217;ll be unstoppable.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n8nh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n8nh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg 424w, https://substackcdn.com/image/fetch/$s_!n8nh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg 848w, https://substackcdn.com/image/fetch/$s_!n8nh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!n8nh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n8nh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg" width="1456" height="444" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:444,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!n8nh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg 424w, https://substackcdn.com/image/fetch/$s_!n8nh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg 848w, https://substackcdn.com/image/fetch/$s_!n8nh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!n8nh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb11e4243-dd7d-42e5-a85f-e06767a4025f_2715x827.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><h3><strong>3. Project and Professional Skills</strong></h3><h4><strong>Business Context Awareness</strong></h4><p>This is the game-changer. Knowing how your application aligns with business goals will not only make you a better engineer but also ensure your contributions are recognized. Always ask:</p><ul><li><p>Why is this feature important?</p></li><li><p>How will this decision impact the user or business?</p></li></ul><h4><strong>Experimentation Over Perfection</strong></h4><p>Start small. Use APIs to create prototypes and simulate workflows. For instance:</p><ul><li><p>Identify areas in your organization where generative AI can add value.</p></li><li><p>Build mock solutions with sample data to prove concepts.</p></li></ul><h4><strong>MLOps and Deployment</strong></h4><p>Understanding MLOps tools and practices is becoming essential for deploying AI solutions. Even if you&#8217;re not directly managing infrastructure, knowing how to streamline deployment pipelines will make you invaluable to your team.</p><div><hr></div><h3><strong>My Journey: From Experimentation to Mastery</strong></h3><p>When I transitioned into AI engineering in early 2023, I didn&#8217;t start by mastering machine learning fundamentals. Instead, I began tinkering with LLM APIs and building prototypes. This hands-on experimentation allowed me to solve real-world problems while gradually deepening my knowledge of ML fundamentals over the next six months.</p><p>This approach worked wonders for me, and I recommend it to anyone looking to enter the field. Don&#8217;t get bogged down by theory. Instead, balance learning with application. Keep a 60/40 or even 50/50 ratio between theory and practice to maximize your growth.</p><div><hr></div><h3><strong>Final Thoughts</strong></h3><p>The expectations for full-stack engineers are evolving, and AI skills are no longer optional.</p><p>By mastering core AI/ML engineering concepts, staying updated with the latest frameworks, and understanding business context, you&#8217;ll position yourself as a leader in your field.</p><p>So, what&#8217;s your game plan for 2025? Let me know in the comments below. And if you&#8217;re ready to start tinkering, I&#8217;ve got tons of tutorials on my channel to help you get started. Until next time, happy coding!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Why Jinja Rules Prompt Engineering & Building Price Monitoring Agent - Full Tutorial]]></title><description><![CDATA[Colab Notebook: colab.research.google.com/drive/18nzaXc7__K..]]></description><link>https://newsletter.adaptiveengineer.com/p/why-jinja-rules-prompt-engineering</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/why-jinja-rules-prompt-engineering</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Sun, 22 Dec 2024 13:53:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/Rq2zM7_5yw0" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Colab Notebook:</strong> <strong><a href="https://colab.research.google.com/drive/18nzaXc7__KDYaPSRyf2mZyCK_pj4ON26">colab.research.google.com/drive/18nzaXc7__K..</a></strong></p><div id="youtube2-Rq2zM7_5yw0" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;Rq2zM7_5yw0&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/Rq2zM7_5yw0?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Dynamic prompt generation has become a cornerstone of modern AI workflows.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>Whether you're building personalized email campaigns, travel itineraries, or AI-driven recommendations, the ability to generate structured content dynamically is invaluable.</p><p>In this blog, we'll explore how <strong>Jinja2</strong>, a powerful templating engine, stands out in this domain and compare it with tools like LangChain for crafting dynamic prompts.</p><div><hr></div><h2><strong>Why Dynamic Prompting Matters</strong></h2><p>If you are building an AI assistant tasked with creating personalized travel itineraries or summarizing user activities, static prompts won't cut it here &#8211; you need templates that adapt to the data at hand. This is where tools like <strong>Jinja2</strong> and LangChain's prompt templates shine.</p><div><hr></div><h2><strong>Jinja2: The All-Rounder for Dynamic Templates</strong></h2><p>Jinja2 is a versatile templating engine widely known for its use in web development but equally adept at generating dynamic text for emails, reports, and prompts. Here's why Jinja2 should be in your toolkit:</p><h3><strong>1. Seamless Integration of Logic</strong></h3><p>Jinja2 allows you to embed loops, conditionals, and filters directly in your templates. For example, creating tailored recommendations becomes straightforward:</p><pre><code><code>Dear {{ user_name }},

Here&#8217;s a summary of your recent activities:
{% for activity in activities %}
- On {{ activity.date }}: {{ activity.description }}
{% endfor %}

{% if status == "pass" %}
Congratulations on passing the test. Keep up the great work!
{% else %}
Keep trying, and you'll get there!
{% endif %}
</code></code></pre><h3><strong>2. Readable and Reusable</strong></h3><p>With its clean syntax, Jinja2 makes templates easy to maintain and reuse across projects. It's perfect for use cases like:</p><ul><li><p>Personalized emails</p></li><li><p>Travel itineraries</p></li><li><p>AI-driven content generation</p></li></ul><h3><strong>3. Performance Efficiency</strong></h3><p>Jinja2 minimizes overhead, making it an excellent choice for applications requiring rapid dynamic rendering.</p><div><hr></div><h2><strong>Comparing Jinja2 and LangChain for Prompt Templates</strong></h2><p>While Jinja2 excels in general-purpose dynamic content generation, LangChain's <code>PromptTemplate</code> is specifically designed for AI workflows, making it the go-to for LLM integrations.</p><h3><strong>LangChain Example:</strong></h3><pre><code><code>from langchain.prompts import PromptTemplate

template = """
Dear {user_name},

Here&#8217;s a summary of your recent activities:
{activities}

Here are some tailored recommendations for you:
{recommendations}

{closing_note}
"""

prompt = PromptTemplate(
    input_variables=["user_name", "activities", "recommendations", "closing_note"],
    template=template,
)

email = prompt.format(
    user_name="Alice",
    activities="- Completed the Python course.\n- Joined the AI workshop.",
    recommendations="- Read 'Deep Learning for Beginners'.\n- Join the Advanced AI Projects Club.",
    closing_note="Congratulations on passing the test!",
)

print(email)
</code></code></pre><h3><strong>Key Differences:</strong></h3><ul><li><p><strong>Flexibility</strong>: Jinja2 supports complex logic directly in the template, while LangChain separates logic and content.</p></li><li><p><strong>AI Integration</strong>: LangChain is optimized for workflows where prompts are fed into LLMs.</p></li><li><p><strong>Learning Curve</strong>: Jinja2 has a gentler curve for general developers, whereas LangChain is ideal for those already in the AI ecosystem.</p></li></ul><div><hr></div><h2><strong>Real-World Use Case: Personalized Travel Itineraries</strong></h2><p>Using Jinja2, you can craft luxurious travel experiences tailored to user preferences. Here's an example:</p><h3><strong>Input Data</strong></h3><pre><code><code>codeinput_data = {
    "name": "John Doe",
    "destination": "Paris, France",
    "interests": ["art", "history", "fine dining"],
    "travel_type": "luxury",
    "suggested_activities": [
        {"name": "Private Louvre Tour", "description": "Explore iconic art pieces with a guide."},
        {"name": "Seine River Dinner Cruise", "description": "Enjoy a gourmet dinner on a Seine cruise."},
    ],
    "recommended_accommodations": [
        {"name": "Le Meurice", "description": "5-star luxury hotel with Michelin dining."},
    ],
}
</code></code></pre><h3><strong>Jinja2 Template</strong></h3><pre><code><code> """
Traveler Profile:
- Name: {{ name }}
- Age: {{ age }}
- Travel Dates: {{ travel_dates }}
- Travel Destination: {{ destination }}
- Interests: {{ interests|join(", ") }}

{% if travel_type == 'luxury' %}
The traveler prefers a luxury experience. Suggest the following premium activities and accommodations:
{% elif travel_type == 'adventure' %}
The traveler seeks adventure. Recommend these thrilling activities and adventurous destinations:
{% else %}
The traveler is interested in a balanced experience. Consider these activities and attractions:
{% endif %}

{% for activity in suggested_activities %}
- {{ activity.name }}: {{ activity.description }}
  {% if activity.requirements %}
  Requirements: {{ activity.requirements|join(", ") }}
  {% endif %}
{% endfor %}

{% if recommended_accommodations %}
Recommended Accommodations:
{% for accommodation in recommended_accommodations %}
- {{ accommodation.name }}: {{ accommodation.description }}
  Location: {{ accommodation.location }}
  Amenities: {{ accommodation.amenities|join(", ") }}
{% endfor %}
{% endif %}

Traveler's Notes:
{% if traveler_notes %}
{% for note in traveler_notes %}
- {{ note }}
{% endfor %}
{% endif %}

Based on the above information, create a 3-day itinerary tailored to the traveler&#8217;s preferences and needs. Ensure activities, meals, and downtime are appropriately balanced.
""
</code></code></pre><h3><strong>Output</strong></h3><pre><code><code>Traveler Profile:
- Name: John Doe
- Age: 35
- Travel Dates: 2024-01-15 to 2024-01-18
- Travel Destination: Paris, France
- Interests: art, history, fine dining, luxury shopping


The traveler prefers a luxury experience. Suggest the following premium activities and accommodations:



- Private Louvre Tour: Enjoy a private, guided tour of the Louvre Museum, exploring its iconic art pieces.

  Requirements: Comfortable walking shoes, Museum pass


- Seine River Dinner Cruise: Experience a luxurious evening with a gourmet dinner on a Seine River cruise.

  Requirements: Formal attire


- Champs-&#201;lys&#233;es Shopping Tour: Indulge in a day of shopping at high-end boutiques along the Champs-&#201;lys&#233;es.




Recommended Accommodations:

- Le Meurice: A 5-star luxury hotel offering Michelin-star dining and exceptional service.
  Location: Rue de Rivoli, Paris
  Amenities: Spa, Fine dining, Concierge service

- H&#244;tel Plaza Ath&#233;n&#233;e: Iconic Parisian hotel with stunning views of the Eiffel Tower.
  Location: Avenue Montaigne, Paris
  Amenities: Luxury suites, Haute couture stores, Gourmet restaurants



Traveler's Notes:


- Has dietary restrictions: no shellfish.

- Prefers private tours over group activities.



Based on the above information, create a 3-day itinerary tailored to the traveler&#8217;s preferences and needs. Ensure activities, meals, and downtime are appropriately balanced.
</code></code></pre><div><hr></div><h1>Price Monitoring Agent | Part 2 | Full Tutorial</h1><p>I published a full video tutorial on building a Price Monitoring Agent using Pydantic AI. I accomplished the below goal.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MZqm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MZqm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MZqm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg" width="1456" height="866" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:866,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MZqm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.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><div id="youtube2-qaVIkk9M6Pg" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;qaVIkk9M6Pg&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/qaVIkk9M6Pg?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h2></h2><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[How to Build a Price Monitoring Agent with Pydantic AI]]></title><description><![CDATA[Part 1 of the Pydantic AI series]]></description><link>https://newsletter.adaptiveengineer.com/p/how-to-build-a-price-monitoring-agent</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/how-to-build-a-price-monitoring-agent</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Mon, 16 Dec 2024 06:19:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/hlropi13fO8" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Video Tutorial</h2><div id="youtube2-hlropi13fO8" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;hlropi13fO8&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/hlropi13fO8?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p></p><p>Keeping track of fluctuating product prices across e-commerce platforms can be a daunting task.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>Whether you're tracking a personal wishlist or monitoring competitors' pricing for your business, automating this process can save time and effort.</p><p>In this guide, we&#8217;ll explore how to build a <strong>price monitoring agent</strong> using the <strong>Pydantic AI framework</strong>&#8212;a robust agentic framework from the creators of Pantic, a popular data validation library.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MZqm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MZqm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MZqm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg" width="1456" height="866" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:866,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MZqm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MZqm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9551a54-440d-431b-9d81-a390bdea3fa8_2155x1282.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg 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 tutorial is part one of a series. Today, we&#8217;ll focus on building a scraper agent to extract key product details like title, description, price, and more.</p><p>In the next part, we&#8217;ll expand this agent to store data in a database and send notifications for price changes.</p><div><hr></div><h2><strong>What is Pydantic AI?</strong></h2><p><strong><a href="https://ai.pydantic.dev/">Pydantic AI</a></strong> is revolutionizing the way developers build applications that leverage Generative AI. As a Python Agent Framework, it simplifies the creation of production-grade applications by integrating robust data validation with the power of LLMs. Here&#8217;s why Pydantic AI stands out:</p><ul><li><p><strong>Built on Proven Foundations</strong>: Developed by the creators of Pydantic, which is widely used in various AI frameworks like OpenAI and LangChain, Pydantic AI inherits a strong legacy of type safety and structured data management.</p></li><li><p><strong>Model-Agnostic Flexibility</strong>: Currently supporting models like OpenAI, Gemini, and Groq, Pydantic AI allows developers to easily implement support for additional models through a simple interface. This flexibility ensures that your application can adapt to various AI technologies without significant overhead.</p></li><li><p><strong>Enhanced Developer Experience</strong>: With features like vanilla Python control flow and a novel dependency injection system, Pydantic AI empowers developers to apply familiar coding practices. This leads to more maintainable code and a smoother development process.</p></li><li><p><strong>Streamlined Response Validation</strong>: The framework not only validates incoming data but also ensures that responses from LLMs are structured and validated, enhancing reliability in application behavior.</p></li></ul><div><hr></div><h2><strong>Overview of the Price Monitoring Agent</strong></h2><p>Our agent will:</p><ol><li><p>Scrape product details (title, description, price, currency, and image URL) from a given URL.</p></li><li><p>Parse the information into a structured format.</p></li><li><p>Prepare for database storage and notification handling (to be implemented in part two).</p></li></ol><p>Here&#8217;s how the process works (diagram above)</p><ol><li><p><strong>Input</strong>: Product page URL</p></li><li><p><strong>Scraper Tool</strong>: Extracts structured data using Beautiful Soup and Markdownify.</p></li><li><p><strong>Agent</strong>: Processes the scraped data using Pydantic AI for type-safe responses.</p></li></ol><h2>Code</h2><p>https://colab.research.google.com/drive/1wEFO0_W13J_DBtjd55vNK7vQa_UGo7Hm#scrollTo=3O2V5Jth2Q8F</p><p>To be continued in Part 2</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Building a Multi-Agent Orchestrator: A Step-by-Step Guide]]></title><description><![CDATA[If you prefer watching a video.]]></description><link>https://newsletter.adaptiveengineer.com/p/building-a-multi-agent-orchestrator</link><guid isPermaLink="false">https://newsletter.adaptiveengineer.com/p/building-a-multi-agent-orchestrator</guid><dc:creator><![CDATA[Zahiruddin Tavargere]]></dc:creator><pubDate>Fri, 06 Dec 2024 14:02:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/5CDlqSLlPlU" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you prefer watching a video.</p><div id="youtube2-5CDlqSLlPlU" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;5CDlqSLlPlU&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/5CDlqSLlPlU?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Today, we&#8217;re diving into an exciting project: <strong>creating a Multi-Agent Orchestrator</strong>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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><strong><a href="https://zahere.com/how-to-build-an-ai-agent-without-using-any-libraries-a-step-by-step-guide">This post is an extension of my earlier guide, </a></strong><em><strong><a href="https://zahere.com/how-to-build-an-ai-agent-without-using-any-libraries-a-step-by-step-guide">"Building an AI Agent from Scratch."</a></strong></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_!Npf-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Npf-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Npf-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Npf-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Npf-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Npf-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg" width="1456" height="791" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:791,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Npf-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Npf-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Npf-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Npf-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb34e4998-fb94-486f-bec2-1ac70c0b65c6_2430x1320.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg 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>If you&#8217;re new here, I recommend revisiting that post to get up to speed, as we&#8217;ll build upon its concepts and code.</p><p>In this project, we&#8217;ll tackle orchestrating actions between multiple agents, enabling seamless execution of tasks such as fetching weather information and the current time. Let&#8217;s jump in!</p><div><hr></div><h3><strong>What Is a Multi-Agent Orchestrator?</strong></h3><p>A Multi-Agent Orchestrator is a system that:</p><ol><li><p><strong>Identifies the intent</strong> of a user&#8217;s input.</p></li><li><p><strong>Selects the appropriate agent</strong> to handle the request.</p></li><li><p><strong>Executes tasks</strong> using tools associated with the agent.</p></li></ol><p>Think of it as a manager assigning tasks to specialized team members. This orchestration ensures complex queries involving multiple tasks are handled efficiently.</p><div><hr></div><h3><strong>What We&#8217;ll Build</strong></h3><p>We&#8217;ll create:</p><ul><li><p><strong>Agents</strong>: Specialized entities to handle tasks like fetching weather or time.</p></li><li><p><strong>Tools</strong>: Functional utilities for the agents, such as APIs or database queries.</p></li><li><p><strong>Orchestrator</strong>: The central system managing task delegation and execution.</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_!hrPL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hrPL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hrPL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hrPL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hrPL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hrPL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg" width="1456" height="859" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:859,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hrPL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hrPL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hrPL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hrPL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6eb9abe2-b5c9-4f58-9015-bd9d3fd07a73_2315x1365.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><div><hr></div><h3><strong>Key Components of an Agent</strong></h3><p>An agent has three main components:</p><ol><li><p><strong>Reasoning Loop</strong>: Decides the next action based on context.</p></li><li><p><strong>Model</strong>: Uses a language model (LLM) for decision-making.</p></li><li><p><strong>Tools</strong>: A list of utilities to perform specific tasks.</p></li></ol><p>Our agents will dynamically decide which tool to use, making them highly adaptable.</p><div><hr></div><h3><strong>The Agent Class</strong></h3><p>Here&#8217;s a high-level breakdown of the <code>Agent</code> class:</p><ul><li><p><strong>Constructor</strong>: Initializes the agent with a name, description, tools, and an LLM model.</p></li><li><p><strong>Process Input</strong>: Takes user input, decides on a tool, and executes the task.</p></li><li><p><strong>Prompting</strong>: Constructs a prompt for the LLM to guide decision-making.</p></li></ul><p>Agents also handle parsing JSON responses from the LLM to ensure smooth execution.</p><pre><code><code>from abc import ABC, abstractmethod
import ast
import os
import requests
from llm.llm_ops import query_llm
from tools.base_tool import Tool
import json


class Agent:
    def __init__(self, Name: str, Description: str, Tools: list, Model: str):        
        self.memory = []
        self.name = Name
        self.description = Description
        self.tools = Tools
        self.model = Model
        self.max_memory = 10

    def json_parser(self, input_string):

      print(type(input_string))

      python_dict = ast.literal_eval(input_string)
      json_string = json.dumps(python_dict)
      json_dict = json.loads(json_string)

      if isinstance(json_dict, dict) or isinstance(json_dict,list):
        return json_dict

      raise "Invalid JSON response"

    def process_input(self, user_input):
        self.memory.append(f"User: {user_input}")
        12

        context = "\n".join(self.memory)
        tool_descriptions = "\n".join([f"- {tool.name()}: {tool.description()}" for tool in self.tools])
        response_format = {"action":"", "args":""}

        prompt = f"""Context:
        {context}

        Available tools:
        {tool_descriptions}

        Based on the user's input and context, decide if you should use a tool or respond directly.        
        If you identify a action, respond with the tool name and the arguments for the tool.        
        If you decide to respond directly to the user then make the action "respond_to_user" with args as your response in the following format.

        Response Format:
        {response_format}

        """

        response = query_llm(prompt)
        self.memory.append(f"Agent: {response}")

        response_dict = self.json_parser(response)

        # Check if any tool can handle the input
        for tool in self.tools:
            if tool.name().lower() == response_dict["action"].lower():
                return tool.use(response_dict["args"])

        return response_dict
</code></code></pre><div><hr></div><h3><strong>The Orchestrator</strong></h3><p>The orchestrator coordinates multiple agents:</p><ol><li><p>Accepts user input.</p></li><li><p>Selects the right agent based on the intent.</p></li><li><p>Manages task execution, including cases where multiple tasks are requested.</p></li></ol><p><strong>Core Features of the Orchestrator</strong>:</p><ul><li><p>Maintains context by storing user queries, agent responses, and intermediate results.</p></li><li><p>Uses a reasoning loop to determine the next steps.</p></li><li><p>Constructs prompts to guide the LLM in selecting the right agent and tools.</p></li></ul><pre><code><code>import ast
import json
from llm.llm_ops import query_llm
from agents.base_agent import Agent
from logger import log_message

class AgentOrchestrator:
    def __init__(self, agents: list[Agent]):
        self.agents = agents
        self.memory = []  # Stores the reasoning and action steps taken
        self.max_memory = 10

    def json_parser(self, input_string):

      print(type(input_string))

      python_dict = ast.literal_eval(input_string)
      json_string = json.dumps(python_dict)
      json_dict = json.loads(json_string)

      if isinstance(json_dict, dict) or isinstance(json_dict,list):
        return json_dict

      raise "Invalid JSON response"

    def orchestrate_task(self, user_input: str):        
        self.memory = self.memory[-self.max_memory:]

        context = "\n".join(self.memory)

        print(f"Context: {context}")

        response_format = {"action":"", "input":"", "next_action":""}

        def get_prompt(user_input):
            return f"""

                Use the context from memory to plan next steps.                
                Context:
                {context}

                You are an expert intent classifier.
                You need will use the context provided and the user's input to classify the intent select the appropriate agent.                
                You will rewrite the input for the agent so that the agent can efficiently execute the task.                                                

                Here are the available agents and their descriptions:
                {", ".join([f"- {agent.name}: {agent.description}" for agent in self.agents])}

                User Input:
                {user_input}              

                ###Guidelines###
                - Sometimes you might have to use multiple agent's to solve user's input. You have to do that in a loop.
                - The original userinput could have multiple tasks, you will use the context to understand the previous actions taken and the next steps you should take.
                - Read the context, take your time to understand, see if there were many tasks and if you executed them all
                - If there are no actions to be taken, then make the action "respond_to_user" with your final thoughts combining all previous responses as input.
                - Respond with "respond_to_user" only when there are no agents to select from or there is no next_action
                - You will return the agent name in the form of {response_format}
                - Always return valid JSON like {response_format} and nothing else.                

                """


        response = ""
        loop_count = 0
        self.memory = self.memory[-10:]        
        prompt = get_prompt(user_input)
        llm_response = query_llm(prompt)

        llm_response = self.json_parser(llm_response)
        print(f"LLM Response: {llm_response}")

        self.memory.append(f"Orchestrator: {llm_response}")


        action=  llm_response["action"]
        user_input = llm_response["input"]

        print(f"Action identified by LLM: {action}")


        if action == "respond_to_user":
            return llm_response
        for agent in self.agents:
            if agent.name == action:
                print("*******************Found Agent Name*******************************")
                agent_response = agent.process_input(user_input)
                print(f"{action} response: {agent_response}")
                self.memory.append(f"Agent Response for Task: {agent_response}")
                print(self.memory)
                return agent_response                


    def run(self):
        print("LLM Agent: Hello! How can I assist you today?")
        user_input = input("You: ")
        self.memory.append(f"User: {user_input}")

        while True:            
            if user_input.lower() in ["exit", "bye", "close"]:
                print("See you later!")
                break

            response = self.orchestrate_task(user_input)
            print(f"Final response of orchestrator {response}")
            if isinstance(response, dict) and response["action"] == "respond_to_user":                
                log_message(f"Reponse from Agent: {response["input"]}", "RESPONSE")
                user_input = input("You: ")
                self.memory.append(f"User: {user_input}")                
            elif response == "No action or agent needed":
                print("Reponse from Agent: ", response)
                user_input = input("You: ")
            else:
                user_input = response
</code></code></pre><div><hr></div><h3><strong>Tools in Action</strong></h3><p>Agents use tools to perform tasks. For example:</p><ul><li><p><strong>Weather Tool</strong>: Fetches real-time weather data from OpenWeatherMap.</p></li><li><p><strong>Time Tool</strong>: Determines the local time for a given city, even without a timezone.</p></li></ul><p>Each tool includes:</p><ul><li><p>A <strong>name</strong> and <strong>description</strong> to guide the LLM.</p></li><li><p>A <strong>use method</strong> to perform the task.</p></li></ul><pre><code><code>import os
import requests
from tools.base_tool import Tool

class WeatherTool(Tool):
    def name(self):
        return "Weather Tool"

    def description(self):
        return "Provides weather information for a given location. The payload is just the location. Example: New York"

    def use(self, location:str):        
        api_key = os.getenv("OPENWEATHERMAP_API_KEY")
        url = f"http://api.openweathermap.org/data/2.5/weather?q={location}&amp;appid={api_key}&amp;units=metric"
        response = requests.get(url)
        data = response.json()
        if data["cod"] == 200:
            temp = data["main"]["temp"]
            description = data["weather"][0]["description"]
            response = f"The weather in {location} is currently {description} with a temperature of {temp}&#176;C."
            print(response)
            return response
        else:
            return f"Sorry, I couldn't find weather information for {location}."
</code></code></pre><div><hr></div><h3><strong>Demo: Running the Orchestrator</strong></h3><p>Here&#8217;s a quick demonstration:</p><ol><li><p><strong>Query</strong>: <em>&#8220;What&#8217;s the weather in Bangalore, and what&#8217;s the current time?&#8221;</em></p></li><li><p><strong>Execution</strong>:</p><ul><li><p>The orchestrator identifies the intent (weather and time).</p></li><li><p>Delegates tasks to the respective agents.</p></li><li><p>Combines responses to provide the final answer.</p></li></ul></li></ol><p><strong>Example Output</strong>:</p><ul><li><p><em>"The weather in Bangalore is misty with a temperature of 22&#176;C. The current time in Bangalore is 12:27 AM."</em></p></li></ul><pre><code><code>from agents.base_agent import Agent
from tools.weather_tool import WeatherTool
from tools.time_tool import TimeTool
from orchestrator import AgentOrchestrator

from dotenv import load_dotenv
import os

# Load environment variables from .env file
load_dotenv()

# Create Weather Agent
weather_agent = Agent(
    Name="Weather Agent",
    Description="Provides weather information for a given location",
    Tools=[WeatherTool()],
    Model="gpt-4o-mini"
)

# Create Time Agent
time_agent = Agent(
    Name="Time Agent",
    Description="Provides the current time for a given city",
    Tools=[TimeTool()],
    Model="gpt-4o-mini"
)

# Create AgentOrchestrator
agent_orchestrator = AgentOrchestrator([weather_agent, time_agent])

# Run the orchestrator
agent_orchestrator.run()
</code></code></pre><div><hr></div><h3><strong>What&#8217;s Next?</strong></h3><p>This orchestrator is just the beginning. You can:</p><ul><li><p>Add more agents for tasks like translation, currency conversion, or database queries.</p></li><li><p>Optimize prompts for better LLM responses.</p></li><li><p>Extend the system for real-world applications like customer support or smart assistants.</p></li></ul><div><hr></div><h3><strong>Full Code</strong></h3><p><strong><a href="https://github.com/zahere-dev/augmate">https://github.com/zahere-dev/augmate</a></strong></p><h3><strong>Final Thoughts</strong></h3><p>Building a Multi-Agent Orchestrator showcases the power of combining LLMs with task-specific agents. By modularizing tasks and leveraging context effectively, you can create systems that are both scalable and intelligent.</p><p>Stay tuned for more updates, and feel free to share your thoughts or ask questions in the comments below. Don&#8217;t forget to check out the accompanying video for a detailed walkthrough of the code.</p><p>Happy coding! &#128640;</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.adaptiveengineer.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 The Adaptive Engineer! 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>