<script data-pm-proxy="intercept"></script><?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[The Underdoc]]></title><description><![CDATA[Building AI systems and writing about the process, bridging medicine and tech for anyone doing the same from a different background.]]></description><link>https://ricardoheredia.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!7Z1G!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20046b3b-539a-43f7-8114-9704dfda33e0_500x500.png</url><title>The Underdoc</title><link>https://ricardoheredia.substack.com</link></image><generator>Substack</generator><lastBuildDate>Sat, 05 Sep 2026 09:04:05 GMT</lastBuildDate><atom:link href="/__u/ricardoheredia.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Ricardo Heredia]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[ricardoheredia@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[ricardoheredia@substack.com]]></itunes:email><itunes:name><![CDATA[Ricardo Heredia]]></itunes:name></itunes:owner><itunes:author><![CDATA[Ricardo Heredia]]></itunes:author><googleplay:owner><![CDATA[ricardoheredia@substack.com]]></googleplay:owner><googleplay:email><![CDATA[ricardoheredia@substack.com]]></googleplay:email><googleplay:author><![CDATA[Ricardo Heredia]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[A Greek God and Two Cetaceans to Build With AI]]></title><description><![CDATA[Testing Hermes Agent + DeepSeek V4 Flash inside Orca as a Claude Code alternative]]></description><link>https://ricardoheredia.substack.com/p/a-greek-god-and-two-cetaceans-to</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/a-greek-god-and-two-cetaceans-to</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Mon, 17 Aug 2026 05:31:52 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V7dj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp" 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="/__u/substackcdn.com/image/fetch/$s_!V7dj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!V7dj!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp 424w, /__u/substackcdn.com/image/fetch/$s_!V7dj!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp 848w, /__u/substackcdn.com/image/fetch/$s_!V7dj!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp 1272w, /__u/substackcdn.com/image/fetch/$s_!V7dj!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!V7dj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp" width="1408" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1408,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83954,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/211359857?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!V7dj!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp 424w, /__u/substackcdn.com/image/fetch/$s_!V7dj!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp 848w, /__u/substackcdn.com/image/fetch/$s_!V7dj!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp 1272w, /__u/substackcdn.com/image/fetch/$s_!V7dj!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe85fc7c0-f8d5-4b94-af30-af573654c06a_1408x768.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><blockquote><p>Messenger of the Gods</p><p>Protector of travelers</p><p>Oh so many titles</p><p>Great is your speed</p><p>Great is your might</p></blockquote><p>As a Greek mythology lover I could not help to look for a poem or related phrase to Hermes and use it to open the article with it since I&#8217;ll be talking about an agent that carries his name. You can read the full poem some good fella wrote in <a href="https://www.reddit.com/r/Hellenism/comments/12cu6hf/poem_for_hermes_day/">Reddit</a>. </p><p>With this in mind, last week I built a <a href="/__u/ricardoheredia.substack.com/p/a-claude-skill-to-build-your-own?r=56fjux&amp;utm_campaign=post&amp;utm_medium=web">football analytics Skill</a> for my football analytics tutorial repo using a stack I felt curious about: Hermes Agent + DeepSeek V4 Flash + Orca ADE. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!FxPr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!FxPr!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png 424w, /__u/substackcdn.com/image/fetch/$s_!FxPr!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png 848w, /__u/substackcdn.com/image/fetch/$s_!FxPr!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png 1272w, /__u/substackcdn.com/image/fetch/$s_!FxPr!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!FxPr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png" width="640" height="346.30450321658327" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:757,&quot;width&quot;:1399,&quot;resizeWidth&quot;:640,&quot;bytes&quot;:133781,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/211359857?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!FxPr!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png 424w, /__u/substackcdn.com/image/fetch/$s_!FxPr!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png 848w, /__u/substackcdn.com/image/fetch/$s_!FxPr!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.png 1272w, /__u/substackcdn.com/image/fetch/$s_!FxPr!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ddf952-2f59-4dfe-a462-a5ee847a3eab_1399x757.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 aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Since someone I follow on X mentioned it, I decided to give it a go with a simple task: refactor the old repo and package it as a Skill to automate the process of generating football post match reports for teams and players. </p><p>In this article I&#8217;m talking about how to set it up, how much it costed, how I reviewed it, and the potential of using these harnesses for agentic coding.</p><h3>The Setup</h3><p><a href="https://github.com/NousResearch/hermes-agent">Hermes</a> is Nous Research's autonomous agent &#8594; it&#8217;s MIT-licensed, it&#8217;s like a general agent with persistent memory and its own skills that good at code. Depending on their plan, they include more than 300+ models.  </p><p><a href="https://api-docs.deepseek.com/updates/">DeepSeek V4 Flash</a> is the model I used, both the Flash and the official 0731, a 284B-parameter mixture-of-experts model with 1M-token context, built specifically for agentic and coding tasks. </p><p><a href="https://www.onorca.dev/">Orca</a> is the ADE (Agentic Development Environment) that runs both. It&#8217;s helpful to orchestrate agents and session to writes code so you can direct it and review it. Orca runs any CLI agent (Hermes, Claude Code, Codex, etc.) in isolated git worktrees, with terminals, diffs, and browser preview in one app.</p><h4>Installing the pieces</h4><p><a href="https://hermes-agent.nousresearch.com/">Hermes Agent</a> installs with one command:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;3bbe8567-c7fc-406a-8797-daa6cd22827e&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash</code></pre></div><p>It pulls in uv, Python 3.11.15, ripgrep, ffmpeg, and Chromium (via Playwright) as dependencies, and drops the binary at this path: </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;1b8c8627-5d66-4cf8-9b22-70b9a87c7acd&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">~/.local/bin/hermes</code></pre></div><p>You can also run: </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;3f30988a-68dd-4b14-9f53-d245debf2ecd&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">hermes doctor </code></pre></div><p>To check if it came back clean, with no critical errors.</p><p>Nous Portal is the provider behind it </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;a811e754-9c49-4ff0-915e-98e188c9e62c&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">hermes portal </code></pre></div><p>It oppens an OAuth login in the browser, and once you&#8217;re in, in the billing and tool layer (Nous Portal).</p><p>I loaded $5.10 in credit ($5 top-up + $0.10  courtesy of the subscription) and got access to a tool gateway with many perks: top LLM model providers, web search/extract via Firecrawl, image and video generation via FAL, speech-to-text via Whisper, text-to-speech, and browser automation, all callable from Hermes.</p><p><a href="https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash-0731">DeepSeek V4 Flash</a> was the main model I ran, Nous Portal exposes both <code>deepseek-v4-flash</code> at $0.11 / $0.22 per Mtok and a cheaper <code>deepseek-v4-flash-0731</code> variant. More on the actual split in the cost section below.</p><p><a href="https://www.onorca.dev/">Orca</a> is where I actually worked. I installed it directly from its web. Once installed, you can get Hermes set as the default agent CLI inside Orca, and that&#8217;s the set I actually worked with: Orca as the workspace &#8594; Hermes as the CLI agent &#8594; DeepSeek as the model underneath.</p><p>Once installations were verified, I registered the football repo as its own workspace</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;4316a993-16cf-491a-9faa-06ae358c521b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">orca repo add --path ~/orca/workspaces/football-analytics-tutorials</code></pre></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!fAJb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!fAJb!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png 424w, /__u/substackcdn.com/image/fetch/$s_!fAJb!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png 848w, /__u/substackcdn.com/image/fetch/$s_!fAJb!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png 1272w, /__u/substackcdn.com/image/fetch/$s_!fAJb!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!fAJb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png" width="1456" height="901" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:901,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:519390,&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://ricardoheredia.substack.com/i/211359857?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!fAJb!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png 424w, /__u/substackcdn.com/image/fetch/$s_!fAJb!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png 848w, /__u/substackcdn.com/image/fetch/$s_!fAJb!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png 1272w, /__u/substackcdn.com/image/fetch/$s_!fAJb!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4193cd5f-a7c7-4424-a46c-c370e85dd0a4_2914x1804.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>The Approach and How Much it Costed</h4><p>Together, Hermes and Orca give you what's called a <strong>harness</strong> (the tools, memory, and execution control around a model), already built for you. </p><p>What I had to design was the <strong>goal</strong> <strong>loop</strong> &#8594; which is how you give it a goal, how you check its work, and when you call it done. </p><p>I asked Hermes to refactor the repo into a package and wrap it as a Skill that could be useful for any agent. Basically what I did was setting the /goal functionality and told it to: </p><ul><li><p>Check the <a href="https://github.com/ricardoherediaj/football-analytics-tutorials">repo</a> and understand how it was structured: the web scraping, the visualization code, the metrics.</p></li><li><p>A simple way of parametrizing the process with scripts and testing using software engineering best practices.</p></li><li><p>Wrapping it under a skill that receives an input URL and outputs a rendered match report.</p></li></ul><p>After the generation, I reviewed the generated charts (a process called human in the loop) and flagged what looked off. </p><p>There were minimal things in the charts like bad rendering on pass networks, stat labels that were unreadable against the background. </p><p>So I pointed them out to Hermes, which re-ran the tests and re-rendered the charts. I was based solely on how the chart looked like, so no elaborated eval for now. Same thing for both team and player reports.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!tbST!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!tbST!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png 424w, /__u/substackcdn.com/image/fetch/$s_!tbST!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png 848w, /__u/substackcdn.com/image/fetch/$s_!tbST!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png 1272w, /__u/substackcdn.com/image/fetch/$s_!tbST!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!tbST!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png" width="556" height="643.8296703296703" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59108cde-9705-418a-8781-2437f665a28a_2732x3164.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1686,&quot;width&quot;:1456,&quot;resizeWidth&quot;:556,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Match report 1&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="Match report 1" title="Match report 1" srcset="/__u/substackcdn.com/image/fetch/$s_!tbST!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png 424w, /__u/substackcdn.com/image/fetch/$s_!tbST!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png 848w, /__u/substackcdn.com/image/fetch/$s_!tbST!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png 1272w, /__u/substackcdn.com/image/fetch/$s_!tbST!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59108cde-9705-418a-8781-2437f665a28a_2732x3164.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When I checked the match report was good enough, I asked the LLM to document the results in a <strong>SESSION.md</strong>, to keep track of what was done, including decisions, mistakes and how it fixed it. </p><p>This helped a ton to build the player report, which was built a bit different than the match report, with a set of specific charts. </p><p>The model made less mistakes this time cause it had the context of what was being built.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!113C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!113C!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp 424w, /__u/substackcdn.com/image/fetch/$s_!113C!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp 848w, /__u/substackcdn.com/image/fetch/$s_!113C!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp 1272w, /__u/substackcdn.com/image/fetch/$s_!113C!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!113C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp" width="1456" height="815" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp&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;:80090,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/211359857?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!113C!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp 424w, /__u/substackcdn.com/image/fetch/$s_!113C!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp 848w, /__u/substackcdn.com/image/fetch/$s_!113C!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp 1272w, /__u/substackcdn.com/image/fetch/$s_!113C!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe690b5-2d6b-4873-abc4-2a9a9ec2c9aa_1456x815.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Checking costs in Nous Portal</h4><p>Verifying how much credits/tokens is the agent spending is crucial for budget and observability matters. </p><p>In Nous Portal you can track this easily, they even give you a CSV to export for analytics purposes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!CSLE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!CSLE!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png 424w, /__u/substackcdn.com/image/fetch/$s_!CSLE!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png 848w, /__u/substackcdn.com/image/fetch/$s_!CSLE!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png 1272w, /__u/substackcdn.com/image/fetch/$s_!CSLE!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!CSLE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png" width="1456" height="991" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:991,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:414557,&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://ricardoheredia.substack.com/i/211359857?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!CSLE!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png 424w, /__u/substackcdn.com/image/fetch/$s_!CSLE!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png 848w, /__u/substackcdn.com/image/fetch/$s_!CSLE!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png 1272w, /__u/substackcdn.com/image/fetch/$s_!CSLE!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0d1f3f-d18d-4715-99cf-870d24c6b9c5_2456x1672.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Looking at the numbers the whole session cost $2.88. </p><p>Almost all of that went to two DeepSeek V4 Flash variant models, the default <code>deepseek/deepseek-v4-flash </code>which processed 119.5 million input tokens and 351K output tokens for $2.82, and the cheaper <code>deepseek/deepseek-v4-flash-0731</code> which added 24.5 million input tokens and 213K output for another $0.05. </p><p>Combined: ~144 million tokens for $2.87. The rest was a few free calls to Step 3.7 Flash and some Firecrawl tool usage for lighter tasks along the way.</p><h3>Key Takeaways</h3><p><strong>Cost effective models can do real work if the harness carries the memory.</strong> DeepSeek V4 Flash isn&#8217;t Claude of course but for the price, what it offers, and a tool gateway, the output was pretty decent. Hopefully there&#8217;ll be more competent models at better prices and with better harnesses.</p><p><strong>SESSION.md helped the agent to improve the task.</strong> The player report came out with fewer mistakes than the match report, the fact that I had it to keep record of what broke last time and read before it started also improved the output.</p><p><strong>Human-in-the-loop by analyzing the report result.</strong> There was a noticeable error in the match report where substitute players kept showing up labeled on the pass network with the same marker as starters a bug I caught cause I looked at the chart, flagged it, and told Hermes where the error was. It found the fix and ultimately solved it. </p><p>If you&#8217;ve ben using agentic coding tools and/or open models, what challenges have you find so far? Let me know in the comments! </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/subscribe"><span>Subscribe now</span></a></p><p>PS: As effect of August 16th DeepSeek increased their <a href="https://api-docs.deepseek.com/quick_start/pricing/">model pricing</a> for V4 series. </p><div><hr></div><p>Till next time,</p><p>Ricardo. </p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[A Claude Skill to Build Your Own Football Analytics Post Match Reports Automatically]]></title><description><![CDATA[Use an Agent to create a Custom Skill]]></description><link>https://ricardoheredia.substack.com/p/a-claude-skill-to-build-your-own</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/a-claude-skill-to-build-your-own</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Sat, 08 Aug 2026 10:51:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!J9AJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A year ago, I built this<a href="https://github.com/ricardoherediaj/football-analytics-tutorials/tree/main"> football-analytics-tutorial repo</a> for anyone wanting to practice their Python coding skills with football. In that article I explained what a post match dashboard was and the plots I decided to include.</p><p>Although it worked as a standalone notebook and was well received, I wanted to give it some love. I wanted to improve it as a Python package and create a Skill that anyone can reuse to plug it into their preferred agent in order to automate the generation of single post match reports.</p><p>Much has changed in the AI landscape since I created that notebook. </p><p>Yesterday I was playing around with a setup I saw on <a href="https://x.com/theunderdoc14">X/Twitter</a> &#8594; Hermes Agent + DeepSeek V4 Flash + Orca as Agentic IDE, so I decided to set it up and test it by giving it this repo and letting it run with clear goals: refactor it, improve the report, test it and build the skill.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!eVpM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!eVpM!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png 424w, /__u/substackcdn.com/image/fetch/$s_!eVpM!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png 848w, /__u/substackcdn.com/image/fetch/$s_!eVpM!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png 1272w, /__u/substackcdn.com/image/fetch/$s_!eVpM!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!eVpM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png" width="1456" height="926" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:926,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:411601,&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://ricardoheredia.substack.com/i/210328898?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!eVpM!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png 424w, /__u/substackcdn.com/image/fetch/$s_!eVpM!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png 848w, /__u/substackcdn.com/image/fetch/$s_!eVpM!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png 1272w, /__u/substackcdn.com/image/fetch/$s_!eVpM!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a623127-b93d-4b06-94c9-ecc29a5d05cd_2936x1868.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In this article I&#8217;ll talk about the repo itself, the skill and its result. I&#8217;ll talk briefly about the tools I used to generate this but will leave the setup details and what they are for another article since I believe they deserve their own piece. </p><p>What you&#8217;ll get in this article: a skill that receives one URL from WhoScored as input and generates a 24-chart report out, ready to use in an agent that can run the whole thing for you. </p><p>Let&#8217;s see what changed. </p><h2>The new feature</h2><p>I wanted to make a simple skill which core capability was just one thing &#8594; you input a Match URL from WhoScored and obtain a post match report out.</p><pre><code><code>uv run football-match-report scrape "&lt;whoscored-url&gt;" --out ./data
uv run football-match-report render --data ./data --out ./report</code></code></pre><p>These two commands turn any match into two PNGs: the team report and the zone analysis (a new part of the report I included)</p><p>I tested it end to end on Salzburg 0&#8211;3 Real Madrid from last year Club World Cup, and on Chelsea 2&#8211;1 Tottenham from the Premier League from last season. </p><h4>Data Sources</h4><p>The report merges two data sources:</p><ul><li><p>WhoScored, scraped through headless Chromium, provides the full event stream: passes, tackles, carries, and recoveries with coordinates. That powers the passing networks, defensive blocks, progressive passes and carries, and the xT momentum chart. </p></li><li><p>FotMob, fetched with plain requests and no token, provides shots with xG and xGOT, the official stats, the player of the match, and real team colors. A tricky part: mapping the date and team names which is pretty much solved from the WhoScored data (check the repo for more details)</p></li></ul><p>The charts follow the <a href="https://github.com/adnaaan433/Post-Match-Report-2.0">Post-Match-Report-2.0</a> blueprint from my pal Adnaan. The pitch is rendered using UEFA pitch coordinates at 105&#215;68, black background, shirt numbers inside player nodes, circles for starters and squares for subs, and an xT momentum bar. Assembling sixteen chart types into two figures of twelve panels each.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!J9AJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!J9AJ!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png 424w, /__u/substackcdn.com/image/fetch/$s_!J9AJ!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png 848w, /__u/substackcdn.com/image/fetch/$s_!J9AJ!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png 1272w, /__u/substackcdn.com/image/fetch/$s_!J9AJ!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!J9AJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png" width="1456" height="1686" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1686,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Match report 1&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="Match report 1" title="Match report 1" srcset="/__u/substackcdn.com/image/fetch/$s_!J9AJ!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png 424w, /__u/substackcdn.com/image/fetch/$s_!J9AJ!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png 848w, /__u/substackcdn.com/image/fetch/$s_!J9AJ!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png 1272w, /__u/substackcdn.com/image/fetch/$s_!J9AJ!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa087c29b-3a35-42f0-9875-ae578f1fd44f_2732x3164.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>The professional Python package</h2><p><strong>The repo now behaves like a real open-source package.</strong> </p><p>The code lives in <code>src/football_match_report/</code>, split into core, io, and viz modules. </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;219579d8-d6cd-4327-8365-8668603145b7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">src/football_match_report/     # the package
  core/events.py               # event pipeline: carries, possession, xT, UEFA scaling
  core/stats.py                # match/shot statistics
  io/whoscored.py              # Playwright scraper
  io/fotmob.py                 # FotMob API (id resolve, matchDetails)
  viz/pass_network.py          # passing networks (shirt numbers, line heights)
  viz/defensive_block.py       # defensive KDE heatmaps
  viz/progressive.py           # progressive passes &amp; carries
  viz/shots.py                 # shot map + goalkeeper saves
  viz/momentum.py              # xT momentum chart
  viz/match_stats.py           # stats bars
  viz/zones.py                 # 8 advanced zone charts
  viz/report.py                # 2x 4x3 figure assembly
  cli.py                       # scrape + render commands
skills/football-match-report/  # installable agent skill (SKILL.md + thin wrappers)
tests/                         # offline unit + render tests (synthetic match data)
docs/                          # sample report images</code></pre></div><p>This way you can use the package to install, import, test, and extend it as you wish. The scraping logic, the coordinate conversions, and the chart code are separate modules with single responsibilities in order to follow software development best practices. </p><h2>The Skill Itself</h2><p><strong>The same repo ships as an installable agent skill &#8594;</strong> <code>skills/football-match-report/</code> contains a SKILL.md, reference docs, and the scripts the agent needs. </p><p>An agent that has this skill installed can run the whole workflow from a natural-language request, because the skill carries the knowledge: the commands, the data format, the coordinate conventions, the verification steps.</p><p>Launching it from Hermes, my code agent, takes one request. </p><p>The skill lives in the agent&#8217;s skills folder. From there, asking for the report for a WhoScored URL match is enough. The agent hands me the two PNGs.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!VXYw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!VXYw!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png 424w, /__u/substackcdn.com/image/fetch/$s_!VXYw!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png 848w, /__u/substackcdn.com/image/fetch/$s_!VXYw!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png 1272w, /__u/substackcdn.com/image/fetch/$s_!VXYw!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!VXYw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png" width="1456" height="636" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:636,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:225375,&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://ricardoheredia.substack.com/i/210328898?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!VXYw!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png 424w, /__u/substackcdn.com/image/fetch/$s_!VXYw!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png 848w, /__u/substackcdn.com/image/fetch/$s_!VXYw!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png 1272w, /__u/substackcdn.com/image/fetch/$s_!VXYw!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a0520a5-341f-4aae-844d-983757eb3cd3_2382x1040.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That&#8217;s the shift I wanted to give it and what I love about the process of creating skills. You can move all the knowledge from your head into a document and then handing over the execution to the agent.</p><h2>The process</h2><p>The original dashboard was created along with by Claude Sonnet 4 in Cursor last year but this version was built on a different setup, one I chose as an alternative to Claude Code.</p><p>I built it with this agent stack:</p><p><a href="https://github.com/NousResearch/hermes-agent/tree/main">Hermes</a> running DeepSeek V4 Flash as the default model, inside <a href="https://www.onorca.dev/">Orca</a>, an agentic development environment. </p><p>The agent did the heavy lifting during the 3-4 hours session: the package structure, the scrapers, the test suite, the CI workflow, the skill packaging. </p><p>I did the human in the loop review by opening the rendered PNGs and looking at potential errors. </p><p>Doing this loop I caught some rendering issues problems, like: every player node rendered as a circle, because WhoScored only sets <code>isFirstEleven</code> on starters, substitutes get <code>NaN</code>, and <code>bool(np.nan)</code> evaluates to <code>True</code> in Python. </p><p>So in order to fix it I had to: tell the agent where the fix was &#8594; tell it to test it again with the data and logic &#8594; check the rendered result again. </p><p>How I set up that stack, the models, the cost, and why it works as a Claude Code alternative deserves its own post in the upcoming days.</p><h2>Next steps</h2><p>Using this report as the foundation to generate a new player-level dashboards with top passers, individual pass maps, per-player shot and defensive stats from that specific match.</p><p>Maybe more leagues and competitions and a simple persistent storage for the scraped data would turn one-off reports into a history you can track (which is something I was trying to do with my <a href="https://github.com/ricardoherediaj/football-rag-intelligence">Football RAG project</a>). </p><h2>Why this matters</h2><p>This is an improved version of the tutorial repo. </p><p>You as a fan, technical person, or curious coach/scout that knows Python and wants to see tactical execution from a match, flag a concrete player, analysts spot patterns across matches, can reuse this in a more straightforward way.</p><p>The difference now is that instead of plotting everything each time by yourself you can run two commands or a Skill in natural language with an agent.</p><p>If you build football analytics, or you build with agents, the repo is open source: https://github.com/ricardoherediaj/football-analytics-tutorials</p><p>Enjoy it, and feel free to share with anyone!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/subscribe"><span>Subscribe now</span></a></p><div><hr></div><p>Till next time, </p><p>Ricardo. </p>]]></content:encoded></item><item><title><![CDATA[I Automated My Personal Finance Tracking With a Claude Skill and Two MCP Servers]]></title><description><![CDATA[A simple approach using a custom skill]]></description><link>https://ricardoheredia.substack.com/p/i-automated-my-personal-finance-tracking</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/i-automated-my-personal-finance-tracking</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Sun, 12 Jul 2026 18:30:45 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f7307f24-729e-4912-8a53-07a2a4c36b8a_1024x318.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For the past few years, my personal &#8220;finance system&#8221; was just noting down expenses in Notes app.</p><p>At the end of the month I'd copy everything into a &#8220;cleaner format&#8221;, add up the totals, and try to understand where my money actually went. </p><p>More recently I moved the capture part to Notion, which made the notes prettier but didn't remove the manual copying making it boring still.</p><p>For me, knowing my balance at the end of the month matters because I can tell how much I spent, saved, and invested, and that helps me decide how I organize the next month. The issue comes when tracking lags two weeks behind, so entries pile up.</p><h2>Notion &#129309; Superhuman</h2><p>One day probably in 2024, in an online investing community I'm part of, the owner shared a finance template built in an app called Coda (now renamed as <a href="https://superhuman.com/docs/use-cases/project-management?utm_source=google-brand&amp;utm_medium=cpc&amp;utm_campaign=23174568893&amp;utm_bu=corp&amp;utm_content=816119603654&amp;utm_term=superhuman%20docs&amp;target=&amp;targetid=kwd-2108297563608&amp;adgroup=187069800683&amp;device=c&amp;matchtype=e&amp;placement=&amp;network=g&amp;extension=&amp;clickid=CjwKCAjw9szSBhBNEiwAC57SqyMKV-0HurOgEeMXZH4BxQGZO7uVjEN532s5Xw3BZL6Xbdb7cdLSnxoCqsYQAvD_BwE&amp;gad_source=1&amp;gad_campaignid=23174568893&amp;gbraid=0AAAABBoNLYwk8VMfb3d8vDr_SKSgMMt5x&amp;gclid=CjwKCAjw9szSBhBNEiwAC57SqyMKV-0HurOgEeMXZH4BxQGZO7uVjEN532s5Xw3BZL6Xbdb7cdLSnxoCqsYQAvD_BwE">Superhuman</a>). I see it like Notion but with steroids.</p><p>The template has three pages with databases and charts linked between each other: one for expenses, one for income, and a balance page that recalculates income, spending, and savings per month on its own. For each row you just need a date, and the monthly formulas do the rest.</p><p>Here are pictures with some mocked data: </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Mt6c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Mt6c!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png 424w, /__u/substackcdn.com/image/fetch/$s_!Mt6c!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png 848w, /__u/substackcdn.com/image/fetch/$s_!Mt6c!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Mt6c!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Mt6c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:106438,&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://ricardoheredia.substack.com/i/203448113?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Mt6c!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png 424w, /__u/substackcdn.com/image/fetch/$s_!Mt6c!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png 848w, /__u/substackcdn.com/image/fetch/$s_!Mt6c!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Mt6c!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c34f779-e005-4fe2-89dc-dc1c71ec8fcf_1916x958.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!FQNo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!FQNo!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png 424w, /__u/substackcdn.com/image/fetch/$s_!FQNo!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png 848w, /__u/substackcdn.com/image/fetch/$s_!FQNo!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png 1272w, /__u/substackcdn.com/image/fetch/$s_!FQNo!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!FQNo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png" width="1456" height="723" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:723,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:117586,&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://ricardoheredia.substack.com/i/203448113?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!FQNo!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png 424w, /__u/substackcdn.com/image/fetch/$s_!FQNo!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png 848w, /__u/substackcdn.com/image/fetch/$s_!FQNo!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png 1272w, /__u/substackcdn.com/image/fetch/$s_!FQNo!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84f0cf7e-82b7-4e7f-8518-34cf7060e8bf_1912x949.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!CcJc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!CcJc!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png 424w, /__u/substackcdn.com/image/fetch/$s_!CcJc!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png 848w, /__u/substackcdn.com/image/fetch/$s_!CcJc!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png 1272w, /__u/substackcdn.com/image/fetch/$s_!CcJc!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!CcJc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png" width="1456" height="730" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:730,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:108440,&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://ricardoheredia.substack.com/i/203448113?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!CcJc!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png 424w, /__u/substackcdn.com/image/fetch/$s_!CcJc!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png 848w, /__u/substackcdn.com/image/fetch/$s_!CcJc!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png 1272w, /__u/substackcdn.com/image/fetch/$s_!CcJc!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003e7b92-5d1c-4e6b-9163-8626fe2ceccf_1906x956.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>So my process became: register expenses in Notion each day &#8594; then move them to Superhuman at the end of the week or month, row by row.</p><p>There were like thirty plus entries every single month, and doing it by hand became tedious.</p><h2>A Simple Solution</h2><p>Both Notion and Superhuman have MCP servers, which means Claude can read and write to them directly. I&#8217;m trying to make Claude the manager of many areas of my life by using its skills. So far I have a writing skill that helps me create and review articles like this one. Now I&#8217;ve created one to automate my finances.</p><p>So I wrote a Claude Code skill called <code>finance-sync</code> that does the tedious part for me by connecting to both Notion and Superhuman through the MCP servers in my Claude settings.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!j77r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!j77r!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png 424w, /__u/substackcdn.com/image/fetch/$s_!j77r!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png 848w, /__u/substackcdn.com/image/fetch/$s_!j77r!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png 1272w, /__u/substackcdn.com/image/fetch/$s_!j77r!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!j77r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png" width="1456" height="827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:827,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:208035,&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://ricardoheredia.substack.com/i/203448113?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!j77r!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png 424w, /__u/substackcdn.com/image/fetch/$s_!j77r!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png 848w, /__u/substackcdn.com/image/fetch/$s_!j77r!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png 1272w, /__u/substackcdn.com/image/fetch/$s_!j77r!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F527779cb-2f4d-466f-92d6-4a21ee9a75e6_1533x871.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!dUo0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!dUo0!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png 424w, /__u/substackcdn.com/image/fetch/$s_!dUo0!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png 848w, /__u/substackcdn.com/image/fetch/$s_!dUo0!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png 1272w, /__u/substackcdn.com/image/fetch/$s_!dUo0!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!dUo0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png" width="1372" height="658" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:658,&quot;width&quot;:1372,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:206560,&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://ricardoheredia.substack.com/i/203448113?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!dUo0!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png 424w, /__u/substackcdn.com/image/fetch/$s_!dUo0!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png 848w, /__u/substackcdn.com/image/fetch/$s_!dUo0!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png 1272w, /__u/substackcdn.com/image/fetch/$s_!dUo0!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82bd266-94b4-4ecd-9e47-228e91896113_1372x658.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><blockquote><p>In case you&#8217;re not familiar with <a href="https://claude.com/skills">skills</a> yet, as defined by Anthropic they basically are: </p><p>A way to turn your expertise, procedures, and best practices into reusable capabilities so Claude can apply them automatically, every time.</p><p>And if you want a quick understanding on what MCP is you can read this <a href="/__u/ricardoheredia.substack.com/p/understanding-model-context-protocol?utm_source=profile&amp;utm_medium=reader2">article</a> with a practical example I built a while ago or redirect to the <a href="https://modelcontextprotocol.io/docs/getting-started/intro">official site</a>. </p></blockquote><p>The daily habit stays the same: I type each expense into a small Notion database, one per month, with four fields: concept, amount, a free-text category, and a date. There's a fifth field too, a checkbox called <code>Synced</code>, which is the actual checkpoint that lets me know what I have already tracked.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!kN6U!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!kN6U!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png 424w, /__u/substackcdn.com/image/fetch/$s_!kN6U!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png 848w, /__u/substackcdn.com/image/fetch/$s_!kN6U!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png 1272w, /__u/substackcdn.com/image/fetch/$s_!kN6U!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!kN6U!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png" width="725" height="278.3482142857143" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:559,&quot;width&quot;:1456,&quot;resizeWidth&quot;:725,&quot;bytes&quot;:143080,&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://ricardoheredia.substack.com/i/203448113?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!kN6U!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png 424w, /__u/substackcdn.com/image/fetch/$s_!kN6U!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png 848w, /__u/substackcdn.com/image/fetch/$s_!kN6U!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png 1272w, /__u/substackcdn.com/image/fetch/$s_!kN6U!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a1e1cb-edf0-49aa-a247-9ef2059a5930_1910x733.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Notion table with fictional data</figcaption></figure></div><p>When I want to sync, I run the skill. </p><p>Claude reads every row where the checkbox is unchecked, figures out whether each one is an expense or income, maps my lazy free-text categories to the real category rows in Superhuman, shows me a summary table, and waits for my confirmation. </p><p>Only then does it write the rows into Superhuman and ticks the checkboxes back in Notion.</p><p>The Superhuman balance page actually needs nothing from the skill cause its formulas pick up the new rows by date and recalculate the month on their own.</p><h2>How to set it up for yourself</h2><p><strong>Create free accounts</strong> in Notion and Superhuman. </p><p><strong>Connect the MCP servers.</strong> To do it Claude Desktop, you can go to Settings,  <a href="https://claude.com/connectors">Connectors</a>,  and Add them. I added <a href="https://developers.notion.com/guides/mcp/overview">Notion</a> and <a href="https://developers.notion.com/guides/mcp/overview">Superhuman</a> the same way you&#8217;d connect to any other app: log in, authorize, done.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!EiIA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!EiIA!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png 424w, /__u/substackcdn.com/image/fetch/$s_!EiIA!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png 848w, /__u/substackcdn.com/image/fetch/$s_!EiIA!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png 1272w, /__u/substackcdn.com/image/fetch/$s_!EiIA!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!EiIA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png" width="1456" height="1087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1087,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:329727,&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://ricardoheredia.substack.com/i/203448113?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!EiIA!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png 424w, /__u/substackcdn.com/image/fetch/$s_!EiIA!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png 848w, /__u/substackcdn.com/image/fetch/$s_!EiIA!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png 1272w, /__u/substackcdn.com/image/fetch/$s_!EiIA!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77c804d0-2e35-4d62-b844-bfe9b1f629ad_2078x1552.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Grab the template and write the skill.</strong> I made a copy with mocked data of my Superhuman doc so you can duplicate this <a href="https://docs.superhuman.com/d/finances-2026_d9AGlDBJpds">Finances 2026 template</a> yourself, so instead of starting from a blank page you have some fake data to play around with. </p><p>Once you have your own copy, adding the skill is as simple as dropping in a markdown file that tells Claude the shape of your tables: the column IDs, the category list, and one hard rule, never mark a row as synced until the write actually succeeds. I put my own version in this Drive <a href="https://drive.google.com/drive/folders/18Z55FPb4pnPe4QaYi0wimHhMslwzNzNI?usp=sharing">link</a>, so you can download the files and adapt them.</p><p>This is how it&#8217;s structured:</p><pre><code><code>finance-sync/
&#9500;&#9472;&#9472; SKILL.md # the file that tells Claude how to do the task
&#9492;&#9472;&#9472; references/ # folder Claude uses as a reference to run the skill right
    &#9500;&#9472;&#9472; notion.md # reference of the Notion database tracker
    &#9500;&#9472;&#9472; coda.md # Coda/Superhuman template, rename it to superhuman.md
    &#9492;&#9472;&#9472; categories.md # existing categories reference</code></code></pre><p><span>To install it: in Claude Desktop, go to Settings &#8594; Capabilities &#8594; Skills &#8594; Add &#8594; Upload or "Write the skill's instructions," and paste it in. If you use Claude Code instead, drop the same file at </span><code>~/.claude/skills/finance-sync/SKILL.md</code><span>, plus its </span><code>references/</code><span> folder, and Claude picks it up automatically.</span></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!QPg0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!QPg0!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png 424w, /__u/substackcdn.com/image/fetch/$s_!QPg0!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png 848w, /__u/substackcdn.com/image/fetch/$s_!QPg0!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QPg0!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!QPg0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png" width="1456" height="1093" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1093,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:229628,&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://ricardoheredia.substack.com/i/203448113?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!QPg0!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png 424w, /__u/substackcdn.com/image/fetch/$s_!QPg0!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png 848w, /__u/substackcdn.com/image/fetch/$s_!QPg0!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QPg0!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde90d30f-dcfd-4acf-b246-399e7064630a_2078x1560.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Run it once and check by hand before trusting it.</strong> The first time, I compared Claude&#8217;s proposed summary against my own notes for one full month before saying go. After that, I just run it.</p><h2>Three problems I found out</h2><p><strong>The first problem was duplicates.</strong> If I run the sync twice, I don't want my rent showing up twice in October for example. There's no reliable way to detect duplicates on the Superhuman side, so the <code>Synced</code> checkbox in Notion is the only source of truth for what's pending. </p><p>The ordering is what makes it safe: rows get marked as synced only after the Superhuman write succeeds. If the write fails halfway, the unwritten rows stay unchecked and nothing is lost. If you run the skill on a month with no pending rows  it just reports "nothing pending" and touches nothing.</p><p>The only caveat: if that checkbox is wrong, the sync is wrong too. There's no real duplicate detection here, just one checkbox per row. For a personal tracker, that's good enough.</p><p><strong>The second problem was categories.</strong> Notion lets me type whatever category I want; Superhuman expects a reference to an existing category row. Most of the time the mapping is obvious. But when I typed "Donation" for a charity gift and no such category existed in Superhuman, instead of guessing Claude proposed creating the new category and asked me first. I said yes, and it created the row and used it. That confirmation step I like: the model classifies but I approve.</p><p><strong>The third problem </strong>was that the Superhuman MCP has a 30 message quota for the free plan which is the one I&#8217;m using, so this made me want to look for other flexible options but keeping the same workflow. </p><h2>The first real run</h2><p>The first time I ran it for real, I had 5 unsynced rows from June and 19 from July, eleven days of expenses I hadn't moved, which tells you how well the manual process was going.</p><p>One run: 24 expenses and 1 income written into the template, two new categories created with my confirmation, every checkbox ticked, and the July balance recalculated by the time the skill reported back.</p><p>The part that used to take me more than 30 minutes now takes a couple of seconds by just writing:"sync my finances." or &#8220;/finance-sync&#8221;</p><h2>What I'd tell you to steal</h2><p>Build a skill that moves the data to wherever you actually analyze it, and use a checkbox to track what's already been moved. Any two tools with MCP servers can play these roles.</p><p>My version still has rough edges. The template doc only works for one year, so I&#8217;ll need a new one every January. And the whole thing trusts one checkbox right now. </p><p>That&#8217;s what I want to find out next: how it holds up after a few more months of real use.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/p/i-automated-my-personal-finance-tracking?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The Underdoc! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/p/i-automated-my-personal-finance-tracking?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/p/i-automated-my-personal-finance-tracking?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share</span></a></p></div><p>I hope this approach gives you an idea on how to use Claude to work with skills and MCP servers to automate boring tasks.</p><div><hr></div><p>Till next time,</p><p>Ricardo.</p>]]></content:encoded></item><item><title><![CDATA[Venezuela's Earthquake Tragedy: What's Happening and How to Help from Abroad]]></title><description><![CDATA[Last Wednesday June 24, 2026 two earthquakes of 7.2.]]></description><link>https://ricardoheredia.substack.com/p/venezuelas-earthquake-tragedy-whats</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/venezuelas-earthquake-tragedy-whats</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Sat, 27 Jun 2026 19:18:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Ifwh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last Wednesday June 24, 2026 two earthquakes of 7.2. and 7.5 on Richter scale hit Venezuela in less than a minute. At 18:04:33 and 18:05:11 respectively. </p><p>Geologists call this a "doublet". It&#8217;s defined as two major quakes close in time. </p><p>We&#8217;ve had earthquakes before but none like this.</p><p>Entire buildings collapsed. Families torn apart. Kids, pets, men, women buried under concrete. La Guaira became one of the most affected areas of loss. Over 100 residential and tourist buildings collapsed entirely. And many people with them.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Ifwh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Ifwh!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!Ifwh!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!Ifwh!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!Ifwh!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Ifwh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg" width="462" height="635.891019172553" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1364,&quot;width&quot;:991,&quot;resizeWidth&quot;:462,&quot;bytes&quot;:503002,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/203837272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Ifwh!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!Ifwh!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!Ifwh!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!Ifwh!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36577427-974c-4435-b3af-0fb46a9c2e88_991x1364.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">La Guaira, Venezuela, 2026</figcaption></figure></div><p>At the time of writing this, the numbers are still moving, which is the worst part cause people are still being rescued. As of June 27, the official toll sits near 920 dead and over 3,300 injured. The UN estimates more than 50,000 people are still missing under the rubble. Citizen-made lists circulating on social media name over 52,000. Still everyone is affected directly or indirectly by this.</p><h3>Supporting From the Distance</h3><p>I left Venezuela five years ago, I built a different reality, in another country but when something like this happens you realize the migratory grief was always there, latent, underneath. </p><p>Thankfully, my family is safe since they live in a state outside the worst-hit zones. Still I can&#8217;t feel relieve because of seeing other people suffer, as that suffering becomes mine too.</p><p>I saw colleagues and friends of mine driving from one state to another carrying supplies (water, food, clothes, medicine), showing up to hospitals already overwhelmed, rescue workers and regular neighbors digging through collapsed concrete with their bare hands and tools to rescue people. </p><p>Several businesses and companies gathering supplies, giving free rides, and gathering funds (like <a href="https://dona.yummyrides.com/">Yummy</a>) to aid the victims. </p><p>All of this made me feel really proud and moved. It&#8217;s the reason I&#8217;m writing this. To showcase the best part of Venezuela: their people. </p><p>Other countries showed up too. More than 17 countries sent aid. Over 30 international search-and-rescue teams with hundreds of specialists deployed on the ground, like El Salvador&#8217;s, Madrid&#8217;s own ERICAM, American rescuers, and many others giving a hand to a catastrophe this country was never prepared for.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!E9IV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!E9IV!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png 424w, /__u/substackcdn.com/image/fetch/$s_!E9IV!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png 848w, /__u/substackcdn.com/image/fetch/$s_!E9IV!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png 1272w, /__u/substackcdn.com/image/fetch/$s_!E9IV!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!E9IV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png" width="1134" height="840" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:840,&quot;width&quot;:1134,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1265740,&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://ricardoheredia.substack.com/i/203837272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!E9IV!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png 424w, /__u/substackcdn.com/image/fetch/$s_!E9IV!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png 848w, /__u/substackcdn.com/image/fetch/$s_!E9IV!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png 1272w, /__u/substackcdn.com/image/fetch/$s_!E9IV!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91e58b7-8cb9-4b17-9909-120cd5ef094a_1134x840.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Comunidad de Madrid ERICAM arriving to Venezuela.</figcaption></figure></div><h3>Why the consequences are worse than they should be </h3><p>Simply: because of twenty-six years of Chavismo. </p><p>Hospitals were already damaged and under-resourced <em><strong>before</strong></em> the earthquake. </p><p>More than 90% of households reported chronic failures in basic water and electricity <em><strong>before</strong></em> June 24.</p><p>Nearly 8 million people already needed humanitarian assistance <em><strong>before</strong></em> a single building fell.</p><p>Fire departments, police, public infrastructure, building codes, roads, systematically downgraded on purpose. Gutting the country&#8217;s capacity to protect itself by stealing the money to enrich themselves. </p><p>This is the worst tragedy of all the daily tragedies these 26 years have produced. All made on purpose. There&#8217;s enough material for a series of articles, movies, and series of Netflix on how the regime destroyed our nation, but the goal of this post is to highlight what the citizens in and out of Venezuela are doing right at this very moment, and how to actually help wherever you are reading this. </p><h3>How to Help From Anywhere</h3><ul><li><p><strong>Deliver supplies in your city: </strong>Look for Venezuelan collection points (centros de acopio) in your area this might be churches, community organizations, warehouses. Diaspora groups are coordinating shipments. What's most needed: water, non-perishable food, hygiene kits, blankets, flashlights, batteries, first aid supplies, medications, USEFUL clothes. Check this web to locate centers in and out of Venezuela: <a href="https://centrosayudavenezuela.org">Donation centers for Venezuela</a></p></li><li><p><strong>Donate money</strong>: in my opinion this is the highest-impact option from abroad, because it lets organizations buy exactly what's needed locally. </p><p></p><p>These are some verified and trustworthy links you can point to: </p></li></ul><p>&#127384; <a href="https://www.gofundme.com/f/emergency-relief-for-venezuela-earthquake-victims">Emergency Relief for Venezuela Earthquake Victims (GoFundMe)</a> organised by the I Love Venezuela Foundation</p><p>&#127968; <a href="https://thehouse-project.org/">The House Project</a> providing on-the-ground support </p><p>&#129309; <a href="https://donate.stripe.com/eVq14m62u9BRdpm4Xw2sM02">Venezuelan Chamber of American Commerce</a> for direct donations </p><p>&#10084;&#65039; <a href="https://www.caritas.es/dona/?q=10146067&amp;purpose=emergencia&amp;campana_id=1163">C&#225;ritas por Venezuela</a> humanitarian aid </p><p>&#128757; <a href="https://dona.yummyrides.com/">Yummy Venezuela</a> </p><ul><li><p><strong>Spread the word on these type of webs that the tech ecosystem is building for Venezuela:</strong><a href="https://redquipu.com/"> redquipu.com</a></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!704R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!704R!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic 424w, /__u/substackcdn.com/image/fetch/$s_!704R!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic 848w, /__u/substackcdn.com/image/fetch/$s_!704R!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!704R!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!704R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic" width="592" height="583.9318568994889" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1158,&quot;width&quot;:1174,&quot;resizeWidth&quot;:592,&quot;bytes&quot;:105694,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/203837272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!704R!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic 424w, /__u/substackcdn.com/image/fetch/$s_!704R!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic 848w, /__u/substackcdn.com/image/fetch/$s_!704R!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!704R!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cbaa100-aaf0-4d92-9ae6-ad0243d7a3f9_1174x1158.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><p>I hope the one reading this now or further in time can connect with the suffering and needs of Venezuela. I also hope this takes part of our collective memorial. To remember we stood together during tough times.</p><p>Please share this with anyone you think can help and want to have some context on the situation.</p><p>For all the victims, all the families who lost someone they loved.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/p/venezuelas-earthquake-tragedy-whats?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/p/venezuelas-earthquake-tragedy-whats?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[How To Use Tool Calling To Build a Football Agent]]></title><description><![CDATA[A basic stats analyst use case]]></description><link>https://ricardoheredia.substack.com/p/how-to-use-tool-calling-to-build</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/how-to-use-tool-calling-to-build</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Tue, 26 May 2026 06:02:08 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/84c1748b-dbe6-4ea3-8b48-9ff3ca1e94aa_1867x1326.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You may have seen people trying to build agents using different solutions, with code, no-code/low-code alternatives, different frameworks and models, depending on the use case. </p><p>There&#8217;s not just one way of building them, it depends on what you want to achieve and the level of control you want to have over your agentic system. </p><p>Today, I want to talk to you about a real use case applied to football so you can see how is it to define the scope of building an agent, the rationale behind choosing certain tools, the errors, and thoughts on the process.</p><h3>A Basic Stats Analyst</h3><p>I recently built an agent with my teammates during the <a href="https://twelve.football/courses/context-engineering-for-football">Context Engineering course by Twelve Football</a> that finished just a couple weeks ago. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!8iyP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!8iyP!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic 424w, /__u/substackcdn.com/image/fetch/$s_!8iyP!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic 848w, /__u/substackcdn.com/image/fetch/$s_!8iyP!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!8iyP!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!8iyP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic" width="1456" height="843" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:843,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:102557,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/198384832?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!8iyP!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic 424w, /__u/substackcdn.com/image/fetch/$s_!8iyP!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic 848w, /__u/substackcdn.com/image/fetch/$s_!8iyP!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!8iyP!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc5b80ab-c5ba-44ca-99e7-6af2a36d8085_2220x1286.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Screenshot of the Streamlit demo</figcaption></figure></div><p>The goal was to build a basic stats analyst agent that answered questions grounded on the Premier League 2024/2025 season dataset from Wyscout.</p><p>For that we used a defined set of tools: </p><ul><li><p>Pydantic models for data validation and structured outputs</p></li></ul><ul><li><p>OpenAI tool calling </p></li><li><p>DuckDB as our light weight SQL and vector database </p></li><li><p>OpenAI LLM and embeddings models</p></li><li><p>Streamlit as frontend for demo purposes</p></li></ul><p>Down the road, we found out these were our preferred tools to build it, but it started out slightly different.</p><h3>The First Version (v1)</h3><p>In the beginning we had a shaky Python script with ~1,400 lines of regex code that relied heavily on pattern matching, and it broke every time we asked something different.</p><p>The LLM was giving responses but only those that were included in the if/else loops.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!VZjb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!VZjb!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic 424w, /__u/substackcdn.com/image/fetch/$s_!VZjb!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic 848w, /__u/substackcdn.com/image/fetch/$s_!VZjb!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!VZjb!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!VZjb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic" width="1456" height="457" data-attrs="{&quot;src&quot;:&quot;https://substackcdn.com/image/fetch/$s_!VZjb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:457,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:76241,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/198384832?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!VZjb!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic 424w, /__u/substackcdn.com/image/fetch/$s_!VZjb!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic 848w, /__u/substackcdn.com/image/fetch/$s_!VZjb!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!VZjb!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16114b65-adb7-4505-98fa-f8fc84d3f5c4_1764x554.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Questions like these were answered pretty well, but if you wanted to follow up the conversation, it lost context entirely. Also note that the wording is too verbose on metrics, a weird way to display the stats cause nobody talks like that.</p><p>So with every new question, we needed to patch more code.</p><p>We weren&#8217;t using the LLM properly to interrogate the dataset well.</p><h3>The Data Goes First </h3><p>Before any answer reached the user, it had to pass through two data layers.</p><p>The first was <strong>Pydantic</strong>. We used it both to structured the output and to evaluate the responses against our questions benchmark. The LLM returned a verdict whether an answer was faithful or correct against a typed schema that matched our benchmark. </p><p><code>passed: bool</code>, <code>reason: str</code>. </p><p>If the output didn&#8217;t match, it failed explicitly to avoid wrong responses and data leakage downstream.</p><p>The second was <strong><a href="https://duckdb.org/">DuckDB</a></strong>, a lightweight SQL database that runs in-process without  servers or heavy infrastructure. It read the Wyscout parquet files natively and, through its vector similarity extension (VSS), also stored the player and team embeddings for name resolution. Giving us the power of SQL queries and vector storage in the same tables.</p><p>Both of these were used to making sure the data the agent worked with was grounded data and it gave back grounded answers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!sb1R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!sb1R!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic 424w, /__u/substackcdn.com/image/fetch/$s_!sb1R!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic 848w, /__u/substackcdn.com/image/fetch/$s_!sb1R!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!sb1R!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!sb1R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic" width="1280" height="1142" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1142,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:106993,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/198384832?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!sb1R!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic 424w, /__u/substackcdn.com/image/fetch/$s_!sb1R!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic 848w, /__u/substackcdn.com/image/fetch/$s_!sb1R!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!sb1R!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38f042ce-bb30-488f-b22c-8e92f33d25e2_1280x1142.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">DuckD Database Schema.</figcaption></figure></div><h3>How the Tools Work (v2)</h3><p>Now with the data layer in place, we needed the agent to actually use it.</p><p>So we used <strong>Tool calling</strong>.  </p><p>It is how the LLM interacts with the database without touching it directly. The user asks a question, the LLM decides which tool to call and with what parameters, Python executes it against DuckDB, the result comes back, and the LLM writes the answer from that data.</p><p>We defined 4 tools: <code>query_player_stats</code>, <code>query_team_stats</code>, <code>query_ranking</code>, and <code>get_league_standings</code>.</p><p>Each tool has a name, a description, and a parameters schema. The description is what the LLM reads to decide whether to use it. The parameters tell it what arguments to pass.</p><p>Here&#8217;s how we defined the position filter inside <code>query_player_stats</code>:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!7fnl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!7fnl!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic 424w, /__u/substackcdn.com/image/fetch/$s_!7fnl!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic 848w, /__u/substackcdn.com/image/fetch/$s_!7fnl!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!7fnl!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!7fnl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic" width="499" height="414.7651376146789" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:906,&quot;width&quot;:1090,&quot;resizeWidth&quot;:499,&quot;bytes&quot;:67348,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/198384832?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!7fnl!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic 424w, /__u/substackcdn.com/image/fetch/$s_!7fnl!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic 848w, /__u/substackcdn.com/image/fetch/$s_!7fnl!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!7fnl!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94217e84-a434-46b6-ac4e-f435b4abf14a_1090x906.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That description is doing what you&#8217;d write as a Python dictionary. The alias mapping, the edge cases, and the <code>forward</code> exception all lives in a string the LLM reads at inference time.</p><p>And it worked. </p><p>Here&#8217;s the agent handling a multi-step question about Salah, where it had to build a custom opponent bucket, compare it against the rest of the season, then filter again by Champions League teams, all in the same conversation:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!k2cP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!k2cP!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic 424w, /__u/substackcdn.com/image/fetch/$s_!k2cP!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic 848w, /__u/substackcdn.com/image/fetch/$s_!k2cP!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!k2cP!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!k2cP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic" width="548" height="461.8413597733711" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:595,&quot;width&quot;:706,&quot;resizeWidth&quot;:548,&quot;bytes&quot;:43285,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/198384832?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!k2cP!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic 424w, /__u/substackcdn.com/image/fetch/$s_!k2cP!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic 848w, /__u/substackcdn.com/image/fetch/$s_!k2cP!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!k2cP!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9a6f1a3-c49c-405a-9d5d-72a67f8a4652_706x595.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Questions answers about a player in many turns.</figcaption></figure></div><p>But we started with 9 tools. </p><p>There were separate tools for top scorers, best passers, most progressive carriers, each its own function. </p><p>The problem was the LLM kept picking the wrong one because the descriptions overlapped. It would call <code>get_top_scorers</code> when it should have called <code>query_ranking</code> with <code>metric=goals</code>.</p><p>So we merged them down to 4, with broader scope and cleaner descriptions.</p><p>Going from 9 to 4 reduced routing errors more than any prompt tweak we tried. With fewer tools the LLM had fewer decisions to get wrong.</p><p>While building the position filter, we had a Python dictionary in <code>agent_tools.py</code> that mapped user aliases to database values at execution time. </p><p>Every time the LLM passed <code>"CB"</code>, Python caught it and translated it to <code>"Central Defender"</code>.</p><p>It worked. But we deleted it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!YvXb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!YvXb!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic 424w, /__u/substackcdn.com/image/fetch/$s_!YvXb!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic 848w, /__u/substackcdn.com/image/fetch/$s_!YvXb!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!YvXb!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!YvXb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic" width="539" height="308.3311827956989" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:532,&quot;width&quot;:930,&quot;resizeWidth&quot;:539,&quot;bytes&quot;:39371,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/198384832?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!YvXb!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic 424w, /__u/substackcdn.com/image/fetch/$s_!YvXb!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic 848w, /__u/substackcdn.com/image/fetch/$s_!YvXb!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!YvXb!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F042f3740-0d2f-4958-85df-1c36b588ae59_930x532.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We realized the same logic could live in the tool description instead. If you write it clearly enough, like documentation, the LLM passes the right value before the code ever runs. </p><h3><strong>Memory</strong></h3><p>In v1, the conversation had no memory between turns. If you followed up on a question, the context was entirely lost.</p><p>We fixed it with one line of code using the OpenAI Responses API. It kept the conversation state through <code>previous_response_id</code>. You pass the last response ID and the API handles the rest.</p><p>This how it looks in code: </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!eqwt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!eqwt!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic 424w, /__u/substackcdn.com/image/fetch/$s_!eqwt!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic 848w, /__u/substackcdn.com/image/fetch/$s_!eqwt!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!eqwt!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!eqwt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic" width="555" height="384.2307692307692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1040,&quot;resizeWidth&quot;:555,&quot;bytes&quot;:52269,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/198384832?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!eqwt!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic 424w, /__u/substackcdn.com/image/fetch/$s_!eqwt!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic 848w, /__u/substackcdn.com/image/fetch/$s_!eqwt!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!eqwt!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb79a6aca-9941-41da-bb3c-24942181fe75_1040x720.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is how it looked in the Streamlit UI:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Khk0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Khk0!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!Khk0!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!Khk0!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!Khk0!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Khk0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg" width="706" height="387" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:387,&quot;width&quot;:706,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:35456,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/198384832?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b407380-e02b-4a09-9518-a21020cff35a_706x595.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Khk0!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!Khk0!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!Khk0!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!Khk0!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2817517e-e62d-4aa3-82fa-c39244b92fa0_706x387.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Salah follow-up chain</figcaption></figure></div><h3>How We Knew It Worked</h3><p>We built a benchmark of 61 questions and ran it after every change we made. Each answer was scored by an LLM judge against the expected output, so we didn't have to go through them manually.</p><p>At the end, we threw 21 random questions at it that none of us had prepared for. It got 21 out of 21.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!LtIY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!LtIY!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!LtIY!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!LtIY!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!LtIY!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!LtIY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg" width="726" height="249" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:249,&quot;width&quot;:726,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:26919,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/198384832?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59997c1-d4cf-4871-a3dc-3ca19afe3c68_726x862.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!LtIY!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!LtIY!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!LtIY!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!LtIY!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecbb18a-99c4-4d60-8199-ffd50e47f12a_726x249.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The screenshot also shows the agent refusing questions it can't answer. That's something we had to build explicitly in order to make it refuse out of scope questions and not hallucinated.</p><h3>Wrapping Up</h3><p>Right now it only covers the Premier League 2024/25. Just one league and one season.</p><p>The interesting question is whether the same approach holds when you scale it. More leagues, more seasons, harder questions. </p><p>That&#8217;s what we want to find out next.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/subscribe"><span>Subscribe now</span></a></p><p>Till next time,</p><p>Ricardo. </p>]]></content:encoded></item><item><title><![CDATA[Got interviewed by Ryan Day in his Tip Sheet issue #65 and some extra thoughts]]></title><description><![CDATA[Ryan Day (author of Hands-On APIs for AI and Data Science, O&#8217;Reilly) and writer of the Tip Sheet newsletter featured me in his issue #65 last week.]]></description><link>https://ricardoheredia.substack.com/p/got-interviewed-by-ryan-day-in-his</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/got-interviewed-by-ryan-day-in-his</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Tue, 05 May 2026 19:26:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qxHj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!qxHj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!qxHj!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!qxHj!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!qxHj!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!qxHj!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!qxHj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg" width="1170" height="2051" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:2051,&quot;width&quot;:1170,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:0,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!qxHj!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!qxHj!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!qxHj!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!qxHj!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bc49534-20f2-4ac3-8f28-71a17e26878f_1170x2051.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Ryan Day (author of <em>Hands-On APIs for AI and Data Science, </em>O&#8217;Reilly) and writer of the Tip Sheet newsletter featured me in his <a href="https://ryan-day.kit.com/posts/tip-sheet-65-data-scientist-doctor-football-aficionado">issue #65 </a>last week.</p><p>He asked eight questions about my background, my stack, and how I learn. </p><p>There were three of them I wanted to expand a bit and share some thoughts with you.</p><div><hr></div><h3>Q4: Why are side projects valuable for people learning data science?</h3><p>In a side project you set the tone of what you want to build, why it matters, and how to measure if it worked.</p><p>You pick a problem you care enough about, you define the requirements, the scope, the technology and the dataset. It forces you to learn and think with a kind of clarity that structured learning rarely does. </p><p>I started with football analytics because I wanted to apply what I was learning to something I cared about and found fun enough and it has led me to push my knowledge forwards and collaborate with special people I wouldn&#8217;t think I&#8217;d meet if I didn&#8217;t build these kind of projects.</p><p>Fun fact is: this also helped to me work on healthcare data/AI projects on my day job. </p><h3>Q6: What methods of skill development have you benefited from most?</h3><p>I told Ryan I combine three: structured learning, project-based learning, and unstructured learning. </p><p>In this case my opinion is that the order matters.</p><p>Structured learning gives you the map and foundations to get the knowledge that you can then apply to projects. It doesn&#8217;t mean you need to learn everything there is about a topic and fall into rabbit holes, but just learning the necessary info to start building and leaving room for experimentation while you research stuff when you&#8217;re stuck.</p><p>On the other side unstructured learning like newsletters, blog posts, a well-curated social media timeline, keeps you updated to where the field is actually going. It can even give you some ideas to implement them yourself on your projects.</p><p>A dangerous trap is staying too long in one mode. </p><p>Entering tutorial hell by finishing a course and starting another course with no meaningful output (been there) creates an illusion of learning. Or jumping straight to building without a minimal foundation, spending weeks debugging something a couple hours read (or documentation) would have clarified.</p><p>The sweet spot is knowing when to shift from one to another. For example, if you&#8217;re new to something or you&#8217;re a bit confused, go with structured. </p><p>When you feel you got a good initial grasp of that knowledge, go build something even if it&#8217;s small, to make it stick. </p><p>If you feel you want to see how the field evolves, go with unstructured.</p><p>Right now I&#8217;m running all three in parallel: taking Agentic AI Engineering course at Towards AI Academy by Paul Iusztin and Louis-Fran&#231;ois Bouchard, applying it directly to a tool I&#8217;m building for myself, and constantly reading newsletters like Ryan&#8217;s to stay sharp on what people are shipping.</p><div><hr></div><h3>Q7: What would you tell people who want to keep developing their technical skills?</h3><p>To make it stick, I&#8217;ll put it inside quotes:</p><blockquote><p>Write about what you learn and share it online.</p></blockquote><p>Not for personal branding but because explaining something forces you to actually understand it.</p><p>Every post I&#8217;ve written about RAG pipelines, MCP, or football data sources has exposed gaps in my own thinking that I didn&#8217;t know were there until I tried to put them into words. This makes me want to understand things better. </p><p>Th big myth we need to debunk is the need for a big audience. You actually don&#8217;t. The &#8220;trick&#8221; is to be consistent even if you have a &#8220;small audience&#8221; or you think nobody&#8217;s going to listen. There are people out there that will definitely benefit from your point of view. </p><p>You can write a bug you fixed, the trade-off you made when deciding on your tech stack, the framework you just learn from one field and how you applied it to solve a problem in another.</p><p>Maybe ten people will read it but one of them might be building the exact same thing and needed exactly that post. Or one of them might be writing a newsletter and looking for someone to interview &#129335;&#127995;&#8205;&#9794;&#65039; </p><p>Your job is to make it exist. </p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?utm_source=email&r=&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/subscribe?utm_source=email&amp;r="><span>Subscribe</span></a></p><p>Here&#8217;s the link to the full interview: <strong><a href="https://ryan-day.kit.com/posts/tip-sheet-65-data-scientist-doctor-football-aficionado">Tip Sheet #65: Data Scientist, Doctor, Football Aficionado</a></strong></p><p></p><p>Till next time,</p><p>Ricardo.</p>]]></content:encoded></item><item><title><![CDATA[How a Football Framework for Measuring Performance Works For Other Industries]]></title><description><![CDATA[How you can apply this to healthcare, business or any other industry]]></description><link>https://ricardoheredia.substack.com/p/how-a-football-framework-for-measuring</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/how-a-football-framework-for-measuring</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Mon, 09 Mar 2026 07:03:03 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/77645acd-c8eb-461a-82fb-49b0c10ffdc8_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I used to think starting a data project was about jumping straight to the data, looking at what&#8217;s available and drawing conclusions. </p><p>That led to dashboards and models nobody used or cared. </p><p>Then last week in the Twelve Football Context Engineering course, I realized how the concept behind the framework for measuring team and player performance they teach could be used for solving problems in other areas.</p><h4>Asking questions first, then data </h4><p>I&#8217;ve been taking this course for the past two weeks and the knowledge compounds incrementally from one week to another. The goal is to create a project around qualities, metrics, pitch visuals and time series approach that they emphasize at Twelve. </p><p>Their framework starts with a simple instruction:</p><p><strong>Start with football. Not data.</strong></p><p>The first step is asking a human question like &#8220;what you are trying to answer and for whom?&#8221;.</p><p>What insight can you bring that no-one else has brought before?</p><p>An initial question might be: <em>What makes a good midfielder? </em>or <em>What makes a team dangerous in defensive transitions?</em></p><p>Once you&#8217;ve answered that in plain football language you move to the data. The idea is to build <em>Qualities &#8594; </em>composite scores that capture a specific aspect of player or team performance.</p><p>You choose 3 to 10 metrics that capture different aspects of the concept. Assign weights based on how important each one is to the original definition. Compute scores using z-scores and compare each player against the right group.</p><p>That last part is highly important.</p><p>For example when building a <em>Passing Quality</em> score for midfielders, you can end up with five metrics: Passes (xT), Passes into the final third (xT), Passes in the final third (xT), Crosses (xT), and Creative passes weighted at 30%, 20%, 20%, 20%, and 10% respectively. The result is a single score that tells you how threatening a midfielder&#8217;s passing is.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Buqg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Buqg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic 424w, /__u/substackcdn.com/image/fetch/$s_!Buqg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic 848w, /__u/substackcdn.com/image/fetch/$s_!Buqg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!Buqg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Buqg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic" width="1456" height="818" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:818,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83782,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/190276623?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Buqg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic 424w, /__u/substackcdn.com/image/fetch/$s_!Buqg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic 848w, /__u/substackcdn.com/image/fetch/$s_!Buqg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!Buqg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd6f3589-1ea2-434b-b2f6-6be3cb5d7e03_2482x1394.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Example for Kevin De Bruyne in PL 2022/2023 season</figcaption></figure></div><p>In this image you can see Belgian player Kevin De Bruyne scores near the top but the framework also tells you <em>why</em>, and which specific dimension he excels at versus where he&#8217;s merely good compared to other players. </p><p>That&#8217;s the useful part.</p><h4>Context is everything</h4><blockquote><p><em>&#8220;Metrics are meaningless without context. Choosing the correct comparison group is essential.&#8221;</em></p></blockquote><p>The comparison group (position, age, league, minutes played) is where we need to emphasize the analysis. Posing the problem and thinking clearly about it before writing the first line of code.</p><p>For example a midfielder with high progressive passes has a different meaning than an attacking midfield who sits deep in the field. </p><p>A 25 y/o player that has an elevated duel success rate has a different interpretation than a 32 y/o player in the same league. </p><p>To produce accurate insights, we need to use the same comparison pool of players.</p><h4>How you can use it in other industries </h4><p>Take diabetic patient monitoring. A case I&#8217;ve been actively working on in my day job.</p><p>The human question becomes: <em>How well is this patient managing their blood sugar?</em> </p><p>You define it in clinical terms first, consistent glucose levels, avoiding dangerous highs and lows, showing improvement over time. Then you look at what you can measure: HbA1c, time above range, time below range, trend direction, glucose variability.</p><p>You weight them by clinical importance to finally compare against patients of similar age, diabetes type, and diagnosis duration.</p><p>The output is a sentence a physician can actually use: </p><blockquote><p><em>&#8220;This patient&#8217;s glycemic control is below average for their profile, but trending in the right direction over the last six months. The main challenge is post-meal spikes, not overnight lows.&#8221;</em></p></blockquote><p>The focus is on turning data into a decision.</p><p>You could also apply this template for industries like customer churn in SaaS or credit risk in finance, by always starting with a human question.</p><h4>Key Takeaways</h4><p>The best analytical frameworks are domain-agnostic. They travel between industries.</p><p>Start with the human question by defining the concept before you open the dataset, choosing your comparison group deliberately, then let the data answer.</p><p>The framework already exists in your field and most people just never look outside their own.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share The Underdoc&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share The Underdoc</span></a></p><p>Thanks for reading one more time. </p><p>Till next time, </p><p>Ricardo. </p>]]></content:encoded></item><item><title><![CDATA[Wordalisation & Context Engineering: What Finally Made My RAG System Sound Like Football]]></title><description><![CDATA[My RAG system was technically correct but the resulting insights were useless for an analyst or a scout.]]></description><link>https://ricardoheredia.substack.com/p/wordalisation-and-context-engineering</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/wordalisation-and-context-engineering</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Tue, 03 Mar 2026 07:02:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1Mvg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>My RAG system was technically correct but the resulting insights were useless for an analyst or a scout.</p><p>The numbers and metrics were being computed, the LLM was receiving them, acknowledging them, and then repeating them back to me as if reading from a spreadsheet.</p><p>&#8220;Home xG was 1.2 and they scored 3 goals. Away PPDA was 4.8, indicating a high press...&#8221;</p><p>There was no enriched analysis it was just data recitation that didn&#8217;t sound like football language.</p><p>I was using claude-haiku-4.5 which is capable of writing football language. If you ask it to analyze a match in prose it&#8217;ll produce something close to what a scout would write. The model actually knew what a high press looked like, what a low block meant, defensive compactness, progressive passing patterns, etc, but by asking it to recite metrics I just wasn&#8217;t letting it &#8220;speak&#8221; football.</p><h4>The problem was my prompt not the model</h4><p>I was passing raw floats directly to the LLM (PPDA of 4.8, expected goals of 1.2, progressive pass counts, compactness scores) and then instructing it to &#8220;state only what the metrics directly prove&#8221; with &#8220;technical terminology and neutral tone.&#8221;</p><p>David Sumpter, the brain behind Soccermatics and Twelve Football, calls the solution &#8594; <a href="https://soccermatics.medium.com/introducing-wordalisations-automated-explanations-of-data-8e6687ad2d77">Wordalisation</a>. The idea is straightforward: before you call the LLM, classify your raw metrics into qualitative English labels. The model never sees the numbers. It only sees what those numbers mean in the language of the domain.</p><p>Here&#8217;s what the change looked like in practice.</p><p>Before, the user prompt contained something like this:</p><pre><code><code>home_ppda: 4.8
home_high_press_count: 12
home_compactness: 33.4
home_field_tilt: 67.9</code></code></pre><p>After applying Wordalisation, the LLM received this instead:</p><pre><code><code>home_press_style: pressed_aggressively_allowing_few_passes
home_defensive_shape: compact_block
home_territorial_dominance: dominated_final_third
home_shot_quality: created_high_quality_chances</code></code></pre><p>Just English labels describing what the team actually did, derived from the real Eredivisie 2025-2026 distributions rather than arbitrary thresholds.</p><p>The smoke test output shifted the result for good:</p><p>Before:</p><blockquote><p>&#8220;Home xG was 1.2 and they scored 3 goals. Away PPDA was 4.8...&#8221;</p></blockquote><p>After:</p><blockquote><p>&#8220;Heracles set up to frustrate, sitting deep and inviting PEC Zwolle to come at them &#8212; a coherent enough plan in isolation, but one that demanded defensive discipline and clinical use of the rare moments they could hurt the visitors on the break. A low block without the finishing to punish opponents on the counter is simply a slow surrender.&#8221;</p></blockquote><p>The data from the pipeline was exactly the same, but thanks to this tweak the output changed completely.</p><h4>The second change: how I formatted the context</h4><p>I implemented this one from a course I&#8217;m working through called <a href="https://academy.towardsai.net/courses/agent-engineering?ref=6f2638">Agentic AI Engineering from Towards AI</a>. </p><p>The lesson was about Context Engineering, the discipline of deciding what goes into a model&#8217;s context window in order to make it follow the right instructions.</p><p>One of the practical recommendations was: <strong>prefer YAML over JSON when providing structured data as input.</strong></p><p>I&#8217;d been using Python dicts serialized as JSON. The lesson argued YAML is more token-efficient and reads more naturally alongside prose examples in a prompt.</p><p>I ran a quick comparison on my own <code>&lt;tactical_labels&gt;</code> block.</p><p>JSON version:</p><pre><code><code>{
  "home_press_style": "pressed_aggressively_allowing_few_passes",
  "home_defensive_shape": "compact_block",
  "home_territorial_dominance": "dominated_final_third"
}
</code></code></pre><p>YAML version:</p><pre><code><code>home_press_style: pressed_aggressively_allowing_few_passes
home_defensive_shape: compact_block
home_territorial_dominance: dominated_final_third
</code></code></pre><p>The YAML block is shorter (no brackets, no quotes, no commas), and it reads more like prose which matters when it&#8217;s sitting next to few-shot examples written in natural language. The model processes both from the same context window. Found out that small token savings compound across many calls, and a cleaner context means less noise for the model to work through.</p><p><strong>The other Context Engineering principle I applied was prompt structure.</strong></p><p>The lesson covered something called the &#8220;lost-in-the-middle&#8221; problem: LLMs tend to underweight information placed in the middle of long contexts, so what they remember best is what comes first and what comes last.</p><p>The practical implication: you have to put your most important instructions at the START (system prompt) and at the END (<code>&lt;instructions&gt;</code> block). Dynamic content like match labels and retrieved facts goes in the middle.</p><p>And for caching: put static content first. That way the system prompt and few-shot examples don&#8217;t change between calls. Both go at the top, before any dynamic match data. This allows the provider to cache the static prefix and skips re-processing it on every requests.</p><p>My prompt structure now looks like this:</p><pre><code><code>&lt;system_prompt&gt;     &#8592; static, cached
  [scouting style instructions]

&lt;few_shot_examples&gt; &#8592; static, cached
  [two reference match analyses]

&lt;match_context&gt;     &#8592; dynamic per call
  [YAML labels for this match]

&lt;instructions&gt;      &#8592; static, repeated at end
  [core constraints, re-anchored]
</code></code></pre><p>The model gets its instructions twice. </p><p>Once at the top before anything else and once at the bottom after seeing the data. This is how we can avoid lost-in-the-middle.</p><h4>A broader principle connecting Wordalisation and Context Engineering</h4><p>Both are fundamentally about the same thing: giving the model the right kind of information.</p><p><strong>Wordalisation</strong> says: don&#8217;t give the model numbers and ask it to interpret them. Classify the numbers into domain language first, then give the model language it can work with.</p><p><strong>Context Engineering</strong>: don&#8217;t give the model everything you have. Select what&#8217;s relevant, compress what&#8217;s not, format it so the model can use it without fighting its own architecture.</p><p>Since the LLM does not work as a calculator nor a database we need to feed it with the right data: language.</p><h4>Key Takeaways</h4><p>The RAG system has a well curated data pipeline but now, at the point where structured data meets the language model, there&#8217;s a much needed translation layer that needs to be included.</p><p>The data flows like: Numbers &#8594; Labels &#8594; LLM &#8594; football insight.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!1Mvg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!1Mvg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!1Mvg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!1Mvg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!1Mvg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!1Mvg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1062725,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/189698006?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!1Mvg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!1Mvg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!1Mvg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!1Mvg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd921920d-f096-4a2d-9089-40c5a993db2e_2816x1536.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That&#8217;s exactly the principle of Wordalisation applied to Context Engineering.</p><p>Hope this gives you an idea on how to translate metrics into text, by leveraging LLM&#8217;s text generation capabilities.</p><p>Till next time, </p><p>Ricardo.</p><div><hr></div><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Underdoc! 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></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Embrace Your Weirdness]]></title><description><![CDATA[You might be an outlier and you might haven't realized it yet]]></description><link>https://ricardoheredia.substack.com/p/embrace-your-weirdness</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/embrace-your-weirdness</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Sat, 21 Feb 2026 13:38:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!nVLs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A concept I believe is really important nowadays when AI is closing the gap of what you can create and where you come from is: weirdness. The strange combination of skills that make you a valuable individual.</p><p>At some point of our lives, someone tells you to pick a lane.</p><p>The school, a teacher, family, social media. Maybe your own head at 2am wondering if you&#8217;re interested on too many things to ever be taken seriously at any of them.</p><p>&#8220;<em>Pick one thing, go deep enough and become an expert at that for the rest of your life.</em>&#8221;</p><p>Although the most interesting people I&#8217;ve come across didn&#8217;t get there by picking a lane but by refusing to.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/subscribe"><span>Subscribe now</span></a></p><h4>Specialists &amp; Outliers</h4><p>I&#8217;ve been recently reading Dan Koe&#8217;s <em>Purpose &amp; Profit</em> and a concept that grasped my attention was that the education system was never designed to help you reach your potential but to turn you into a useful workers in an interchangeable role.</p><p>Debatable but I can see the point behind it, if you&#8217;re only trained to do one thing you can&#8217;t adapt. Specialization isn't bad. But betting your entire identity on a single skill, in a world that's moving this fast, is the riskiest thing you can do.</p><h4>Your Weird Combination Is the Advantage</h4><p>I&#8217;ll use my own story here because it&#8217;s the most honest one I have.</p><p>I graduated from med school in Venezuela in 2019. But I felt something was off. Not wrong exactly, I knew I was supposed to be there but I wasn&#8217;t feeling fulfilled. </p><p>So I started exploring other things on the side: bartending, mobile app development, whatever I could get my hands on.</p><p>Then the pandemic hit, and I stumbled upon Python.</p><p>Something clicked. </p><p>I started applying it to football analytics and got immediately hooked. </p><p>I took MOOCs, networked with people in the industry, and eventually joined a non-profit group of analysts working with NWSL and national teams with real data from top providers like StatsBomb, Tracab, Opta.</p><p>Then I expanded into data science and machine learning applied to business. This expertise helped me land my first tech role at an AI consultancy, working on health projects and speech recognition. </p><p>Along the way, LLMs and RAGs came into the picture, and I started applying all of it to the projects I was already building.</p><p>At every step, someone raised an eyebrow.</p><p><em>Why tech? You are a doctor. Why football? You&#8217;re a doctor in tech. </em></p><p>I never had a clean answer, but I knew I was shaping the foundations of my identity. </p><p>At some point I got honest with myself about where I actually stood. I listed the gaps in my foundations: systems thinking, engineering depth, the ability to build things that work in production and not just in a notebook.</p><p>So I looked back at my background as my advantage and started building from it.</p><p>I had: </p><ul><li><p>A medical mindset </p></li><li><p>Data/AI engineering foundations </p></li><li><p>Football domain knowledge </p></li><li><p>AI tools to help me build and mix all of these. </p></li></ul><p>That led me to create my own Venn diagram intersection.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!nVLs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!nVLs!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic 424w, /__u/substackcdn.com/image/fetch/$s_!nVLs!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic 848w, /__u/substackcdn.com/image/fetch/$s_!nVLs!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!nVLs!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!nVLs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic" width="1456" height="874" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:874,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:22688,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/188697676?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!nVLs!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic 424w, /__u/substackcdn.com/image/fetch/$s_!nVLs!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic 848w, /__u/substackcdn.com/image/fetch/$s_!nVLs!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!nVLs!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee549504-5888-47ed-a9c7-cd26bc607355_1500x900.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image by Claude</figcaption></figure></div><p>That&#8217;s Koe&#8217;s point when he says <em>you are the niche</em>. </p><p>Most people spend their careers searching for an external niche to fit into (I&#8217;ve been guilty of that too). But your specific combination of experience and context it&#8217;s already a niche. You're standing in it.</p><p>A couple of days ago on a Saturday night, I was building my football RAG system (a project that&#8217;s teaching a lot on engineering foundations), and I lost track of time. I ended working from 9pm to 3am. It felt like craft and I think that&#8217;s what happens when you stop fighting your weird path and start building from it. </p><h4>Mapping Your Own Stack</h4><p>Some self-awareness is necessary here to understand how to mix your skills, (might sound like a self help book advice but trust me, you need to sit with yourself on this). I want to give you something I didn&#8217;t have at the beginning of my journey: a starting point. </p><p>Start by asking yourself these three questions. Note them down on a notepad, Notion, or somewhere else you can easily go back to:</p><ul><li><p><strong>Is there something you know that most people in your field don&#8217;t?</strong> Something specific rather than general. What context do you bring that wasn&#8217;t in the job description?</p></li><li><p><strong>Where do your interests converge?</strong> The things you read on weekends, the problems you notice in one domain that nobody there is thinking about because they don&#8217;t have your other domain to compare it to.</p></li><li><p><strong>What can you build to work at the intersection of it?</strong> Think in projects, tools, analyses, newsletters. Something concrete that only you could have built from exactly where you&#8217;re standing.</p></li><li><p>An extra: <strong>How can you leverage the use of AI to boost your skills?</strong> </p></li></ul><p>I would start from there. </p><h4>May The Weird Ones Prevail</h4><p>We now know the system was not designed for this but AI is compressing the value of standard skills faster than most people are ready for. </p><p>What it can&#8217;t compress is taste, context, and the specific lens you&#8217;ve built from an unusual combination of experiences.</p><p>The people who do well in what&#8217;s coming won&#8217;t be the deepest specialists or the broadest generalists.</p><p>They&#8217;ll be the ones who can see across domains, connect things that shouldn&#8217;t logically connect, and build things that require a very specific, very strange set of keys to unlock.</p><p>Your weirdness is your moat. </p><div><hr></div><p>This newsletter is about building AI systems, using football analytics as the sandbox. But every now and then it's worth stepping back to talk about why we build what we build, and how we decide what's worth building next.</p><p>Till next time, </p><p>Ricardo. </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share The Underdoc&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share The Underdoc</span></a></p><p></p><p></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Shipping a RAG System App to HF Spaces with Gradio]]></title><description><![CDATA[Building the GUI for the end user and next steps to scale this]]></description><link>https://ricardoheredia.substack.com/p/shipping-a-rag-system-app-to-hf-spaces</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/shipping-a-rag-system-app-to-hf-spaces</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Tue, 10 Feb 2026 07:02:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Avxv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is the last article from the series: <a href="/__u/substack.com/@theunderdoc/p-182493528">Building a RAG System That Generates Football Post-Match Tactical Reports Automatically</a></p><p>In previous articles we&#8217;ve covered: </p><ul><li><p>Engineering the data pipeline: <a href="/__u/ricardoheredia.substack.com/p/rag-is-a-data-engineering-heavy-problem?r=56fjux">RAG is a Data Engineering Heavy Problem: Building a Football ETL for AI</a></p></li><li><p>Evaluating the prompt and system outputs with EDD: <a href="/__u/ricardoheredia.substack.com/p/from-vibes-to-metrics-how-i-evaluated">From Vibes to Metrics: How I Evaluated A Football RAG System</a></p></li></ul><p>Today I&#8217;ll be talking about the challenges of designing a user interface to interact with in an effort to make it as comfortable as possible. </p><p>This marks the end of these series on how I&#8217;ve built this MVP, which I&#8217;m scaling into an automated data platform that generates football post match reports and can run on your own computer.</p><p>You can find the entire code on the GitHub repository and the new releases: <a href="https://github.com/ricardoherediaj/football-rag-intelligence">Football RAG Intelligence</a></p><h3>What&#8217;s Gradio and Why I Chose it</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!6njm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!6njm!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!6njm!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!6njm!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!6njm!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!6njm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg" width="600" height="161" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:161,&quot;width&quot;:600,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:18498,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/187177098?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce81acd5-6d1a-4477-8a50-842dd3ab8255_600x600.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!6njm!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!6njm!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!6njm!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!6njm!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc1526f7-e17c-4a82-a4dc-6e91c3750462_600x161.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>If you haven&#8217;t heard of it already, Gradio is an open-source Python framework that allows developers to quickly build and deploy interactive web interfaces for ML models and data pipelines. </p><p>In the context of the Football RAG platform, I used it as a lightweight presentation layer to connect the user to all the backend logic (pipelines, LLM orchestration). </p><p>At this stage of development, the goal was to keep it simple. I chose Gradio over Streamlit for these reasons:</p><ul><li><p>Avoid rerunning the script each time there&#8217;s retrieval. </p></li><li><p><strong>API capabilities</strong>: Gradio automatically generates a REST API for your interface, making it easier to treat the UI as modular rather than a monolith.</p></li><li><p><strong>LLM Integration</strong>: Gradio&#8217;s <code>ChatInterface</code> component is purpose-built for the conversational nature of RAG, allowing me to focus on prompt<strong> </strong>optimization rather than building widgets.</p></li><li><p><strong>Fast iteration</strong>: working with 108 matches, it allowed for a full database rebuild and UI refresh in seconds.</p></li></ul><p>Although in the future I could move to another frontend, this was enough to validate the idea. </p><h3>HuggingFace Spaces Deployment</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!GKF_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!GKF_!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic 424w, /__u/substackcdn.com/image/fetch/$s_!GKF_!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic 848w, /__u/substackcdn.com/image/fetch/$s_!GKF_!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!GKF_!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!GKF_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic" width="608" height="342" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:608,&quot;bytes&quot;:19707,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/187177098?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!GKF_!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic 424w, /__u/substackcdn.com/image/fetch/$s_!GKF_!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic 848w, /__u/substackcdn.com/image/fetch/$s_!GKF_!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!GKF_!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6b8f7ff-ab4a-4809-8b34-33cba36edda6_1280x720.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The simplest way to host an AI/ML demo without becoming a full-time DevOps engineer was a using HuggingFace Spaces.</p><p>It&#8217;s basically a managed hosting service where you can drop your Gradio app. </p><p>Some characteristics: </p><ul><li><p><strong>GitHub-Style Deployment:</strong> You push your code to a repository, and Spaces automatically builds the container and serves the app to a public URL.</p></li><li><p><strong>Seamless Integration:</strong> Since it&#8217;s natively built for the ecosystem, it handles the Gradio environment and Python dependencies out of the box.</p></li><li><p><strong>Free Tier:</strong> It provided the perfect &#8220;sandbox&#8221; for the MVP, giving me a URL to share it publicly using generous CPU compute.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!ryxo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!ryxo!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic 424w, /__u/substackcdn.com/image/fetch/$s_!ryxo!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic 848w, /__u/substackcdn.com/image/fetch/$s_!ryxo!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!ryxo!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!ryxo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic" width="692" height="394.00274725274727" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:829,&quot;width&quot;:1456,&quot;resizeWidth&quot;:692,&quot;bytes&quot;:248575,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/187177098?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!ryxo!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic 424w, /__u/substackcdn.com/image/fetch/$s_!ryxo!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic 848w, /__u/substackcdn.com/image/fetch/$s_!ryxo!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!ryxo!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9163375-7bd3-453d-8863-6bdda6f3c936_2870x1634.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>A Reality Check: MVP vs. Production</h4><p>Grado helped to build the UI easily, but making it "industrial-grade" meant facing a few technical issues.</p><h5>1. Deployment Binary Bug</h5><p>I hit a snag where the specific binaries for my vector store behaved differently on Mac vs. the Linux environment in Spaces. </p><p>Standardizing with <strong>uv</strong> and clean lockfiles was the way out.</p><h5>2. The $0 Intent Routing Trick:</h5><p>Saving tokens was necessary from the beginning, so I built a <strong>Smart Router</strong>:</p><ul><li><p><strong>Questions</strong> like &#8220;How did this team play?&#8221; or &#8220;Why did this team had X metric during that match?&#8221; &#8594; It goes to the LLM for tactical analysis.</p></li><li><p><strong>Visualization commands</strong> like &#8220;Show passing network plot from the match&#8221; &#8594; These bypass the LLM and trigger my Matplotlib visualizers at zero cost. </p></li></ul><h5>The "Airlock" ETL</h5><p>Talked about this in previous matches but decoupling the ingestion from the UI helped me caught data bugs like a "Home/Away swap" that was messing up team stats before they reached the user.</p><p>Here&#8217;s how the frontend looks for now in HF Spaces: </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!xVFA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!xVFA!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic 424w, /__u/substackcdn.com/image/fetch/$s_!xVFA!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic 848w, /__u/substackcdn.com/image/fetch/$s_!xVFA!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!xVFA!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!xVFA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic" width="1456" height="859" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic&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;:188624,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/187177098?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!xVFA!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic 424w, /__u/substackcdn.com/image/fetch/$s_!xVFA!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic 848w, /__u/substackcdn.com/image/fetch/$s_!xVFA!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!xVFA!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3520e-cc6e-4183-bc3f-013353e06dee_2880x1700.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!ZC4K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!ZC4K!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic 424w, /__u/substackcdn.com/image/fetch/$s_!ZC4K!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic 848w, /__u/substackcdn.com/image/fetch/$s_!ZC4K!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!ZC4K!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!ZC4K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic" width="1456" height="854" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:854,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:241478,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/187177098?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!ZC4K!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic 424w, /__u/substackcdn.com/image/fetch/$s_!ZC4K!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic 848w, /__u/substackcdn.com/image/fetch/$s_!ZC4K!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!ZC4K!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43d750c0-f25d-47b8-8dfd-f1c36fdc9efb_2876x1686.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Lesson Learned</h3><p>The biggest takeaway from building this GUI and deploying the MVP is:</p><p><strong> 90% is Data Engineering, and the AI part is just the tip.</strong></p><p>You need to provide a well crafted plumbing so the system does meaningful retrieval and the user, through a comfortable UI can obtain valuable information. </p><p>Precalculating everything (compute 38 tactical metrics during ETL) helps for instant retrieval.</p><p>Validate with data contracts before moving the data forward (Pydantic)</p><p>Keeping it simple for the GUI, for quick adoption. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Avxv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Avxv!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!Avxv!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!Avxv!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!Avxv!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Avxv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:438592,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/187177098?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Avxv!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!Avxv!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!Avxv!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!Avxv!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aaee7f9-6ecd-45dd-9488-62f4f9164e45_2816x1536.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Final Architecture</figcaption></figure></div><h3>What&#8217;s Next?</h3><p>Now that the demo is live and the concept is validated, I&#8217;m scaling from 108 matches to 1,000+. </p><p>I&#8217;ll be documenting that journey. In the next series we&#8217;re talking about moving to a proper infrastructure: </p><ul><li><p><strong>MinIO</strong> for object storage (S3-compatible, runs locally)</p></li><li><p>Dagster orchestrating the pipelines </p></li><li><p>dbt + DuckDB handling the analytical workloads. </p></li><li><p>Everything on-premise with Docker services </p></li><li><p>Modal free tier for serverless LLM inference on cloud GPU<strong>s.</strong></p></li></ul><p>The goal: </p><blockquote><p>An automated data platform that generates post-match tactical reports for any match, running entirely on your own machine, with cheap cloud costs for the heavy lifting.</p></blockquote><p>If you&#8217;ve been following along, you now have a blueprint for building a working RAG system with documented engineering decisions.</p><p>The next series starts soon.</p><p>If there&#8217;s a specific part of the architecture you want me to dig deeper into, please let me know in the comments.</p><div><hr></div><p><strong>Check out the code:</strong> <a href="/__u/ricardoheredia.substack.com/link">Football RAG Intelligence GitHub Repository</a></p><p><strong>Try the live demo:</strong> <a href="/__u/ricardoheredia.substack.com/link">HuggingFace Spaces</a></p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Underdoc! 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>Thanks for reading till the end.</p><p>See you next time,</p><p>Ricardo. </p><p></p>]]></content:encoded></item><item><title><![CDATA[From Vibes to Metrics: How I Evaluated A Football RAG System]]></title><description><![CDATA[Before I started building this project, my initial workflow for creating post match reports was based in pure vibes.]]></description><link>https://ricardoheredia.substack.com/p/from-vibes-to-metrics-how-i-evaluated</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/from-vibes-to-metrics-how-i-evaluated</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Fri, 30 Jan 2026 12:12:36 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/d42ac607-f2d5-4708-9d8f-3826bab28cd7_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Before I started building this project, my initial workflow for creating post match reports was based in pure vibes. </p><p>I would write a massive prompt, ask the LLM to analyze a match, read the response, and think, <em>&#8220;good enough.&#8221;</em> </p><p>This approach is not bad at the beginning, but if you want a <strong>successful </strong>system that generates trustworthy outputs, they should be evaluated from beginning to end both subjectively and <strong>objectively</strong>. </p><h3>Moving to EDD</h3><p>After reviewing different approaches, I adopted the <strong>Evaluation Driven Development (EDD)</strong>, a methodology discussed by <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Hugo Bowne-Anderson&quot;,&quot;id&quot;:63978139,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!_vkH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941a1d5e-0a5f-45f8-8400-737c0bf9f85d_400x400.jpeg&quot;,&quot;uuid&quot;:&quot;8dc72fc6-cd6b-483e-b334-addb6f8eb64f&quot;}" data-component-name="MentionToDOM"></span> in <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Decoding AI Magazine&quot;,&quot;id&quot;:1526003,&quot;type&quot;:&quot;pub&quot;,&quot;url&quot;:&quot;https://open.substack.com/pub/decodingml&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/00bc74e0-3601-49ce-8ab9-4c7b499ce597_1280x1280.png&quot;,&quot;uuid&quot;:&quot;1b8b5fa9-23be-40b2-a76f-d81306ea5c00&quot;}" data-component-name="MentionToDOM"></span> article <a href="https://www.decodingai.com/p/escaping-poc-purgatory-evaluation">Escaping POC Purgatory: Evaluation-Driven Development for AI Systems</a>. </p><p>Where the core philosophy is: </p><blockquote><p><em><strong>You cannot optimize what you cannot measure</strong></em></p></blockquote><p>So instead of treating evaluation as a final step, you build the test harness <em>before</em> you finish building the system.</p><p>I&#8217;ll walk you through thow I used EDD to engineer my prompts in three steps:</p><ol><li><p><strong>The Metrics:</strong> Why I chose <strong>Retrieval Accuracy</strong>, <strong>Faithfulness</strong>, and <strong>Tactical Insights </strong>rules<strong>.</strong></p></li><li><p><strong>The Optimization Loop:</strong> Moving from <strong>Prompt V1.0</strong> (1800 tokens, slower, and a bit more expensive) to <strong>Prompt V3.5</strong> (360 tokens, more precise to what I wanted).</p></li><li><p><strong>The Results:</strong> Critical bugs caught at the beginning.</p></li></ol><h3>Golden Answers</h3><p>In my <a href="/__u/www.google.com/search?q=LINK_TO_PREVIOUS_ARTICLE">previous article</a>, I broke down how I built the <strong>Golden Dataset</strong> (<code>matches_gold.json</code>) since it&#8217;s crucial to understand <em>why</em> that dataset exists in the context of evaluation.</p><p>In standard software engineering, you write unit tests based on expected inputs and outputs, that&#8217;s the traditional software development lifecycle (SDLC). </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!y4vU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!y4vU!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png 424w, /__u/substackcdn.com/image/fetch/$s_!y4vU!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png 848w, /__u/substackcdn.com/image/fetch/$s_!y4vU!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png 1272w, /__u/substackcdn.com/image/fetch/$s_!y4vU!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!y4vU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png" width="611" height="243.8125" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:581,&quot;width&quot;:1456,&quot;resizeWidth&quot;:611,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!y4vU!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png 424w, /__u/substackcdn.com/image/fetch/$s_!y4vU!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png 848w, /__u/substackcdn.com/image/fetch/$s_!y4vU!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png 1272w, /__u/substackcdn.com/image/fetch/$s_!y4vU!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f89465-43be-4c95-b126-3e350ad77ddd_1600x638.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Traditional software development: linear, testable, predictable. <a href="https://www.decodingai.com/p/escaping-poc-purgatory-evaluation">Escaping POC Purgatory: Evaluation-Driven Development for AI Systems</a>. </figcaption></figure></div><p>When working with LLMs, defining &#8220;expected output&#8221; is harder because these models are non-deterministic, meaning you can give an LLM the same input and get two different outputs. </p><p>This leads to a more dynamic process through the entire GenAI application lifecycle. More iterations during your development and your way to production. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!vDEK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!vDEK!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png 424w, /__u/substackcdn.com/image/fetch/$s_!vDEK!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png 848w, /__u/substackcdn.com/image/fetch/$s_!vDEK!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png 1272w, /__u/substackcdn.com/image/fetch/$s_!vDEK!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!vDEK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png" width="624" height="297.42857142857144" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:694,&quot;width&quot;:1456,&quot;resizeWidth&quot;:624,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!vDEK!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png 424w, /__u/substackcdn.com/image/fetch/$s_!vDEK!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png 848w, /__u/substackcdn.com/image/fetch/$s_!vDEK!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png 1272w, /__u/substackcdn.com/image/fetch/$s_!vDEK!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bb1996b-b4a1-48a9-be8c-01fb5d521ca0_1600x763.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Evaluation &amp; Monitoring are part of the process since day one. <a href="https://www.decodingai.com/p/escaping-poc-purgatory-evaluation">Escaping POC Purgatory: Evaluation-Driven Development for AI Systems</a>. </figcaption></figure></div><p>In order to battle with that non-deterministic nature, I wanted to grade the system responses. See if they matched with the answers I was expecting. </p><p>That meant combining football knowledge with technology capabilities and creating a &#8220;Source of Truth&#8221; that I trusted 100% &#8594; <strong>The</strong> <strong>Golden Dataset</strong>. A ground truth that acts as the teacher&#8217;s answer key, containing the exact stats (validated by Pydantic before) for every match.</p><p>Without this, I would be just guessing and depending entirely on the LLM&#8217;s capacity.</p><p>Now that I had the answer key in hand, I needed a way to automate the grading of the system.</p><h3>The Judge: A 3-Metric Framework</h3><p>Since human evaluation doesn't go that far as LLM can, I adopted the "LLM-as-a-Judge" methodology. In the book <em>AI Engineering</em>, Chip Huyen identifies the AI judge as:</p><blockquote><p>A critical evaluation method, noting its specific utility in measuring complex metrics such as the "factual consistency between the response and the whole context&#8221;. (Huyen, 2024).</p></blockquote><p>By implementing this, we can automate the evaluation without only relying on manual review.</p><p>The evaluation harness uses the <strong>LLM-as-a-Judge</strong> pattern:</p><ol><li><p><strong>The Analyst:</strong> Claude 3 Haiku (Fast, Cheap ~$0.0001 per query) generates the report. It's optimized for speed but since speed comes with trade-offs, Haiku can occasionally miss nuances or hallucinate stats.</p></li><li><p><strong>The Judge:</strong> Claude 3.5 Sonnet (Stronger, Slower) grades the report. It catches these issues. It's slower and more expensive, but it only runs during evaluation, not intended for production. This means I can test rigorously without blowing my API budget. </p></li></ol><p>Why Anthropic's models? Honestly, I had a remaining balance there from previous experiments and wanted to blow them away. But I could have used Gemini, OpenAI, whatever. You can use any other "bigger" model for this, even a local one with Ollama.</p><h4>The 3-Metric System</h4><p>However, I needed to know why a report failed. If it was hallucination or did it ignore the charts or any other relevant part?</p><p>The evaluation framework measures three dimensions:</p><p><strong>1. Retrieval Accuracy (30%)</strong> - Did we find the right match?</p><p>Early on, I noticed reports would analyze the wrong match or mix up team stats. The system would retrieve &#8220;Ajax vs. Heracles&#8221; when I asked about &#8220;Ajax vs. Telstar.&#8221; (I&#8217;ll show you an error like this at the end).</p><p>This metric uses metadata filtering to verify the system found the exact match requested. It&#8217;s deterministic in a way so either it got the right match (100%) or it didn&#8217;t (0%). </p><p><strong>Evaluation Result: 100%</strong> &#9989;</p><p><strong>2. Faithfulness (30%)</strong> - Are the numbers accurate?</p><p>This is the guardrail preventing &#8220;hallucinations&#8221; where the model invents stats. </p><p>Early reports claiming &#8220;Ajax had 73% possession&#8221; when the actual number was 64.3%. Or &#8220;Player #14 made 28 passes&#8221; when it was 23.</p><p>The judge uses regex to extract every number from the report, then cross-checks it against <code>matches_gold.json</code>. Any number not in the source data = hallucination = failed faithfulness check.</p><p><strong>Evaluation Result: 99.4%</strong> &#9989;</p><p><strong>3. Tactical Insight (40%)</strong> - Is the analysis tactically sound?</p><p>I broke it into four measurable components:</p><ul><li><p><strong>Specificity (10%)</strong>: Does it cite concrete evidence? Counts specific references like player IDs, exact percentages, tactical metrics. </p></li><li><p><strong>Visual Grounding (10%)</strong>: Does it reference what&#8217;s actually in the visualizations? Reports should mention &#8220;The Passing Network shows Player #14 as the hub&#8221; and not just a generic commentary. This forces the system to tie text to visuals.</p></li><li><p><strong>Terminology (10%)</strong>: Does it use correct football language? The judge verifies terms against <code>tactical_rules.py</code> (e.g., &#8220;Field Tilt,&#8221; &#8220;Progressive Passes,&#8221; &#8220;PPDA,&#8221; &#8220;Verticality&#8221;) to avoid generic concepts</p></li><li><p><strong>Relevance (10%)</strong>: Does it answer the user&#8217;s actual question? If someone asks about pressing strategy, then the response shouldn&#8217;t be about passing accuracy.</p></li></ul><p>A report can be factually accurate (Faithfulness = 100%) but tactically shallow (Tactical Insight = 40%). </p><p><strong>Evaluation Result: 95.0%</strong> &#9989;</p><h4>Codifying "Vibes" into Rules</h4><p>This question was also bugging me from the start: &#8220;How do you mathematically prove a report is tactically sound?&#8221; </p><p>Since what I&#8217;m trying to do there is translating stats and tactical dashboards from post match analyses into explainable text, I couldn't let the LLM guess what the stats meant. </p><p>I had to define a way of teaching the system the coordinates used in the WhoScored and Fotmob data, how they are calculated, and displayed in the field visualizations with the mplsoccer library. </p><p>So, I built a file called <code>tactical_rules.py</code> that reverse-engineers the visualizations into text logic.</p><p>For example, I defined <strong>Verticality</strong> thresholds explicitly:</p><pre><code>def interpret_verticality(verticality: float) -&gt; str:
    if verticality &gt; 50:
        return "direct vertical passing - quick transitions"
    elif verticality &gt; 35:
        return "balanced build-up"
    else:
        return "patient possession-based build-up"</code></pre><ul><li><p><strong>Scenario:</strong> Ajax has a verticality of <strong>72%</strong>.</p></li><li><p><strong>Bad Output:</strong> &#8220;Ajax played patiently.&#8221; (Judge fails this: 72% &gt; 50%, so it <em>must</em> be direct).</p></li><li><p><strong>Good Output:</strong> &#8220;Ajax played a direct game with quick transitions.&#8221; (Judge passes this).</p></li></ul><p>If Ajax has 72% verticality and the report says "patient build-up," is a vague description. The judge verifies those numbers exist and it checks if the tactical language matches what <code>tactical_rules.py</code> says those numbers should mean.</p><p>Think of `tactical_rules.py` as the rubric, and the judge as the grader applying it.</p><p>Of course, in the future this can change depending on what rules you want to add or readapt. This was a first attempt of contributing to the evaluation harness trustworthiness.</p><h4>The Weighted Scoring Rubric</h4><p>To bring it all together, I created a weighted rubric that scores every generated report on a 10-point scale.</p><pre><code>Weighted Score = (Retrieval &#215; 0.30) + (Faithfulness &#215; 0.30) + (Specificity &#215; 0.15) + (Visual Grounding &#215; 0.15) + (Terminology &#215; 0.15) + (Relevance &#215; 0.15) + (Conciseness &#215; 0.10) </code></pre><p><strong>A report must score &#8805; 7.0/10 to be considered production-ready.</strong></p><h4>Scoring Examples: A Good Analysis But Wrong Retrieval</h4><p>Here's where evaluation gets interesting. Sometimes the system produces excellent tactical analysis but for the wrong match.</p><p><strong>What I asked:</strong> &#8220;Analyse Feyenoord vs Ajax match&#8221;</p><p><strong>What the system retrieved:</strong> Feyenoord vs FC Volendam</p><p><strong>Report Generated:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!eCy_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!eCy_!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png 424w, /__u/substackcdn.com/image/fetch/$s_!eCy_!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png 848w, /__u/substackcdn.com/image/fetch/$s_!eCy_!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png 1272w, /__u/substackcdn.com/image/fetch/$s_!eCy_!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!eCy_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png" width="725" height="427.7300824175824" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:859,&quot;width&quot;:1456,&quot;resizeWidth&quot;:725,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Text Analysis&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="Text Analysis" title="Text Analysis" srcset="/__u/substackcdn.com/image/fetch/$s_!eCy_!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png 424w, /__u/substackcdn.com/image/fetch/$s_!eCy_!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png 848w, /__u/substackcdn.com/image/fetch/$s_!eCy_!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png 1272w, /__u/substackcdn.com/image/fetch/$s_!eCy_!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c0c9470-b97c-4e71-8c3b-29e9f90e4993_2880x1700.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Here's what the system actually returned (screenshot from the live demo).</figcaption></figure></div><p>That might be too small to read, here&#8217;s the answer: </p><p>&#8220;<strong>Match Overview</strong>: Feyenoord demonstrated superior territorial dominance with a significantly higher average team position (62.4m vs 33.9m). The home team&#8217;s lower PPDA of 9.2 indicated more aggressive pressing compared to Volendam&#8217;s 15.36, suggesting consistent offensive pressure and a controlled possession strategy.</p><p><strong>xG &amp; Shot Efficiency</strong>: Feyenoord generated substantially higher shot volume and quality, with 37 shots generating 4.82 xG versus Volendam&#8217;s 9 shots and 0.83 xG. The significant xG differential suggests consistent high-quality chance creation, with each Feyenoord shot averaging approximately 0.13 xG compared to Volendam&#8217;s 0.09 xG per shot.</p><p><strong>Pressing &amp; Progression</strong>: Progressive passing metrics (156 vs 114) reinforced Feyenoord&#8217;s offensive control. High press events (5 vs 3) further illustrated their tactical superiority in disrupting opponent&#8217;s build-up play. The defensive line positioning (13.0m vs 8.6m) confirmed Feyenoord&#8217;s ability to maintain more advanced, proactive defensive structure.</p><p><strong>Key Tactical Insight</strong>: Total pass volume (513 vs 429) combined with superior progressive passing demonstrates Feyenoord&#8217;s systematic approach to ball progression and territorial domination, directly translating into offensive efficiency and match control.&#8220;</p><p><strong>Judge Evaluation:</strong></p><ul><li><p>Retrieval: <strong>0/10</strong> (30%) - <strong>Wrong match retrieved</strong> (asked for Ajax, got Volendam)</p></li><li><p>Faithfulness: 10/10 (30%) - All numbers verified for Feyenoord vs Volendam match</p></li><li><p>Tactical Insight breakdown:</p><ul><li><p>Specificity: 10/10 (15%) - Dense with exact metrics (62.4m, 9.2 PPDA, 4.82 xG, 156 progressive passes)</p></li><li><p>Visual Grounding: 9/10 (15%) - References positional data and tactical patterns</p></li><li><p>Terminology: 10/10 (15%) - Perfect use of PPDA, progressive passes, xG/shot, defensive line</p></li><li><p>Relevance: 10/10 (15%) - Excellent explanation of tactical dominance</p></li></ul></li></ul><p>Conciseness: 10/10 (10%) - 220 words, slightly over but acceptable</p><p><strong>Weighted Final Score: 6.7/10</strong> &#10060; <strong>Failed</strong> </p><p>This is a dangerous type of failure in production systems.</p><p>The analysis is <strong>tactically excellent</strong>. If you only read the commentary, you&#8217;d think the system nailed it.</p><p>But it&#8217;s analyzing the <strong>wrong match</strong>.</p><p>This is<strong> </strong>likely a vector database issue, either the embedding similarity between &#8220;Feyenoord vs Ajax&#8221; and &#8220;Feyenoord vs FC Volendam&#8221; was high enough to return the wrong match, or the metadata filtering didn&#8217;t catch it.</p><p>This example shows why without the retrieval check, this report would score <strong>9.5/10</strong> on analysis quality alone. But it&#8217;s completely useless because it&#8217;s not what the user asked for.</p><p>A coach asking about the Ajax match would make wrong decisions based on Volendam data.</p><p><strong>The fix:</strong> Tighter metadata filtering + explicit team name verification in the retrieval step. This is why <code>matches_gold.json </code>exists, in order to verify we&#8217;re analyzing the exact match that was requested.</p><h4>What Good Evaluation Looks Like and Common Failure Modes</h4><p>When all three dimensions work correctly (right match retrieved, accurate numbers, insightful analysis) the system produces reports that score high &#8805;9.0/10:</p><ul><li><p>Retrieval: 10/10 - Correct match identified</p></li><li><p>Faithfulness: 10/10 - Every number verified against <code>matches_gold.json</code></p></li><li><p>Tactical Insight: 9-10/10 across all four checks (Specificity, Visual Grounding, Terminology, Relevance)</p></li><li><p>Conciseness: 10/10 - Under 200 words (it&#8217;s ok if slightly longer)</p></li></ul><p>The judge validates this automatically across all 108 matches in the dataset, catching failures that manual review would miss.</p><p>That away the system surfaced three failure patterns:</p><ol><li><p>Wrong retrieval: Feyenoord vs Volendam example above &#8594; fix with stricter metadata filtering.</p></li><li><p>Shallow analysis: generic commentary with no specific metrics or insights &#8594; tweaking prompt to emphasize specificity.</p></li><li><p>Hallucinated stats &#8594; catch errors early in the data engineering pipeline. </p></li></ol><h4>Takeaways from this Section</h4><ul><li><p>Turn subjective quality ("does this sound good?") into objective metrics (&#8220;does this score &#8805;7.0/10?&#8220;)</p></li><li><p>Numerical verification + tactical interpretation allows the system to move from "vibes-based development" to evaluation-driven development.</p></li><li><p>A system can sound smart while being completely wrong. This helps you catch errors in an automatic way since the beginning. </p></li></ul><h3>The Prompt Optimization Loop: From 1800 to 360 Tokens</h3><p>With the evaluation harness in place, In parallel I could measure what was actually working.</p><p>I tested prompts in Anthropic Console before touching code. </p><p>Each iteration was scored against the 10-match eval dataset.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!C6Xd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!C6Xd!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic 424w, /__u/substackcdn.com/image/fetch/$s_!C6Xd!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic 848w, /__u/substackcdn.com/image/fetch/$s_!C6Xd!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!C6Xd!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!C6Xd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic" width="724" height="378.9065934065934" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:762,&quot;width&quot;:1456,&quot;resizeWidth&quot;:724,&quot;bytes&quot;:335689,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/186174038?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!C6Xd!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic 424w, /__u/substackcdn.com/image/fetch/$s_!C6Xd!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic 848w, /__u/substackcdn.com/image/fetch/$s_!C6Xd!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!C6Xd!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F762cc7dd-d6c8-4eee-9828-a1c6516c67a9_2866x1500.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Claude Console with the winning System Prompt from V3.5. </figcaption></figure></div><p>The evolution of iteration was like this:</p><p><strong>V1.0</strong>: 1800 tokens, 5.0/5.0 quality &#8594; Everything explicit, verbose<br><strong>V2.0</strong>: 800 tokens, 3.2/5.0 quality &#8594; Removed too much, quality tanked<br><strong>V3.0</strong>: 400 tokens, 3.8/5.0 quality &#8594; Added structured sections back<br><strong>V3.5</strong>: 360 tokens, 4.9/5.0 quality &#8594; <strong>Winner</strong></p><p>You can check how I stablished this prompt testing workflow in the repo: <a href="https://github.com/ricardoherediaj/football-rag-intelligence/tree/main/prompts">&#9917; Football RAG Intelligence</a></p><p>The V3.5 version added explicit metric interpretations directly in the prompt like: </p><ul><li><p>&#8220;Lower PPDA = more aggressive pressing&#8221;</p></li><li><p>&#8220;Higher position values = more advanced positioning&#8221;</p></li></ul><p>Also adding the required section headers (Match Overview, xG &amp; Shot Efficiency, Pressing &amp; Progression, Key Tactical Insight).</p><p>And limited constraints in the amount of text generated: &#8220;180-220 words&#8221; instead of just &#8220;be concise.&#8221;</p><p><strong>Result:</strong> 80% token reduction, dropping the cost per query from about $0.0018 to $0.0004.</p><h3>Wrapping Up</h3><p>When building GenAI systems you need to stick to a set of  best practices. I considered this ones:</p><p><strong>Evaluate first optimize later.</strong> I built the judge before iterating with prompts and before creating the vector database, cause I wanted every change measured and every response in consonance with the data I had. </p><p><strong>Prompt-first design pays off.</strong> I designed Prompt V3.5 before building the ChromaDB schema, in an attempt to reduce retrieval-generation mismatch. The ideal scenario is to align the metadata with what the prompt needs.</p><p><strong>Pre-calculate during ingestion.</strong> 38 tactical metrics were computed during ingestion, this helps to make fast rebuilds if the logic changes, a simpler RAG pipeline, fewer tokens, and stable prompts.</p><p>Building systems requires evaluation in every step of the journey. </p><p>Using Evaluation-Driven Development to cut tokens, go from vibes to data-driven analyses, and automated validation is what helps you get more a trustworthy working product.</p><p>Thanks for reading until the end, hope this helps you think of a way to evaluate your own systems. </p><p>If so, I&#8217;d love to know what other approaches are you considering when evaluating your RAG/LLM/Agentic apps.</p><div><hr></div><p>See you next time,</p><p>Ricardo. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Underdoc! 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></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Farewell FBref Advanced Stats: When One Door Closes Another Opens]]></title><description><![CDATA[A huge strike to data democratization in football analytics]]></description><link>https://ricardoheredia.substack.com/p/farewell-fbref-advanced-stats-when</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/farewell-fbref-advanced-stats-when</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Thu, 22 Jan 2026 21:16:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/d3e625ce-6e0c-478b-96d0-be30dbdc7989_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!3dAj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!3dAj!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic 424w, /__u/substackcdn.com/image/fetch/$s_!3dAj!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic 848w, /__u/substackcdn.com/image/fetch/$s_!3dAj!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!3dAj!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!3dAj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic" width="395" height="106" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:106,&quot;width&quot;:395,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4044,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/185450643?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!3dAj!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic 424w, /__u/substackcdn.com/image/fetch/$s_!3dAj!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic 848w, /__u/substackcdn.com/image/fetch/$s_!3dAj!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!3dAj!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6871e6-2274-4d9d-8906-77cb86d3d36b_395x106.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p><strong>FBRef announced this week they removed all the Advanced Stats provided by Stats Perform by Opta. </strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!pFZV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!pFZV!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic 424w, /__u/substackcdn.com/image/fetch/$s_!pFZV!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic 848w, /__u/substackcdn.com/image/fetch/$s_!pFZV!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!pFZV!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!pFZV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic" width="617" height="474.1916208791209" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1119,&quot;width&quot;:1456,&quot;resizeWidth&quot;:617,&quot;bytes&quot;:286993,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/185450643?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!pFZV!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic 424w, /__u/substackcdn.com/image/fetch/$s_!pFZV!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic 848w, /__u/substackcdn.com/image/fetch/$s_!pFZV!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!pFZV!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35a1e90f-6fb0-40f3-8f2d-6a523613551f_1710x1314.heic 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 aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://www.sports-reference.com/blog/2026/01/fbref-stathead-data-update/">Article Reference</a></figcaption></figure></div><p>Something that took the football analytics community by surprise. </p><p>FBRef was maybe one of the first (if not the first) source you could think of to grab data and build high-level analysis. Whether you were a student, analyst, scout, fan, whoever, their web was a must. They these great level of detail in their data that actually made you go down rabbit holes just by looking at the granularity of their metrics.</p><p>I used to recommend it as one of the go-to places to get in contact with advanced football data stats &#8594; <a href="/__u/substack.com/@thenetpass14/p-168793687">How to Use FBRef for Football Scouting with Python?</a></p><p>This new situation far from being discouraging should make us all football lovers develop our <strong>creativity </strong>to make the most out of the available sources on the internet and explore other angles. For example: places like <a href="https://github.com/SkillCorner/opendata">SkillCorner Open Tracking &amp; Physical Data</a> or <a href="https://www.hudl.com/blog/elite/statsbomb">Hudl StatsBomb Event &amp; Physical Open Data</a> are well known data providers where you can obtain top valuable data to run different analyses but with a &#8220;detective mind&#8221;.</p><p>What I mean by that is trying to look at the data as a vehicle to derive close-to-real-world analyses of how technical staff at clubs or pro teams use this data, and also how other fellow colleagues use it. </p><p>You can see it on social media. The majority of professionals and data practitioners are active on X or LinkedIn. Perfect places to take a look at how this data is being used and inspire yourself of those signals to craft your own dashboards or reports how they consult other data sources, how they collect, clean, model and even how they present that data. </p><p>Having different POVs around how others manage sports data helps you upskill in the data field way faster, which is ultimately what we actually want: be more competent data professionals independently where the data comes from. </p><p>I also wouldn&#8217;t rule out the use of synthetic data for practicing purposes. With the rise of Generative AI and LLMs, this has become a popular alternative within the industry due to lack of access to closed source data. </p><p>Spending some time on crafting comprehensive prompts, using few shot examples, with metrics and well-defined ranges, can help you mimic real-world data for your own practice. </p><p>The main thing to remember from this FBRef situation is that it is essential that we adapt by focusing on sharpening skills with what&#8217;s available, or by creating our own way of accessing to data sources. </p><p>This is a great signal to start <strong>creating </strong>now. </p><p>Till next time,</p><p>Ricardo. </p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The NetPass! 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[RAG is a Data Engineering Heavy Problem: Building a Football ETL for AI]]></title><description><![CDATA[How to use a Pydantic airlock and a Golden Dataset to set the information right for your RAG]]></description><link>https://ricardoheredia.substack.com/p/rag-is-a-data-engineering-heavy-problem</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/rag-is-a-data-engineering-heavy-problem</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Mon, 12 Jan 2026 08:03:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!6Tya!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my last post, I shared the big picture of the Football RAG system I&#8217;ve launched (<a href="/__u/substack.com/@thenetpass14/p-182493528">Building a RAG System That Generates Football Post-Match Tactical Reports Automatically</a>), and today, I want to talk about what is for me the most critical part of the system: the data pipeline. </p><p><strong>RAG efficiency relies on great Data Engineering.</strong> </p><p>This refers to building a solid ETL process: Extract, Transform, Load &#8212; the process that prevents bad retrieval and bad generation, helping the system produce accurate responses.</p><p>So, I&#8217;ll go over the origin of the data, the sources I used, and the decisions I made to build the pipeline.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!6Tya!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!6Tya!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!6Tya!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!6Tya!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!6Tya!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!6Tya!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:963551,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/184194299?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!6Tya!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!6Tya!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!6Tya!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!6Tya!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc246079e-6fc2-43c0-bb0e-7fad0de3e895_2816x1536.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Overview of the system thanks to Nano Banana Pro.</figcaption></figure></div><h3>Where the Data Comes From</h3><p>Starting from the main goal of the system: automatically provide concise post match reports using free updated post match data from a league gathered in one place. That way, you can save time hopping from one site to another and focus on what really matters: the analysis.</p><p>To build these tactical reports, I wanted to use <strong>match event data</strong>.</p><p>I reused and improved a version of the scrapers I built for my <a href="/__u/ricardoheredia.substack.com/p/building-your-own-football-analytics">previous dashboard project</a>. The goal was to move from scraping one match for a plot to indexing 108 matches for a system.</p><p>The main data sources are: </p><ul><li><p><strong>WhoScored:</strong> with more than 1,300+ events per match: passes, tackles, coordinates.</p></li><li><p><strong>Fotmob:</strong> source for more specific match data like xG, numbers of shots and shot quality.</p></li></ul><p>Fotmob provides the shot as a number, whereas WhoScored only provides if the action was a shot (True) or not (False). They complement each other. </p><p>The first wall I hit in this Data Engineering process was: <strong>Entity Resolution.</strong> </p><p>Source A calls the team &#8220;R. Madrid,&#8221; Source B calls them &#8220;Real Madrid.&#8221; I needed to map them, so the RAG system wouldn&#8217;t think they are different teams.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!1ncf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!1ncf!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!1ncf!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!1ncf!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!1ncf!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!1ncf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg" width="409" height="427.10235131396956" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:755,&quot;width&quot;:723,&quot;resizeWidth&quot;:409,&quot;bytes&quot;:85418,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/184194299?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b477a7-beb3-460a-87e9-7bd705cac867_890x940.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!1ncf!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!1ncf!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!1ncf!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!1ncf!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff754142d-98e0-41fa-accc-243bc10a84eb_723x755.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>This file is the glue. It&#8217;s a simple but effective way to prevent silent data corruption.</em></figcaption></figure></div><h3>Extracting the Data</h3><p>The scrapers development evolved from a one-off scraping to more matches. In this case I used just 108 matches from the first leg of the Eredivisie league. </p><p>Why the Dutch league? It&#8217;s a league I&#8217;m really curious about, they are one of the best breeding talent leagues in Europe and it is always worth it looking at their emergent talents. </p><p>The scrapers followed a simple rule: <strong>the Raw information is immutable.</strong> I save the JSON exactly as it comes from the web into a &#8220;Raw Zone&#8221; (local for now). That way if I find a bug in my tactical metrics calculation later, I don&#8217;t need to scrape the web again. I just re-run it from the raw files.</p><p>Quick summary of how it works:</p><pre><code>Scraper WhoScored --(JSON)--&gt; [ Raw Zone /whoscored/ ]
                                            |
 Scraper Fotmob   --(JSON)--&gt; [ Raw Zone /fotmob/   ]
                                            |
                              [ scrape_all_matches.py ]
                                            |
                               ( Orchestration &amp; Logs )</code></pre><ul><li><p><strong>The Workers:</strong> Specialized scrapers (one for WhoScored, another for Fotmob) designed with a single responsibility: extracting raw data.</p></li><li><p><strong>The Storage:</strong> A local directory that serves as my immutable &#8220;Raw Zone.&#8221;</p></li><li><p><strong>The Orchestrator:</strong> A central script (<code>scrape_all_matches.py</code>) that acts as the conductor, identifying missing matches and triggering the workers accordingly.</p></li></ul><pre><code>
# scripts/scrape_all_matches.py (A Simplified version of the Orchestrator)

def run_pipeline():
    # 1. Check what we already have (Incremental mode)
    existing_matches = get_local_raw_manifest()

    # 2. Run WhoScored Scraper
    print("&#128640; Starting WhoScored extraction...")
    ws_data = scrape_whoscored_season(mode="incremental", exclude=existing_matches)
    save_to_raw_zone(ws_data, source="whoscored")

    # 3. Run Fotmob Scraper
    print("&#128640; Starting Fotmob extraction...")
    fm_data = scrape_fotmob_eredivisie(mode="incremental", exclude=existing_matches)
    save_to_raw_zone(fm_data, source="fotmob")

    print("&#9989; Raw Zone updated. Ready for ETL.")</code></pre><h3>Pydantic Contracts: the &#8220;Airlock&#8221; Pattern</h3><p>To safely store data in a vector database, I needed a <strong>Contract</strong>. It is a strict, machine-checkable definition of what your data must look like before it&#8217;s allowed to move downstream.</p><p>In my case, it&#8217;s the schema for a &#8220;valid match&#8221; (required fields, types, constraints). If the scraped payload doesn&#8217;t satisfy that contract&#8212;missing <code>xG</code>, null team IDs, wrong types&#8212;the pipeline fails fast and the match never gets stored in the vector database.</p><p><strong>Pydantic</strong> is in charge to validate that match, working as an airlock. It defines exactly what a &#8220;valid match&#8221; looks like. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!_93h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!_93h!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!_93h!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!_93h!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!_93h!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!_93h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:797828,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/184194299?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!_93h!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!_93h!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!_93h!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!_93h!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a52c02-238e-4de5-b02b-179127a692c4_2816x1536.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>This is the guardrail, it forces the data to be &#8220;clean&#8221; before it touches the system.</em></figcaption></figure></div><h3>Pre-calculating +30 Metrics</h3><p>Dumping 1,300 raw events into the LLM didn&#8217;t seem realistic nor cost-effective. It&#8217;s  expensive in matters of tokens and slow latency, which ultimately confuses the model, making it prone to give back unreliable information.</p><p>Instead of the ETL just moving data, it acts as a <strong>Factory</strong>. </p><p>It processes raw, messy coordinates and distills them into <strong>Tactical Insights</strong> (or <strong>Actionable Metrics</strong>):</p><ul><li><p>Instead of 500 raw pass coordinates &#8594; <strong>Verticality: 0.65</strong></p></li><li><p>Instead of 20 defensive events &#8594; <strong>PPDA: 8.2</strong></p></li></ul><p><strong>The logic is simple:</strong> I don&#8217;t want the LLM to waste its &#8220;brainpower&#8221; (and tokens) trying to do math on thousands of x,y points. I want it to focus on what it does best: <strong>reasoning over tactical concepts.</strong> </p><p>By pre-calculating these metrics, I&#8217;m handing the AI a &#8220;scout&#8217;s report&#8221; instead of raw notes.</p><p>This is the <strong>transformation</strong> step of the pipeline: where raw events, shots, and mappings are stitched together into a single, validated match profile.</p><pre><code># scripts/process_raw_data.py (simplified version of the transformation logic)

def process_matches():
    # 1. Load the "Glue": Match mappings and raw data
    mappings = load_json("data/match_mapping.json")
    
    for ws_id, mapping in mappings.items():
        # 2. Resolve IDs (The fix for the Home/Away swap bug)
        home_id, away_id = resolve_team_ids(mapping)
        
        # 3. Stitch data sources (WhoScored Events + Fotmob Shots)
        ws_data = load_json(f"raw/whoscored_matches/match_{ws_id}.json")
        fotmob_match = find_match_in_bulk(mapping['fotmob_id'])
        
        # 4. The "Factory": Distill 1,300+ events into 38 tactical metrics
        events_df = pd.DataFrame(ws_data['events'])
        raw_metrics = calculate_all_metrics(events_df, fotmob_match['shots'], home_id, away_id)
        
        # 5. The "Airlock": Validate everything with Pydantic
        match_profile = MatchProfile(
            metadata=MatchMetadata(match_id=ws_id, date=mapping['match_date']),
            home_team=TeamMatchStats(**map_metrics(raw_metrics, "home")),
            away_team=TeamMatchStats(**map_metrics(raw_metrics, "away")),
            home_score=calculate_score(fotmob_match['shots'], "home"),
            away_score=calculate_score(fotmob_match['shots'], "away")
        )
        
        # 6. Save to the Golden Dataset
        save_to_gold(match_profile)</code></pre><p>In essence, it resolves team IDs, stitches two different data sources together, calculates tactical metrics, and finally passes everything through a Pydantic "airlock" to ensure the Golden Dataset is 100% reliable.</p><h4>An issue I found at the beginning </h4><p>Early in development, the system told me Zwolle dominated a game they actually lost 2-8 (https://www.sofascore.com/football/match/heracles-almelo-pec-zwolle/wjbsCjb)</p><p>The LLM was just reading the data I gave it and I thought it was hallucinating. </p><p>The ETL had a bug in the team ID mapping that swapped the Home and Away stats. </p><p>Something that made me understand that paying attention to the DE part is central.</p><h3>The Golden Dataset &amp; The Sniper Approach</h3><p>The final output of the ETL is the <code>matches_gold.json</code>. </p><p>This file became the center of the system. Everything downstream: reports, evaluations, and rebuilds started here. That&#8217;s why I treat it as the <strong>Source of Truth</strong>, and not the vector database.</p><p>Once the data is in this shape, the next step was loading it into ChromaDB. </p><p>To do that, I used a simple <strong>2-chunk architecture</strong> when indexing each match:</p><ul><li><p><strong>Summary Chunk: </strong>Contains match metadata: teams, date, score, and competition. Its job is to make sure the system finds the <em>right </em>match.</p></li><li><p><strong>Tactical Chunk: </strong>Contains the pre-calculated metrics. This is what the LLM actually reads to generate the analysis.</p></li></ul><p>I ended up calling this setup the <strong>&#8220;Sniper Approach.&#8221;</strong></p><p>I wanted to avoid relying entirely on semantic search: embed the query, retrieve the closest vectors, and hope the correct match is somewhere near the top. That works, but it always felt a bit loose for this use case.</p><p>When a user asks about <em>PSV vs Ajax</em>, I don&#8217;t want the system to &#8220;kind of&#8221; get it right. I already know the exact match I&#8217;m looking for, so I use <strong>metadata filtering</strong> to narrow it down first. Once the match is identified, only then does the LLM see the tactical data.</p><p>This way, the vector database serves exactly what I ask for and retrieval becomes deterministic.</p><p><strong>[SNIPPET F: </strong><code>scripts/rebuild_chromadb.py</code><strong> &#8211; Chunking &amp; Metadata logic]</strong></p><pre><code># scripts/rebuild_chromadb.py 

for match in matches:
    match_id = match['metadata']['match_id']
    home = match['home_team']
    away = match['away_team']
    
    # Chunk 1: Summary (for metadata filtering)
    summary_text = (
        f"{home['team_name']} vs {away['team_name']} "
        f"({match['home_score']}-{match['away_score']}). "
        f"Possession: {home['possession']}% vs {away['possession']}%. "
        f"xG: {home['xg']} vs {away['xg']}."
    )
    
    summary_meta = {
        "match_id": match_id,
        "chunk_type": "summary",
        "home_team": home['team_name'],
        "away_team": away['team_name'],
        "match_date": match['metadata']['match_date']
    }
    
    collection.add(
        documents=[summary_text],
        metadatas=[summary_meta],
        ids=[f"{match_id}_summary"]
    )
    
    # Chunk 2: Tactical Metrics (for LLM generation)
    tactical_meta = {
        "match_id": match_id,
        "chunk_type": "tactical_metrics",
        "home_ppda": home['ppda'],
        "home_verticality": home['verticality'],
        "home_xg": home['xg'],
        "away_ppda": away['ppda'],
        "away_verticality": away['verticality'],
        "away_xg": away['xg'],
        # ... (38 total metrics)
    }
    
    collection.add(
        documents=[f"Tactical metrics for {home['team_name']} vs {away['team_name']}"],
        metadatas=[tactical_meta],
        ids=[f"{match_id}_tactical_metrics"]
    )</code></pre><p><em>Two chunks per match: one for finding it (metadata filtering), one for analyzing it (LLM generation). The vector database doesn't guess; it serves exactly what I ask for. </em></p><p>I also added a <code>sanitize_metadata()</code> function to prevent ChromaDB from crashing on <code>None</code> values. It saved me from silent failures during indexing.</p><p>Link to the repo so you can check all the code: <a href="https://github.com/ricardoherediaj/football-rag-intelligence">Football RAG Intelligence</a></p><h3>Bottom Line</h3><p>At the end of the day, a football analyst needs to trust the numbers, and a developer needs to trust the pipeline.</p><p>By building a strict ETL with Pydantic and a Golden Dataset, I managed to reduce the &#8220;hallucination surface&#8221; before even writing a prompt. The idea was to make the data so clear that the AI didn&#8217;t have to guess.</p><div><hr></div><h3>What&#8217;s next?</h3><p>Now that we&#8217;ve tackled the data preparation, we need to talk to it.</p><p>In the next article, I&#8217;ll dive into the <strong>Prompt Engineering</strong> side of the project. </p><p>I&#8217;ll show you why I spent a good amount of time designing a Tailored Prompt and how that decision helped me cut token costs by 80%.</p><p>If you're interested in the intersection of Data Engineering and Generative AI, subscribe to follow this series.</p><p>See you then, </p><p>Ricardo. </p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The NetPass! 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></p><p></p>]]></content:encoded></item><item><title><![CDATA[A Thank You, Two Ideas From a Book That Changed My 2025 and Timothée Chalamet's Pursuit of Greatness]]></title><description><![CDATA[The career mindset shift that changed my 2025 that I hope can help you in 2026.]]></description><link>https://ricardoheredia.substack.com/p/a-thank-you-two-ideas-from-a-book</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/a-thank-you-two-ideas-from-a-book</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Wed, 31 Dec 2025 17:24:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Jgnb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>What a year, captain&#8230;</p><p>I won't take much of your time, but before it ends, I wanted to thank you for reading this newsletter during the year. </p><p>I wrote about football, AI, RAG systems, agentic IDEs, and a bunch of technical experiments, things I hope helped you apply them to your own work.</p><p>So thank you. It really means a lot that you share this space with me.</p><p>To wrap it up, I want to share one thing that changed my thinking this year and will serve as my compass for years to come. </p><p>It's about how I want to perform my work and develop my career. </p><p>I'm sure it can help you start 2026 with a different perspective.</p><h2>The Book That Made Me Rethink About Purpose</h2><p>I recently finished reading <em>So Good They Can&#8217;t Ignore You</em> by Cal Newport, a book recommended by <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Juli&#225;n Campos&quot;,&quot;id&quot;:173193757,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6dd3c21-1194-409d-9b45-d2d0fc8333ac_1175x1177.jpeg&quot;,&quot;uuid&quot;:&quot;810c4bd2-a8f4-41ee-b604-a7077d3cf6a9&quot;}" data-component-name="MentionToDOM"></span> on a brilliant X/Twitter thread about books every developer should read.  </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!MeyT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!MeyT!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp 424w, /__u/substackcdn.com/image/fetch/$s_!MeyT!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp 848w, /__u/substackcdn.com/image/fetch/$s_!MeyT!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp 1272w, /__u/substackcdn.com/image/fetch/$s_!MeyT!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!MeyT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp" width="262" height="438.17241379310343" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:388,&quot;width&quot;:232,&quot;resizeWidth&quot;:262,&quot;bytes&quot;:17458,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/183047952?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!MeyT!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp 424w, /__u/substackcdn.com/image/fetch/$s_!MeyT!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp 848w, /__u/substackcdn.com/image/fetch/$s_!MeyT!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp 1272w, /__u/substackcdn.com/image/fetch/$s_!MeyT!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0277b094-27a0-4e80-8611-0e7db201a7d4_232x388.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Book cover.</figcaption></figure></div><p>This was the book that really hit me this year. </p><p>Why? Cause all my life I&#8217;ve thought the popular advice &#8220;find your passion and the rest will follow&#8221; was real. Too many decisions made using this mantra. </p><p>Then, to my surprise, Newport argues the opposite in the chapters of this book. </p><p>Telling stories of people from each path and ultimately showing who developed more successful and satisfying lives. </p><p>Here&#8217;s the deal.</p><h2>Passion Mindset vs. Craft Mindset </h2><p>The central subject of the book is these two concepts.</p><p>The passion mindset is about finding work that matches a passion you supposedly already have. It&#8217;s asking &#8220;what can the world offer me?&#8221; and assuming passion comes first, then the work follows.</p><p>The craft mindset flips this. It&#8217;s about getting really good at something rare and valuable. Asking &#8220;what can I offer?&#8221; instead. </p><p>The key difference: <strong>passion comes after you develop mastery, not before.</strong></p><p>This made me rethink how I approach my own career in tech. Since I pivoted from medicine I&#8217;ve been unknowingly following this path, trying to get better at managing data, programming and ultimately building AI systems. </p><p>I was lucky enough to apply it to football (which I love) and healthcare, my background. </p><p>But the true passion came from pushing through the work and wanting to get better each day. </p><h4>How Chalamet Pursues Greatness Through Craft</h4><p>In February, at the SAG Awards ceremony, Timoth&#233;e Chalamet said something unusual: &#8220;I&#8217;m really in pursuit of greatness. I want to be one of the greats.&#8221;</p><p>I felt that quote was really honest because he was actually talking about becoming great through the work. </p><p>He mentioned being inspired by Daniel Day-Lewis, Marlon Brando, and Viola Davis, and spending 5.5 years of his life preparing for <em>A Complete Unknown </em>where he portrayed Bob Dylan.</p><p>That&#8217;s the craft mindset in action. </p><p>Greatness is something you build deliberately over years of committed work.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Jgnb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Jgnb!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic 424w, /__u/substackcdn.com/image/fetch/$s_!Jgnb!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic 848w, /__u/substackcdn.com/image/fetch/$s_!Jgnb!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!Jgnb!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Jgnb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic" width="556" height="370.852" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:667,&quot;width&quot;:1000,&quot;resizeWidth&quot;:556,&quot;bytes&quot;:82019,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/183047952?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Jgnb!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic 424w, /__u/substackcdn.com/image/fetch/$s_!Jgnb!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic 848w, /__u/substackcdn.com/image/fetch/$s_!Jgnb!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!Jgnb!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13264168-2a9d-44b4-8ce4-0f2884980c24_1000x667.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Career Capital: The Currency to Buy What You Want in Your Career</h2><p>Career capital is the set of rare and valuable skills you&#8217;ve accumulated through the years. </p><p>Newport uses this economic metaphor deliberately: great jobs (those offering creativity, impact, and control) are scarce and valuable. </p><p>To get one, you need to offer something scarce and valuable in return. </p><p>Most people want autonomy, interesting projects, and meaningful work from day one (happened to me). But you need currency to buy those things. First you accumulate the capital, then you invest it to negotiate the career you actually want.</p><p>You build it by developing skills that are rare and valuable, ones others don&#8217;t have and the market needs.</p><p>This changed how I choose what to learn. </p><p>Before, I chased new technologies that sounded interesting but now I ask myself if it gives me the career capital I want to build. Or is it rare and valuable, more than a commodity. </p><p>For example: Python is valuable but not rare. Instead, using Python to create AI systems applied to a niche domain like football analytics or healthcare is a rare combination.</p><p>This lens shows if you're building capital or just chasing noise.</p><h2>What This Means for 2026</h2><p>For 2026, my plan is simple: keep accumulating capital, investing it by building projects that combine rare and valuable skills, sharing what I learn here, and iterating.</p><p>If there&#8217;s something you can take from this for your own 2026, let it be this:</p><blockquote><p>Build mastery first. The passion will come on its own.</p></blockquote><p>Have a great year.</p><p>Till next time, </p><p>Ricardo.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The NetPass! 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></p>]]></content:encoded></item><item><title><![CDATA[Building a RAG System That Generates Football Post-Match Tactical Reports Automatically]]></title><description><![CDATA[Transforming free event data from WhoScored and Fotmob into instant, comprehensive reports with LLMs for less than $0.50]]></description><link>https://ricardoheredia.substack.com/p/building-a-rag-system-that-generates</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/building-a-rag-system-that-generates</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Fri, 26 Dec 2025 06:01:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!WMWM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic" 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="/__u/substackcdn.com/image/fetch/$s_!WMWM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!WMWM!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic 424w, /__u/substackcdn.com/image/fetch/$s_!WMWM!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic 848w, /__u/substackcdn.com/image/fetch/$s_!WMWM!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!WMWM!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!WMWM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic" width="465" height="465" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:465,&quot;bytes&quot;:88116,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/182493528?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!WMWM!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic 424w, /__u/substackcdn.com/image/fetch/$s_!WMWM!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic 848w, /__u/substackcdn.com/image/fetch/$s_!WMWM!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!WMWM!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59c871ce-0be7-463e-8457-16d43dd3d553_1024x1024.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A summary of the project courtesy of Nano Banana Pro</figcaption></figure></div><h2>Long time no see </h2><p>First of all, Merry Christmas &#127876;</p><p>It&#8217;s been a while since I last send a post, but life happens. So, here I am before finishing the year.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The NetPass! 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>I wanted to end 2025 with the same vibe I want to start 2026: <em>building projects and sharing knowledge. </em></p><p>Lately, I&#8217;ve been working on something that mixes my interest in AI and my passion for football. I&#8217;m really excited to go over its details and how the idea came up. </p><p>When I started analyzing football data and creating post match reports, I had a problem that I think a lot of coaches, analysts, and football data practitioners can relate to.</p><p><strong>Gathering free match data from various sources to build reports is tedious.</strong></p><p>This makes it difficult to create a summarized report from any match without hopping from one web to another.</p><p>Say if you want to analyze PSV&#8217;s pressing patterns from last week&#8217;s Eredivisie match day, you need to go to WhoScored, then Fotmob for shot and xG values, Understat, BeSoccer etc, and obtaining the data manually.</p><p>That&#8217;s why I wanted to built this system:</p><p><strong>One where I could ask &#8220;What was PSV&#8217;s pressing strategy against Ajax?&#8221; in natural language and get an instant tactical report&#8212;with real stats, context, and visualizations from multiple free data sources.</strong></p><p>I want to show you how it works.</p><h2>What I Built</h2><p>This is the live demo hosted at Hugging Face Spaces: <strong><a href="https://huggingface.co/spaces/rheredia8/football-rag-intelligence">Football RAG Intelligence - Live Demo</a></strong></p><p>It&#8217;s a RAG (Retrieval-Augmented Generation) system that ingests Eredivisie match data from WhoScored and Fotmob, stores it in a vector database, and generates tactical analysis grounded in actual statistics.</p><p>You ask questions in natural language. It retrieves the match data and then generates comprehensive rundowns thanks to the LLM text-generation capability.</p><p>Reduced hallucinations and instant visualizations at low cost.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!uYkg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!uYkg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic 424w, /__u/substackcdn.com/image/fetch/$s_!uYkg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic 848w, /__u/substackcdn.com/image/fetch/$s_!uYkg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!uYkg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!uYkg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic" width="1456" height="854" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:854,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:241478,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/182493528?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!uYkg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic 424w, /__u/substackcdn.com/image/fetch/$s_!uYkg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic 848w, /__u/substackcdn.com/image/fetch/$s_!uYkg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!uYkg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5dcd68d6-6851-4fdf-a877-592ef79c2b7e_2876x1686.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here&#8217;s what it handles:</p><ul><li><p><strong>108 Eredivisie matches indexed</strong> with event-level data (~1355 events per match).</p></li><li><p><strong>Dual-mode interface:</strong> Ask a question and get tactical commentary. Request a visualization and get instant plots.</p></li><li><p><strong>Multi-provider support:</strong> Works with Anthropic&#8217;s Claude, OpenAI, and Gemini models. </p></li><li><p><strong>$0.50 total cost</strong> to test everything.</p></li></ul><p>The visualizations I used were already created using a prior code. I went through it in an earlier article, you can go check it here: <a href="/__u/ricardoheredia.substack.com/p/building-your-own-football-analytics?r=56fjux">Building Your Own Football Analytics Dashboards With Free Data</a></p><h2>Why This Matters</h2><p>Your match data lives in one place so you don&#8217;t have to hop around internet to get it. Ask questions in plain language, get answers backed by recent stats. Need a passing network or shot map? Type &#8220;show passing network for Feyenoord&#8221;.</p><p><strong>Who can leverage this?</strong></p><p>Coaches, scouts, and analysts at small/medium/big clubs, football fans, developers. Pretty much anyone involved in analyzing football with data.</p><h2>How It Works</h2><p>Here&#8217;s the high-level flow:</p><pre><code><code>User Query &#8594; Router (classify intent)
             &#8595;
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#8595;                  &#8595;
LLM Analysis      Visualization
(Tailored Prompt)     (Keyword-based)
    &#8595;                  &#8595;
ChromaDB          pre-built matplotlib
retrieval         plots
    &#8595;                  &#8595;
Grounded          $0 cost
Commentary        images
</code></code></pre><p>The system does five things:</p><p><strong>1. Routes your query:</strong> Questions like &#8220;What was PSV&#8217;s pressing strategy?&#8221; go to the LLM pipeline. Commands like &#8220;Show shot map&#8221; trigger visualizations.</p><p><strong>2. Retrieves match data:</strong> ChromaDB finds the exact match using team names and metadata filtering instead of semantic search guessing.</p><p><strong>3. Generates analysis:</strong> The LLM gets the actual stats and writes tactical commentary using a carefully engineered prompt (which I&#8217;ll cover in Article 2).</p><p><strong>4. Validates output:</strong> Every statistic cited in the response is checked against the golden dataset. If it&#8217;s not there, it doesn&#8217;t make it into the output.</p><p><strong>5. Delivers instantly:</strong> Text analysis in 6-7 seconds or visualizations in under a second because they bypass the LLM entirely.</p><p>Hints on the key architectural decisions I made (I&#8217;ll dig deeper into these in future articles):</p><ul><li><p><strong>Prompt-first design:</strong> I designed the Tailored Prompt before building the ChromaDB schema. I wanted to tackle the mismatch between what the LLM expected and what the database provided.</p></li><li><p><strong>2-chunk architecture:</strong> Each match gets two documents in ChromaDB. One summary chunk (team names, score, date) for filtering. One tactical metrics chunk (38 pre-calculated features) for LLM generation.</p></li><li><p><strong>Pre-calculated metrics:</strong> All tactical metrics are computed during data ingestion. PPDA, progressive passes, field tilt, compactness, etc. The RAG pipeline doesn&#8217;t calculate anything, it just retrieves and interprets.</p></li><li><p><strong>Smart routing:</strong> Text questions go to the LLM. Visualization commands go straight to the plots generation with matplotlib. This was to reduce the cost for every viz request.</p></li><li><p><strong>Golden Dataset ETL:</strong> Raw data from WhoScored and Fotmob flows through a Pydantic validation pipeline. Only clean, validated data makes it into ChromaDB. This &#8220;airlock&#8221; pattern caught bugs before they could cause hallucinations.</p></li></ul><h2>The Results</h2><p>In initial evaluation testing on 10 diverse matches, these were the obtained results:</p><p><strong>Retrieval Accuracy: 100%</strong></p><p>Every query found the correct match data. Metadata filtering (team names, dates) acts like a &#8220;sniper&#8221; approach versus pure semantic search, which only hit 70% accuracy.</p><p><strong>Faithfulness: 99.4%</strong></p><p>Generated analysis matched source statistics. Every number cited in the commentary exists in the golden dataset. One test case had a minor discrepancy due to rounding, hence 99.4% instead of 100%.</p><p><strong>Tactical Insight: 95.0%</strong></p><p>The commentary provided actual both tactical depth and data reporting. </p><p>I evaluated the system using an LLM-as-a-Judge methodology with specific rubrics and reference answers.</p><p>The cost: <strong>~$0.0001 per query with Claude Haiku 4.5.</strong></p><p>The system still occasionally generates erroneous team names or statistics, which is why continuous evaluation is important. I'll cover my evaluation approach in Article 4.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!-DhJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!-DhJ!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic 424w, /__u/substackcdn.com/image/fetch/$s_!-DhJ!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic 848w, /__u/substackcdn.com/image/fetch/$s_!-DhJ!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!-DhJ!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!-DhJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic" width="1456" height="859" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic&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;:188624,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/182493528?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!-DhJ!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic 424w, /__u/substackcdn.com/image/fetch/$s_!-DhJ!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic 848w, /__u/substackcdn.com/image/fetch/$s_!-DhJ!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!-DhJ!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F000473d0-43ea-4ebf-8e4a-44e25b5dc1ce_2880x1700.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>What&#8217;s Next: The Series Roadmap</h2><p>This article gives a big picture of what I built and how it works.</p><p>In next articles I&#8217;ll go deeper into specific aspects of the journey:</p><ul><li><p><strong>Crafting a Football ETL Pipeline with free event data for RAG:</strong> What sources I used, why, how I managed all this data to make it useful for the system, and what is RAG.</p></li></ul><ul><li><p><strong>Why Prompt Engineering Came before the vector database and how it helped optimize costs: </strong>Designing the Tailored Prompt to avoid retrieval-generation mismatch. I&#8217;ll show the many prompt iterations from V1.0 (1800 tokens, slow, vague) to V3.5 (360 tokens, fast, precise).</p></li><li><p><strong>Evaluating the system with the Evaluation Driven Development approach: </strong>The LLM-as-a-Judge methodology. How I built the three-metric evaluation framework. Creating test datasets that actually matter. Debugging false failures.</p></li><li><p><strong>Deploying the App: </strong>Hosting an initial version of the app in HF Spaces, a well-known place for AI/ML developers to deploy applications.  </p></li><li><p><strong>Next steps to Production Scaling: </strong>Current MVP limitations. Production stack design following data, software, and AI engineering best practices (CID/CD, pipeline orchestration, LLM cloud hosting and inference, automated evaluations) to go from proof-of-concept to a system that obtains weekly matches and generates fully automated reports on demand hosted on premise.</p></li></ul><h2>Try It Yourself</h2><p>Demo Link: <strong><a href="https://huggingface.co/spaces/rheredia8/football-rag-intelligence">Football RAG Intelligence</a></strong></p><p>Pick a provider (Claude, GPT, or Gemini), paste your API key, and start asking questions.</p><p>Example queries to try:</p><p><strong>Text analysis:</strong></p><ul><li><p>&#8220;What was PSV&#8217;s pressing strategy against Ajax?&#8221;</p></li><li><p>&#8220;How did Heracles build up play against PEC Zwolle?&#8221;</p></li><li><p>&#8220;Explain the tactics in Feyenoord vs Ajax&#8221;</p></li></ul><p><strong>Visualizations:</strong></p><ul><li><p>&#8220;Show dashboard for Heracles vs PEC Zwolle&#8221;</p></li><li><p>&#8220;Show passing network for Feyenoord&#8221;</p></li><li><p>&#8220;Show shot map for AZ vs Utrecht&#8221;</p></li></ul><p>The code is fully open source: <strong><a href="https://github.com/ricardoherediaj/football-rag-intelligence">GitHub Repository</a></strong></p><p>Clone it. </p><p>Run it locally. </p><p>Modify it for your own league or data sources.</p><p>I included all the  documented architecture decisions to showcase the entire process and next steps. </p><h2>Bottom Line</h2><p>The goal of this project is to show that:</p><p>A RAG system and an LLM of your choice fed by your own clean data, clear architecture, and careful prompt engineering, helps you solve a real problem like automated post match analysis.</p><p>Leveraging AI to create systems or tools is one of the things that excites me the most. There's something incredible about going from idea to working system so fast. </p><p>AI helps blur that line between "I want to build this" and "I built this."</p><p>I would love to hear some thoughts on this on how useful is this to you.</p><p>Til next time, </p><p>Ricardo. </p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The NetPass! 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[Understanding Model Context Protocol (MCP): Connecting LLMs to Real Data]]></title><description><![CDATA[How to build bridges between AI models and your data using a MinIO MCP Server as a practical example]]></description><link>https://ricardoheredia.substack.com/p/understanding-model-context-protocol</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/understanding-model-context-protocol</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Mon, 29 Sep 2025 05:02:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!xvfB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Trying to get an AI model to work with your actual data instead of just hallucinating responses, can end in frustration some times.</p><p>For example, you want ChatGPT to analyze files in your S3 bucket, or to help you manage your databases, but you end up copying and pasting data manually.</p><p>Every new data source requires its own custom connector same as every AI application needs its own integration code. </p><p>There&#8217;s a solution which has risen in popularity as new way of how we work with AI and data integration: <strong>Model Context Protocol (MCP)</strong>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The NetPass! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>What is an MCP and What is it Used For?</h2><p><strong>Model Context Protocol (MCP) is an open standard that allows AI models to securely connect to external data sources and tools through a unified interface.</strong></p><p>MCP acts as an USB-C port for AI applications.</p><p>Just as USB-C provides a standardized way to connect any device to any peripheral without custom cables for each combination, MCP provides a standardized way to connect any AI model to any data source without writing custom integration code.</p><p>Before MCP, if you wanted Claude to access your MinIO storage, your GitHub repositories, or your database, you&#8217;d need three separate custom integrations. With MCP, you write one MCP server for each data source, and any MCP-compatible AI client (like Claude Desktop, Cursor, or your custom application) can instantly use all of them.</p><p>The key is the <strong>standardization.</strong> Instead of AI models needing to know the specific APIs of hundreds of different services, they just need to understand one protocol: <strong>MCP</strong>.</p><h2>General Structure</h2><p>MCP follows a client-server architecture that separates concerns in the following way:</p><h3>MCP Host</h3><p>The user-facing AI application (like Claude Desktop, Cursor, or your custom AI app) that coordinates everything.</p><h3>MCP Client</h3><p>Lives inside the host application and manages secure connections to MCP servers. Each server gets its own isolated client connection.</p><h3>MCP Server</h3><p>External programs that expose specific capabilities to AI models like connecting to databases, file systems, APIs, or any other data source.</p><p>The communication happens through <strong>JSON-RPC</strong>, a lightweight protocol that enables secure, two-way communication between clients and servers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!xvfB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!xvfB!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic 424w, /__u/substackcdn.com/image/fetch/$s_!xvfB!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic 848w, /__u/substackcdn.com/image/fetch/$s_!xvfB!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!xvfB!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!xvfB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic" width="800" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29696,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/174750596?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!xvfB!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic 424w, /__u/substackcdn.com/image/fetch/$s_!xvfB!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic 848w, /__u/substackcdn.com/image/fetch/$s_!xvfB!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!xvfB!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7cbca14-5e64-40a4-8c15-9a1cae8259d1_800x600.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>MCP image obtained from the MCP lesson of the Full Stack AI Engineering course from Towards AI Academy. </em></figcaption></figure></div><h3>Three Core Primitives</h3><p>MCP organizes functionality into three main types:</p><p><strong>Resources</strong>: Read-only data that the AI can access (like files, database records, or API responses). We can call them &#8220;things the AI can read.&#8221;</p><p><strong>Tools</strong>: Actions the AI can perform (like creating files, sending emails, or running queries). These are &#8220;functions the AI can call.&#8221;</p><p><strong>Prompts</strong>: Reusable conversation templates or workflows that provide structured interactions.</p><p>The importance of this design is that the AI model doesn&#8217;t need to know anything about MinIO&#8217;s S3 API, your database schema, or any specific service. It just knows how to ask for resources, call tools, and use prompts through the MCP interface.</p><h2>Practical Use Cases</h2><p>MCP is useful in scenarios where you need AI models to work with real, live data:</p><p><strong>Development Workflows</strong>: AI coding assistants that can read your codebase, access your Git history, and understand your project structure in real-time.</p><p><strong>Data Analysis</strong>: Models that can query your databases, analyze your files, and generate insights from your actual business data.</p><p><strong>Content Management</strong>: AI that can access your document repositories, and help you manage and organize content.</p><p><strong>Business Intelligence</strong>: Models that connect to your analytics platforms, CRM systems, and help you make data-driven decisions.</p><p><strong>Infrastructure Management</strong>: AI that can interact with your cloud storage, monitor your systems, and help with operational tasks.</p><p>The key advantage is <strong>real-time access</strong>. Instead of feeding static data to AI models, MCP enables dynamic, contextual interactions with live systems.</p><h2>Practical Example: MinIO MCP Server</h2><p>Now let&#8217;s see MCP in action with a real example: the <strong>MinIO MCP Server</strong> built in collaboration with my colleague <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Rafa&quot;,&quot;id&quot;:17515645,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/0363a2a9-0bcf-49fd-8caa-853dbb73f087_144x144.png&quot;,&quot;uuid&quot;:&quot;2838e084-2357-4544-be9b-b7952fe2bcb4&quot;}" data-component-name="MentionToDOM"></span> Ginard, a brilliant senior software engineer (<a href="https://github.com/Rafitis">Rafa's GitHub</a> and <a href="https://www.linkedin.com/in/rafa-ginard/">Rafa's LinkedIn</a>) who came up with this idea of connecting your MinIO object storage with any host and client, even a local LLM. </p><h3>What the MinIO MCP Server Does</h3><p>The server exposes MinIO object storage operations as MCP tools, allowing any MCP-compatible AI client to manage buckets and objects through natural language.</p><p><strong>Repository</strong>: <a href="https://github.com/Rafitis/minio-mcp-server">https://github.com/Rafitis/minio-mcp-server</a></p><h3>Key Features</h3><p><strong>7 MCP Tools</strong> organized by domain:</p><p><em>Bucket Operations</em>:</p><ul><li><p><code>list_buckets</code>: Get all available buckets with creation dates</p></li><li><p><code>get_bucket_info</code>: Detailed bucket metadata, policies, object count, and size</p></li><li><p><code>create_bucket</code>: Create new buckets with validation</p></li><li><p><code>delete_bucket</code>: Delete empty buckets or force delete with contents</p></li></ul><p><em>Object Operations</em>:</p><ul><li><p><code>list_objects</code>: List objects with filtering and pagination</p></li><li><p><code>get_object_info</code>: Get detailed object metadata</p></li><li><p><code>delete_object</code>: Remove objects with version support</p></li></ul><h3>Architecture Highlights</h3><p><strong>Built on FastMCP</strong>: Uses the FastMCP framework for robust MCP protocol support</p><p><strong>Async Architecture</strong>: Full async/await support for better performance</p><p><strong>Comprehensive Validation</strong>: Input validation and error handling with proper HTTP status codes</p><p><strong>Modular Design</strong>: Separated BucketTools and ObjectTools classes for clean organization</p><h3>Quick Setup</h3><p>The setup process demonstrates how streamlined MCP can be:</p><pre><code><code># Clone and install
git clone https://github.com/Rafitis/minio-mcp-server
cd minio-mcp-server
uv sync

# Configure your MinIO connection
cp .env.example .env
# Edit .env with your MinIO credentials

# Start the MCP server
uv run python src/minio_mcp/server.py
</code></code></pre><h3>Claude Desktop Integration</h3><p>To connect with Claude Desktop, you just add this configuration:</p><pre><code><code>{
  &#8220;mcpServers&#8221;: {
    &#8220;minio-mcp-server&#8221;: {
      &#8220;command&#8221;: &#8220;/path/to/uv&#8221;,
      &#8220;args&#8221;: [
        &#8220;--directory&#8221;, &#8220;/path/to/minio-mcp-server&#8221;,
        &#8220;run&#8221;, &#8220;python&#8221;, &#8220;src/minio_mcp/server.py&#8221;
      ],
      &#8220;env&#8221;: {
        &#8220;MINIO_ENDPOINT&#8221;: &#8220;localhost:9000&#8221;,
        &#8220;MINIO_ACCESS_KEY&#8221;: &#8220;minioadmin&#8221;,
        &#8220;MINIO_SECRET_KEY&#8221;: &#8220;minioadmin&#8221;,
        &#8220;MINIO_SECURE&#8221;: &#8220;false&#8221;
      }
    }
  }
}
</code></code></pre><p>After restarting Claude Desktop, you can use natural language commands like:</p><ul><li><p>&#8220;List all buckets in MinIO&#8221;</p></li><li><p>&#8220;Show me information about the &#8216;analytics-data&#8217; bucket&#8221;</p></li><li><p>&#8220;Delete &#8216;old-backup.zip&#8217; from the &#8216;archives&#8217; bucket&#8221;</p></li></ul><p><strong>The AI model automatically translates these requests into the appropriate MCP tool calls.</strong></p><h2>Connecting with Local LLMs and Optimal Prompts</h2><p>One particular aspect of MCP is its model-agnostic design. You can use the same MCP server with cloud-based models like Claude or with local models like Mistral.</p><h3>Local LLM Integration</h3><p>The <code>feature/llm-rest-api-integration</code> branch of our repository shows how to connect MCP servers with local LLMs for maximum privacy and control.</p><p><strong>Key Benefits of Local Integration</strong>:</p><ul><li><p><strong>Privacy</strong>: Your data never leaves your infrastructure</p></li><li><p><strong>Cost Control</strong>: No per-token pricing from cloud providers</p></li><li><p><strong>Customization</strong>: Fine-tune models for your specific domain</p></li><li><p><strong>Offline Capability</strong>: Works without internet connectivity</p></li></ul><h3>Setting Up with Enterprise LLMs</h3><p>Here&#8217;s how you can connect with your company&#8217;s enterprise LLM infrastructure:</p><p><strong>Enterprise LLM Setup</strong> (OpenAI-compatible API):</p><pre><code><code>import asyncio
from openai import OpenAI
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

class EnterpriseMinioMCPClient:
    def __init__(self):
        # Configure your enterprise LLM as an OpenAI-compatible client
        self.enterprise_llm = OpenAI(
            api_key=&#8221;your-enterprise-api-key&#8221;,  # Your company&#8217;s API key
            base_url=&#8221;https://llm-service.yourcompany.com/v1&#8221;  # Your company&#8217;s LLM endpoint
        )
        
    async def connect_to_minio_server(self, server_script_path: str):
        &#8220;&#8221;&#8220;Connect to MinIO MCP server&#8221;&#8220;&#8221;
        server_params = StdioServerParameters(
            command=&#8221;python&#8221;,
            args=[server_script_path],
            env=os.environ.copy()
        )
        
        # Establish connection to MCP server
        stdio_transport = await stdio_client(server_params)
        self.stdio, self.write = stdio_transport
        self.session = ClientSession(self.stdio, self.write)
        await self.session.initialize()
        
    async def process_query(self, query: str) -&gt; str:
        &#8220;&#8221;&#8220;Process user query through Enterprise LLM + MinIO tools&#8221;&#8220;&#8221;
        
        # Get available MinIO tools
        tools_response = await self.session.list_tools()
        
        # Build tool descriptions for the LLM
        tools_info = &#8220;\n&#8221;.join([
            f&#8221;- {tool.name}: {tool.description}&#8221;
            for tool in tools_response.tools
        ])
        
        # Ask enterprise LLM which tool to use
        messages = [
            {
                &#8220;role&#8221;: &#8220;system&#8221;, 
                &#8220;content&#8221;: f&#8221;You are a MinIO assistant with these tools:\n{tools_info}\n&#8221;
                          &#8220;Respond with TOOL_CALL: {{\&#8221;tool_name\&#8221;: \&#8221;name\&#8221;, \&#8221;parameters\&#8221;: {{}}}} or answer directly.&#8221;
            },
            {&#8221;role&#8221;: &#8220;user&#8221;, &#8220;content&#8221;: query}
        ]
        
        response = self.enterprise_llm.chat.completions.create(
            model=&#8221;your-company-model&#8221;,  # Your enterprise model name
            messages=messages,
            max_tokens=500
        )
        
        llm_decision = response.choices[0].message.content.strip()
        
        # Execute tool if LLM decided to use one
        if llm_decision.startswith(&#8221;TOOL_CALL:&#8221;):
            tool_call = json.loads(llm_decision.replace(&#8221;TOOL_CALL:&#8221;, &#8220;&#8221;).strip())
            tool_result = await self.session.call_tool(
                tool_call[&#8221;tool_name&#8221;], 
                tool_call[&#8221;parameters&#8221;]
            )
            
            # Format result with enterprise LLM
            format_messages = [
                {
                    &#8220;role&#8221;: &#8220;system&#8221;, 
                    &#8220;content&#8221;: &#8220;Format this MinIO tool result into a natural language response.&#8221;
                },
                {
                    &#8220;role&#8221;: &#8220;user&#8221;, 
                    &#8220;content&#8221;: f&#8221;Query: {query}\nResult: {tool_result.content}&#8221;
                }
            ]
            
            final_response = self.enterprise_llm.chat.completions.create(
                model=&#8221;your-company-model&#8221;,
                messages=format_messages,
                max_tokens=1500
            )
            
            return final_response.choices[0].message.content
        
        return llm_decision

# Usage
client = EnterpriseMinioMCPClient()
await client.connect_to_minio_server(&#8221;src/minio_mcp/server.py&#8221;)
result = await client.process_query(&#8221;Show me all buckets and find the largest files in each one&#8221;)</code></code></pre><h3>Optimal Prompting Strategies</h3><p>When working with MCP and local LLMs, these prompting techniques can help deliver a better result:</p><p><strong>Be specific about the context</strong>:</p><pre><code><code>&#8220;Using the MinIO tools, list all buckets and then show me 
the 5 largest objects in the &#8216;backups&#8217; bucket&#8221;</code></code></pre><p><strong>Structure multi-step operations</strong>:</p><pre><code><code>&#8220;First, check what buckets exist in MinIO. Then, for the 
bucket with the most objects, show me a summary of file 
types and total storage used.&#8221;</code></code></pre><p><strong>Provide clear constraints</strong>:</p><pre><code><code>&#8220;List objects in the &#8216;logs&#8217; bucket, but only show files 
from the last 7 days and limit results to 20 items&#8221;</code></code></pre><p><strong>Use domain-specific language</strong>:</p><pre><code><code>&#8220;Check the health of our data lake by listing all buckets, 
showing their sizes, and identifying any empty buckets 
that might need cleanup&#8221;</code></code></pre><p>The key: leveraging the AI&#8217;s natural language understanding while being precise about what data operations you want performed.</p><h3>Performance Considerations</h3><p>Local LLMs with MCP work best when you:</p><ul><li><p><strong>Choose function or tool-calling capable models</strong> (Mistral, Llama 3.2, Qwen)</p></li><li><p><strong>Optimize context windows</strong> for your data size</p></li><li><p><strong>Use streaming responses</strong> for real-time feedback</p></li><li><p><strong>Implement proper error handling</strong> for network timeouts</p></li></ul><h2>Relevant Resources and Documentation</h2><p>If you want to dive deeper into MCP, here are the essential resources:</p><p><strong>Official Documentation</strong>: <a href="https://spec.modelcontextprotocol.io/">Model Context Protocol Specification</a> - The complete technical specification</p><p><strong>Anthropic&#8217;s MCP Guide</strong>: <a href="https://docs.claude.com/en/docs/mcp">MCP Documentation</a> - Practical guides and tutorials</p><p><strong>MCP GitHub Organization</strong>: <a href="https://github.com/modelcontextprotocol">GitHub ModelContextProtocol</a> - SDKs, examples, and community contributions</p><p><strong>Awesome MCP Servers</strong>: A growing collection of community-built MCP servers for popular services</p><p><strong>MCP.so: </strong><a href="https://mcp.so">MCP.so</a>  - A web to &#8220;Find Awesome MCP Servers and Clients&#8221;</p><p>The ecosystem is expanding rapidly, with new MCP servers being built for everything from Slack and GitHub to specialized databases and custom APIs, even to write your own articles in Substack/Medium.</p><h2>Key Takeaways</h2><p>Model Context Protocol helps solving a big challenge in AI development: connecting models to real, live data in a standardized way, providing a universal interface that works across the entire ecosystem.</p><ul><li><p><strong>For developers</strong>, it means more time building intelligent features using AI.</p></li><li><p><strong>For organizations</strong>, this means building AI applications that can actually work with the nuances of your data infrastructure.</p></li><li><p><strong>For the AI ecosystem</strong>, this means faster innovation as everyone builds on shared standards and sharing this servers as open source. </p></li></ul><p>The goal of the MinIO MCP Server is to demonstrate how straightforward it can be to expose powerful data operations to AI models, by creating a bridge between your object store and an LLM with just a few hundred lines of code.</p><p>Whether you&#8217;re using cloud models like Claude or local models like Mistral, the same MCP server works seamlessly. </p><p>Besides improving models to make them smarter, the future of AI relies on making models seamlessly interact with the tools and data that power our workflows.</p><p>Check out the <a href="https://github.com/Rafitis/minio-mcp-server">MinIO MCP Server repository</a> and start building your own AI-data bridges today.</p><p>Til&#8217; next time, </p><p>Ricardo. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The NetPass! 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[uv: The Tool That Helps You Manage Your Python Project Dependencies Smoothly]]></title><description><![CDATA[If you've been working with Python for a while, you've probably experienced the frustration when you're trying to set up a project and you're dealing with conflicting package versions, virtual environment headaches, or waiting forever for pip or Conda to resolve dependencies.]]></description><link>https://ricardoheredia.substack.com/p/uv-the-tool-that-helps-you-manage</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/uv-the-tool-that-helps-you-manage</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Sun, 31 Aug 2025 17:28:37 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!fmvg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you've been working with Python for a while, you've probably experienced the frustration when you're trying to set up a project and you're dealing with conflicting package versions, virtual environment headaches, or waiting forever for pip or Conda to resolve dependencies.</p><p>We've all been there.</p><p>But fortunately there's a tool that can solve all of these problems in second. </p><p><strong>uv</strong> is the Python package that's helps setting up and managing Python projects blazingly fast.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/subscribe"><span>Subscribe now</span></a></p><h2>What is uv?</h2><p>Is a Python package manager built in Rust that promises to be "an extremely fast Python package installer and resolver."</p><p>uv was created by the team at Astral (the same people behind Ruff), and it's designed to replace not just pip, but also pipenv, poetry, pyenv, and conda in many use cases. It's a unified tool that handles:</p><ul><li><p>Package installation and resolution</p></li><li><p>Virtual environment management</p></li><li><p>Python version management</p></li><li><p>Project scaffolding</p></li></ul><p>Think of it as the Swiss Army knife for Python development, but one that actually works smoothly instead of having unstable tools.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!fmvg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!fmvg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic 424w, /__u/substackcdn.com/image/fetch/$s_!fmvg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic 848w, /__u/substackcdn.com/image/fetch/$s_!fmvg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!fmvg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!fmvg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic" width="1350" height="578" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:578,&quot;width&quot;:1350,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29036,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/172396761?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!fmvg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic 424w, /__u/substackcdn.com/image/fetch/$s_!fmvg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic 848w, /__u/substackcdn.com/image/fetch/$s_!fmvg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!fmvg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4c9d5e-db89-4659-b2d2-44a6229481da_1350x578.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Why uv Beats Everything Else</h2><h3>Speed</h3><p>Where uv really shines. While pip can take minutes to install a complex set of dependencies, uv does it in seconds. We're talking about 10-100x faster installation times.</p><p>The first time you use it, you'll think something went wrong because it finished too quickly (happened to me).</p><h3>Better Than pip</h3><p>pip is the default, but it's also slow and doesn't handle dependency resolution as elegantly as it could. </p><p>uv uses a modern resolver that's both faster and more reliable. Plus, unlike pip, uv creates isolated environments by default.</p><h3>Simpler Than Poetry</h3><p>Poetry is great for dependency management, but it has its quirks. The configuration can be complex, and it sometimes feels like overkill for simple projects. </p><blockquote><p><strong>uv gives you the power of Poetry with the simplicity of pip.</strong></p></blockquote><h3>More Reliable Than Conda</h3><p>Conda has its place, it was the first package manager I used, especially for scientific computing and data science. But for pure Python projects, Conda environments can be heavy and sometimes unpredictable, they can easily break and sometimes trying to find the root of that error and fixing it is worse than creating a new environment from scratch.</p><p> uv keeps things lightweight and consistent.</p><h2>What Makes uv Special: The Technical Bits</h2><p>When you use uv, you get three key files that make your life easier:</p><h3>1. pyproject.toml</h3><p>This is your project's configuration file. It contains all your dependencies, project metadata, and build settings in a standardized format. Unlike requirements.txt, it separates development dependencies from production ones and includes version constraints clearly.</p><p>When you run <code>uv pip install</code> in a project with a <code>pyproject.toml</code> file, <code>uv</code> will:</p><ol><li><p><strong>Read Dependencies</strong>: Automatically detect and install the dependencies listed in the <code>[project]</code> and <code>[project.optional-dependencies]</code> sections.</p></li><li><p><strong>Manage Environments</strong>: Create and sync a virtual environment with the exact dependencies specified in the <code>uv.lock</code> file (if present) or <code>pyproject.toml</code>.</p></li><li><p><strong>Lock Dependencies</strong>: Generate a <code>uv.lock</code> file that pins the versions of all direct and transitive dependencies, ensuring fully reproducible builds.</p></li></ol><p>This makes <code>uv</code> a powerful tool for managing complex projects without needing higher-level workflow managers.</p><h3>2. uv.lock</h3><p>It contains the exact versions of every package (and their dependencies) that your project uses. This means when someone else runs your project, they get the exact same package versions you used. Helps to avoid the "but it works on my machine" issues.</p><h3>3. Automatic .venv Creation</h3><p>uv automatically creates and manages virtual environments. No more remembering to activate environments or wondering which packages belong to which project.</p><p><code>uv</code> streamlines virtual environment creation and management.</p><ul><li><p><strong>Creating a virtual environment</strong>:</p></li></ul><pre><code><code># Creates a .venv directory in the current folder
uv venv</code></code></pre><p>This command automatically finds your system's Python and creates a virtual environment. To use a specific Python version, use the <code>--python</code> flag (e.g., <code>uv venv --python 3.11</code>).</p><ul><li><p><strong>Activating the virtual environment</strong>:</p></li></ul><p>Activation commands remain standard for your shell:</p><pre><code><code># For bash or zsh
source .venv/bin/activate
</code></code></pre><p>Once a virtual environment is active, <code>uv</code> commands like <code>uv pip install</code> will automatically use it.</p><h2>The Modern Data Stack Connection</h2><p>If you're working in data science or analytics (for example in football analytics), uv is particularly valuable regarding: </p><ul><li><p><strong>Reproducible analyses</strong>: The lock file ensures your analysis can be reproduced exactly</p></li><li><p><strong>Faster iteration</strong>: Quick environment setup means less time waiting, more time analyzing</p></li><li><p><strong>Clean project structure</strong>: Clear separation between development and production dependencies</p></li><li><p><strong>Better collaboration</strong>: Team members can quickly get identical environments</p></li></ul><h2>Real Example: Setting Up My Football Analytics Project</h2><p>Here&#8217;s an example on how to get started with my football analytics tutorials repository using uv.</p><h3>Step 1: Install uv</h3><pre><code><code># On macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# On Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

# Or via pip if you prefer
pip install uv
</code></code></pre><h3>Step 2: Clone and Set Up the Project</h3><pre><code><code>git clone https://github.com/ricardoheredia/football-analytics-tutorials.git
cd football-analytics-tutorials
</code></code></pre><p>Now, instead of dealing with virtual environments, requirements files, and all that complexity, you just run:</p><pre><code><code>uv sync
</code></code></pre><p>And uv will:</p><ul><li><p>Create a virtual environment automatically</p></li><li><p>Install all dependencies from the lock file</p></li><li><p>Ensure everything is isolated</p></li><li><p>Do it all in seconds</p></li></ul><h3>Step 3: Start Working</h3><pre><code><code>uv run jupyter notebook
</code></code></pre><p>This command runs Jupyter in the project's environment without you having to manually activate it.</p><h2>The Files That Make It Work</h2><p>In the repo, you'll see these key files:</p><p><strong>pyproject.toml</strong> contains our project configuration:</p><pre><code><code>[project]
name = "football-analytics-tutorials"
dependencies = [
    "pandas&gt;=2.0.0",
    "matplotlib&gt;=3.7.0",
    "seaborn&gt;=0.12.0",
    "jupyter&gt;=1.0.0",
    # ... more dependencies
]

[project.optional-dependencies]
dev = [
    "pytest&gt;=7.0.0",
    "black&gt;=23.0.0",
]
</code></code></pre><p><strong>uv.lock</strong> ensures everyone gets the exact same package versions (this file is quite long, but that's the point &#8211; it's comprehensive).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!NE2R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!NE2R!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic 424w, /__u/substackcdn.com/image/fetch/$s_!NE2R!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic 848w, /__u/substackcdn.com/image/fetch/$s_!NE2R!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!NE2R!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!NE2R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic" width="554" height="452.064" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:612,&quot;width&quot;:750,&quot;resizeWidth&quot;:554,&quot;bytes&quot;:25405,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/172396761?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!NE2R!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic 424w, /__u/substackcdn.com/image/fetch/$s_!NE2R!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic 848w, /__u/substackcdn.com/image/fetch/$s_!NE2R!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!NE2R!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86495572-c6f7-4317-a944-7da0f9380d95_750x612.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Why This Matters for Your Workflow</h2><p>Using uv has changed how I approach new projects. Instead of spending minutes setting up environments and installing packages, I spend a few seconds. It helps removing the friction that often prevents us from starting new experiments or sharing our work.</p><p>Now, if I want to test a football analytics technique, I can:</p><ol><li><p>Create a new project with <code>uv init</code></p></li><li><p>Add dependencies with <code>uv add pandas matplotlib</code></p></li><li><p>Start coding immediately</p></li></ol><h2>Getting Started Today</h2><p>If you want to try this out with the example repository:</p><ol><li><p>Install uv using one of the methods above</p></li><li><p>Clone the repo: <code>git clone https://github.com/ricardoheredia/football-analytics-tutorials.git</code></p></li><li><p>Run <code>uv sync</code></p></li><li><p>Start exploring: <code>uv run jupyter notebook</code></p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!eZGr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!eZGr!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!eZGr!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!eZGr!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!eZGr!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!eZGr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic" width="1456" height="806" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:806,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:167133,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/172396761?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!eZGr!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic 424w, /__u/substackcdn.com/image/fetch/$s_!eZGr!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic 848w, /__u/substackcdn.com/image/fetch/$s_!eZGr!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!eZGr!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa918ebd0-d32d-468c-8257-462f30b4bb07_2774x1536.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Check the documentation from the website if you want to go deeper: <a href="https://docs.astral.sh/uv/">uv documentation</a></p><p>You'll be up and running under a minute.</p><h2>The Bottom Line</h2><p>Python package management has been a pain point for too long. </p><p>uv solves the problem and makes the whole experience smooth. Fast installation, reliable dependency resolution, and automatic environment management mean less time fighting with tools.</p><p>For football analytics, data science, machine learning, or any Python project, uv is rapidly becoming the standard. </p><p>The combination of speed, reliability, and simplicity is hard to beat.</p><div><hr></div><p>Let me know in the comments if you have already tried it before or what&#8217;s your preferred Python package manager.</p><p><strong>Check out the <a href="https://github.com/ricardoheredia/football-analytics-tutorials">tutorials repository</a> and start building your own match analysis dashboards today</strong></p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/p/uv-the-tool-that-helps-you-manage?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The NetPass! This post is public so feel free to share it with anyone you  think might like reading about data, AI/ML, football analytics and more.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/p/uv-the-tool-that-helps-you-manage?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/p/uv-the-tool-that-helps-you-manage?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share</span></a></p></div><p>Till next time, </p><p>Ricardo.</p>]]></content:encoded></item><item><title><![CDATA[The Data Learning Diary: Tracking Your Weekly Learning Progress]]></title><description><![CDATA[Why checking your learning at the end of the week helps you advance in projects]]></description><link>https://ricardoheredia.substack.com/p/the-data-learning-diary-tracking</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/the-data-learning-diary-tracking</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Sat, 23 Aug 2025 12:00:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!gKyD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!gKyD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!gKyD!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic 424w, /__u/substackcdn.com/image/fetch/$s_!gKyD!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic 848w, /__u/substackcdn.com/image/fetch/$s_!gKyD!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!gKyD!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!gKyD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic" width="486" height="648" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1152,&quot;width&quot;:864,&quot;resizeWidth&quot;:486,&quot;bytes&quot;:110758,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630595?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!gKyD!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic 424w, /__u/substackcdn.com/image/fetch/$s_!gKyD!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic 848w, /__u/substackcdn.com/image/fetch/$s_!gKyD!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!gKyD!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074a94be-7b4b-412b-8755-e16ca8be4e36_864x1152.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A data guy taking notes backwards (?). Image By GPT-5-Mini. </figcaption></figure></div><p>When we think about writing we might believe that we have an inherent obligation of writing something ground breaking, a scientific article, an encyclopedia, etc. </p><p>But the reality is simpler. </p><p>Writing is a powerful tool that you can use pretty much for any purpose: writing short stories, listing things to remember them, or journaling, for example. </p><p>One of my favorite uses besides writing for this newsletter and sharing content online is: tracking my weekly knowledge. </p><p>A writing use case I&#8217;m sure will help you advance your learning progress, your projects, and your career in general. </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/subscribe"><span>Subscribe now</span></a></p><h3>Using a Paper and Digital Notebook</h3><p>Not so long ago, when I started in this world of technology, especially in data science, in my very first day of work,  I was handed a laptop along with a small notebook and a pen. I immediately thought: &#8220;What&#8217;s the use of this? I&#8217;ll have everything inside my IDE, I don&#8217;t think I&#8217;ll forget anything.&#8221;</p><p>Boy, I was wrong. </p><p>At the same time I was advancing through projects and meetings, that notebook saved my life. It helped me: </p><ul><li><p>Organize my thoughts before presenting results in a meeting.</p></li></ul><ul><li><p>Summarize key ideas from daily standup and sprints.</p></li><li><p>Highlight key results and suggestions from my peers. </p></li><li><p>Note down next steps. </p></li><li><p>And one of my favorites: annotate new things to learn.    </p></li></ul><p>The importance of that notebook (and its content) grew more and more in my daily workflow. </p><p>Soon, I felt I needed a little &#8220;upgrade&#8221;, so I decided to expand my note taking to a digital format. </p><p>I chose Notion as my main notes storage. This helped me organized my notes in simple categories:</p><ul><li><p>Work Projects: meeting summaries, progress, next steps, deadlines, pain points.</p></li><li><p>Personal Projects</p></li><li><p>Learning (courses, new technologies, tools, etc.)</p></li><li><p>Newsletter posts ideas</p></li><li><p>Notes about books (technical and non-technical)</p></li></ul><p>This way, every note was allocated in a specific category, helping me organize the mess I was accumulating in the physical notebook. </p><p>I then realized something: I was noting down things I learned and implemented during the week, but wasn&#8217;t actually reflecting about them nor documenting them with detail. </p><p>Here, documenting the process you go through when learning something new is important. It helps you be aware of what you&#8217;re putting into practice, the failed experiments, and the final success.</p><p>That&#8217;s why I created a specific category in my notes: </p><h3>The Data Learning Diary</h3><p>I fill this diary (a basic separate page in Notion) with the things I&#8217;ve learnt through the week. </p><p> What I do in <strong>3 steps</strong>: </p><ol><li><p>I see something I want to learn &#8594; note down the topic </p></li><li><p>Go over the topic and use the Feynman technique by writing a summary in simple words to see if I understood &#8594; note down that summary (depending on the case I later ask Claude or ChatGPT to help me understand difficult concepts). </p></li><li><p>If it&#8217;s relevant to the project, apply that knowledge immediately &#8594; document every single step in the way: the <strong>goal</strong> of the project, first <strong>implementation</strong>, failed <strong>experiments</strong>, what <strong>worked</strong>, what <strong>didn't</strong>. </p></li></ol><p>I do this daily, so at the end of the week I have a list of all the things I've been going over. </p><p>This is an example of last week.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!lM8Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!lM8Z!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic 424w, /__u/substackcdn.com/image/fetch/$s_!lM8Z!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic 848w, /__u/substackcdn.com/image/fetch/$s_!lM8Z!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!lM8Z!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!lM8Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic" width="536" height="485.9490662139219" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1068,&quot;width&quot;:1178,&quot;resizeWidth&quot;:536,&quot;bytes&quot;:60569,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630595?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!lM8Z!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic 424w, /__u/substackcdn.com/image/fetch/$s_!lM8Z!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic 848w, /__u/substackcdn.com/image/fetch/$s_!lM8Z!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!lM8Z!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b365c87-59d4-49da-8046-769952b2d715_1178x1068.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Screenshot from Notion. You can add &#8216;toggle&#8217; list to write things inside each one and nest them inside. It&#8217;s useful to include subcategories.</figcaption></figure></div><p>On Friday, I did the exercise of going over each of the things I learned from Monday to Friday. Checking what I documented and rereading it to recall it. </p><p>This took me about 20-30 minutes at the end of the day, and I felt it was a powerful way of fixing that knowledge. </p><p>Giving room for your mind to process everything it went through the week, may feel overwhelming at first, but it helps your brain settle the information you&#8217;ve been learning. </p><p>Creating your own note taking methodology can make wonders in the long term. It can make a compound effect and help you advance in areas you feel stuck, understand concepts better, apply them or discard them for others that might be more suitable for your project. It&#8217;s your choice. </p><h3>Key Takeaways</h3><ul><li><p>Whether you&#8217;re advancing on your data career or you&#8217;re more experienced, writing down and organizing your notes will help you retain the daily information better. </p></li><li><p>Choose any tool you want, physical or digital, the important is to have one you feel comfortable with.</p></li><li><p>Make the effort of writing things daily, just a few comprehensive lines of what you&#8217;ve learnt that day and put aside some minutes at the end of the week to go over it. </p></li><li><p>Ask AI to help you ease the way, be it summarizing, understanding, or reframing ideas. </p></li></ul><p>You&#8217;ll see the big picture at the end of the week and adjust your methodology for a next occasion. </p><p>Hope this idea is valuable to you, and if you have any suggestions on what other note-taking methods are helpful, feel free to comment! </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The NetPass! 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>See you next time, </p><p>Ricardo. </p><p></p>]]></content:encoded></item><item><title><![CDATA[Using Agentic IDEs for Football Analytics]]></title><description><![CDATA[How you can create projects coding with AI, and a brief comparison of Cursor vs. Trae]]></description><link>https://ricardoheredia.substack.com/p/using-agentic-ides-for-football-analytics</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/using-agentic-ides-for-football-analytics</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Tue, 12 Aug 2025 12:07:18 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!waLc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg" 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="/__u/substackcdn.com/image/fetch/$s_!waLc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!waLc!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!waLc!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!waLc!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!waLc!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!waLc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg" width="1795" height="1074" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1074,&quot;width&quot;:1795,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:225580,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2fe3b39-603e-4e12-95db-cb4cf3392f2a_1920x1080.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!waLc!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!waLc!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!waLc!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!waLc!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7437c5a6-d527-407b-b929-e47f01c7539b_1795x1074.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Writing code has changed in the last a couple of years. When ChatGPT appeared in the map, using a chat window and asking GPT to create something was a new way of interacting with AI. </p><p>This definitely changes the way that code and software is created. </p><p>According to the great Andrej Karpathy, who talked about this at the AI Startup School lecture in San Francisco called &#8220;<strong>Software Is Changing (Again)&#8221;<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a>, </strong>by comparing an old vs. new paradigm<strong> </strong>on creating software:<strong> </strong></p><blockquote><p><strong>&#8220;</strong><em>We now spend more time <strong>thinking, planning, and reviewing</strong> code generated by LLMs than memorizing syntax and programming from scratch</em>&#8221;.</p></blockquote><p>With time, LLMs market has risen, different AI labs have developed their own open and closed source ones. New tools have also been created to help developers improve their workflows by leveraging these models, practically embedding them inside development environments, which are known as: agentic IDEs. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">To receive new posts and support my work, consider becoming a free or paid subscriber.</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></p><h4>What are Agentic IDEs? </h4><p>They are development environments enhanced with AI that assists with code generation. They are also compared to Agentic CLIs (command line interfaces) like Claude Code and Gemini CLI, which can be used from both the terminal and as a chat window. </p><p>These tools offer capabilities like: </p><ul><li><p>A variety of LLMs from different providers to use.</p></li><li><p>Capacity to index your codebase and libraries documentation </p></li><li><p>Model Context Protocols (MCP) &#8594; open standard that connects AI models to external tools, execute actions, and read data sources, through structured interfaces with LLMs.</p></li></ul><ul><li><p>Ability to edit files autonomously, providing tab completions and code suggestions.</p></li><li><p>Help in projects from planning phase to execution phase, leveraging the use of contextual documentation to understand the nuances of the project.</p></li><li><p>Adaptation to your workflows to help amplify your development in your own domain knowledge. </p></li></ul><h4>What are their main challenges?</h4><p>For the last months I&#8217;ve been using Cursor and a couple weeks ago I started using Trae, one that looks like an affordable competitor. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!w1GN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!w1GN!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic 424w, /__u/substackcdn.com/image/fetch/$s_!w1GN!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic 848w, /__u/substackcdn.com/image/fetch/$s_!w1GN!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!w1GN!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!w1GN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic" width="1456" height="818" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:818,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:232527,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!w1GN!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic 424w, /__u/substackcdn.com/image/fetch/$s_!w1GN!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic 848w, /__u/substackcdn.com/image/fetch/$s_!w1GN!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!w1GN!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd603d406-cabd-46b4-99f2-2eadef16c953_2546x1430.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!BTUg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!BTUg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic 424w, /__u/substackcdn.com/image/fetch/$s_!BTUg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic 848w, /__u/substackcdn.com/image/fetch/$s_!BTUg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!BTUg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!BTUg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic" width="1456" height="787" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:787,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:130883,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!BTUg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic 424w, /__u/substackcdn.com/image/fetch/$s_!BTUg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic 848w, /__u/substackcdn.com/image/fetch/$s_!BTUg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!BTUg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2950bdf6-3fe2-4a5d-96bd-6fbd3bda17b3_2220x1200.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>These tools are intuitive at first and you can get proficient at using them them pretty quickly, especially if you come from VSCode. </p><p>But like Uncle Ben says: </p><blockquote><p>&#8220;<em><strong>With great power comes great responsibility</strong></em>" &#128375;&#65039;</p></blockquote><p>Things can go sideways pretty fast if you are not on the steering wheel. </p><p>Some of the main challenges I&#8217;ve faced: </p><ul><li><p>Understanding how the different LLMs work, and which one excels at which task.</p></li><li><p>Rate limit: tracking how much of your monthly quota are you consuming. This helps you understand how to prompt better to achieve results in less iterations.</p></li><li><p>Testing different prompt formats, to see what helps to achieve better results with each model.</p></li><li><p>Knowing how to leverage the context window of each model. </p></li><li><p>Keeping the leash tight in Agent mode, trying not to let it go rogue and make extreme codebase changes without supervision.</p></li><li><p>Integrating MCPs using them as extra tools that improves my workflow. Especially the ones that are suitable for my project.</p></li></ul><p>You&#8217;'ll see how to tackle these challenges with a framework I used and how I applied it in two football-related use cases.</p><h4>How can you leverage them for Football Analytics? </h4><p>One of the things I like the most about AI is that it is here to augment our capabilities and help us create opportunities within our domain knowledge.</p><p>In this case, I followed a general framework that you can replicate for any project, it works for both Cursor and Trae. </p><ol><li><p>As soon as you open your project, create <strong>three</strong> files: </p><ol><li><p><strong>rules.mdc</strong>: this one sets the context of the rules<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a> that the agent must follow in each project when generating code. In any conversation, it will consider anything you want your project to have: role the AI must adopt, your Python version, the libraries you use, your coding style, design pattern, etc.</p></li><li><p><strong>project_context.md</strong>: you&#8217;ll entire context, this is the document where you set your project&#8217;s main idea goal, characteristics of the project, steps to achieve it, anything. It&#8217;s an opportunity to describe clearly and concisely what you&#8217;re working on. </p></li><li><p><strong>tasks.m</strong>d: granular description of your project tasks. You can use it as a log so models understand what you&#8217;ve done and your progress.</p></li></ol></li></ol><ol start="2"><li><p><strong>Version Control</strong> initiating <strong>Git</strong> from the beginning of the project: commit changes before accepting the code suggestions from the Agent, if you&#8217;re satisfied then test and proceed. </p><p></p></li><li><p><strong>Index</strong> only necessary folders, files, and libraries documentations at the beginning, this will help the Agent pay attention to your codebase structure and understand the last version of the documentation you&#8217;re using, for example the last version of Pandas or Matplotlib. </p></li></ol><p>In summary:</p><div class="pullquote"><p>Open Project &#8594; create rules.mdc + project context file + initial tasks &#8594; version control &#8594; index codebase and documentation</p></div><h4>Football Examples</h4><h5>Example 1: six&#8209;plot match dashboard</h5><p>For this I needed to do a bunch of stuff: </p><ul><li><p>Scraping match event data from different sources. </p></li><li><p>Cleaning and unifying pitch coordinates and IDs </p></li><li><p>Precalculating the metrics </p></li><li><p>Generate the plotting functions. </p></li></ul><p>You can refer the last article so see what the project is about: <a href="/__u/ricardoheredia.substack.com/p/building-your-own-football-analytics">Building Your Own Football Analytics Dashboards With Free Data</a></p><p>And I needed to go over each step with a structure. </p><ol><li><p>Files</p><ol><li><p><strong>rules.mdc</strong>: emphasized the generation of the code in functions and simplified code, sometimes LLMs go way over their head and make up stuff.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!3uRn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!3uRn!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic 424w, /__u/substackcdn.com/image/fetch/$s_!3uRn!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic 848w, /__u/substackcdn.com/image/fetch/$s_!3uRn!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!3uRn!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!3uRn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic" width="1360" height="1126" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1126,&quot;width&quot;:1360,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:148336,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!3uRn!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic 424w, /__u/substackcdn.com/image/fetch/$s_!3uRn!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic 848w, /__u/substackcdn.com/image/fetch/$s_!3uRn!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!3uRn!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a7def2e-2574-4bce-84ef-e7f62e49fe8e_1360x1126.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p><strong>project_context.md: </strong>I went from broad to specific explanation of my project. Main goa, key components, steps to create it, plots characteristics, color and aesthetic I wanted to implement. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!dOOA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!dOOA!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic 424w, /__u/substackcdn.com/image/fetch/$s_!dOOA!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic 848w, /__u/substackcdn.com/image/fetch/$s_!dOOA!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!dOOA!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!dOOA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic" width="696" height="467.0274725274725" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:977,&quot;width&quot;:1456,&quot;resizeWidth&quot;:696,&quot;bytes&quot;:95433,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!dOOA!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic 424w, /__u/substackcdn.com/image/fetch/$s_!dOOA!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic 848w, /__u/substackcdn.com/image/fetch/$s_!dOOA!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!dOOA!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdeca6-cfb2-4165-9045-cf4388e98536_1586x1064.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p><strong>project_log2025.md: </strong>this is the task document where I only set the specific task to accomplish and next steps. </p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!GWRg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!GWRg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic 424w, /__u/substackcdn.com/image/fetch/$s_!GWRg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic 848w, /__u/substackcdn.com/image/fetch/$s_!GWRg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!GWRg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!GWRg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic" width="696" height="141.0164835164835" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:295,&quot;width&quot;:1456,&quot;resizeWidth&quot;:696,&quot;bytes&quot;:54641,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!GWRg!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic 424w, /__u/substackcdn.com/image/fetch/$s_!GWRg!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic 848w, /__u/substackcdn.com/image/fetch/$s_!GWRg!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!GWRg!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fc9bc4d-9686-415f-8a86-7f801e6f02e3_1600x324.heic 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p></li><li><p><strong>Version control with Git</strong></p></li><li><p><strong>Index files and folders: </strong>in Trae, the context indexes automatically, in Cursor you need to indicating it at the beginning but then files are automatically synced.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!n1vx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!n1vx!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic 424w, /__u/substackcdn.com/image/fetch/$s_!n1vx!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic 848w, /__u/substackcdn.com/image/fetch/$s_!n1vx!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!n1vx!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!n1vx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic" width="1456" height="754" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:754,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:53295,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!n1vx!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic 424w, /__u/substackcdn.com/image/fetch/$s_!n1vx!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic 848w, /__u/substackcdn.com/image/fetch/$s_!n1vx!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!n1vx!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4478cbe-6830-46d1-a99b-2948b179b912_1970x1020.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>From this point onwards,  is a back and forth iteration, tweaking the documents, and adapting the prompts to obtain satisfactory outputs from the LLMs.</p><p>Some of the <strong>challenges</strong>: the model confused coordinate systems (0&#8211;100 vs 120&#215;80), misnamed some columns, or repeated different Matplotlib functions. Had to pass the dimensions explicitly in a document to be used as context. </p><h5>Example 2: on&#8209;ball sequences with GPT&#8209;5 in Cursor (Trae didn&#8217;t have it yet)</h5><p>Sequence helps you not only analyze what happened in a match (player passed a ball in a specific direction and zone of the field) but also &#8216;<strong>how</strong>&#8217; it happened <strong>before</strong> and <strong>after</strong> that, it adds context. </p><p>I asked GPT&#8209;5 to find sequences based on my data from Salzburg vs. Real Madrid in the CWC, and gave it freedom to pick any event and any player. I did it in 3 steps: </p><ul><li><p>Asked it to adopt the role of a PhD Level Football Machine Learning Engineer and that it needed to understand my codebase and recent progress. </p></li><li><p>Indexed my event data, so it could understand the type of events and specifications of the plots colors.</p></li><li><p>I asked it to plot coordinates X and Y of any event and any player. </p></li></ul><p>It chose a pass where Dean Huijsen receives deep on the left in his own half and carries into the attacking half on the same flank. </p><p>Then plotted two examples with a dark mplsoccer theme and label the player. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Xslj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Xslj!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic 424w, /__u/substackcdn.com/image/fetch/$s_!Xslj!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic 848w, /__u/substackcdn.com/image/fetch/$s_!Xslj!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!Xslj!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Xslj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic" width="1456" height="530" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:530,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32781,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/170630648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Xslj!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic 424w, /__u/substackcdn.com/image/fetch/$s_!Xslj!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic 848w, /__u/substackcdn.com/image/fetch/$s_!Xslj!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!Xslj!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f462093-6b95-445d-b0a7-1518d93323f5_1996x726.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It filtered events, computed distance gained (about 39&#8211;43m in two cases), and drew the trajectory of the sequence. </p><p>The <strong>takeaway</strong>: when your instruction is specific and concrete, agentic IDEs translate it into working code quickly.</p><h4>How to get reliable results from the models</h4><ul><li><p>Be specific with inputs: a well-described tasks, specific code format (generate functions). </p></li><li><p>Paste snippets of your information (e.g. rows of your data frame) and state plotting specifications. </p></li><li><p>Index your context: point the Agent to the exact files or docs you want it to use.</p></li><li><p>Have it explain the logic in plain language before you run anything. </p></li></ul><h4>Quick comparison between Cursor vs Trae based on my experience</h4><h5>Cursor </h5><p>Is one of the most populars, I personally find these specs useful: </p><ul><li><p>Agent mode in Claude Sonnet 4: best model I&#8217;ve tested inside Cursor, it provides well structured code and understands the codebase when you give it the entire context. </p></li><li><p>MCP integration: most of the MCPs have integration for Cursor, for example setting Supabase was easier here than in Trae which is newer. </p></li><li><p>Haven&#8217;t tried but looks interesting: Background Agents &#8594; edit and run code in a remote environment.</p></li><li><p>Broader range of models: for small tasks the Cursor small own model helped me for writing specifications for project and I also liked using Deepseek v3.1 for coding, it was pretty solid. </p></li><li><p>Something I didn&#8217;t like: the rate limit. With pro plan ($20 a month), you were suppose to have unlimited requests but one day they changed it quietly and people started to hit rate limits all of a sudden. </p></li></ul><h5>Trae</h5><ul><li><p>Is cheaper: first month $3, next bill $10.</p></li><li><p>Has two modes: </p><ul><li><p>Builder: to execute routine and end-to-end tasks. </p></li><li><p>Builder with MCP: use MCP servers to run tasks. </p></li></ul></li><li><p>MCP: setting them is easier than in Cursor and they have a marketplace where you can grab and the ones you need. </p></li><li><p>Haven&#8217;t tried but looks interesting: Custom Agent &#8594; use MCP tools and built-in ones from Trae to use a specific Agent for specific tasks. </p></li><li><p>Needs more popularity but they are clear with the limits you have 600 a month.</p></li><li><p>Something I didn&#8217;t like: they have a SOLO builder mode which is more autonomous and you can see the development of your app during the whole process: backend and frontend, but you have to join a waitlist to get an invitation codes that hasn&#8217;t arrived yet. </p></li></ul><p>To help you evaluate them deeply you can check these two sources to help you decide: </p><p><a href="https://www.datacamp.com/tutorial/trae-ai">Trae AI: A Guide With Practical Examples</a></p><p><a href="https://www.datacamp.com/tutorial/cursor-ai-code-editor">Cursor AI: A Guide With 10 Practical Examples</a></p><h4>Final thoughts</h4><p>Agentic IDEs can help you move fast from any question you have to working code. </p><p>Start small: aim for iteration and then repeatable workflows. Keep guardrails in place: index your documents, do sanity&#8209;checks after every iteration, have the IDE generate simple tests, and ask models to state assumptions before coding. </p><p>As you polish prompts and set rules, you&#8217;ll see the improvements. </p><div class="pullquote"><p>Open Project &#8594; create rules.mdc + project context file + initial tasks &#8594; version control &#8594; index codebase and documentation</p></div><p></p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p><a href="https://www.youtube.com/watch?v=LCEmiRjPEtQ">Link to Lecture</a></p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p><a href="https://github.com/PatrickJS/awesome-cursorrules/tree/main">Awesome Cursor Rules</a></p></div></div>]]></content:encoded></item><item><title><![CDATA[Building Your Own Football Analytics Dashboards With Free Data]]></title><description><![CDATA[A template you can use for further automations]]></description><link>https://ricardoheredia.substack.com/p/building-your-own-football-analytics</link><guid isPermaLink="false">https://ricardoheredia.substack.com/p/building-your-own-football-analytics</guid><dc:creator><![CDATA[Ricardo Heredia]]></dc:creator><pubDate>Sun, 27 Jul 2025 07:31:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!si8p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>What&#8217;s a match dashboard? </h3><p>Is a comprehensive visual report that provides a <em>quick</em>-<em>analytical</em> overview of a football match. </p><p>If you missed a match or watched the 90+ minutes and you want to review the statistics quickly, a dashboard helps you get an overview of the tactical and performance insights in one place.</p><p>In case you're tracking a league as an analyst, as a scout to flag a player, or even as fan that wants to know how your favorite team performed this weekend, building them can make a difference in how fast you retrieve that information. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!si8p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!si8p!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic 424w, /__u/substackcdn.com/image/fetch/$s_!si8p!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic 848w, /__u/substackcdn.com/image/fetch/$s_!si8p!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!si8p!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!si8p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic" width="725" height="535.782967032967" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1076,&quot;width&quot;:1456,&quot;resizeWidth&quot;:725,&quot;bytes&quot;:304201,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/169314648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!si8p!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic 424w, /__u/substackcdn.com/image/fetch/$s_!si8p!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic 848w, /__u/substackcdn.com/image/fetch/$s_!si8p!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!si8p!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F238480ed-bd03-471a-b935-4f27b0b0b3e3_2370x1751.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Match Report from Club World Cup Match between Salzburg and Real Madrid.  </figcaption></figure></div><p>I built this dashboard using: </p><ul><li><p>Python 3.10</p></li><li><p>Beautiful Soup </p></li><li><p>Pandas</p></li><li><p>NumPy</p></li><li><p>Pandas</p></li><li><p>Matplolib</p></li><li><p>Mplsoccer </p></li></ul><p>The goal was to build a template with just 6 key analytical plots:</p><ul><li><p>Passing Networks: Shows team shape, player positions, and passing combinations.</p></li><li><p>Defensive Actions: Reveals pressing intensity, defensive positioning, and team compactness.</p></li><li><p>Progressive Passes: Analyzes forward progression and attacking build-up patterns</p></li><li><p>Shot Map: Comprehensive shooting analysis with xG, shot types, and quality assessment.</p></li><li><p>xT Momentum: Tracks dangerous situation creation, goals, and match momentum shifts over time. </p></li><li><p>Match Statistics: Side-by-side comparison of key performance metrics between teams.</p></li></ul><h3>Where to get the data from? </h3><p>This is the most important part. </p><p>In this case I needed event data for only one match, using coordinates from different situations in the offensive and defensive phases like: Passes, Progressive Passes, Interceptions, Blocks, etc. </p><p>These coordinates are represented as X and Y, paired with its end_x and end_y. This helps understanding where and when a situation started, same as where it ended on the pitch.</p><p>WhoScored was my go to place to obtain the majority of them. But I was still missing the shots coordinates. Fotmob has them, though it&#8217;s a tricky place to obtain them. </p><blockquote><p><em>I suggest you to visit the GitHub repo and give the scraping logic a look: <a href="https://github.com/ricardoherediaj/football-analytics-tutorials/blob/main/notebooks/cwc_scraping_test.ipynb">https://github.com/ricardoherediaj/football-analytics tutorials/blob/main/notebooks/cwc_scraping_test.ipynb</a></em><a href="https://github.com/ricardoherediaj/football-analytics-tutorials/blob/main/notebooks/cwc_scraping_test.ipynb"> </a></p></blockquote><h2>Plotting the Dashboard</h2><p>After obtaining the data sources, I transformed the raw match events into insights. </p><p>In this case I saved the data in CSV and JSON format, you&#8217;ll see it at: <em><a href="https://github.com/ricardoherediaj/football-analytics-tutorials/tree/main/data">https://github.com/ricardoherediaj/football-analytics tutorials/blob/main/data</a></em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!50eZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!50eZ!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic 424w, /__u/substackcdn.com/image/fetch/$s_!50eZ!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic 848w, /__u/substackcdn.com/image/fetch/$s_!50eZ!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!50eZ!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_webp, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!50eZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic" width="498" height="419.1409978308026" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:776,&quot;width&quot;:922,&quot;resizeWidth&quot;:498,&quot;bytes&quot;:23836,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ricardoheredia.substack.com/i/169314648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!50eZ!, /__u/ricardoheredia.substack.com/w_424, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic 424w, /__u/substackcdn.com/image/fetch/$s_!50eZ!, /__u/ricardoheredia.substack.com/w_848, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic 848w, /__u/substackcdn.com/image/fetch/$s_!50eZ!, /__u/ricardoheredia.substack.com/w_1272, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic 1272w, /__u/substackcdn.com/image/fetch/$s_!50eZ!, /__u/ricardoheredia.substack.com/w_1456, /__u/ricardoheredia.substack.com/c_limit, /__u/ricardoheredia.substack.com/f_auto, /__u/ricardoheredia.substack.com/q_auto:good, /__u/ricardoheredia.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a71b7a-2c2b-4a01-bb1f-8ce1998de77d_922x776.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>df_events contains the main events and coordinates I used for the plotting</p></li><li><p>match_events.json and matchdict.json contain players numbers and shirts </p></li><li><p>shots_df includes the shots data from Fotmob in the match</p></li><li><p>xT_grid.csv has the values to understand the highest and lowest threat actions a team makes during a match on the pitch. </p></li></ul><p>Assisted by Claude Sonnet 4 inside the Cursor IDE, I designed this template around six plots that I found interesting for the dashboard. </p><p>I selected just six to try not to overcrowd the report. Each plot shows specific characteristics of team&#8217;s performances.</p><h3>1. Passing Networks</h3><p>Shows the team shape, players average positions, and passing combinations.</p><p>I also calculated measures for <strong>verticality</strong>, to see how direct a team's passing is. I'm also tracking the <strong>defensive line</strong>, <strong>forward line</strong>, and <strong>team median position</strong> to understand how compact or stretched a team's shape is.</p><p>When you visualize them size-by-size, Salzburg's network might show a compact, possession-based approach with short passing triangles, while Real Madrid could display a more vertical, counter-attacking structure with longer passing connections.</p><p>I converted WhoScored coordinates (0-100 scale) to StatsBomb format (0-120x0-80) for consistency across all visualizations. </p><p>The bidirectional pass combinations reveal which player partnerships are most active during the match.</p><h3>2. Defensive Actions</h3><p>This heat map shows where each team applies pressure and wins possession. </p><p>I tracked every tackle, interception, ball recovery, and blocked pass, then creating a KDE (kernel density estimation) heat map that shows the intensity of defensive actions across the pitch. </p><p>The <strong>Defensive Action Height</strong> metric tells you how high up the pitch a team typically wins the ball.</p><p>Combined with the <strong>compactness percentage</strong>, you can immediately see if a team is playing a high press or sitting deep.</p><h3>3. Progressive Passes</h3><p>Passes that significantly advance the ball toward the opponent's goal at least 30%.</p><p>The pitch is divided by zones where<strong> </strong>you can see if a team builds attacks primarily through the left flank, through the center, or via the right side.</p><p><strong>Example</strong>: If Salzburg completed 23 progressive passes with 65% coming from the left side, you can deduct they're targeting Real Madrid's right defensive lane.</p><h3>4. Shot Map</h3><p>It shows where shots were taken and incorporates <strong>Expected Goals (xG)</strong>, <strong>big chances</strong>, and different shot outcomes to give you a complete attacking picture.</p><p>Each shot is sized by its xG value and color-coded by outcome. Green circles are goals, hatched circles are saves, and larger markers indicate big chances. This shows you which team created better opportunities, regardless of the final score.</p><p><strong>For example</strong>: a team with 8 shots worth 0.3 xG total had a very different performance than a team with 4 shots worth 1.2 xG total.</p><h3>5. xT Momentum</h3><p>Expected Threat (xT) momentum tracks which team is creating more dangerous situations throughout the match, smoothed over time to show momentum shifts.</p><p>I'm calculating the xT value for every successful pass and carry, then using a weighted rolling window to show how momentum builds and shifts. When you see the line spike upward, that team is creating dangerous situations. When it dips, they're losing control.</p><p>Momentum spikes often correlate with goals, substitutions, or tactical changes. </p><h3>6. Match Statistics</h3><p>The final central plot is a comparative view of key performance metrics. </p><p>Possession percentage, field tilt (percentage of touches in the attacking third), passing accuracy, defensive actions, and PPDA (Passes Per Defensive Action - a pressing intensity metric).</p><h3>Notes on the Development Journey</h3><p>I've left my experimental attempts visible in the notebook because I wanted to show the messy development process before the final dashboard code.</p><p><strong>Experiment 1</strong>: data integration challenges, mixing WhoScored events and Fotmob shot coordinates. Since they&#8217;re different platforms they use different coordinate systems and player ID formats but still the plotting was poor.</p><p><strong>Experiment 2</strong>: used the data preprocessing from experiment 1, builds the layout and makes the visualizations work as subplots rather than standalone plots. This required making three functions to be "subplot-friendly&#8221;. </p><p><strong>Experiment 3</strong>: improved the &#8220;dual ID system&#8221; issue, since WhoScored uses different team IDs than Fotmob, so I needed to map between them correctly for the shot map while keeping everything else consistent.</p><p><strong>Experiment 6:</strong> the final version I'm satisfied with (for now). It did the preprocessing process more straightforward and plotted all six plots into a meaningful dashboard.</p><h3>Next Steps</h3><p>This template is designed to be the foundation for a larger end-to-end football analytics pipeline. The next steps would be:</p><ul><li><p><strong>Modularizing the code</strong> into separate Python scripts for easier maintenance</p></li><li><p><strong>Database integration</strong> in Supabase to store scraped data persistently</p></li><li><p><strong>Automated data collection</strong> <strong>and reports visualization</strong> using GitHub Actions or similar</p></li><li><p><strong>Individual players performance reports</strong></p></li><li><p><strong>Obtaining data for more leagues and matches </strong></p></li></ul><p>Once you have the template working for one match, you can generate these reports for any match in any league, as long as you get the underlying event data.</p><p>The goal of this is to think it a systematic approach to football analysis that combines the best of data science with tactical understanding. </p><p>Each visualization answers specific questions that matter to different stakeholders:</p><ul><li><p><strong>Coaches</strong> can see their team's tactical execution and identify areas for improvement</p></li><li><p><strong>Scouts</strong> can quickly assess player and team performance across multiple matches</p></li><li><p><strong>Analysts</strong> can spot patterns and trends that aren't visible from watching alone</p></li><li><p><strong>Developers/Fans</strong> can understand the tactical nuances of matches beyond just the final score</p></li></ul><p>I invite you to grab a cup of coffee, subscribe to my newsletter, and give it a check to the repo: https://github.com/ricardoherediaj/football-analytics-tutorials/blob/main/notebooks/match_dashboard_template.ipynb</p><p>You might learn something new, discover something to improve, or ideas to make your own football plots!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ricardoheredia.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/ricardoheredia.substack.com/subscribe"><span>Subscribe now</span></a></p><p></p><h4>References</h4><p>Special mention to the main reference I based on: </p><p>https://github.com/adnaaan433/Post-Match-Report-2.0/tree/main</p><p></p><p></p><p></p><p></p><p></p><p></p>]]></content:encoded></item></channel></rss>