<?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 AI Practitioner: Posts]]></title><description><![CDATA[Real-world AI, tested in code — what works, what doesn’t, and why.]]></description><link>https://aipractitioner.substack.com/s/post</link><image><url>https://substackcdn.com/image/fetch/$s_!ivps!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png</url><title>The AI Practitioner: Posts</title><link>https://aipractitioner.substack.com/s/post</link></image><generator>Substack</generator><lastBuildDate>Thu, 23 Apr 2026 23:12:18 GMT</lastBuildDate><atom:link href="https://aipractitioner.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Lina Faik]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[ai-practitioner@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[ai-practitioner@substack.com]]></itunes:email><itunes:name><![CDATA[Lina Faik]]></itunes:name></itunes:owner><itunes:author><![CDATA[Lina Faik]]></itunes:author><googleplay:owner><![CDATA[ai-practitioner@substack.com]]></googleplay:owner><googleplay:email><![CDATA[ai-practitioner@substack.com]]></googleplay:email><googleplay:author><![CDATA[Lina Faik]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Building Claude Skills: A New Paradigm for Interacting with LLMs]]></title><description><![CDATA[A Practical Guide for Data Scientists, From Theory to an Automated Slide Generator]]></description><link>https://aipractitioner.substack.com/p/building-claude-skills-a-new-paradigm</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/building-claude-skills-a-new-paradigm</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Tue, 10 Mar 2026 13:24:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Hg4-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Hg4-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Hg4-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png 424w, https://substackcdn.com/image/fetch/$s_!Hg4-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png 848w, https://substackcdn.com/image/fetch/$s_!Hg4-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png 1272w, https://substackcdn.com/image/fetch/$s_!Hg4-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Hg4-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png" width="1456" height="605" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:605,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1061906,&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://aipractitioner.substack.com/i/190262322?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Hg4-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png 424w, https://substackcdn.com/image/fetch/$s_!Hg4-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png 848w, https://substackcdn.com/image/fetch/$s_!Hg4-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png 1272w, https://substackcdn.com/image/fetch/$s_!Hg4-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20ab64ff-5289-4259-871f-e784735c7300_2928x1216.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This article is also available as a podcast! If you&#8217;re on the go or just want to absorb the content in audio format, you can listen to the full episode below &#128071; The podcast is also available on <a href="https://open.spotify.com/show/6MROBKvrjx0Mey8tHud5LX">Spotify</a> and <a href="https://podcasts.apple.com/us/podcast/the-ai-practitioner-podcast/id1830285899">Apple Podcasts</a>.</em></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;8090e6a1-06c1-4e09-9360-a865f1aebc7b&quot;,&quot;caption&quot;:&quot;Prefer reading instead? The full article is available here. The podcast is also available on Spotify and Apple Podcasts. Subscribe to keep up with the latest drops.&quot;,&quot;cta&quot;:&quot;Listen now&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;PODCAST &#8212; Building Claude Skills: A New Paradigm for Interacting with LLMs&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:7177021,&quot;name&quot;:&quot;Lina Faik&quot;,&quot;bio&quot;:&quot;Lead AI Scientist bringing AI research to real-world impact across industries. Founder, Data Impulse | Author, The AI Practitioner | ex-Dataiku&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bdaf5e6-a6c6-48fe-80f6-3d69aaac1694_2256x2256.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-03-10T13:23:04.401Z&quot;,&quot;cover_image&quot;:&quot;https://substack-video.s3.amazonaws.com/video_upload/post/190434342/a58934ca-d6d6-4432-8df8-896c525d6ec5/transcoded-1773087907.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://aipractitioner.substack.com/p/podcast-building-claude-skills-a&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:190434342,&quot;type&quot;:&quot;podcast&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4815372,&quot;publication_name&quot;:&quot;The AI Practitioner&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ivps!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>As LLM workflows move from simple chat experiments to production-grade automation, developers are starting to hit a <strong>&#8220;prompt ceiling.&#8221;</strong> Traditional prompt engineering relies on large system prompts that are difficult to version, hard to maintain across teams, and increasingly fragile as context windows grow. Instructions must often be repeated, and small wording changes can significantly alter model behavior.</p><p>Until recently, the main alternatives were either platform-locked assistants inside apps like ChatGPT or the Gemini app (e.g., custom GPTs or Gems) or more complex infrastructures built around function calling and custom orchestration. Neither approach provides a simple way to package and reuse procedural knowledge across projects.</p><p>A more structured alternative has recently emerged with Claude Skills, introduced by Anthropic. Instead of embedding workflows inside prompts, developers can package expertise into skills: structured folders containing instructions, resources, and scripts that Claude can discover and load dynamically when needed. This approach turns AI workflows into modular, versionable components that can live in a filesystem or repository alongside the rest of a project.</p><h3>Objective</h3><p>This article focuses on Agent Skills for Claude: what they are, how they differ from existing approaches, and how to build one from scratch.</p><p>After reading this article, you will understand:</p><ol><li><p><strong>Why prompt engineering does not scale</strong>, and the limitations shared by existing alternatives</p></li><li><p><strong>How Agent Skills work</strong>, from their internal structure to their discovery and loading model</p></li><li><p><strong>How to design, iterate, and deploy a Claude Skill</strong> in practice across Claude&#8217;s different surfaces</p></li></ol><blockquote><p><strong>Prerequisites</strong> &#8212; None. This article is self-contained and assumes no prior knowledge of Agent Skills or Claude Code.</p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><p></p><h2>1. The Limits of Current LLM Workflow Approaches</h2><h3>1.1 The Limits of Prompt-Based Workflows</h3><h4>Why Traditional Prompting Does Not Scale</h4><p>Prompt engineering, which consists of crafting inputs to guide model outputs, became the dominant way to control LLMs without modifying their weights. It is attractive because it requires no infrastructure or training pipeline: just text.</p><p>However, control expressed through text is fragile. Instructions must be repeated in every session, degrade as context grows, and are difficult to version or reuse. Prompts are also <strong>model-sensitive</strong>: one tuned for GPT-4o may behave differently on Claude 3.5 Sonnet or even on a newer model version.</p><p>As a result, over 65% of LLM developers report that prompt versioning and observability are among the main challenges when moving from prototypes to production [1].</p><h4>Repeated Instructions and Fragile Prompt Logic</h4><p>Unlike traditional software, which runs deterministic code, prompt engineering operates in a probabilistic system. Small wording changes can produce very different outputs, and identical prompts may yield different results across sessions, making reproducibility difficult.</p><p>Teams often end up copying large system prompts across projects, creating diverging versions that are hard to maintain. Over time, prompts grow into long instruction blocks where even small edits risk breaking hidden logic [1].</p><h4>The Challenge of Reusable AI Workflows</h4><p>The deeper issue is <strong>knowledge portability</strong>. Expertise often lives in documents or personal notes rather than in a structured form that models can reliably access.</p><p>Prompt engineering works well for experimentation, but it is a weak foundation for building reusable and maintainable AI workflows.</p><h3>1.2 Existing Approaches to Extending LLMs</h3><p>Before Skills, several strategies emerged to make LLMs more capable or specialized.</p><h4>Custom GPTs, Gemini Gems, and ChatGPT / Claude Projects</h4><p>These are the closest alternatives. Each lets you create a persistent assistant with instructions and optional knowledge files, without additional infrastructure. They work well for interactive chat use, but have clear limits for developer workflows.</p><ol><li><p><strong>Platform lock-in</strong>: these configurations live inside their respective interfaces and cannot be version-controlled, packaged, or used programmatically.</p></li><li><p><strong>Monolithic by design</strong>: each is a single, fixed configuration. If you need slide generation <em>and</em> SQL generation <em>and</em> report formatting, you maintain separate assistants with no way to combine them dynamically in a single session.</p></li><li><p><strong>Static knowledge, no execution</strong>: uploaded files are read-only context, not code LLM can run. Anything that cannot be expressed in prose is simply out of scope.</p></li></ol><h4>Function Calling</h4><p>Function calling gives the model the ability to act, calling APIs, writing files, or querying databases. But it does not define behavioral patterns or workflows across sessions.</p><h2>2. From Prompts to Skills: A New Interaction Model for LLMs</h2><h3>2.1 Skills: Packaging Expertise Instead of Writing Prompts</h3><p>Introduced by Anthropic in October 2025, Agent Skills represent a new way to structure the way language models perform tasks. Instead of repeatedly crafting prompts, developers can package procedural knowledge into reusable capabilities called skills.</p><p>A skill is essentially a structured folder containing instructions, scripts, and supporting resources that an agent can discover and load dynamically. Once created, it can be reused across conversations and projects without rewriting prompts.</p><p>In other words, building a skill is like writing an onboarding guide for a new employee. Procedural expertise is documented once in a structured format, and the model applies it whenever relevant.</p><p>In December 2025, Anthropic released <a href="https://agentskills.io/home">Agent Skills</a> as an open standard, signaling a broader ambition: making skills portable across tools and platforms rather than tied to a single product ecosystem.</p><p>For teams, the implications are significant. Skills can be stored in a filesystem or Git repository, versioned alongside code, and shared across projects. This makes LLM workflows into maintainable infrastructure rather than prompt engineering experiments.</p><h3>2.2 Anatomy of a Skill</h3><p>At the most basic level, a skill requires only one file: <code>SKILL.md</code>. Everything else in the directory is optional and loaded only when needed.</p><p>To illustrate the structure, consider a skill designed to generate branded client presentations from predefined templates and upload them to Google Drive:</p><pre><code><code>branded-slides/
&#9500;&#9472;&#9472; SKILL.md
&#9500;&#9472;&#9472; assets/
&#9474;   &#9500;&#9472;&#9472; infographics-library.pptx
&#9474;   &#9492;&#9472;&#9472; slide-example.pptx
&#9500;&#9472;&#9472; references/
&#9474;   &#9500;&#9472;&#9472; brand-guidelines.md
&#9474;   &#9492;&#9472;&#9472; google-slides-setup.md
&#9492;&#9472;&#9472; scripts/
    &#9500;&#9472;&#9472; credentials.json
    &#9492;&#9472;&#9472; upload_to_google_slides.py
</code></code></pre><p>The <code>SKILL.md</code> file begins with YAML frontmatter, which tells the model when the skill should be activated.</p><pre><code><code>---
name: branded-slides
description: Generate branded client slide decks as .pptx files and upload
  to Google Drive. Use when asked to create a presentation, deck, or slides
  for a client or course.
---
</code></code></pre><p>Only two fields are required:</p><ul><li><p><code>name</code> : unique identifier for the skill</p></li><li><p><code>description</code> : the trigger description the model uses to decide whether to activate the skill</p></li></ul><p>Because the model relies entirely on the description to detect when to invoke the skill, specific wording matters: a vague description reduces the likelihood that the skill will be triggered automatically.</p><p>Skills can optionally declare the tools they are allowed to use via the <code>allowed-tools</code> field:</p><pre><code><code>---
name: branded-slides
description: Generate and upload branded slide decks to Google Drive.
allowed-tools: Bash, Read, Write
---
</code></code></pre><p>In practice, the tool scope should match the <strong>risk level of the workflow</strong>. For example:</p><p><strong>Example 1 &#8212; Read-only skill (safe analysis)</strong></p><p>A skill designed only to inspect files should not have permission to modify them.</p><pre><code><code># Read-only skill &#8212; analysis without any risk of modification
allowed-tools: Read, Grep, Glob
</code></code></pre><p>This configuration allows the model to search and analyze a codebase or document collection without any possibility of altering files.</p><p><strong>Example 2 &#8212; Full file workflow</strong></p><p>More complex automation tasks require the ability to read files, generate content, and write results.</p><pre><code><code># Full file workflow &#8212; read, generate, write
allowed-tools: Bash, Read, Write
</code></code></pre><p>This setup is typical for automation workflows, such as generating reports, building artifacts, or running scripts that produce output files.</p><p>Below the frontmatter, the rest of <code>SKILL.md</code> contains the <strong>procedural workflow</strong> the model should follow.</p><pre><code><code># Branded Slides

## Instructions
1. Read references/brand-guidelines.md
2. Inspect assets/infographics-library.pptx
3. Run scripts/upload_to_google_slides.py

## Constraints
- Start with a title slide and executive summary
- Use amber #FBB831 for headers
- Maximum 5 bullet points per slide
</code></code></pre><p>Supporting files play distinct roles:</p><ul><li><p><code>brand-guidelines.md</code> defines visual and branding rules</p></li><li><p><code>upload_to_google_slides.py</code> performs deterministic operations like generating slides and uploading them</p></li><li><p>the <code>assets/</code> folder provides visual templates and references</p></li></ul><h3>2.3 Progressive Loading &amp; Skill Discovery</h3><p>A key architectural feature of skills is <strong>progressive disclosure</strong>. Instead of loading all information at once, the model retrieves instructions only when needed.</p><p>Information is loaded in three stages:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!x6un!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!x6un!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png 424w, https://substackcdn.com/image/fetch/$s_!x6un!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png 848w, https://substackcdn.com/image/fetch/$s_!x6un!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png 1272w, https://substackcdn.com/image/fetch/$s_!x6un!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!x6un!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png" width="375" height="408.99725274725273" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1588,&quot;width&quot;:1456,&quot;resizeWidth&quot;:375,&quot;bytes&quot;:254770,&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://aipractitioner.substack.com/i/190262322?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!x6un!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png 424w, https://substackcdn.com/image/fetch/$s_!x6un!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png 848w, https://substackcdn.com/image/fetch/$s_!x6un!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png 1272w, https://substackcdn.com/image/fetch/$s_!x6un!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de27520-a442-4b06-969c-2bc0f884e44e_1584x1728.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Progressive loading model for Claude Skills: metadata &#8594; instructions &#8594; resources, loaded only when required.</figcaption></figure></div><p>Skills are invoked by the model, not the user. The agent decides when to activate a skill based on the request and the skill&#8217;s description. Initially, the model only knows the skill exists. When a relevant request appears, it loads the instructions and fetches additional resources only if required.</p><p>Unlike system prompts, which are always present and consume tokens, skills stay dormant until needed and load only the necessary information.</p><p>This modular approach lets teams treat LLM capabilities as reusable building blocks. For example, a team might create separate skills for generating slide decks, analyzing SQL queries, or producing reports, and the model activates each one only when the task requires it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fj6L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fj6L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif 424w, https://substackcdn.com/image/fetch/$s_!fj6L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif 848w, https://substackcdn.com/image/fetch/$s_!fj6L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif 1272w, https://substackcdn.com/image/fetch/$s_!fj6L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fj6L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif" width="800" height="502" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:502,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3097494,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/190262322?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fj6L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif 424w, https://substackcdn.com/image/fetch/$s_!fj6L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif 848w, https://substackcdn.com/image/fetch/$s_!fj6L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif 1272w, https://substackcdn.com/image/fetch/$s_!fj6L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0907b9a7-ebad-4a52-8390-26eebdc31e4a_800x502.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Claude automatically activating the <code>branded-slides</code> skill to generate and upload a presentation</figcaption></figure></div><h2>3. Building a Claude Skill in Practice</h2><h3>3.1 Start With the Workflow &amp; Use Claude as the Skill Writer</h3><p>The most effective way to build a skill is <strong>not to start with a text editor</strong>. Instead, begin in Claude and work through the task in a normal conversation.</p><p>For example, when building a skill to generate branded client presentations, the first step is simply asking Claude to produce a presentation and guiding the process: providing brand rules, clarifying slide structure, correcting formatting, and adding any steps needed to produce the final output.</p><p>This approach works because the conversation naturally contains everything a skill requires: brand constraints, file paths, sequencing rules, and edge cases. The workflow itself becomes the raw material.</p><p>Once the task is complete, a single prompt is enough:</p><p><em>&#8220;Create a </em><code>SKILL.md</code><em> from the workflow we just used.&#8221;</em></p><p>Claude understands the Skill format natively, so no special system prompt or &#8220;skill-writing&#8221; tool is required. The model extracts the reusable pattern from the interaction and structures it correctly.</p><p>One important detail: <strong>the description comes last</strong>. Only after the workflow is complete, the real trigger phrases become clear: terms like &#8220;deck&#8221;, &#8220;slides&#8221;, &#8220;presentation for a client&#8221;, or &#8220;pitch&#8221;. This ordering, workflow first, description second, is a key departure from traditional documentation practices.</p><p>A final review pass is still useful. Claude can check whether <code>SKILL.md</code> includes explanations it already knows, such as Python import syntax, what a <code>.pptx</code> file is, or general Drive authentication behavior. Those details should be removed.</p><p>Ideally, <code>SKILL.md</code> remains <strong>under roughly 500 lines</strong> and reads like a table of contents. It should point to supporting files e.g. <code>brand-guidelines.md</code> for visual constraints, <code>google-slides-setup.md</code> for configuration, and the scripts directory for execution, and stop there. Supporting files are loaded <strong>on demand</strong>, so they add no overhead until they are needed.</p><h3>3.2 Deploying the Skill</h3><p>There are four surfaces, each with a completely separate skill system. They do not sync with one another.</p><ul><li><p><strong><a href="http://Claude.ai">Claude.ai</a> and the Claude desktop app</strong> share the same installation method: zip the skill directory with <code>SKILL.md</code> at the root and upload it via <strong>Settings &#8594; Features &#8594; Skills</strong>. Skills installed this way are personal, no org-wide distribution exists, so each team member uploads their own copy. It requires Pro, Max, Team, or Enterprise with code execution enabled. More information in the documentation: <a href="https://support.claude.com/en/articles/12512180-using-skills-in-claude">Using Skills in Claude</a></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7_6N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7_6N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif 424w, https://substackcdn.com/image/fetch/$s_!7_6N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif 848w, https://substackcdn.com/image/fetch/$s_!7_6N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif 1272w, https://substackcdn.com/image/fetch/$s_!7_6N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7_6N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif" width="800" height="502" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:502,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:786864,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/190262322?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7_6N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif 424w, https://substackcdn.com/image/fetch/$s_!7_6N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif 848w, https://substackcdn.com/image/fetch/$s_!7_6N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif 1272w, https://substackcdn.com/image/fetch/$s_!7_6N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F934c63b9-cc1a-473d-a0d8-42071ecfe456_800x502.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Uploading a skill in the Claude app</figcaption></figure></div><ul><li><p><strong>Claude Code</strong> (the command-line tool) uses the local filesystem instead. Place the skill at <code>~/.claude/skills/branded-slides/</code> and Claude Code discovers it automatically at startup. This is the right place to develop and iterate. When stable, move it to <code>.claude/skills/branded-slides/</code> inside a project repository and commit it: every teammate who pulls the repo gets the skill immediately, no setup required. More information in the documentation: <a href="https://code.claude.com/docs/en/skills">Agent Skills in Claude Code</a></p></li><li><p><strong>The Claude API</strong> is for automated pipelines. Skills are uploaded via <code>/v1/skills</code> endpoints and become workspace-wide. The important constraint here is that the API container has no outbound network access, which means for instance, in our use case, that the Drive upload step will not work as-is. More information in the documentation: <a href="https://docs.claude.com/en/build-with-claude/skills-guide">Using Skills with the Claude API</a></p></li></ul><h3>3.3. Iterating With Claude as Co-Author</h3><p>A skill is rarely correct on the first attempt. The recommended approach uses two Claude contexts: one for authoring, one for testing.</p><p>In the authoring context, the current <code>SKILL.md</code> is shared and the observed issue is described. For example: <em>&#8220;Claude skipped the executive summary slide.&#8221;</em> Claude analyzes the behavior and proposes a fix. The change is then validated in a fresh testing session with the updated skill loaded. This loop, observe, revise, retest, continues until the behavior stabilizes.</p><p>Most issues fall into a few predictable categories:</p><ul><li><p>The description misses trigger phrases users naturally use</p></li><li><p>An important constraint is buried too deep in <code>SKILL.md</code></p></li><li><p>A reference file is structured in a way that Claude reads only partially</p></li></ul><p>Once identified, each of these problems is usually straightforward to fix.</p><p>Changes can be tracked directly in <code>SKILL.md</code> using a simple changelog block, which keeps the iteration history visible without requiring additional tooling.</p><div><hr></div><h2>Key Takeaways</h2><p>&#10003; <strong>Prompt engineering does not scale as a workflow foundation:</strong> Large system prompts are difficult to version, fragile to small wording changes, and hard to maintain across teams. As workflows grow more complex, prompt-based control becomes increasingly brittle.</p><p>&#10003; <strong>Skills package expertise, not instructions:</strong> A skill is a structured folder containing a workflow the model can discover and load on demand. The shift is conceptual: instead of telling the model what to do each time, you document the procedure once and let the model apply it whenever relevant.</p><p>&#10003; <strong>Progressive loading keeps skills lightweight:</strong> The model loads only what it needs, when it needs it. Instructions, brand guidelines, and scripts stay dormant until triggered, adding no token overhead to unrelated tasks.</p><p>&#10003; <strong>Build the workflow first, write the skill second:</strong> The most reliable path to a good skill is running the task in Claude first, then extracting the reusable pattern. Trigger phrases, constraints, and edge cases only become clear once the workflow actually works.</p><p>&#10003; <strong>Skill development is an iterative process:</strong> Effective skills emerge through a loop of observing model behavior, refining <code>SKILL.md</code>, and testing again in a clean session until the workflow stabilizes.</p><p>&#10003; <strong>Skills turn LLM workflows into maintainable infrastructure:</strong> Because they live in the filesystem or a repository, skills can be versioned, shared across projects, and maintained alongside the rest of the codebase.</p><div><hr></div><h2>References</h2><p>[1] Accelirate. <em>Getting Started with Prompt Engineering: A Technical Guide for Developers</em>. 2024. <a href="https://www.accelirate.com/prompt-engineering-guide-for-developers">https://www.accelirate.com/prompt-engineering-guide-for-developers</a></p><p>[2] PromptLayer Blog. <em>Disadvantage of Long Prompt for LLM</em>. September 2025. <a href="https://blog.promptlayer.com/disadvantage-of-long-prompt-for-llm">https://blog.promptlayer.com/disadvantage-of-long-prompt-for-llm</a></p><p>[3] DigitalOcean. <em>ChatGPT vs Gemini: How AI Assistants Stack Up in 2026</em>. <a href="https://www.digitalocean.com/resources/articles/gemini-vs-chatgpt">https://www.digitalocean.com/resources/articles/gemini-vs-chatgpt</a></p><p>[4] Zhang, B., Lazuka, K., Murag, M. (Anthropic). <em>Equipping agents for the real world with Agent Skills</em>. October 2025. <a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills">https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills</a></p><p>[5] Anthropic. <em>Agent Skills &#8212; Claude Code Docs</em>. <a href="https://code.claude.com/docs/en/skills">https://code.claude.com/docs/en/skills</a></p><p>[6] Jackson, F. <em>Custom GPTs vs. Gemini Gems: A Technical Comparison</em>. SSRN, December 2025. <a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5903642">https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5903642</a></p>]]></content:encoded></item><item><title><![CDATA[Understanding User Intent Through AI Bot Traffic: A Practical Framework]]></title><description><![CDATA[Turning Bot Logs into Actionable Insights for Product & SEO Teams]]></description><link>https://aipractitioner.substack.com/p/understanding-user-intent-through</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/understanding-user-intent-through</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 05 Mar 2026 12:01:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!pDMS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pDMS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pDMS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png 424w, https://substackcdn.com/image/fetch/$s_!pDMS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png 848w, https://substackcdn.com/image/fetch/$s_!pDMS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png 1272w, https://substackcdn.com/image/fetch/$s_!pDMS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pDMS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png" width="1456" height="605" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:605,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1081192,&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://aipractitioner.substack.com/i/189971641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pDMS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png 424w, https://substackcdn.com/image/fetch/$s_!pDMS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png 848w, https://substackcdn.com/image/fetch/$s_!pDMS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png 1272w, https://substackcdn.com/image/fetch/$s_!pDMS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a581bb-3061-4f32-bf9c-621a301bf7f3_2928x1216.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This article is also available as a podcast! If you&#8217;re on the go or just want to absorb the content in audio format, you can listen to the full episode below &#128071; The podcast is also available on <a href="https://open.spotify.com/show/6MROBKvrjx0Mey8tHud5LX">Spotify</a> and <a href="https://podcasts.apple.com/us/podcast/the-ai-practitioner-podcast/id1830285899">Apple Podcasts</a>.</em></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;da4c8968-89c5-470e-af30-9c3784d68107&quot;,&quot;caption&quot;:&quot;Prefer reading instead? The full article is available here. The podcast is also available on Spotify and Apple Podcasts. Subscribe to keep up with the latest drops.&quot;,&quot;cta&quot;:&quot;Listen now&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;PODCAST &#8212; Understanding User Intent Through AI Bot Traffic: A Practical Framework&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:7177021,&quot;name&quot;:&quot;Lina Faik&quot;,&quot;bio&quot;:&quot;Lead AI Scientist bringing AI research to real-world impact across industries. Founder, Data Impulse | Author, The AI Practitioner | ex-Dataiku&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bdaf5e6-a6c6-48fe-80f6-3d69aaac1694_2256x2256.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-03-05T12:00:28.748Z&quot;,&quot;cover_image&quot;:&quot;https://substack-video.s3.amazonaws.com/video_upload/post/189973382/85139fd9-296d-407d-985d-799a35458a33/transcoded-1772711948.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://aipractitioner.substack.com/p/podcast-understanding-user-intent&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:189973382,&quot;type&quot;:&quot;podcast&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4815372,&quot;publication_name&quot;:&quot;The AI Practitioner&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ivps!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>A growing blind spot is emerging in website analytics: the user intent behind AI assistant traffic.</p><p>Every day, ChatGPT, Claude, Perplexity, and other AI tools visit documentation, scan product pages, and access content on behalf of real users searching for answers. While modern analytics platforms have sophisticated bot filtering mechanisms that automatically exclude spam bots and malicious crawlers [1], they face a different challenge with AI assistants: these tools represent genuine user needs, yet their traffic patterns are fundamentally different from direct human browsing.</p><p>The problem isn&#8217;t simply about filtering, it&#8217;s about context loss. When a user asks an AI assistant &#8220;How do I integrate payment processing with [product X]?&#8221; or prompts it to &#8220;Compare pricing plans for [service Y],&#8221; the resulting bot traffic to those websites represents authentic user intent. And with assistants increasingly grounding their answers in real-time web search and retrieval, not just relying on their pre-trained LLM weights, these visits are happening continuously, invisibly, and with growing frequency.</p><blockquote><p>Moreover, most users receive the final answer directly inside the AI interface without ever clicking through to the original site [2]. This creates an &#8220;invisible visit&#8221; phenomenon where content provides value, AI systems access and process the information, but traditional analytics either record nothing or strip away the critical context of what the user was actually trying to accomplish.</p></blockquote><p>Recent research suggests AI crawler traffic accounts for 5-10% of total server requests for knowledge-based websites [2], yet this traffic is either aggregated into generic &#8220;bot&#8221; categories or excluded entirely. The distinction matters: newer AI crawlers often aren&#8217;t covered by standard bot filtering lists [3], and even when detected, analytical frameworks treat them like search engine crawlers rather than proxies for human questions and needs.</p><h3>Objective</h3><p>This article presents a practical framework for extracting actionable intelligence from AI bot traffic, treating it not as noise to filter out, but as a complementary signal that reveals user intent.</p><p>After reading this article, you will understand:</p><ol><li><p><strong>Why does AI bot traffic contain different intelligence than traditional analytics?</strong> How AI-mediated user interactions fundamentally differ from direct human browsing, what makes them valuable despite being non-human traffic, and why current analytics frameworks fail to capture this value</p></li><li><p><strong>What insights can be extracted from AI bot access patterns?</strong> Which specific patterns in bot traffic reveal user questions, documentation gaps, and product understanding issues, supported by analysis of real-world data</p></li><li><p><strong>How can organizations operationalize AI bot insights?</strong> Practical methods to segment, analyze, and integrate AI bot data into product, content, and marketing workflows, with concrete examples from actual implementation</p></li></ol><p>Whether you&#8217;re a product manager trying to understand user needs, a data analyst seeking new signal sources, or a content strategist optimizing documentation, this framework will help you see AI bot traffic not as a measurement problem, but as an untapped source of user intelligence.</p><blockquote><p>This article is part of a series exploring the evolving landscape of AI-powered search and content discovery, available at <a href="https://siteline.ai/blog/">https://siteline.ai/blog/</a>. SiteLine is a platform that tracks and optimizes product and service visibility across the AI search ecosystem, providing comprehensive insights into how brands perform in AI-powered responses from ChatGPT, Perplexity, Gemini, Claude, and other AI assistants.</p><p><strong>Prerequisites:</strong> No prior knowledge is required. The concepts are explained in and accessible way for anyone interested in how AI assistant traffic can inform business and content strategy.</p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>1. The Framework in Brief</h2><p><strong>The Core Innovation: Why LLMs Beat Clustering</strong></p><p>Most teams try to understand user behavior with URL rules, regex, or embedding-based clustering. The problem: these methods are <strong>descriptive, not interpretive</strong>. They group hits that look similar on the surface, but they can&#8217;t reconstruct the <em>story</em> behind a session.</p><p>For instance, basic clustering might lump together a &#8220;Pricing&#8221; page visit and a &#8220;Login&#8221; attempt simply because they share common keywords or happened in sequence. This means you can&#8217;t distinguish between a new prospect moving through your sales funnel and an existing customer performing routine tasks. The critical difference between someone evaluating your product versus someone already using it is completely invisible in your analytics.</p><p>This framework flips the approach:</p><ul><li><p>Instead of pre-defined rules, we use an <strong>LLM as a reasoning engine</strong>.</p></li><li><p>Instead of isolated pageviews, we analyze <strong>full journeys</strong>: which pages were visited, in what order, and for how long.</p></li><li><p>Instead of a fixed taxonomy, we let the model create <strong>dynamic tags and categories</strong> as it discovers new patterns in the traffic.</p></li><li><p>Instead of generic tags, we ask the model to <strong>interpret the session</strong>: <em>who is behind this query, and what are they trying to do?</em></p></li></ul><p>In other words, we move from &#8220;this session visited <code>/pricing</code> and <code>/docs</code>&#8221; to &#8220;this is a <strong>developer evaluating integration feasibility</strong> based on API limits, then checking whether the pricing fits their use case.&#8221;</p><p><strong>How It Works: The 4-Stage Process</strong></p><p>The framework treats every AI bot visit as a breadcrumb trail, reconstructing them into coherent sessions to decode the human intent behind the prompt.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fYh3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fYh3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png 424w, https://substackcdn.com/image/fetch/$s_!fYh3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png 848w, https://substackcdn.com/image/fetch/$s_!fYh3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png 1272w, https://substackcdn.com/image/fetch/$s_!fYh3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fYh3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png" width="1456" height="675" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:675,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:399562,&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://aipractitioner.substack.com/i/189971641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fYh3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png 424w, https://substackcdn.com/image/fetch/$s_!fYh3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png 848w, https://substackcdn.com/image/fetch/$s_!fYh3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png 1272w, https://substackcdn.com/image/fetch/$s_!fYh3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1638a98b-5ce1-4d67-94b0-807aebcab05a_2914x1350.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Framework Overview: From Raw Bot Logs to Intent Classification</figcaption></figure></div><p><strong>Stage 1: Separating Signal from Noise</strong> The analysis starts at the source: server logs. Unlike traditional web analytics that rely on JavaScript tracking pixels and client-side sessions, AI assistant visits leave traces in the raw HTTP request logs maintained by your hosting infrastructure, whether that&#8217;s an edge service like Vercel, a CDN like Cloudflare, or your origin servers.</p><p>A typical log entry might look like this:</p><pre><code><code>185.72.144.53 yourwebsite.com - [12/Feb/2025:14:32:09 +0000]
"GET /features/our-brand-new-awesome-feature HTTP/1.0" 200 64312 "-"
"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/97.0.4692.71 Mobile Safari/537.36
(compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
</code></code></pre><p>Raw data is filtered to keep only AI assistants acting on real user queries, removing noise from SEO crawlers, uptime monitors, spam bots, and internal automation.</p><p><strong>Stage 2: Reconstructing User Journeys &gt;</strong> Individual hits are grouped by IP address and temporal proximity. A natural break in activity (e.g., a 5-minute gap) signals the start of a new session. This transforms your bot logs from a list of disconnected URLs into a collection of browsing narratives, each representing someone&#8217;s attempt to understand something about your product or service.</p><p><strong>Stage 3: Semantic Enrichment</strong> <strong>&gt;</strong> To decode cryptic URLs, the system scrapes every unique page visited and uses a lightweight LLM to generate a semantic title and summary. This translates technical paths (e.g., <code>/docs/v2/auth</code>) into a clear sequence of consumed concepts, creating a human-readable storyline for the LLM to analyze.</p><p><strong>Stage 4: Inferring User Intent</strong> <strong>&gt;</strong> A reasoning LLM analyzes the full enriched journey to answer three core questions, assigning a <strong>confidence score</strong> to each classification:</p><ol><li><p><strong>Topic:</strong> What is the precise subject? (e.g., &#8220;Payment Integration Errors&#8221;).</p></li><li><p><strong>Role:</strong> Who is the user? (e.g., Developer vs. Decision-Maker).</p></li><li><p><strong>Goal:</strong> What are they trying to do? (e.g., Evaluation vs. Active Implementation).</p></li></ol><p>This final stage converts raw data into dynamic, quantified insights that evolve automatically as new content and user behaviors emerge.</p><h2>2. Case Study: What the Data Actually Reveals</h2><p>Let&#8217;s see what happens when the framework is applied in practice. For this analysis, server logs were collected from three pilot websites over a 24-hour period and filtered to isolate only ChatGPT bot traffic. For this analysis, we&#8217;ll go in depth with <a href="http://Tradevision.io">Tradevision.io</a>, a data platform for stock and options trading.</p><h3>Anatomy of an AI-Mediated Session</h3><p>Before examining aggregate patterns across thousands of sessions, let&#8217;s trace a single journey to understand what session reconstruction and LLM-based classification reveals and why it matters.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CKY8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CKY8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png 424w, https://substackcdn.com/image/fetch/$s_!CKY8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png 848w, https://substackcdn.com/image/fetch/$s_!CKY8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png 1272w, https://substackcdn.com/image/fetch/$s_!CKY8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CKY8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png" width="1456" height="948" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:948,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:126261,&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://aipractitioner.substack.com/i/189971641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CKY8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png 424w, https://substackcdn.com/image/fetch/$s_!CKY8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png 848w, https://substackcdn.com/image/fetch/$s_!CKY8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png 1272w, https://substackcdn.com/image/fetch/$s_!CKY8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa272f813-5622-4a12-852e-fdfc6893df34_1600x1042.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2 &#8212; Example of a Reconstructed AI Assistant Session</figcaption></figure></div><p>The framework&#8217;s LLM classifier analyzed this sequence and produced:</p><blockquote><p><strong>- Topic:</strong> Trading platform review <br><strong>- User Role:</strong> <code>decision-maker</code> (confidence: 90/100) <br><strong>- Intent Type:</strong> <code>comparison</code> (confidence: 92/100) <br><strong>- Reasoning:</strong> The session comprises multiple TradeVision blog pages focused on comparing and evaluating trading platforms (AI-driven tools, 2025 platform rankings, mobile vs desktop, and platform reviews). This indicates a decision-making, comparison-oriented intent rather than learning or implementation.</p></blockquote><p><strong>This session likely reflects a user asking something like </strong><em><strong>&#8220;What&#8217;s the best AI trading platform for mobile in 2025?&#8221;</strong></em> The assistant gathered comparative information step by step, moving from general guidance to specific recommendations to product details.</p><p>The next sections scale this analysis across thousands of sessions to reveal broader patterns in user segmentation, content performance, and optimization priorities.</p><h3>Topic Distribution: Identifying Content Opportunities</h3><p>The traffic data reveals two dominant themes: <strong>strong demand for options trading education</strong> and <strong>consistent interest in platform comparison content.</strong> Understanding these patterns helps identify where content investment delivers the highest return for <a href="http://tradevision.io">tradevision.io</a> in AI search visibility.</p><p>Figure 3 shows that options trading content captures over 400 sessions across three related topics: &#8220;Options trading strategies&#8221; (153), &#8220;Options trading toolkit&#8221; (144), and &#8220;Options trading concepts&#8221; (119). Together, these three topics account for 47% of all sessions, out of a total of 873.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qHZN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qHZN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png 424w, https://substackcdn.com/image/fetch/$s_!qHZN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png 848w, https://substackcdn.com/image/fetch/$s_!qHZN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png 1272w, https://substackcdn.com/image/fetch/$s_!qHZN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qHZN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png" width="900" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:900,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:91555,&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://aipractitioner.substack.com/i/189971641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qHZN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png 424w, https://substackcdn.com/image/fetch/$s_!qHZN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png 848w, https://substackcdn.com/image/fetch/$s_!qHZN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png 1272w, https://substackcdn.com/image/fetch/$s_!qHZN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6466779d-aaae-4c44-87f1-15c4c657a232_900x500.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3 &#8212; Top 20 Topics for <a href="http://tradevision.io/">tradevision.io</a></figcaption></figure></div><p>The topic-intent relationship displayed in Figure 4 shows distinct patterns. Options content attracts pure learning intent while &#8220;Trading platform review&#8221; shows balanced distribution, indicating the content successfully serves both discovery and evaluation stages.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nx0c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nx0c!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png 424w, https://substackcdn.com/image/fetch/$s_!nx0c!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png 848w, https://substackcdn.com/image/fetch/$s_!nx0c!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png 1272w, https://substackcdn.com/image/fetch/$s_!nx0c!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nx0c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png" width="800" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png&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;:88604,&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://aipractitioner.substack.com/i/189971641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nx0c!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png 424w, https://substackcdn.com/image/fetch/$s_!nx0c!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png 848w, https://substackcdn.com/image/fetch/$s_!nx0c!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png 1272w, https://substackcdn.com/image/fetch/$s_!nx0c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11e74652-ed16-417d-9b5b-ddb721d1a84b_800x600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4 &#8212; Primary Topic vs Intent Type Heatmap</figcaption></figure></div><h3>User Segmentation: Understanding User Roles, Intent, and Behavioral Patterns</h3><p>The findings become even stronger when we analyze the user-level segmentation.</p><p>Figure [8] shows that end-users represent the majority of traffic and demonstrate 93.9% learning intent with minimal comparison (5.4%). Decision-makers show the inverse pattern: 60.4% comparison intent with secondary learning (39.6%).</p><p>These fundamentally different browsing behaviors reflect different stages in the consideration journey, end-users building knowledge, decision-makers actively evaluating alternatives.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-yqa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-yqa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png 424w, https://substackcdn.com/image/fetch/$s_!-yqa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png 848w, https://substackcdn.com/image/fetch/$s_!-yqa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png 1272w, https://substackcdn.com/image/fetch/$s_!-yqa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-yqa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png" width="984" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/acd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:984,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:73216,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/189971641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-yqa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png 424w, https://substackcdn.com/image/fetch/$s_!-yqa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png 848w, https://substackcdn.com/image/fetch/$s_!-yqa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png 1272w, https://substackcdn.com/image/fetch/$s_!-yqa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd19b8b-4043-4381-9d90-db8c4f83b6e0_984x600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 8 &#8212; Intent Type Distribution by User Role for <a href="http://tradevision.io/">tradevision.io</a></figcaption></figure></div><h2>3. Why This Matters: Strategic Implications</h2><p><strong>The Zero-Click Blind Spot</strong></p><p>For Tradevision, AI assistants account for 17% of all sessions to content about options trading strategies. Traditional analytics, however, register zero visits, zero engagement, zero value. And yet, real users received answers, while AI systems began associating TradeVision with expertise in options trading.</p><p>This is the core challenge: content is delivering business value without activating conventional success metrics. Companies focused only on direct traffic are measuring a shrinking slice of how users actually discover, evaluate, and understand their products. This framework surfaces that hidden demand.</p><p><strong>Early Signal Detection as Competitive Edge</strong></p><p>AI assistants capture user intent long before a prospect commits to visiting a website, trying a product, or contacting support.</p><p>Consider the case of <strong>TradeVision</strong>. By analyzing AI search behavior, they detected a surge of decision-makers on platform comparison pages but there was near-zero intent to actually implement the software. Traditional funnel analysis would simply see this as &#8220;bounced traffic,&#8221; but AI signals revealed a potential issue: a hidden onboarding gap?</p><p>This kind of signal allows for a <strong>predictive strategy</strong>:</p><ul><li><p><strong>Fix friction</strong> before it escalates into support tickets.</p></li><li><p><strong>Expand content</strong> before feature requests pile up.</p></li><li><p><strong>Claim ownership</strong> of topics before competitors even notice the trend.</p></li></ul><p><strong>The Compound Effect:</strong> Most importantly, this first-mover advantage compounds over time. When AI assistants consistently cite TradeVision for options trading, they build deep mental associations. Competitors entering the market later face a steeper challenge: they must not only match the product but also unseat an established algorithmic bias in your favor.</p><p><strong>AI Discoverability: The New Game</strong></p><p>While traditional SEO focuses on visibility on a search engine results page, AI discoverability focuses on <strong>retrieval and citation</strong>. The goal is to be the primary source used by an assistant to generate an answer, often without the user ever visiting a website.</p><p>This shift demands that we prioritize <strong>structure over keywords</strong>.</p><p><strong>TradeVision</strong> exemplifies this success. Their content performs well not due to backlink volume, but because it is architected for synthesis as it provides self-contained, comprehensive answers. Conversely, content strategies that fragment information across multiple pages perform poorly in AI-mediated discovery.</p><p>The proposed framework allows companies to audit their digital footprint, identifying which assets successfully serve this new discovery layer and which are invisible to the algorithms that matter most.</p><div><hr></div><h2>What&#8217;s Next?</h2><p>AI assistant traffic represents a paradigm shift in how we understand user behavior online. Traditional analytics tell us <em>what</em> users do when they visit our sites, which pages they view, how long they stay, and where they click. AI bot traffic, when properly analyzed, reveals something more fundamental: <em>what users are trying to accomplish</em> before they even decide whether to visit.</p><p>These insights can be operationalized across teams.</p><ul><li><p>Product managers can spot recurring workarounds or friction points that assistants repeatedly access and prioritize features accordingly.</p></li><li><p>Content teams can identify high-traffic topics where assistants still struggle to find clear answers, signaling documentation gaps.</p></li><li><p>Marketing and sales can understand the comparison patterns and evaluation criteria users rely on long before they land on the pricing page.</p></li><li><p>Engineering teams can uncover technical blockers such as rate limits, authentication quirks, crawler-unfriendly endpoints [1] [5].</p></li></ul><p>There are limitations. Session attribution remains imprecise, as a single user query can trigger multiple bot requests across different pages. Intent inference has natural boundaries: sequences reveal likely goals, but without the original prompt, certainty is impossible. And AI behavior itself evolves as models and retrieval systems improve, requiring the framework to adapt continuously.</p><div><hr></div><h2>References</h2><p>[1] Google Analytics Help. <a href="https://support.google.com/analytics/answer/9888366">&#8220;[GA4] Known bot-traffic exclusion.&#8221;</a></p><p>[2] Writesonic. (2025). &#8220;<a href="https://writesonic.com/blog/introducing-ai-traffic-analytics-track-chatgpt-gemini">Introducing AI Traffic Analytics: Track Traffic from ChatGPT, Gemini &amp; Perplexity</a>.&#8221;</p><p>[3] IronPlane. (2025). &#8220;<a href="https://www.ironplane.com/ironplane-ecommerce-blog/how-to-clean-up-your-google-analytics-data-from-ai-bot-traffic">How to Clean Up Your Google Analytics Data from AI Bot Traffic.</a>&#8220;</p><p>[4] Vlad Zotov, <a href="https://gptrends.io/blog/the-ai-crawler-optimization-guide-to-increase-site-visibility/">The AI Crawler Optimization Guide to Increase Site Visibility</a>, Siteline</p><p>[5] Giacomo Zecchini, Alice Alexandra Moore, Malte Ubl, Ryan Siddle, <a href="https://vercel.com/blog/the-rise-of-the-ai-crawler">The rise of the AI crawler</a>, Vercel</p>]]></content:encoded></item><item><title><![CDATA[Long-Term Memory: Unlocking Smarter, Scalable AI Agents]]></title><description><![CDATA[Concepts & Practical Strategies for Memory-Augmented Agents with LangChain]]></description><link>https://aipractitioner.substack.com/p/long-term-memory-unlocking-smarter-38d</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/long-term-memory-unlocking-smarter-38d</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Tue, 10 Feb 2026 15:48:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7oUy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7oUy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7oUy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png 424w, https://substackcdn.com/image/fetch/$s_!7oUy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png 848w, https://substackcdn.com/image/fetch/$s_!7oUy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!7oUy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7oUy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png" width="1456" height="605" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:605,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1028188,&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://aipractitioner.substack.com/i/187506364?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7oUy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png 424w, https://substackcdn.com/image/fetch/$s_!7oUy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png 848w, https://substackcdn.com/image/fetch/$s_!7oUy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!7oUy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997bd9-f87d-4fb8-9c3f-e0c678c35e07_2924x1214.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This article is also available as a podcast! If you&#8217;re on the go or just want to absorb the content in audio format, you can listen to the full episode below &#128071; The podcast is also available on <a href="https://open.spotify.com/show/6MROBKvrjx0Mey8tHud5LX">Spotify</a> and <a href="https://podcasts.apple.com/us/podcast/the-ai-practitioner-podcast/id1830285899">Apple Podcasts</a>.</em></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;554f7546-3230-4eb7-82e3-2444f45eae52&quot;,&quot;caption&quot;:&quot;Prefer reading instead? The full article is available here. The podcast is also available on Spotify and Apple Podcasts. Subscribe to keep up with the latest drops.&quot;,&quot;cta&quot;:&quot;Listen now&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Long-Term Memory: Unlocking Smarter, Scalable AI Agents&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:7177021,&quot;name&quot;:&quot;Lina Faik&quot;,&quot;bio&quot;:&quot;Lead AI Scientist bringing AI research to real-world impact across industries. Founder, Data Impulse | Author, The AI Practitioner | ex-Dataiku&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bdaf5e6-a6c6-48fe-80f6-3d69aaac1694_2256x2256.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-02-10T15:48:10.692Z&quot;,&quot;cover_image&quot;:&quot;https://substack-video.s3.amazonaws.com/video_upload/post/187522906/55c0bdbe-d93b-4f8b-86b7-c47de5406223/transcoded-1770737348.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://aipractitioner.substack.com/p/long-term-memory-unlocking-smarter&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:187522906,&quot;type&quot;:&quot;podcast&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4815372,&quot;publication_name&quot;:&quot;The AI Practitioner&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ivps!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>Most agent systems are effectively stateless: they reason well in the moment but forget everything once execution ends. As agents move toward longer-running workflows and repeated interactions, this limitation becomes a structural bottleneck. Long-term memory is what makes agents able to personalize, improve, and coordinate over time, moving them from reactive pipelines into adaptive systems.</p><h3>Objective</h3><p>This article explores how to incorporate long-term memory into LangGraph agent architectures. It discusses how durable memory can be designed, stored, and accessed within graph-based execution flows without sacrificing transparency or debuggability.</p><p>After reading this article, you will understand:</p><ol><li><p><strong>How long-term memory differs from short-term context</strong>: The distinction between ephemeral conversation history and persistent knowledge, and how different memory types map to LangGraph agent architectures.</p></li><li><p><strong>Where LangGraph&#8217;s native memory stops</strong>: What checkpointers and the Store API provide for persistence&#8212;and their critical limitations for structured extraction, validation, and intelligent merging.</p></li><li><p><strong>How to implement production-ready memory with Trustcall</strong>: Using practical examples, you&#8217;ll learn to build schema-driven memory systems that extract, merge, and persist user profiles and collections reliably across sessions.</p></li></ol><blockquote><p>This article is part of a broader series on building agent systems with LangGraph. Short-term memory is already covered in <em><a href="https://aipractitioner.substack.com/p/beyond-the-demo-building-ai-agents">Beyond the Demo: Building AI Agents That Remember, Recover, and Scale (Part 2)</a></em>, which provides additional context on the topic. </p><p><strong>Prerequisites:</strong> Basic knowledge of Python, LLMs, and prompt engineering is recommended. Readers should either be familiar with LangChain concepts (chains, models, prompts) or have read <a href="https://aipractitioner.substack.com/p/from-chains-to-graphs-smarter-and">Part 1</a> of this series (or listen the <a href="https://aipractitioner.substack.com/p/podcast-from-chains-to-graphs-smarter">podcast edition</a>) to understand the foundations of LangGraph&#8217;s graph, node, and state model.</p><p><strong>Tools &amp; libraries:</strong> <a href="https://www.langchain.com/langgraph">LangGraph</a>, <a href="https://www.langchain.com/">LangChain</a>, <a href="https://www.langchain.com/langsmith/observability">LangSmith</a>, <a href="https://openai.com/">OpenAI</a>, <a href="https://info.arxiv.org/help/api/index.html">arXiv API</a></p></blockquote><p>You can find the code <a href="https://github.com/linafaik08/scientific-graph-agent">here</a> on GitHub. The demo video is at the end of the article!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>1. Foundations of Long-Term Memory in Agent Systems</h2><p>Long-term memory in agents is not a single component you &#8220;add&#8221; to an LLM. It is an architecture that separates what must be present right now (for reasoning) from what must persist over time (for personalization, continuity, and learning).</p><p>This section introduces the main memory types used in agent systems, how they interact during execution, and the practical constraints that shape real implementations.</p><h3>1.1 The Four Core Memory Types in Agent Architectures</h3><p>Most long-term memory designs for LLM agents can be explained with four complementary memory types, often discussed in cognitive-inspired frameworks like CoALA [1]. The key idea is simple: different information has different &#8220;lifecycles&#8221;, so it should not all be stored (or retrieved) the same way.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XCx0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XCx0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png 424w, https://substackcdn.com/image/fetch/$s_!XCx0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png 848w, https://substackcdn.com/image/fetch/$s_!XCx0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png 1272w, https://substackcdn.com/image/fetch/$s_!XCx0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XCx0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png" width="643" height="480.0418956043956" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.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;:643,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XCx0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png 424w, https://substackcdn.com/image/fetch/$s_!XCx0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png 848w, https://substackcdn.com/image/fetch/$s_!XCx0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png 1272w, https://substackcdn.com/image/fetch/$s_!XCx0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f621d32-0f93-4677-8d7f-9ab39023e88f_1752x1308.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Core Memory Types in Agent Architectures </figcaption></figure></div><ol><li><p><strong>Working memory (context window):</strong> It&#8217;s the agent&#8217;s immediate awareness. The tokens currently inside the model&#8217;s context window. It holds what the agent is actively reasoning over right now, recent turns, task instructions, intermediate artifacts, and recently retrieved facts. Even with long-context models, this remains the most constrained and expensive resource, so agents need explicit strategies for what stays in-context and what gets evicted [2].</p></li><li><p><strong>Semantic memory (facts and knowledge):</strong> It stores distilled knowledge: facts, concepts, preferences, without needing the full story of when they were learned. In agent systems, this is where many RAG-style approaches live: embeddings in vector databases, structured fact stores, or knowledge graphs.</p></li><li><p><strong>Episodic memory (interaction history):</strong> It preserves sequences of events as they happened: full conversations, task trajectories, ordered observations. Unlike semantic memory, it keeps narrative context and temporal flow. This is valuable for audit trails, debugging, pattern analysis over conversations, and reflection loops that synthesize higher-level insights from experience [4]. In practice, episodic memory often looks like a message store and/or indexed conversation chunks, sometimes designed explicitly to store what was evicted from working memory [2].</p></li><li><p><strong>Procedural memory (skills and behaviors):</strong> This represents the knowledge of how to do things: the agent&#8217;s skills, tool usage patterns, and stable workflows. For LLM agents, procedural memory is typically encoded in model weights, system prompts, and tool/function registries. It changes more slowly than other memory types and usually requires explicit updates (deployments, fine-tuning, tool additions). Recent work also explores agents that can learn reusable &#8220;skills&#8221; from experience rather than only storing facts [5].</p></li></ol><p>Note: In production, many systems also need &#8220;prospective memory&#8221; to remember to execute intended future actions (follow-ups, reminders, scheduled steps). This is often implemented via task queues, reminders, and goal trackers rather than retrieval-based memory.</p><h3>1.2 Coordination Between Memory Types</h3><p>The usefulness of memory is not just storage but also <strong>coordination</strong>: how information moves between memory types during execution.</p><ul><li><p><strong>Semantic &#8594; Working (retrieve before reasoning):</strong> Before an agent responds or acts, it typically retrieves relevant facts from semantic memory and injects them into working memory. This is the core RAG pattern: keep long-lived information outside the context window, then pull only what&#8217;s needed for the current decision.</p></li><li><p><strong>Working &#8594; Episodic (persist what happened):</strong> As interactions unfold, the agent should persist the event sequence to episodic storage. This creates a reliable record for later debugging, audits, or trajectory-based learning. OS-inspired memory systems explicitly treat the context window as scarce &#8220;RAM&#8221; and page information in/out across memory tiers [2].</p></li><li><p><strong>Episodic &#8594; Semantic (consolidate experiences into facts):</strong> Over time, raw experience becomes more useful when summarized into stable knowledge. Generative Agents [4] popularized &#8220;reflection&#8221; mechanisms that periodically synthesize episodic memories into higher-level insights, which can then be stored as semantic memory and reused later. Mem0 formalizes a similar idea as a production-oriented pipeline: extract and consolidate important information from conversations into durable memories [3].</p></li><li><p><strong>Procedural + Semantic (apply skills to knowledge):</strong> Procedural memory provides the capability; semantic memory provides the content. For example, a coding agent uses procedural knowledge (how to refactor, how to call tools) to apply semantic knowledge (project requirements, architecture constraints).</p></li><li><p><strong>Time as a shared dimension:</strong> A subtle but important point is that &#8220;truth&#8221; changes over time: preferences drift, jobs change, policies update. Temporal memory layers explicitly track when facts were true and when they became invalid, enabling queries like &#8220;what was true then?&#8221; vs &#8220;what is true now?&#8221; [6]. This is especially important when semantic memories are mutable rather than append-only.</p></li></ul><h3>1.3 Practical Limits &amp; Trade-offs of Long-Term Memory in Agent Architectures</h3><p>Once memory is introduced, agent design becomes a balancing act across cost, correctness, and control.</p><ul><li><p><strong>Limited working memory does not disappear with long context:</strong></p><ul><li><p>Longer context windows reduce friction, but they do not remove the need for memory management.</p></li><li><p>Models can struggle when relevant information is buried deep inside large contexts (&#8220;lost in the middle&#8221;), and performance can degrade based on where the key information appears [7].</p></li><li><p>Practically, large contexts also increase latency and cost, so it is rarely optimal to treat the context window as a full-history database.</p></li></ul></li><li><p><strong>Storing everything as &#8220;semantic memory&#8221; increases noise</strong></p><ul><li><p>A common failure mode is embedding all messages, logs, and metadata into a single vector index. This often creates retrieval noise, loses narrative structure, and becomes expensive to search at scale.</p></li><li><p>Production approaches therefore separate concerns: keep full transcripts and sequences as episodic memory, and store extracted, consolidated facts as semantic memory [3].</p></li></ul></li><li><p><strong>Long-term memory must handle change, not just accumulation</strong></p><ul><li><p>Without explicit invalidation, agents surface stale or contradictory information. Temporal modeling addresses this by attaching validity semantics to memories (e.g., when a fact became true vs when it stopped being true), which helps prevent outdated facts from dominating retrieval [6]. This is one reason temporal knowledge-graph approaches have become more common for agent memory layers.</p></li></ul></li><li><p><strong>Retrieval quality is often the bottleneck</strong></p><ul><li><p>If retrieval brings the wrong memory into working context, downstream reasoning will amplify it. This is why many systems combine techniques (metadata filtering, hybrid lexical + dense search, reranking, structured retrieval) rather than relying on a single similarity search mechanism. Benchmarks and production architectures increasingly focus on measuring memory quality and reducing retrieval-driven errors [3].</p></li></ul></li><li><p><strong>Efficiency matters at production scale</strong></p><ul><li><p>Memory has an operational footprint: storage, embedding, indexing, reranking, and retrieval all accumulate cost. Architectures like Mem0 report substantial reductions in latency and token usage compared to full-context approaches, by storing distilled facts and retrieving selectively [3]. OS-inspired designs similarly motivate tiered memory and paging strategies to keep working memory small and relevant [2].</p></li></ul></li></ul><p>Building production-grade long-term memory is often more challenging than building the agent itself, and the effort required to make memory reliable, scalable, and correct is frequently underestimated. The next section shows how LangGraph supports the practical implementation of long-term memory in agent systems.</p><h2>2. Implementing Long-Term Memory with LangGraph</h2><h3>2.1 Use Case: A Research Paper Recommender with Persistent User Memory</h3><p>Consider a research paper recommendation system that helps users discover recent publications aligned with their interests. Unlike a simple one-shot query system, this agent needs to remember user preferences across multiple interactions to provide increasingly personalized recommendations.</p><p><strong>The Challenge</strong>: The agent must maintain two types of long-term memory:</p><ol><li><p><strong>Profile-based memory</strong>: Track evolving user interests, expertise level, and reading history</p></li><li><p><strong>Collection-based memory</strong>: Organize recommended papers into topic-based collections that grow over time</p></li></ol><p>For example, when a user first queries &#8220;show me papers on transformers,&#8221; the agent should:</p><ul><li><p>Extract and store &#8220;transformers&#8221; as an interest</p></li><li><p>Fetch relevant recent papers from ArXiv</p></li><li><p>Create a collection grouping papers by subtopic</p></li></ul><p>In subsequent interactions, when the user asks &#8220;what about quantum computing papers?&#8221;, the agent should:</p><ul><li><p>Add &#8220;quantum computing&#8221; to their existing interests (not replace them)</p></li><li><p>Remember their expertise level for appropriate paper selection</p></li><li><p>Maintain separate collections for both topics</p></li></ul><p>This requires <strong>persistent, structured memory</strong> that can be incrementally updated without losing previous information, a capability that goes beyond simple conversation history.</p><p>You can find the code <a href="https://github.com/linafaik08/scientific-graph-agent">here</a> on GitHub.</p><h3>2.2. Built-in Memory Options in LangGraph &amp; Their Limitations</h3><p>LangGraph provides memory mechanisms at different levels.</p><p>For <strong>short-term memory,</strong> which consists of the conversation context within a single session, LangGraph checkpointers and message history work well. These were covered in detail in my previous article on LangGraph fundamentals: <em><a href="https://aipractitioner.substack.com/p/beyond-the-demo-building-ai-agents">Beyond the Demo: Building AI Agents That Remember, Recover, and Scale (Part 2)</a></em></p><p>However, for <strong>long-term memory</strong> that persists across sessions and user interactions, LangGraph introduced the <strong>Store</strong> API [8].</p><p>The Store API provides a dedicated interface for managing persistent, cross-thread memory [9]:</p><pre><code>from langgraph.store.memory import InMemoryStore

# Create a store for long-term memory
store = InMemoryStore()

# user_id would come from your application context (e.g., session, authentication)
user_id = "user_123"  # Example: unique identifier for the current user

# Store user profile
store.put(
    namespace=("user_profiles", user_id),
    key="profile",
    value={"interests": ["transformers"], "expertise_level": "beginner"}
)

# Retrieve later (in a different session/conversation)
profile = store.get(namespace=("user_profiles", user_id), key="profile")</code></pre><p><strong>Key Benefits</strong>:</p><p>The Store API offers several advantages [9]:</p><ul><li><p><strong>Persistence</strong>: Data survives beyond individual conversation threads</p></li><li><p><strong>Namespacing</strong>: Organize memory by user, topic, or custom categories</p></li><li><p><strong>Cross-thread access</strong>: Share memory across different conversation sessions</p></li></ul><p><strong>Limitations of the Store API</strong></p><p>While the Store API handles persistence, it has significant limitations for complex memory management:</p><ul><li><p><strong>No structured extraction</strong>: Store is a key-value database&#8212;it doesn&#8217;t extract structured information from conversations. You must manually parse and structure data before storing [2][3]</p></li><li><p><strong>No intelligent merging</strong>: You&#8217;re responsible for all merge logic, deduplication, and conflict resolution when updating existing memory [9]</p></li><li><p><strong>No schema validation</strong>: Store accepts any data structure with no type checking or field validation, risking schema drift over time [8]</p></li><li><p><strong>Manual extraction pipeline</strong>: Each memory update requires custom code for prompting, LLM calls, parsing, validation, retrieval, merging, and storage [10]</p></li></ul><p><strong>The Core Problem</strong>: LangGraph&#8217;s Store API solves <strong>persistence</strong> but not <strong>structured memory management</strong>. <strong>This is where Trustcall bridges the gap.</strong></p><h3>2.3. Implementing Long-Term Memory with Trustcall</h3><p>Trustcall provides reliable structured extraction for LangGraph agents through its <code>create_extractor</code> function [11]. It handles schema validation, duplicate detection, and incremental updates. This eventually transforms the complex task of memory management into a few lines of code.</p><h4><strong>Profile-Based Memory: Tracking User Preferences</strong></h4><p>Profile-based memory maintains a structured representation of user attributes that evolves over time. Here&#8217;s how to implement it with Trustcall:</p><p><strong>Step 1: Define the Memory Schema</strong></p><pre><code><code>from pydantic import BaseModel, Field

# 1. Define schema for user profile
class ResearchProfile(BaseModel):
    """User's research profile"""
    interests: List[str] = Field(description="Research topics of interest")
    expertise_level: str = Field(description="beginner, intermediate, or expert")
    read_papers: List[str] = Field(default=[], description="Papers already read")
</code></code></pre><p><strong>Step 2: Create the Trustcall Extractor</strong></p><pre><code><code>from trustcall import create_extractor
from langchain_openai import ChatOpenAI

# 2. Create extractor
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

profile_extractor = create_extractor(
    llm,
    tools=[ResearchProfile],
    tool_choice="ResearchProfile"
)</code></code></pre><p>The <code>create_extractor</code> function creates a specialized agent that reliably extracts structured data matching your Pydantic schema [5]. By setting <code>tool_choice</code>, you ensure the extractor always attempts to populate your <code>UserProfile</code> schema.</p><p><strong>Step 3: Extract profile</strong></p><pre><code><code># 3. Extract initial profile

conversation = """
I'm interested in transformers and attention mechanisms.
I'm a beginner in this field.
"""

result = profile_extractor.invoke({
    "messages": [{"role": "user", "content": conversation}]
})

profile = result["responses"][0]
print("Initial profile:")
print(profile.model_dump_json(indent=2))</code></code></pre><p>Output</p><pre><code><code>Initial profile:
{
  "interests": [
    "transformers",
    "attention mechanisms"
  ],
  "expertise_level": "beginner",
  "read_papers": []
}</code></code></pre><pre><code><code># 4. Update profile with new information
new_conversation = """
I've been reading about quantum computing lately.
I think I'm getting better at this, maybe intermediate level now.
"""

updated_result = profile_extractor.invoke({
    "messages": [{"role": "user", "content": new_conversation}],
    "existing": {"ResearchProfile": profile.model_dump()}
})

updated_profile = updated_result["responses"][0]
print("\\nUpdated profile:")
print(updated_profile.model_dump_json(indent=2))
</code></code></pre><p>Output</p><pre><code><code>Updated profile:
{
  "interests": [
    "transformers",
    "attention mechanisms",
    "quantum computing"
  ],
  "expertise_level": "intermediate",
  "read_papers": []
}
</code></code></pre><p><strong>Key Benefits</strong>:</p><ul><li><p><strong>Automatic validation</strong>: Trustcall ensures extracted data matches your Pydantic schema [12]</p></li><li><p><strong>Reliable parsing</strong>: No manual JSON parsing or error handling needed</p></li><li><p><strong>Merge control</strong>: You control merge logic (union, replace, append) while Trustcall handles extraction</p></li></ul><h4>Collection-Based Memory: Growing Lists of Structured Data</h4><p>Collection-based memory maintains growing lists where new items are added over time. Trustcall&#8217;s <code>enable_inserts=True</code> feature makes this seamless [13]:</p><p><strong>Step 1: Define the Collection Schema</strong></p><pre><code><code># 1. Define schema for paper notes
class PaperNote(BaseModel):
    """A note about a research paper"""
    paper_title: str = Field(description="Paper title")
    key_insight: str = Field(description="Main takeaway from the paper")
    relevance: str = Field(description="Why this paper matters")
</code></code></pre><p><strong>Step 2: Create Extractor with Insert Support</strong></p><pre><code><code># 2. Create extractor with enable_inserts=True
collection_extractor = create_extractor(
    llm,
    tools=[PaperNote],
    tool_choice="PaperNote",
    enable_inserts=True  # KEY: allows adding new items
)
</code></code></pre><p>The <code>enable_inserts</code> parameter allows the extractor to create new instances of your schema while preserving existing ones [13]. This is essential for maintaining growing collections.</p><p><strong>Step 3: Manage Collections with Existing Data</strong></p><pre><code><code># 4. Add new papers to collection
conversation_with_new_papers = """
I just read two papers:

1. "Chain-of-Thought Prompting" - Shows that step-by-step reasoning 
   improves LLM accuracy on complex tasks.

2. "RAG: Retrieval-Augmented Generation" - Combines retrieval with 
   generation for better factual accuracy.
"""

result = collection_extractor.invoke({
    "messages": [{"role": "user", "content": conversation_with_new_papers}],
    "existing": existing_data
})

print("\\nUpdated collection:")
for response, metadata in zip(result["responses"], result["response_metadata"]):
    is_new = metadata.get("json_doc_id") is None
    status = "NEW" if is_new else "EXISTING"
    doc_id = metadata.get("json_doc_id", "N/A")
    
    print(f"\\n[{status}] {response.paper_title}")
    print(f"  Insight: {response.key_insight}")
    print(f"  Doc ID: {doc_id}")
</code></code></pre><pre><code><code>Updated collection:

[NEW] Chain-of-Thought Prompting
  Insight: Step-by-step reasoning improves LLM accuracy on complex tasks.
  Doc ID: N/A

[NEW] RAG: Retrieval-Augmented Generation
  Insight: Combines retrieval with generation for better factual accuracy.
  Doc ID: N/A
</code></code></pre><p><strong>Key Benefits</strong>:</p><ul><li><p><strong>Incremental updates</strong>: <code>enable_inserts=True</code> allows adding new collections while preserving existing ones [13]</p></li><li><p><strong>Context awareness</strong>: The <code>existing</code> parameter tells Trustcall about current state [14]</p></li><li><p><strong>Intelligent grouping</strong>: The LLM can merge new papers into existing topics or create new ones</p></li></ul><h4>Putting It All Together</h4><p>In a complete LangGraph agent, these memory extraction patterns integrate seamlessly into your workflow nodes. The research paper recommender demonstrates this integration across three sequential stages:</p><ol><li><p><strong>Profile Management Node</strong>: Uses the profile extractor to update user interests and expertise level from each query. The extracted profile is stored in the graph state and persists across conversation turns through LangGraph&#8217;s checkpointer [9].</p></li><li><p><strong>Recommendation Node</strong>: Leverages the updated profile to fetch relevant papers from ArXiv. This node reads the current interests from state to determine search topics, demonstrating how extracted memory directly influences agent behavior.</p></li><li><p><strong>Collection Management Node</strong>: Uses the collection extractor with <code>enable_inserts=True</code> to organize recommended papers by topic. By passing existing collections via the <code>existing</code> parameter, new papers are intelligently grouped with previous ones, building a growing knowledge base over time.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D9Os!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D9Os!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png 424w, https://substackcdn.com/image/fetch/$s_!D9Os!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png 848w, https://substackcdn.com/image/fetch/$s_!D9Os!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png 1272w, https://substackcdn.com/image/fetch/$s_!D9Os!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D9Os!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png" width="228" height="424.7908745247148" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/09747c22-3da7-4c34-b33e-3e2035030390_526x980.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:980,&quot;width&quot;:526,&quot;resizeWidth&quot;:228,&quot;bytes&quot;:46475,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/187506364?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!D9Os!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png 424w, https://substackcdn.com/image/fetch/$s_!D9Os!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png 848w, https://substackcdn.com/image/fetch/$s_!D9Os!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png 1272w, https://substackcdn.com/image/fetch/$s_!D9Os!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09747c22-3da7-4c34-b33e-3e2035030390_526x980.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Graph-Based Research Paper Recommender Agent Architecture</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Q5UQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Q5UQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif 424w, https://substackcdn.com/image/fetch/$s_!Q5UQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif 848w, https://substackcdn.com/image/fetch/$s_!Q5UQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif 1272w, https://substackcdn.com/image/fetch/$s_!Q5UQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Q5UQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif" width="800" height="465" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:465,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2259763,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/187506364?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Q5UQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif 424w, https://substackcdn.com/image/fetch/$s_!Q5UQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif 848w, https://substackcdn.com/image/fetch/$s_!Q5UQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif 1272w, https://substackcdn.com/image/fetch/$s_!Q5UQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6c4a68f-bd5b-45cb-ad30-4a0c3d35ff1a_800x465.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Example Response Generated by the Research Paper Recommender Agent</figcaption></figure></div><p></p><p>The key architectural insight is that <strong>Trustcall handles the extraction complexity within each node</strong>, while <strong>LangGraph orchestrates the flow</strong> between memory updates, tool calls, and user responses. The graph state serves as the persistence layer, with Trustcall ensuring that all updates to <code>user_profile</code> and <code>collections</code> are structured, validated, and properly merged.</p><p>For the complete implementation showing how these extractors integrate into LangGraph nodes and state management, see the full code example <a href="https://github.com/linafaik08/scientific-graph-agent">https://github.com/linafaik08/scientific-graph-agent</a>.</p><p>Trustcall eliminates the boilerplate of structured memory management, letting you focus on your agent&#8217;s logic rather than extraction plumbing. The combination of Pydantic schemas for validation, intelligent extraction, and merge support makes long-term memory practical and reliable [11][12].</p><div><hr></div><h2>Key Takeaways</h2><p>&#10003; <strong>Long-term memory is architectural, not prompt engineering</strong>: Reliable agent memory requires explicit design around what to store, where it persists, and how it updates. Larger context windows or appending conversation history don&#8217;t solve personalization or</p><p> scalability.</p><p>&#10003; <strong>Different memory types must be coordinated</strong>: Working, semantic, episodic, and procedural memory each have distinct lifecycles. Effective agents emerge from controlled flows between them: episodic consolidation into semantic memory, semantic retrieval into working memory.</p><p>&#10003; <strong>LangGraph makes memory explicit but not automatic</strong>: State and checkpointing provide transparency and debuggability, but don&#8217;t solve structured extraction, schema enforcement, or conflict resolution. These must be handled explicitly in your nodes.</p><p>&#10003; <strong>Schema-driven updates prevent memory drift</strong>: Typed schemas (Pydantic models) for profiles and collections enable controlled updates, deduplication, and validation. This prevents memory from becoming noisy append-only logs.</p><p>&#10003; <strong>Production memory is harder than agent logic</strong>: Most agent failures stem from incorrect retrieval, stale facts, or uncontrolled memory growth, not reasoning quality. Building accurate, scalable memory typically demands more effort than the core agent logic itself. </p><div><hr></div><h2>References</h2><ol><li><p>CoALA &#8212; <em>Cognitive Architectures for Language Agents</em> (arXiv:2309.02427) <a href="https://arxiv.org/abs/2309.02427">https://arxiv.org/abs/2309.02427</a></p></li><li><p>MemGPT &#8212; <em>Towards LLMs as Operating Systems</em> (arXiv:2310.08560) <a href="https://arxiv.org/abs/2310.08560">https://arxiv.org/abs/2310.08560</a></p></li><li><p>Mem0 &#8212; <em>Building Production-Ready AI Agents with Scalable Long-Term Memory</em> (arXiv:2504.19413) <a href="https://arxiv.org/abs/2504.19413">https://arxiv.org/abs/2504.19413</a></p></li><li><p><em>Generative Agents: Interactive Simulacra of Human Behavior</em> (arXiv:2304.03442) <a href="https://arxiv.org/abs/2304.03442">https://arxiv.org/abs/2304.03442</a></p></li><li><p>Letta &#8212; <em>Skill Learning: Bringing Continual Learning to CLI Agents</em> <a href="https://www.letta.com/blog/skill-learning">https://www.letta.com/blog/skill-learning</a></p></li><li><p>Zep &#8212; <em>A Temporal Knowledge Graph Architecture for Agent Memory</em> (arXiv:2501.13956) <a href="https://arxiv.org/abs/2501.13956">https://arxiv.org/abs/2501.13956</a></p></li><li><p><em>Lost in the Middle: How Language Models Use Long Contexts</em> (arXiv:2307.03172) <a href="https://arxiv.org/abs/2307.03172">https://arxiv.org/abs/2307.03172</a></p></li><li><p>LangGraph Documentation &#8212; Store API Overview <a href="https://langchain-ai.github.io/langgraph/concepts/memory/#store">https://langchain-ai.github.io/langgraph/concepts/memory/#store</a></p></li><li><p>LangGraph Documentation &#8212; Using the Store <a href="https://langchain-ai.github.io/langgraph/how-tos/manage-cross-thread-memory/">https://langchain-ai.github.io/langgraph/how-tos/manage-cross-thread-memory/</a></p></li><li><p>The AI Practitioner &#8212; <a href="https://aipractitioner.substack.com/p/beyond-the-demo-building-ai-agents">Beyond the Demo: Building AI Agents That Remember, Recover, and Scale (Part 2)</a>, Lina Faik</p></li><li><p>Trustcall Documentation &#8212; create_extractor <a href="https://github.com/Sizaar/trustcall">https://github.com/Sizaar/trustcall</a></p></li><li><p>Trustcall Documentation &#8212; Schema Validation <a href="https://github.com/Sizaar/trustcall#schema-validation">https://github.com/Sizaar/trustcall#schema-validation</a></p></li><li><p>Trustcall Documentation &#8212; enable_inserts <a href="https://github.com/Sizaar/trustcall#incremental-updates">https://github.com/Sizaar/trustcall#incremental-updates</a></p></li><li><p>Trustcall Documentation &#8212; Passing Existing Data <a href="https://github.com/Sizaar/trustcall#managing-existing-data">https://github.com/Sizaar/trustcall#managing-existing-data</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Scaling LangGraph Agents: Parallelization, Subgraphs, and Map-Reduce Trade-Offs]]></title><description><![CDATA[A Practical Guide to Choosing the Right Orchestration Strategy for Scalable LLM Workflows]]></description><link>https://aipractitioner.substack.com/p/scaling-langgraph-agents-parallelization</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/scaling-langgraph-agents-parallelization</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 27 Nov 2025 10:23:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Dr-4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Dr-4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Dr-4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png 424w, https://substackcdn.com/image/fetch/$s_!Dr-4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png 848w, https://substackcdn.com/image/fetch/$s_!Dr-4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!Dr-4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Dr-4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png" width="1456" height="603" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:603,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:646287,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Dr-4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png 424w, https://substackcdn.com/image/fetch/$s_!Dr-4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png 848w, https://substackcdn.com/image/fetch/$s_!Dr-4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!Dr-4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90e5ffa9-5b19-4d4d-b64b-688b373aa8d5_2932x1214.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p><em>This article is also available as a podcast! If you&#8217;re on the go or just want to absorb the content in audio format, you can listen to the full episode below &#128071; The podcast is also available on <a href="https://open.spotify.com/show/6MROBKvrjx0Mey8tHud5LX">Spotify</a> and <a href="https://podcasts.apple.com/us/podcast/the-ai-practitioner-podcast/id1830285899">Apple Podcasts</a>. </em></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;9d6d4611-96dc-46a9-a46a-4a9d29a309f2&quot;,&quot;caption&quot;:&quot;Prefer reading instead? The full article is available here.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;PODCAST &#8212; Scaling LangGraph Agents: Parallelization, Subgraphs, and Map-Reduce Trade-Offs&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:7177021,&quot;name&quot;:&quot;Lina Faik&quot;,&quot;bio&quot;:&quot;Lead AI Scientist bringing AI research to real-world impact across industries. Founder, Data Impulse | Author, The AI Practitioner | ex-Dataiku&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bdaf5e6-a6c6-48fe-80f6-3d69aaac1694_2256x2256.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-27T10:22:21.066Z&quot;,&quot;cover_image&quot;:&quot;https://substack-video.s3.amazonaws.com/video_upload/post/180043482/d96bc4bd-5fe8-4e74-995d-3cb15c7980d7/transcoded-1764238909.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://aipractitioner.substack.com/p/podcast-scaling-langgraph-agents&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:180043482,&quot;type&quot;:&quot;podcast&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4815372,&quot;publication_name&quot;:&quot;The AI Practitioner&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ivps!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>As agent systems grow from simple chains to complex multi-agent setups, the graphs meant to bring clarity end up creating confusion. What begins as a clean five-node workflow explodes into 30+ nodes, each relying on unclear state changes.</p><p>The key to scaling graph complexity is understanding when to parallelize independent work, when to encapsulate logic in subgraphs, and when to let the system dynamically spawn tasks based on runtime conditions.</p><h3>Objective</h3><p>This article focuses on solving three scalability problems: latency from sequential execution, complexity from oversized graphs, and rigidity from static workflows.</p><p>After reading this article, you will understand:</p><ol><li><p>How to reduce latency through <strong>parallelization</strong> while managing concurrent state updates?</p></li><li><p>How to structure multi-agent architectures using <strong>subgraphs</strong> with isolated or shared state?</p></li><li><p>How to implement <strong>map-reduce</strong> patterns for variable workloads using the Send API?</p></li></ol><blockquote><p>This article is the fourth part of the LangGraph series on graph-based agent architectures. While earlier parts focused on individual graph components, Part 4 explores how to compose and orchestrate multiple agents efficiently.</p><p><strong>Prerequisites:</strong> Basic knowledge of Python, LLMs, and prompt engineering is recommended. Readers should either be familiar with LangChain concepts (chains, models, prompts) or have read <a href="https://aipractitioner.substack.com/p/from-chains-to-graphs-smarter-and">Part 1</a> of this series (or listen the <a href="https://aipractitioner.substack.com/p/podcast-from-chains-to-graphs-smarter">podcast edition</a>) to understand the foundations of LangGraph&#8217;s graph, node, and state model. </p><p><strong>Tools &amp; libraries:</strong> <a href="https://www.langchain.com/langgraph">LangGraph</a>, <a href="https://www.langchain.com/">LangChain</a>, <a href="https://www.langchain.com/langsmith/observability">LangSmith</a>, <a href="https://openai.com/">OpenAI</a>, <a href="https://info.arxiv.org/help/api/index.html">arXiv API</a></p></blockquote><p>You can find the code <a href="https://github.com/linafaik08/scientific-graph-agent">here</a> on GitHub.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>1. Understanding LangGraph&#8217;s Concurrency Models</h2><h3>1.1 When should parallelization be chosen over sequential execution?</h3><p><strong>What is parallelization in LangGraph?</strong></p><p>Parallelization in LangGraph means executing multiple nodes simultaneously rather than one after another. Instead of waiting for one task to complete before starting the next, multiple tasks launch at the same time and run concurrently. </p><p>This is particularly valuable when making multiple independent API calls, database queries, or LLM requests that don&#8217;t depend on each other&#8217;s results.</p><p>In LangGraph, parallel execution is created by adding multiple edges from a single node to multiple destination nodes. The graph automatically detects this fan-out pattern and executes the destination nodes concurrently in what LangGraph calls a &#8220;superstep.&#8221;</p><p><strong>Sequential vs. Parallel: A concrete example</strong></p><p>Consider building a research assistant that answers questions by consulting both ArXiv (for academic papers) and Wikipedia (for general knowledge). </p><p><strong>Sequential execution</strong> (one after another):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RhT4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RhT4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png 424w, https://substackcdn.com/image/fetch/$s_!RhT4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png 848w, https://substackcdn.com/image/fetch/$s_!RhT4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png 1272w, https://substackcdn.com/image/fetch/$s_!RhT4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RhT4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png" width="1456" height="616" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:616,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:199241,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RhT4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png 424w, https://substackcdn.com/image/fetch/$s_!RhT4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png 848w, https://substackcdn.com/image/fetch/$s_!RhT4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png 1272w, https://substackcdn.com/image/fetch/$s_!RhT4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1c9872f-fde6-4d8b-98dd-1ad0cb460cce_1536x650.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>With sequential execution, if ArXiv takes 2 seconds and Wikipedia takes 2 seconds, the total wait time is 4 seconds.</p><p><strong>Parallel execution</strong> (both at once):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RYUx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RYUx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png 424w, https://substackcdn.com/image/fetch/$s_!RYUx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png 848w, https://substackcdn.com/image/fetch/$s_!RYUx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png 1272w, https://substackcdn.com/image/fetch/$s_!RYUx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RYUx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png" width="1456" height="635" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:635,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:216312,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RYUx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png 424w, https://substackcdn.com/image/fetch/$s_!RYUx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png 848w, https://substackcdn.com/image/fetch/$s_!RYUx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png 1272w, https://substackcdn.com/image/fetch/$s_!RYUx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4b4dade-a50a-4299-87dc-1d430deedd4b_1586x692.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>With parallel execution, both APIs are called simultaneously. The total wait time becomes only 2 seconds (the duration of the longest call), cutting execution time in half.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tyEb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tyEb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png 424w, https://substackcdn.com/image/fetch/$s_!tyEb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png 848w, https://substackcdn.com/image/fetch/$s_!tyEb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png 1272w, https://substackcdn.com/image/fetch/$s_!tyEb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tyEb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png" width="636" height="431.13461538461536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:987,&quot;width&quot;:1456,&quot;resizeWidth&quot;:636,&quot;bytes&quot;:223158,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tyEb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png 424w, https://substackcdn.com/image/fetch/$s_!tyEb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png 848w, https://substackcdn.com/image/fetch/$s_!tyEb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png 1272w, https://substackcdn.com/image/fetch/$s_!tyEb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F028ceb7e-ffc6-4be0-ab50-b1805c01e051_1968x1334.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Sequential vs Parallel Execution Flow</figcaption></figure></div><p><strong>Comparisons:</strong></p><p>In the research paper use case, running both tools sequentially took 61.46s, compared to just 0.45s when executed in parallel, a 137&#215; speedup!<br></p><p><strong>Key implementation considerations</strong></p><ul><li><p><strong>The fundamental requirement for parallelization is independence.</strong> The ArXiv and Wikipedia calls work in parallel because neither needs the other&#8217;s output to proceed. When nodes truly run independently, parallelization delivers immediate performance gains.</p></li><li><p><strong>However, state management requires careful attention.</strong> If both nodes update the same state key (like adding results to a &#8220;documents&#8221; list), reducers become essential to merge their updates properly. As discussed in the previous blog post on reducers (cf. <a href="https://aipractitioner.substack.com/p/beyond-the-demo-building-ai-agents">Part 2</a> of the series), these functions define how concurrent updates combine. </p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rtcK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rtcK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png 424w, https://substackcdn.com/image/fetch/$s_!rtcK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png 848w, https://substackcdn.com/image/fetch/$s_!rtcK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png 1272w, https://substackcdn.com/image/fetch/$s_!rtcK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rtcK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png" width="1456" height="327" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:327,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105881,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rtcK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png 424w, https://substackcdn.com/image/fetch/$s_!rtcK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png 848w, https://substackcdn.com/image/fetch/$s_!rtcK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png 1272w, https://substackcdn.com/image/fetch/$s_!rtcK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F763e42e4-3682-445d-95a9-8799d02b5419_1586x356.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><ul><li><p><strong>Understanding supersteps is crucial for managing parallel execution.</strong> A superstep is an execution unit in LangGraph that groups together nodes that can run concurrently. In our previous example, the graph detects multiple edges  fanning out from a single node as ArXiv and Wikipedia starting simultaneously. It creates a superstep containing those parallel nodes. All nodes in a superstep execute at the same time and must all complete before the graph proceeds to the next step.</p></li></ul><ul><li><p><strong>Error handling requires special consideration within supersteps.</strong> If one parallel node fails, the entire superstep fails atomically. This means if Wikipedia succeeds but ArXiv fails, neither result gets saved to state. This transactional behavior prevents inconsistent states but requires robust retry logic or fallback strategies in the node design. When using checkpointing, however, LangGraph saves results from successful nodes internally, so only failing branches need to retry when the graph resumes.</p></li></ul><h2>1.2 What are the performance trade-offs of concurrent node execution?</h2><p><strong>Speed gains vs. resource consumption</strong></p><ul><li><p><strong>Parallel execution reduces latency but increases instantaneous resource usage.</strong> In the ArXiv and Wikipedia example, wait time drops from 4 seconds to 2 seconds, but two API calls now happen simultaneously instead of sequentially. This shift creates several practical implications.</p></li><li><p><strong>Rate limits become a primary concern.</strong> If the Wikipedia API allows 60 requests per minute and five parallel searches run simultaneously, the quota gets consumed in 12 seconds instead of 1 minute. Monitoring and potentially throttling concurrent requests becomes necessary. LangGraph provides a <code>max_concurrency</code> configuration parameter to limit how many nodes can run at once, offering direct control over this trade-off.</p></li></ul><p><strong>Complexity vs. debuggability</strong></p><ul><li><p><strong>Parallel execution trades simplicity for speed.</strong> Sequential execution offers a clear linear path to trace when problems occur. Parallel execution requires tracking multiple simultaneous paths, understanding how states merge, and diagnosing which branch caused failures. If a synthesis node fails, determining whether bad data came from ArXiv, Wikipedia, or both requires investigation.</p></li><li><p><strong>Better logging and observability become essential.</strong> Execution traces show nodes completing in unpredictable order, making bug reproduction challenging. The trade-off is clear: parallelization delivers speed at the cost of operational complexity, making sense primarily when waiting on multiple slow external services that can run independently.</p></li></ul><h2>2. Subgraphs for Modular Agent Architectures</h2><h3>2.1 When to use isolated state vs. shared state between agents?</h3><p><strong>What are subgraphs in LangGraph?</strong></p><p>Subgraphs are complete, self-contained graphs that can be embedded as nodes within a parent graph. They are reusable components or specialized agents that encapsulate their own logic and workflow. A subgraph is compiled independently and then added to a parent graph just like any other node, but internally it can have its own multi-step workflow, state schema, and execution logic. This architecture becomes particularly powerful for multi-agent systems. Instead of building one massive graph with dozens of nodes, the system can be decomposed into specialized agents (subgraphs), each responsible for a specific domain.</p><p>For example, a research assistant might have an orchestrator agent (parent graph) that delegates to specialized subgraphs: a literature review agent that searches and summarizes academic papers, a data extraction agent that pulls statistics and figures from documents, and a citation management agent that formats references. Each subgraph operates as an independent agent with its own internal workflow.</p><p><strong>Shared state: the simple approach</strong></p><p>The simplest subgraph pattern uses shared state keys between the parent and child graphs. According to the LangGraph subgraphs documentation, when a subgraph shares state keys with the parent graph, communication happens automatically through these shared channels. This is common in multi-agent systems where agents communicate over a shared &#8220;messages&#8221; key.</p><p>Consider a research system where an orchestrator agent (parent) delegates to specialized research agents (subgraphs):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PdbJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PdbJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png 424w, https://substackcdn.com/image/fetch/$s_!PdbJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png 848w, https://substackcdn.com/image/fetch/$s_!PdbJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png 1272w, https://substackcdn.com/image/fetch/$s_!PdbJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PdbJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png" width="1456" height="1503" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1503,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:469668,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PdbJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png 424w, https://substackcdn.com/image/fetch/$s_!PdbJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png 848w, https://substackcdn.com/image/fetch/$s_!PdbJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png 1272w, https://substackcdn.com/image/fetch/$s_!PdbJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cd4745-52bb-41f2-8339-189927b11395_1484x1532.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>With shared state, the parent&#8217;s messages flow directly into the subgraph, the subgraph&#8217;s internal nodes can add more documents, and these updates flow back to the parent. This creates seamless communication but also means the subgraph can see and modify all parent state, which may not always be desired.</p><p><strong>Isolated state: maintaining boundaries</strong></p><p>Isolated state becomes necessary when agents need private information that shouldn&#8217;t leak to other parts of the system. With isolated state, the subgraph has its own schema completely independent from the parent. This requires explicit state transformation at the boundaries:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8-2M!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8-2M!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png 424w, https://substackcdn.com/image/fetch/$s_!8-2M!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png 848w, https://substackcdn.com/image/fetch/$s_!8-2M!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png 1272w, https://substackcdn.com/image/fetch/$s_!8-2M!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8-2M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png" width="1456" height="2186" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2186,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:604543,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8-2M!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png 424w, https://substackcdn.com/image/fetch/$s_!8-2M!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png 848w, https://substackcdn.com/image/fetch/$s_!8-2M!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png 1272w, https://substackcdn.com/image/fetch/$s_!8-2M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc33c3177-586d-4713-815e-02aa3ef65d7d_1468x2204.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>The trade-off is clear: shared state offers simplicity and automatic communication, while isolated state provides encapsulation and privacy at the cost of manual state transformation. The choice depends on whether agent boundaries need enforcement or whether seamless information flow is more valuable.</p><h3>2.2 How to maintain separate memory for each agent in a multi-agent system?</h3><p><strong>Independent checkpointing for agent memory</strong></p><p>Each subgraph can maintain its own memory by compiling it with a dedicated checkpointer. This is particularly useful in multi-agent systems where each agent needs to track its own internal history independently. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CH7S!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CH7S!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png 424w, https://substackcdn.com/image/fetch/$s_!CH7S!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png 848w, https://substackcdn.com/image/fetch/$s_!CH7S!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png 1272w, https://substackcdn.com/image/fetch/$s_!CH7S!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CH7S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png" width="1456" height="736" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:736,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:231528,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CH7S!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png 424w, https://substackcdn.com/image/fetch/$s_!CH7S!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png 848w, https://substackcdn.com/image/fetch/$s_!CH7S!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png 1272w, https://substackcdn.com/image/fetch/$s_!CH7S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fc1bff9-d611-4ae0-89bd-6c7d06c441ab_1536x776.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>This architecture enables agents to build up expertise and context over time as each agent maintains focused, relevant memory for its domain.</p><p><strong>Memory visibility and debugging</strong></p><p>The documentation notes that subgraph state can be viewed using <code>graph.get_state(config, subgraphs=True)</code>, but with an important caveat: subgraph state is only accessible when the subgraph is interrupted. Once execution resumes, that checkpoint moves into the past and is no longer directly accessible.</p><p>This has practical implications for debugging and monitoring. To understand what happened inside a subgraph, interruption points need strategic placement, or the subgraph needs to explicitly surface key information back to the parent state. For example, a literature review agent might maintain detailed paper evaluations in its private state but surface only the final summary to the parent.</p><h2>3. Map-Reduce with the Send API</h2><h3>3.1 When should dynamic branching be used vs. static parallelization?</h3><p><strong>What is map-reduce in LangGraph?</strong></p><p>Map-reduce is a pattern for distributing work across multiple parallel tasks and then aggregating their results.</p><ul><li><p>The &#8220;map&#8221; phase splits work into independent units that process in parallel</p></li><li><p>The &#8220;reduce&#8221; phase combines their outputs.</p></li></ul><p>In LangGraph, map-reduce is implemented using the Send API, which enables dynamic task creation at runtime where the number and configuration of parallel tasks are determined by the graph&#8217;s state rather than fixed at design time.</p><p>Consider a research assistant with a query clarifier that interprets ambiguous research questions in multiple ways. The number of interpretations isn&#8217;t known until the clarification completes, and each interpretation needs separate processing.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MqT8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MqT8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png 424w, https://substackcdn.com/image/fetch/$s_!MqT8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png 848w, https://substackcdn.com/image/fetch/$s_!MqT8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png 1272w, https://substackcdn.com/image/fetch/$s_!MqT8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MqT8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png" width="1384" height="3044" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3044,&quot;width&quot;:1384,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:720654,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MqT8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png 424w, https://substackcdn.com/image/fetch/$s_!MqT8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png 848w, https://substackcdn.com/image/fetch/$s_!MqT8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png 1272w, https://substackcdn.com/image/fetch/$s_!MqT8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32f58420-d48b-4cb9-8b2b-561a236d6bcd_1384x3044.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>The <code>route_to_reaserchers</code> function returns a list of Send objects, each specifying which node to invoke and with what state. LangGraph executes all these search tasks in parallel within a single superstep, then proceeds to synthesis once all complete.</p><p><strong>The trade-off: flexibility vs. simplicity</strong></p><ul><li><p><strong>Map-reduce provides flexibility for variable workloads but introduces complexity.</strong> The graph structure isn&#8217;t fully visible at design time since the number of parallel tasks depends on runtime state. A query might generate 2 interpretations or 10, creating different execution patterns each run. This makes visualization and debugging more challenging.</p></li><li><p><strong>Static parallelization offers simplicity and predictability but lacks adaptability.</strong> The choice depends on whether the parallel structure is truly fixed. For research tasks where interpretation counts vary (sometimes needing 2 searches, sometimes 8), map-reduce is essential. For fixed API queries with consistent structure (always ArXiv + PubMed + Semantic Scholar), static parallelization is cleaner and more maintainable.</p></li></ul><h3>3.2 What happens when parallel branches have different execution lengths?</h3><p><strong>The challenge of uneven task durations</strong></p><p>In static parallelization with fixed APIs, branches typically complete around the same time since they perform similar operations. With map-reduce, different tasks may require drastically different processing times. A research assistant searching multiple query interpretations might get instant results for one interpretation (cached or simple query) but wait 20 seconds for another (complex query requiring extensive processing).</p><p>The problem emerges when these tasks of different lengths need to converge. Consider a graph that searches multiple interpretations in parallel, then synthesizes findings. If the synthesis node starts as soon as the first search finishes, it works with incomplete data. The graph needs a way to ensure all parallel work completes before proceeding.</p><p><strong>The defer parameter for synchronization</strong></p><p>In LangGraph, when multiple parallel branches converge to the same node, the system automatically waits for all branches to complete before proceeding <a href="https://docs.langchain.com/oss/python/langgraph/use-graph-api">Langchain</a>. This built-in synchronization is fundamental to how LangGraph&#8217;s superstep execution model works.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3luZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3luZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png 424w, https://substackcdn.com/image/fetch/$s_!3luZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png 848w, https://substackcdn.com/image/fetch/$s_!3luZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png 1272w, https://substackcdn.com/image/fetch/$s_!3luZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3luZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png" width="1456" height="493" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/efa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:493,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:189351,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3luZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png 424w, https://substackcdn.com/image/fetch/$s_!3luZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png 848w, https://substackcdn.com/image/fetch/$s_!3luZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png 1272w, https://substackcdn.com/image/fetch/$s_!3luZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefa64536-e01c-4988-b899-9435ddf2b87c_1670x566.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>The <code>synthesize</code> node automatically waits for every parallel <code>search_papers</code> instance to complete&#8212;no special configuration needed. However, <code>defer=True</code> is useful when branches have different lengths and you want to delay a node&#8217;s execution until all other pending tasks are completed <a href="https://docs.langchain.com/oss/python/langgraph/use-graph-api">Langchain</a>. It&#8217;s passed as a parameter to <code>add_node()</code>:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!w2pO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!w2pO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png 424w, https://substackcdn.com/image/fetch/$s_!w2pO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png 848w, https://substackcdn.com/image/fetch/$s_!w2pO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png 1272w, https://substackcdn.com/image/fetch/$s_!w2pO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!w2pO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png" width="1456" height="553" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:553,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:186553,&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://aipractitioner.substack.com/i/180028943?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!w2pO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png 424w, https://substackcdn.com/image/fetch/$s_!w2pO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png 848w, https://substackcdn.com/image/fetch/$s_!w2pO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png 1272w, https://substackcdn.com/image/fetch/$s_!w2pO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe217fc4b-2ee6-4118-b59e-37b9700f7a2e_1602x608.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>Without <code>defer=True</code>, when branches execute in the same superstep, the downstream node naturally waits for all parallel branches to finish <a href="https://docs.langchain.com/oss/python/langgraph/use-graph-api">Langchain</a>. With <code>defer=True</code>, the node explicitly waits until all pending tasks across different branch lengths are completed&#8212;ensuring complete data collection even when branches have asymmetric execution paths.</p><div><hr></div><h1>Key Takeaways</h1><p>&#10003; <strong>Parallelization delivers dramatic speedups when tasks are independent</strong>: By executing multiple nodes simultaneously rather than sequentially, parallel execution can reduce latency. However, this requires careful state management with reducers to merge concurrent updates and avoid data loss.</p><p>&#10003; <strong>Subgraphs enable modular multi-agent architectures with isolated or shared state</strong>: Use shared state for seamless communication between agents when information needs to flow freely, or isolated state with explicit transformation functions when agents need privacy and clear boundaries between their internal workings.</p><p>&#10003; <strong>Map-reduce with the Send API adapts to variable workloads at runtime</strong>: Unlike static parallelization with fixed branches, map-reduce dynamically creates parallel tasks based on runtime conditions. This is essential when the number of tasks varies (e.g., processing 2 vs. 10 query interpretations) but adds complexity to debugging and visualization.</p><div><hr></div><h1>References</h1><p>[1] LangGraph Documentation - <a href="https://langchain-ai.github.io/langgraph/concepts/low_level/#parallelization">Parallelization and Concurrency</a>, LangChain AI, 2024 </p><p>[2] LangGraph Documentation - <a href="https://langchain-ai.github.io/langgraph/how-tos/subgraph/">Subgraphs, LangChain AI</a>, 2024</p><p>[3] LangGraph Documentation - <a href="https://langchain-ai.github.io/langgraph/how-tos/map-reduce/">Map-Reduce with Send API</a>, LangChain AI, 2024 </p><p>[4] LangGraph Documentation - <a href="https://langchain-ai.github.io/langgraph/concepts/low_level/#nodes">Node Execution and Supersteps</a>, LangChain AI, 2024 </p>]]></content:encoded></item><item><title><![CDATA[Human-in-the-Loop Agents: Steering AI with LangGraph’s Streaming, Breakpoints (Part 3)]]></title><description><![CDATA[Turning Static Reasoning Graphs Into Dynamic Systems Where Humans Can Pause, Inspect, and Redirect an Agent&#8217;s Thinking in Real Time]]></description><link>https://aipractitioner.substack.com/p/human-in-the-loop-agents-steering</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/human-in-the-loop-agents-steering</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 20 Nov 2025 16:05:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mruI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mruI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mruI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png 424w, https://substackcdn.com/image/fetch/$s_!mruI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png 848w, https://substackcdn.com/image/fetch/$s_!mruI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png 1272w, https://substackcdn.com/image/fetch/$s_!mruI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mruI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png" width="1456" height="605" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:605,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:444463,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mruI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png 424w, https://substackcdn.com/image/fetch/$s_!mruI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png 848w, https://substackcdn.com/image/fetch/$s_!mruI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png 1272w, https://substackcdn.com/image/fetch/$s_!mruI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3982cd9a-6ad0-4f1e-9721-ae3452f5078c_2928x1216.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This article is also available as a podcast! If you&#8217;re on the go or just want to absorb the content in audio format, you can listen to the full episode below &#128071; The podcast is also available on <a href="https://open.spotify.com/show/6MROBKvrjx0Mey8tHud5LX">Spotify</a> and <a href="https://podcasts.apple.com/us/podcast/the-ai-practitioner-podcast/id1830285899">Apple Podcasts</a>.</em></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;5a78a512-5882-4574-b48e-83aaddafe28c&quot;,&quot;caption&quot;:&quot;Prefer reading instead? The full article is available here.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;PODCAST &#8212; Human-in-the-Loop Agents: Steering AI with LangGraph&#8217;s Streaming, Breakpoints&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:7177021,&quot;name&quot;:&quot;Lina Faik&quot;,&quot;bio&quot;:&quot;Lead AI Scientist bringing AI research to real-world impact across industries. Founder, Data Impulse | Author, The AI Practitioner | ex-Dataiku&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bdaf5e6-a6c6-48fe-80f6-3d69aaac1694_2256x2256.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-20T14:46:27.689Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/057f4804-7939-4db6-9d30-c5bce5a0387c_2928x1216.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://aipractitioner.substack.com/p/podcast-human-in-the-loop-agents&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:179229290,&quot;type&quot;:&quot;podcast&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4815372,&quot;publication_name&quot;:&quot;The AI Practitioner&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ivps!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>As AI agents become more autonomous, chaining tool calls, making decisions, and executing multi-step workflows, the question of how to maintain meaningful human control without sacrificing automation becomes increasingly urgent.</p><p>Traditional patterns often force a false choice between fully unsupervised agents, which risk errors and unsafe behavior, and fully supervised workflows, which defeat the purpose of automation.</p><p>This tension is especially significant in high-stakes domains such as medical analysis, financial reporting, or content moderation, where an autonomous agent may commit a critical mistake before anyone intervenes, while excessive oversight eliminates efficiency gains.</p><p>What is needed is temporal control: the ability to observe reasoning as it happens, pause execution at key moments, inject corrective guidance, and even rewind to earlier states to explore alternative trajectories.</p><h3>Objective</h3><p>This article demonstrates how to transform agents from opaque black boxes into steerable, inspectable systems through three complementary mechanisms: streaming for real-time visibility, breakpoints for surgical intervention, and time travel for historical navigation. It relies on LangGraph framework.</p><p>These aren&#8217;t just debugging features but fundamental primitives for building production-grade agents that balance autonomy with accountability.</p><p>After reading this article, you will understand:</p><ol><li><p><strong>Streaming</strong>: How to expose an agent&#8217;s reasoning process in real time, surfacing intermediate thoughts, tool calls, and state transitions as they happen, not after the fact</p></li><li><p><strong>Human-in-the-Loop</strong>: How to strategically insert breakpoints that pause execution at critical decision points, allowing humans to inspect context, approve/reject actions, or inject corrective guidance before the agent proceeds</p></li><li><p><strong>Time Travel</strong>: How to rewind an agent&#8217;s execution to any prior state, fork alternative reasoning paths, and replay modified trajectories, enabling &#8220;what-if&#8221; exploration and recovery from mistakes without restarting from scratch</p></li></ol><blockquote><p><strong>Context:</strong> This article is the third part of the series on building production-ready AI agents with LangGraph. <a href="https://aipractitioner.substack.com/p/from-chains-to-graphs-smarter-and">Part 1</a> covered the foundational architecture of stateful agents and graph-based workflows, while <a href="https://aipractitioner.substack.com/p/beyond-the-demo-building-ai-agents">Part 2</a> examined persistence mechanisms for checkpoint management and recovery. This new article addresses the most challenging aspect: maintaining human oversight at scale.</p><p><strong>Prerequisites:</strong></p><ul><li><p>Basic knowledge of Python, LLMs, and prompt engineering is recommended.</p></li><li><p>Readers should either be familiar with LangChain concepts (chains, models, prompts) or have read <a href="https://aipractitioner.substack.com/p/from-chains-to-graphs-smarter-and">Part 1</a> of this series (or listen the <a href="https://aipractitioner.substack.com/p/podcast-from-chains-to-graphs-smarter">podcast edition</a>) to understand the foundations of LangGraph&#8217;s graph, node, and state model.</p></li><li><p>Readers should have read <a href="https://aipractitioner.substack.com/p/beyond-the-demo-building-ai-agents">Part 2</a> (or listen the <a href="https://aipractitioner.substack.com/p/podcast-beyond-the-demo-building">podcast edition</a>) on checkpoint management, state serialization, and recovery mechanisms as these concepts are essential for streaming and time travel.</p></li></ul><p><strong>Tools &amp; libraries:</strong> <a href="https://www.langchain.com/langgraph">LangGraph</a>, <a href="https://www.langchain.com/">LangChain</a>, <a href="https://www.langchain.com/langsmith/observability">LangSmith</a>, <a href="https://openai.com/">OpenAI</a>, <a href="https://info.arxiv.org/help/api/index.html">arXiv API</a></p></blockquote><p>You can find the code <a href="https://github.com/linafaik08/scientific-graph-agent">here</a> on GitHub.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>1. Streaming: Real-Time Visibility into Agent Reasoning</h2><p>Imagine launching your scientific paper explorer agent with a complex query, then staring at a blank screen for 30 seconds. Is it stuck? Is it searching? Did it crash? Without visibility into what&#8217;s happening, you&#8217;re forced to trust blindly or worse, kill the process and start over.</p><p>This is where streaming transforms your agent from an opaque black box into a transparent, observable system.</p><h3>1.1 Why Does Streaming Matter for Human-in-the-Loop Systems?</h3><p>Streaming isn&#8217;t just about user experience, though watching tokens appear is certainly more engaging than staring at a loading spinner. For production AI agents, streaming serves three critical functions for human oversight:</p><ol><li><p><strong>Trust through transparency</strong>: When users see the agent&#8217;s reasoning unfold in real-time (the clarified query being formulated, relevance scores being calculated), they can build confidence in the system&#8217;s logic or catch problems early.</p></li><li><p><strong>Early intervention signals</strong>: If a user watches the agent starting to generate an off-topic query or score irrelevant papers highly, he can interrupt and correct it before wasting compute on the downstream summarization step.</p></li><li><p><strong>Debuggability</strong>: When things go wrong, streaming logs capture <em>exactly</em> what the agent was doing at each millisecond. Instead of &#8220;the agent failed at minute 2,&#8221; you know &#8220;it failed while scoring the 8th paper, right after processing a malformed ArXiv result.&#8221;</p></li></ol><h3>1.2 How to Stream Agent Execution in LangGraph?</h3><p>LangGraph offers three distinct streaming modes, each revealing different aspects of agent execution:</p><ul><li><p><strong>Token-Level Streaming:</strong> Streams tokens in real time as the LLM generates text.</p></li><li><p><strong>Node-Level Streaming:</strong> Emits state updates whenever a node finishes running.</p></li><li><p><strong>Custom Streaming:</strong> Sends progress signals from long-running steps (e.g., API calls, file processing, search loops).</p></li></ul><p>Let&#8217;s implement all three in our research assistant to create complete observability.</p><h4><strong>1. Token-Level Streaming</strong></h4><p><strong>Key idea: </strong>Individual tokens appear as the LLM generates responses, creating a &#8220;typewriter effect.&#8221; This is useful when you want users to see the summary being written in real-time, or to verify that the LLM is actively generating (not stuck).</p><p><strong>Implementation: </strong>In the original synchronous <code>summarizer_node</code>, the LLM returns the full summary only once the entire generation is complete. Users see no intermediate output and must wait 10&#8211;30 seconds with no feedback while the model works.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MVaW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MVaW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png 424w, https://substackcdn.com/image/fetch/$s_!MVaW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png 848w, https://substackcdn.com/image/fetch/$s_!MVaW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png 1272w, https://substackcdn.com/image/fetch/$s_!MVaW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MVaW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png" width="1434" height="692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:692,&quot;width&quot;:1434,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:183179,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MVaW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png 424w, https://substackcdn.com/image/fetch/$s_!MVaW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png 848w, https://substackcdn.com/image/fetch/$s_!MVaW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png 1272w, https://substackcdn.com/image/fetch/$s_!MVaW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9deaf-c1e8-40b2-a0a8-844d5ba6b5b5_1434x692.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>The streaming version uses <code>astream()</code> to yield tokens as they&#8217;re generated:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2L2K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2L2K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png 424w, https://substackcdn.com/image/fetch/$s_!2L2K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png 848w, https://substackcdn.com/image/fetch/$s_!2L2K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png 1272w, https://substackcdn.com/image/fetch/$s_!2L2K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2L2K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png" width="1434" height="902" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:902,&quot;width&quot;:1434,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:238869,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2L2K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png 424w, https://substackcdn.com/image/fetch/$s_!2L2K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png 848w, https://substackcdn.com/image/fetch/$s_!2L2K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png 1272w, https://substackcdn.com/image/fetch/$s_!2L2K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50c0722c-4438-43dd-ae26-b0414a54b3ac_1434x902.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>The user can progressively see the LLM output with this code:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!llQj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!llQj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png 424w, https://substackcdn.com/image/fetch/$s_!llQj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png 848w, https://substackcdn.com/image/fetch/$s_!llQj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png 1272w, https://substackcdn.com/image/fetch/$s_!llQj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!llQj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png" width="1266" height="818" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:818,&quot;width&quot;:1266,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:214993,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!llQj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png 424w, https://substackcdn.com/image/fetch/$s_!llQj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png 848w, https://substackcdn.com/image/fetch/$s_!llQj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png 1272w, https://substackcdn.com/image/fetch/$s_!llQj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d0b67fd-f8d0-4960-9be4-f51515a73d0d_1266x818.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>Output example:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!16hn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!16hn!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif 424w, https://substackcdn.com/image/fetch/$s_!16hn!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif 848w, https://substackcdn.com/image/fetch/$s_!16hn!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif 1272w, https://substackcdn.com/image/fetch/$s_!16hn!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!16hn!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif" width="800" height="319" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:319,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8135175,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!16hn!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif 424w, https://substackcdn.com/image/fetch/$s_!16hn!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif 848w, https://substackcdn.com/image/fetch/$s_!16hn!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif 1272w, https://substackcdn.com/image/fetch/$s_!16hn!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5e46e1-853e-4cd2-8fd7-1764d6550414_800x319.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Demo &#8212; Real-Time Token Streaming Output</figcaption></figure></div><h4><strong>2. Node-Level Streaming</strong></h4><p><strong>Key idea: </strong>It allows users to visualize state updates after each node completes, such as &#8220;Clarifier finished&#8221; or &#8220;Found 5 papers.&#8221; This is useful to show high-level progress through the agent pipeline and display intermediate results.</p><p><strong>Implementation: </strong>Without streaming, only final results are visible.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BOH4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BOH4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png 424w, https://substackcdn.com/image/fetch/$s_!BOH4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png 848w, https://substackcdn.com/image/fetch/$s_!BOH4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png 1272w, https://substackcdn.com/image/fetch/$s_!BOH4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BOH4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png" width="514" height="175.94615384615383" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:1040,&quot;resizeWidth&quot;:514,&quot;bytes&quot;:96359,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BOH4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png 424w, https://substackcdn.com/image/fetch/$s_!BOH4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png 848w, https://substackcdn.com/image/fetch/$s_!BOH4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png 1272w, https://substackcdn.com/image/fetch/$s_!BOH4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F992148ca-c8a5-4652-8c2a-720d224cf053_1040x356.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>There are no major code changes needed in the nodes themselves, as LangGraph automatically emits state updates when using <code>stream_mode=&#8221;updates&#8221;</code>:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!e5RX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!e5RX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png 424w, https://substackcdn.com/image/fetch/$s_!e5RX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png 848w, https://substackcdn.com/image/fetch/$s_!e5RX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png 1272w, https://substackcdn.com/image/fetch/$s_!e5RX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!e5RX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png" width="1456" height="835" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:835,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:342091,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!e5RX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png 424w, https://substackcdn.com/image/fetch/$s_!e5RX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png 848w, https://substackcdn.com/image/fetch/$s_!e5RX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png 1272w, https://substackcdn.com/image/fetch/$s_!e5RX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7801a73f-4e86-44d8-875d-491bf5d5f8e1_1940x1112.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>Output example:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yM7k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yM7k!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif 424w, https://substackcdn.com/image/fetch/$s_!yM7k!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif 848w, https://substackcdn.com/image/fetch/$s_!yM7k!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif 1272w, https://substackcdn.com/image/fetch/$s_!yM7k!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yM7k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif" width="800" height="518" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:518,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3029142,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yM7k!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif 424w, https://substackcdn.com/image/fetch/$s_!yM7k!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif 848w, https://substackcdn.com/image/fetch/$s_!yM7k!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif 1272w, https://substackcdn.com/image/fetch/$s_!yM7k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc664d1b4-fb4f-47a0-9be2-0338f546d1da_800x518.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Demo &#8212; Node-Level Streaming Execution</figcaption></figure></div><h4><strong>3. Custom Streaming</strong></h4><p><strong>Key idea: </strong>It displays custom progress messages during slow operations such as API calls (e.g., &#8220;Searching ArXiv...&#8221;, &#8220;Found paper 3/5&#8221;). This is particularly useful when a single node performs multiple steps or long-running API requests, allowing for more granular progress updates.</p><p><strong>Implementation: </strong>The original ArXiv search is a blocking step that provides no intermediate feedback while the query is being executed.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l0BE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l0BE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png 424w, https://substackcdn.com/image/fetch/$s_!l0BE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png 848w, https://substackcdn.com/image/fetch/$s_!l0BE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png 1272w, https://substackcdn.com/image/fetch/$s_!l0BE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l0BE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png" width="1282" height="734" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:734,&quot;width&quot;:1282,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:185568,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!l0BE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png 424w, https://substackcdn.com/image/fetch/$s_!l0BE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png 848w, https://substackcdn.com/image/fetch/$s_!l0BE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png 1272w, https://substackcdn.com/image/fetch/$s_!l0BE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F824759bb-7743-43cd-b9e9-0fb163877aef_1282x734.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>By adding <code>get_stream_writer()</code>, the agent can emit custom progress updates during execution.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!frN1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!frN1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png 424w, https://substackcdn.com/image/fetch/$s_!frN1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png 848w, https://substackcdn.com/image/fetch/$s_!frN1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png 1272w, https://substackcdn.com/image/fetch/$s_!frN1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!frN1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png" width="1456" height="1333" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1333,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:338285,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!frN1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png 424w, https://substackcdn.com/image/fetch/$s_!frN1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png 848w, https://substackcdn.com/image/fetch/$s_!frN1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png 1272w, https://substackcdn.com/image/fetch/$s_!frN1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1f6ca3b-2aa5-48e9-ab77-1d337a648679_1536x1406.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>This code allows users to see the custom progress updates implemented above.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dKDO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dKDO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png 424w, https://substackcdn.com/image/fetch/$s_!dKDO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png 848w, https://substackcdn.com/image/fetch/$s_!dKDO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png 1272w, https://substackcdn.com/image/fetch/$s_!dKDO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dKDO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png" width="520" height="246.91275167785236" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:566,&quot;width&quot;:1192,&quot;resizeWidth&quot;:520,&quot;bytes&quot;:149867,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dKDO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png 424w, https://substackcdn.com/image/fetch/$s_!dKDO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png 848w, https://substackcdn.com/image/fetch/$s_!dKDO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png 1272w, https://substackcdn.com/image/fetch/$s_!dKDO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c8aa771-096c-4e75-83f3-5cafdc422732_1192x566.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><h4><strong>Combining All Streaming Modes</strong></h4><p>LangGraph allows multiple streaming modes to be combined simultaneously for complete observability.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!h3e6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!h3e6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png 424w, https://substackcdn.com/image/fetch/$s_!h3e6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png 848w, https://substackcdn.com/image/fetch/$s_!h3e6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png 1272w, https://substackcdn.com/image/fetch/$s_!h3e6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!h3e6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png" width="1456" height="1713" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d514138a-1931-466a-8a40-321a6776345f_1838x2162.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1713,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:618275,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!h3e6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png 424w, https://substackcdn.com/image/fetch/$s_!h3e6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png 848w, https://substackcdn.com/image/fetch/$s_!h3e6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png 1272w, https://substackcdn.com/image/fetch/$s_!h3e6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd514138a-1931-466a-8a40-321a6776345f_1838x2162.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>Output example:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ujbd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ujbd!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif 424w, https://substackcdn.com/image/fetch/$s_!ujbd!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif 848w, https://substackcdn.com/image/fetch/$s_!ujbd!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif 1272w, https://substackcdn.com/image/fetch/$s_!ujbd!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ujbd!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif" width="800" height="526" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:526,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:9618157,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ujbd!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif 424w, https://substackcdn.com/image/fetch/$s_!ujbd!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif 848w, https://substackcdn.com/image/fetch/$s_!ujbd!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif 1272w, https://substackcdn.com/image/fetch/$s_!ujbd!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47feddde-3cea-46ff-a9e6-9619adb7550b_800x526.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Demo &#8212; Multi-Mode Streaming Execution</figcaption></figure></div><p><strong>LangGraph Streaming Modes: Quick Recap</strong></p><blockquote><p>LangGraph provides four streaming modes for different levels of visibility into your agent&#8217;s execution:</p><ul><li><p><code>&#8220;values&#8221;</code> streams the complete state after each node. It&#8217;s comprehensive but verbose as it shows everything, including unchanged fields.</p></li></ul><ul><li><p><code>&#8220;updates&#8221;</code> streams only what changed, returned as <code>{node_name: state_updates}</code> It&#8217;s the most efficient way to track pipeline progress without noise.</p></li><li><p><code>&#8220;messages&#8221;</code> streams individual LLM tokens as they&#8217;re generated for that typewriter effect. It requires <code>llm.astream()</code> in your nodes and returns <code>(message_chunk, metadata)</code> tuples.</p></li><li><p><code>&#8220;custom&#8221;</code> lets you emit your own progress signals via <code>get_stream_writer()</code> . It&#8217;s perfect for long-running operations like API calls where you want to show &#8220;Found paper 3/5&#8221; or similar updates.</p></li></ul><p>Combining modes with <code>stream_mode=[&#8221;updates&#8221;, &#8220;messages&#8221;, &#8220;custom&#8221;]</code> is the best way to get multi-level observability. Events then arrive as <code>(mode_name, data)</code> tuples.</p></blockquote><h2>2. Human-in-the-Loop: Intercepting and Modifying Agent Execution</h2><p>Streaming shows users <em>what</em> the agent is doing, but what if you want to let them actually <em>intervene</em>? What if the clarifier misinterprets the query, the researcher ranks irrelevant papers too highly, or you want users to manually approve expensive API calls before they run?</p><p>This is where LangGraph&#8217;s <strong>interrupt system</strong> turns agents from autonomous black boxes into <em>collaborative tools</em> that can pause mid-execution, wait for human input, and incorporate corrections before continuing.</p><p>Interrupts enable three essential capabilities:</p><ol><li><p><strong>Approval workflows:</strong> Pause before expensive or sensitive operations (like sending emails, making purchases, or calling paid APIs) and require explicit human confirmation to proceed.</p></li><li><p><strong>Edits and corrections:</strong> Stop execution when the agent generates intermediate results (refined queries, paper rankings, draft messages), let the user modify the state, then resume with the corrected inputs.</p></li><li><p><strong>Debugging and inspection:</strong> Freeze execution at specific nodes to inspect state, inject test data, or verify that complex logic behaves as intended before continuing.</p></li></ol><h3>2.1 How Does LangGraph Interrupt System Work?</h3><p>LangGraph provides two complementary ways to introduce controlled pauses during execution:</p><ol><li><p><strong>Graph-level interrupts:</strong> These let you designate specific nodes as pause points when building your workflow. Whenever execution reaches one of these points, the graph stops automatically. You can then review the intermediate state, make adjustments, and resume the workflow from the exact same spot.</p></li><li><p><strong>Node-level interrupts:</strong> These allow a node itself to request input mid-execution. The node temporarily hands control back to the user, waits for the missing information or correction, and then continues once the needed value is provided.</p></li></ol><p>In both cases, LangGraph relies on its checkpointer to capture the full execution state. This ensures the pause and the subsequent resume feel seamless and reliable.</p><p>In our scientific paper explorer, interrupts eliminate a classic frustration: watching the agent spend 30 seconds summarizing papers you already know are irrelevant just from reading their titles. Let&#8217;s implement human-in-the-loop controls at three strategic points in our pipeline.</p><h4><strong>1. Graph-Level Interrupts</strong></h4><p><strong>Key idea: </strong>This approach introduces explicit pause points directly in the graph definition. Execution automatically stops at these points, and interaction happens externally through <code>get_state()</code> and <code>update_state()</code>. It enables reviewing intermediate outputs, adjusting state based on observations, or inserting approval steps, all without modifying node logic.</p><p><strong>Implementation: </strong>The pattern looks like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZGBk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZGBk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png 424w, https://substackcdn.com/image/fetch/$s_!ZGBk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png 848w, https://substackcdn.com/image/fetch/$s_!ZGBk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png 1272w, https://substackcdn.com/image/fetch/$s_!ZGBk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZGBk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png" width="1400" height="1364" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1364,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:360751,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZGBk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png 424w, https://substackcdn.com/image/fetch/$s_!ZGBk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png 848w, https://substackcdn.com/image/fetch/$s_!ZGBk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png 1272w, https://substackcdn.com/image/fetch/$s_!ZGBk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdca8b43-31b3-4785-bc04-4c47584da86f_1400x1364.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>In the scientific paper explorer, cost awareness matters. Before the researcher begins querying the ArXiv API and generating expensive summaries, it can be useful to inspect the clarifier&#8217;s refined query. With breakpoints, the workflow pauses at that moment, allowing review or adjustment of the query before the agent continues.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rMRa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rMRa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png 424w, https://substackcdn.com/image/fetch/$s_!rMRa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png 848w, https://substackcdn.com/image/fetch/$s_!rMRa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png 1272w, https://substackcdn.com/image/fetch/$s_!rMRa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rMRa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png" width="1456" height="1889" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1889,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:733763,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rMRa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png 424w, https://substackcdn.com/image/fetch/$s_!rMRa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png 848w, https://substackcdn.com/image/fetch/$s_!rMRa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png 1272w, https://substackcdn.com/image/fetch/$s_!rMRa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F352eafa7-f8b4-44ed-bb6a-25494376b331_1990x2582.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>This example highlights how breakpoints work in practice:</p><ul><li><p>The graph is compiled with <code>interrupt_before=[&#8221;researcher&#8221;]</code> and <code>interrupt_after=[&#8221;clarifier&#8221;]</code>, causing execution to pause right after the clarifier and before any expensive API calls.</p></li><li><p>A <code>thread_id</code> in the <code>config</code> lets LangGraph store and retrieve the execution state via the checkpointer.</p></li><li><p>The first <code>graph.stream(...)</code> runs until an interrupt is reached, then stops.</p></li><li><p><code>graph.get_state(config)</code> retrieves the paused state (including the refined query).</p></li><li><p>You can modify this state with <code>graph.update_state(...)</code> or leave it unchanged.</p></li><li><p>Calling <code>graph.stream(None, config, ...)</code> resumes execution from the checkpoint using the updated state.</p></li></ul><p>This creates a tight approval loop that gives you control before costly steps execute.</p><h4><strong>2. Node-Level Interrupts</strong></h4><p><strong>Key idea: </strong>Graph-level interrupts are great when you can define fixed pause points ahead of time, but what if you want a more user-friendly way to request and handle user input directly within a node&#8217;s logic? What if a node needs to ask for input dynamically based on what it discovers at runtime? That&#8217;s where node-level interrupts shine.</p><p><strong>Implementation: </strong>Let&#8217;s create a dedicated approval node that pauses execution and requests a human decision:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fb44!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fb44!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png 424w, https://substackcdn.com/image/fetch/$s_!fb44!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png 848w, https://substackcdn.com/image/fetch/$s_!fb44!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png 1272w, https://substackcdn.com/image/fetch/$s_!fb44!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fb44!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png" width="1434" height="2750" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2750,&quot;width&quot;:1434,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:617888,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fb44!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png 424w, https://substackcdn.com/image/fetch/$s_!fb44!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png 848w, https://substackcdn.com/image/fetch/$s_!fb44!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png 1272w, https://substackcdn.com/image/fetch/$s_!fb44!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F172b2a76-c05f-49b7-b0e1-1ac1ef56edd4_1434x2750.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>Once the approver node is in place, you still need a conditional edge so that if approval is denied, the workflow routes directly to <strong>END</strong> instead of continuing through the remaining nodes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!S9ZA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!S9ZA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png 424w, https://substackcdn.com/image/fetch/$s_!S9ZA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png 848w, https://substackcdn.com/image/fetch/$s_!S9ZA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png 1272w, https://substackcdn.com/image/fetch/$s_!S9ZA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!S9ZA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png" width="1378" height="2246" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2246,&quot;width&quot;:1378,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:545564,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!S9ZA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png 424w, https://substackcdn.com/image/fetch/$s_!S9ZA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png 848w, https://substackcdn.com/image/fetch/$s_!S9ZA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png 1272w, https://substackcdn.com/image/fetch/$s_!S9ZA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0083e05c-3d7e-410b-877d-e830282fd9db_1378x2246.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>This modifies the structure of the agent graph: after adding the approver node, the workflow now branches based on the approval result, as shown below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xhCZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xhCZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png 424w, https://substackcdn.com/image/fetch/$s_!xhCZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png 848w, https://substackcdn.com/image/fetch/$s_!xhCZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png 1272w, https://substackcdn.com/image/fetch/$s_!xhCZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xhCZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png" width="304" height="570.727969348659" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:980,&quot;width&quot;:522,&quot;resizeWidth&quot;:304,&quot;bytes&quot;:49705,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xhCZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png 424w, https://substackcdn.com/image/fetch/$s_!xhCZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png 848w, https://substackcdn.com/image/fetch/$s_!xhCZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png 1272w, https://substackcdn.com/image/fetch/$s_!xhCZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62df9aff-db10-4440-802d-00c7ea7e9dbe_522x980.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Updated Agent Graph with Approval Gate: Conditional Routing Based on User Decision</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!W4rr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!W4rr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png 424w, https://substackcdn.com/image/fetch/$s_!W4rr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png 848w, https://substackcdn.com/image/fetch/$s_!W4rr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png 1272w, https://substackcdn.com/image/fetch/$s_!W4rr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!W4rr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png" width="1456" height="3094" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/32708317-43da-417b-82ab-e6febcd99542_1630x3464.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3094,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:899160,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!W4rr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png 424w, https://substackcdn.com/image/fetch/$s_!W4rr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png 848w, https://substackcdn.com/image/fetch/$s_!W4rr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png 1272w, https://substackcdn.com/image/fetch/$s_!W4rr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32708317-43da-417b-82ab-e6febcd99542_1630x3464.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>The example above shows how a node can pause itself, request user input, and continue with that input. Technically, this works as follows:</p><ul><li><p>The <code>interrupt()</code> call inside the approval node <strong>pauses execution at that exact line</strong> and stores the interrupt request in the checkpointer under the given <code>thread_id</code>.</p></li><li><p>The paused interrupt payload appears in <code>state.tasks</code>, which is why the code retrieves it to display the message to the user.</p></li><li><p>When the user responds, the value is passed back into the graph via <code>Command(resume=...)</code>, which <strong>feeds the response directly into the waiting node</strong>.</p></li><li><p>Execution then <strong>resumes right after the interrupt</strong>, and the node updates the state based on the user&#8217;s decision.</p></li><li><p>A conditional edge reads the <code>approved</code> flag to route the workflow either forward to the researcher or directly to <code>END</code>.</p></li></ul><p>This creates a fully interactive pause-and-resume node driven by user input.</p><h2>3. Time Travel: Rewinding and Replaying Agent Execution</h2><p>Interrupts let you pause and modify your agent&#8217;s future, but what if you need to change its <em>past</em>? What if you realize three nodes later that the clarifier&#8217;s query refinement was wrong, or you want to A/B test different researcher parameters without starting from scratch?</p><p>This is where LangGraph&#8217;s time-traveling features excel. Building on the same checkpointing system that enables memory and interrupts, time travel lets you rewind execution to any previous state, modify it, and create alternate execution branches, essentially giving you &#8220;undo&#8221; and &#8220;what-if&#8221; superpowers for your agent workflows.</p><p>Time travel serves three powerful use cases:</p><ol><li><p><strong>Rewinding mistakes</strong>: When you discover an error several steps deep (like a misunderstood query leading to irrelevant papers), jump back to that decision point, fix it, and re-run from there without losing subsequent work.</p></li><li><p><strong>A/B testing and experimentation</strong>: Fork execution at a checkpoint to try different parameters (e.g., &#8220;what if I used 10 papers instead of 5?&#8221;) and compare outcomes without re-running the entire pipeline.</p></li><li><p><strong>Debugging and root cause analysis</strong>: Step backward through execution history to pinpoint exactly where things went wrong, examining state at each checkpoint like a debugger&#8217;s stack trace.</p></li></ol><h3>3.1 How Does Time Travel Work in LangGraph?</h3><p>LangGraph&#8217;s time travel relies on the checkpointer, which doesn&#8217;t just store the <em>latest</em> state, but maintains a complete history of every state transition. Each checkpoint is identified by a unique ID, forming a branching tree of execution states. You can navigate this tree like Git commits: inspect any historical state, rewind to it, and optionally fork a new branch from that point.</p><p>The key methods are:</p><ul><li><p><code>graph.get_state_history(config)</code>: Retrieve all checkpoints for a thread, from newest to oldest</p></li><li><p><code>graph.get_state(config, checkpoint_id=id)</code>: Jump to a specific checkpoint</p></li><li><p><code>graph.update_state(config, values, as_node=&#8221;node_name&#8221;)</code>: Rewind to before a specific node and replay with modified state</p></li></ul><h4>Rewinding to Fix Mistakes</h4><p>Imagine you&#8217;ve run clarification, paper search, and scoring, only to realize during summarization that the query refinement missed the mark. Instead of starting over, rewind to the clarifier, fix it, and fast-forward:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BhOp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BhOp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png 424w, https://substackcdn.com/image/fetch/$s_!BhOp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png 848w, https://substackcdn.com/image/fetch/$s_!BhOp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png 1272w, https://substackcdn.com/image/fetch/$s_!BhOp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BhOp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png" width="1456" height="2767" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2767,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:806658,&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://aipractitioner.substack.com/i/179174512?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BhOp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png 424w, https://substackcdn.com/image/fetch/$s_!BhOp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png 848w, https://substackcdn.com/image/fetch/$s_!BhOp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png 1272w, https://substackcdn.com/image/fetch/$s_!BhOp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41e71f37-de32-4a31-b93e-377cdbbc3788_1602x3044.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>Time travel is possible because of three core mechanisms:</p><ol><li><p><strong>State is saved after every node:</strong> Each node execution produces a new state snapshot stored in the checkpointer with a unique identifier.</p></li><li><p><strong>Checkpoints form a branching tree:</strong> Editing a past checkpoint and resuming execution creates a new branch, leaving the original path untouched.</p></li><li><p><strong>The </strong><code>as_node</code><strong> parameter is crucial:</strong> It instructs LangGraph to <em>treat the checkpoint as if a specific node just executed</em>, effectively rewinding the graph to that point.</p></li></ol><pre><code><code>Initial run:
  start &#8594; clarifier &#8594; researcher &#8594; summarizer &#10003;

After rewind with as_node=&#8221;clarifier&#8221;:
  start &#8594; clarifier &#9472;&#9516;&#8594; researcher (old) &#8594; summarizer (old)
                     &#9492;&#8594; researcher (new) &#8594; summarizer (new) &#10003;
</code></code></pre><p>The original branch remains intact in the history; modifying a checkpoint simply creates an alternate timeline.</p><h4>Creating Parallel Branches for A/B Testing</h4><p>Time travel goes far beyond simple corrections, it enables creating multiple branches from the same checkpoint, allowing different approaches to be compared without repeating costly steps.</p><p>For example, suppose you want to test whether fetching 5 papers or 10 papers yields better summaries. Instead of running the clarifier twice (an expensive LLM call), run it once, then fork two branches from that checkpoint with different <code>max_papers</code> values. Both branches reuse the clarifier&#8217;s output and diverge only at the researcher node, enabling an efficient A/B test while paying the clarification cost only once.</p><p>By assigning different <code>thread_id</code> values to each branch, you maintain fully independent execution paths that can be evaluated side by side.</p><pre><code><code>Initial run (thread: base):
  start &#8594; clarifier &#8594; researcher(5) &#8594; summarizer &#10003;

After creating branches:
  start &#8594; clarifier &#9472;&#9516;&#8594; [thread: base]     researcher(5)  &#8594; summarizer
                     &#9500;&#8594; [thread: branch-a] researcher(5)  &#8594; summarizer  
                     &#9492;&#8594; [thread: branch-b] researcher(10) &#8594; summarizer
All three branches share the clarifier checkpoint but diverge afterward.
</code></code></pre><p>With time travel, your agent becomes fully explorable and correctable. You can undo mistakes without re-running expensive operations, compare alternative execution paths side-by-side, and debug complex workflows by stepping through history like a version control system. It&#8217;s the ultimate safety net for production AI agents&#8212;and the foundation for letting humans collaborate with agents iteratively rather than hoping they get it right on the first try.</p><div><hr></div><h1>Key Takeaways</h1><p>&#10003; <strong>Streaming provides three complementary layers of agent observability</strong>: Token-level streaming reveals LLM generation as it happens, node-level streaming exposes state transitions between workflow steps, and custom streaming surfaces progress during long-running operations. Together, they transform opaque agents into transparent, debuggable systems.</p><p>&#10003; <strong>Human-in-the-loop patterns balance automation with control through strategic pause points</strong>: Graph-level interrupts halt execution at predefined nodes for review and approval, while node-level interrupts allow dynamic requests for human input mid-execution. Both maintain full context through checkpointing, enabling seamless resume without data loss.</p><p>&#10003; <strong>Time travel enables non-destructive experimentation and error recovery</strong>: Checkpointers create a complete execution history where any prior state can be inspected, modified, and replayed. Mistakes become fixable through rewinding rather than restarting, and parallel branches allow A/B testing without duplicating expensive operations.</p><div><hr></div><h1>References</h1><p>[1] LangChain Documentation. (2025). <a href="https://langchain-ai.github.io/langgraph/concepts/streaming/">LangGraph: Streaming modes for real-time agent observability</a>. </p><p>[2] LangChain Documentation. (2025). <a href="https://langchain-ai.github.io/langgraph/concepts/human_in_the_loop/">LangGraph: Human-in-the-loop with interrupts and breakpoints</a>. </p><p>[3] LangChain Documentation. (2025). <a href="https://langchain-ai.github.io/langgraph/concepts/persistence/">LangGraph: Persistence and checkpointers for stateful agents</a>. </p><p>[4] LangChain Documentation. (2025). <a href="https://langchain-ai.github.io/langgraph/how-tos/time-travel/">LangGraph: Time travel and state history navigation</a>. </p><p>[5] OpenAI Documentation. (2025). <a href="https://platform.openai.com/docs/api-reference/streaming">Streaming completions with Server-Sent Events</a>. </p><p>[6] arXiv Documentation. (2025). <a href="https://info.arxiv.org/help/api/user-manual.html">arXiv API User&#8217;s Manual: Query interface and metadata retrieval</a>. </p><p>[7] LangSmith Documentation. (2025). <a href="https://docs.smith.langchain.com/">LangSmith: Tracing and debugging LangGraph workflows</a>. </p><p></p><h1><br></h1><p></p>]]></content:encoded></item><item><title><![CDATA[Beyond the Demo: Building AI Agents Remember, Recover, and Scale (Part 2)]]></title><description><![CDATA[A Practical Guide to Reducers, Memory Systems, and Checkpointers in Langgraph for Production-Grade Agents]]></description><link>https://aipractitioner.substack.com/p/beyond-the-demo-building-ai-agents</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/beyond-the-demo-building-ai-agents</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 06 Nov 2025 14:20:18 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!PTp4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PTp4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PTp4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png 424w, https://substackcdn.com/image/fetch/$s_!PTp4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png 848w, https://substackcdn.com/image/fetch/$s_!PTp4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!PTp4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PTp4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png" width="1456" height="604" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:604,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:958993,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PTp4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png 424w, https://substackcdn.com/image/fetch/$s_!PTp4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png 848w, https://substackcdn.com/image/fetch/$s_!PTp4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!PTp4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3fdab87-e179-4cba-8594-41ae6486ba3c_2926x1214.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This article is also available as a podcast! If you&#8217;re on the go or just want to absorb the content in audio format, you can listen to the full episode below &#128071; The podcast is also available on <a href="https://open.spotify.com/show/6MROBKvrjx0Mey8tHud5LX">Spotify</a> and <a href="https://podcasts.apple.com/us/podcast/the-ai-practitioner-podcast/id1830285899">Apple Podcasts</a>.</em></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;e87b26c7-d27a-4790-8c34-1ac8c9c20b88&quot;,&quot;caption&quot;:&quot;Prefer reading instead? The full article is available here.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;PODCAST &#8212; Beyond the Demo: Building AI Agents Remember, Recover, and Scale (Part 2)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:7177021,&quot;name&quot;:&quot;Lina Faik&quot;,&quot;bio&quot;:&quot;Lead AI Scientist bringing AI research to real-world impact across industries. Founder, Data Impulse | Author, The AI Practitioner | ex-Dataiku&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bdaf5e6-a6c6-48fe-80f6-3d69aaac1694_2256x2256.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-06T14:18:53.332Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d7bf46e4-7e23-42e0-a41a-788e95d27dfb_1456x604.webp&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://aipractitioner.substack.com/p/podcast-beyond-the-demo-building&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:177969197,&quot;type&quot;:&quot;podcast&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4815372,&quot;publication_name&quot;:&quot;The AI Practitioner&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ivps!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>Building a demo agent is easy. Chain a few LLM calls, add some tools, and watch it work. But as your agent grows more capable, it becomes more fragile. More steps mean more failure points. More state means more memory pressure. More iterations mean higher costs from redundant work.</p><p><strong>This is the paradox of agentic complexity: the more powerful your agent, the more likely it can fail catastrophically.</strong></p><p>The gap between prototype and production is persistence. Without it, agents remain fragile toys, impressive in demos, unreliable in reality. To bridge this gap, three core mechanisms bring production-grade durability to AI systems:</p><ul><li><p><strong>Reducers and caching</strong> to optimize state updates and skip redundant computation</p></li><li><p><strong>Persistence and memory</strong> to preserve context across sessions</p></li><li><p><strong>Checkpointers</strong> to recover from interruptions without losing progress</p></li></ul><p>Reducers keep state manageable as workflows lengthen. Memory prevents exponential cost growth. Persistence scales with complexity. Together, they turn fragile reasoning graphs into robust, resumable intelligence pipelines.</p><p><strong>The result: agents where capability and reliability grow together, not inversely.</strong></p><h3>Objective</h3><p>This article focuses on implementing persistence mechanisms in LangGraph, from basic memory to advanced checkpointing, to build agents that remember context, optimize computation, and survive failures.</p><p>After reading this article, you will understand:</p><ol><li><p><strong>How to optimize state with reducers and caching</strong> &#8212; managing growing state efficiently through composable update functions and skipping expensive recomputation through intelligent caching strategies.</p></li><li><p><strong>How to implement persistence and memory</strong> &#8212; maintaining state across sessions, preserving conversation history, and ensuring agents remember what they&#8217;ve already done to avoid redundant work</p></li><li><p><strong>How to build fault-tolerant systems with checkpointers</strong> &#8212; saving state at every step, resuming execution from any point, and recovering gracefully from failures without losing progress</p></li></ol><blockquote><p><strong>Context:</strong> This article is Part 2 of a series on building production-grade agents with LangGraph. Future articles will explore advanced multi-agent orchestration patterns, deployment strategies, and scaling considerations for complex agentic systems.</p><p><strong>Prerequisites:</strong> Basic knowledge of Python, LLMs, and prompt engineering is recommended. Readers should either be familiar with LangChain concepts (chains, models, prompts) or have read <a href="https://aipractitioner.substack.com/p/from-chains-to-graphs-smarter-and">Part 1</a> of this series (or listen the <a href="https://aipractitioner.substack.com/p/podcast-from-chains-to-graphs-smarter">podcast edition</a>) to understand the foundations of LangGraph&#8217;s graph, node, and state model.</p><p><strong>Tools &amp; libraries:</strong> <a href="https://www.langchain.com/langgraph">LangGraph</a>, <a href="https://www.langchain.com/">LangChain</a>, <a href="https://www.langchain.com/langsmith/observability">LangSmith</a>, <a href="https://openai.com/">OpenAI</a>, <a href="https://info.arxiv.org/help/api/index.html">arXiv API</a></p></blockquote><p>You can find the code here on <a href="https://github.com/linafaik08/scientific-graph-agent">GitHub</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>1. Reducers &amp; Cache: Doing More with Less</h2><p>Every interaction with your agent adds weight to its state. Messages accumulate. Retrieved documents pile up. Tool outputs compound. Without management, a research agent handling several queries consumes megabytes of context, triggers token limit errors, and starts lagging.</p><p><strong>The solution isn&#8217;t storing less, it&#8217;s storing smarter.</strong></p><p>Two mechanisms help overcome this issue:</p><ul><li><p><strong>Reducers</strong> trim state growth by keeping only what matters.</p></li><li><p><strong>Caches</strong> that skip redundant computation.</p></li></ul><p>Used together, they turn memory from a liability into an asset that scales efficiently with your agent&#8217;s complexity.</p><h3>1.1 How Do States Get Updated?</h3><p>Let&#8217;s revisit the scientific paper explorer from <a href="https://aipractitioner.substack.com/p/from-chains-to-graphs-smarter-and">Part 1</a>. This agent consists of three specialized nodes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lv89!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lv89!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 424w, https://substackcdn.com/image/fetch/$s_!lv89!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 848w, https://substackcdn.com/image/fetch/$s_!lv89!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 1272w, https://substackcdn.com/image/fetch/$s_!lv89!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lv89!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png" width="534" height="428.4845360824742" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:934,&quot;width&quot;:1164,&quot;resizeWidth&quot;:534,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lv89!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 424w, https://substackcdn.com/image/fetch/$s_!lv89!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 848w, https://substackcdn.com/image/fetch/$s_!lv89!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 1272w, https://substackcdn.com/image/fetch/$s_!lv89!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Graph-Based Research Agent Architecture</figcaption></figure></div><p>The graph includes <strong>intelligent retry logic</strong>: if fewer than 3 papers are found, it automatically loops back to search again (up to a configurable max iteration limit).</p><p>Here&#8217;s the state definition:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k3Py!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k3Py!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png 424w, https://substackcdn.com/image/fetch/$s_!k3Py!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png 848w, https://substackcdn.com/image/fetch/$s_!k3Py!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png 1272w, https://substackcdn.com/image/fetch/$s_!k3Py!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k3Py!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png" width="1456" height="549" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:549,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:177190,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!k3Py!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png 424w, https://substackcdn.com/image/fetch/$s_!k3Py!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png 848w, https://substackcdn.com/image/fetch/$s_!k3Py!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png 1272w, https://substackcdn.com/image/fetch/$s_!k3Py!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9b3c1f0-5654-49f7-8c45-a4205fbc5916_1502x566.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>Most fields are straightforward (<code>str</code>, <code>int</code>, <code>List[dict]</code>), but <code>messages</code> includes something special: <code>Annotated[List[BaseMessage], add]</code>. That little annotation changes everything; it defines how state updates behave.</p><p><strong>The Default: Complete Replacement</strong></p><ul><li><p>By default, LangGraph replaces values when updating state. </p></li><li><p>This is perfect for scalar fields like <code>query</code> or <code>summary</code>: as one would only need the latest version. </p></li><li><p>But for collections like <code>messages</code> or <code>papers</code>, replacement is disastrous. Each node would overwrite prior data, erasing the conversation history, previous research results, or user inputs. The agent would lose its memory every time it updates.</p></li></ul><p><strong>The Alternative: Reducers</strong></p><ul><li><p>Reducers are functions that control accumulation, deduplication, or any other merge logic.</p></li><li><p>In the scientific agent example: <code>messages: Annotated[List[BaseMessage], add]</code>tells LangGraph: &#8220;When updating <code>messages</code>, don&#8217;t replace. Use the <code>add</code> function to combine old and new values.&#8221;</p></li><li><p>The <code>add</code> operator (from Python&#8217;s <code>operator</code> module) concatenates lists, allowing the conversation to build naturally.</p></li></ul><h3>1.2 How Do Reducers Control Memory Growth?</h3><p>Preserving history is good, but endless accumulation is not. As an agent reviews more papers, each interaction adds new messages until memory overflows. Context length explodes, inference slows, and token costs rise. This is where reducers shine: they can control how memory grows, not just preserve it.</p><p>Let&#8217;s explore three frequently used reduction strategies:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MwWC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MwWC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png 424w, https://substackcdn.com/image/fetch/$s_!MwWC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png 848w, https://substackcdn.com/image/fetch/$s_!MwWC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png 1272w, https://substackcdn.com/image/fetch/$s_!MwWC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MwWC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png" width="508" height="446.9423076923077" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1281,&quot;width&quot;:1456,&quot;resizeWidth&quot;:508,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MwWC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png 424w, https://substackcdn.com/image/fetch/$s_!MwWC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png 848w, https://substackcdn.com/image/fetch/$s_!MwWC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png 1272w, https://substackcdn.com/image/fetch/$s_!MwWC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F867c52a4-448e-4c9e-a2c4-9aed0d6a53d5_1800x1584.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Reducer Patterns for Memory Control</figcaption></figure></div><ol><li><p><strong>Truncation Reducers</strong></p><p>This is typically used when only recent context matters and historical data becomes irrelevant. For instance, a real-time monitoring agent tracking system errors only needs the last 20 events. Last week&#8217;s logs don&#8217;t inform today&#8217;s diagnosis.<br><strong>Trade-offs:</strong></p><p>&#9989; Simple and predictable memory footprint.</p><p>&#10060; The agent completely forgets history, losing the ability to reference or learn from past patterns beyond your window size.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GMqN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GMqN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png 424w, https://substackcdn.com/image/fetch/$s_!GMqN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png 848w, https://substackcdn.com/image/fetch/$s_!GMqN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png 1272w, https://substackcdn.com/image/fetch/$s_!GMqN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GMqN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png" width="1456" height="452" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:452,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:158066,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GMqN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png 424w, https://substackcdn.com/image/fetch/$s_!GMqN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png 848w, https://substackcdn.com/image/fetch/$s_!GMqN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png 1272w, https://substackcdn.com/image/fetch/$s_!GMqN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3487f0a7-0f34-42ef-a776-24d68d45a407_1688x524.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div></li><li><p><strong>Selective Retention</strong></p><p>This is ideal when you&#8217;re collecting data with varying quality and only want to keep the best items. Think of a research agent that finds 50 papers but only needs the 10 most relevant ones. Instead of keeping everything, only the most valuable is preserved. <br><strong>Trade-offs:</strong><br>&#9989; Maintains bounded memory while keeping the highest-quality information. <br>&#10060; Requires domain-specific logic to define &#8220;quality, with the risk of permanently losing items that seem low-value now but could be relevant later.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FfV-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FfV-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png 424w, https://substackcdn.com/image/fetch/$s_!FfV-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png 848w, https://substackcdn.com/image/fetch/$s_!FfV-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png 1272w, https://substackcdn.com/image/fetch/$s_!FfV-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FfV-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png" width="1456" height="1008" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1008,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:346554,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FfV-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png 424w, https://substackcdn.com/image/fetch/$s_!FfV-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png 848w, https://substackcdn.com/image/fetch/$s_!FfV-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png 1272w, https://substackcdn.com/image/fetch/$s_!FfV-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc91825a2-fe13-4777-9e02-3be0d4c16593_1788x1238.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div></li><li><p><strong>Summarization Reducers</strong></p><p>This is perfect when context is valuable but verbosity isn&#8217;t. For instance, a research agent should remember what papers it&#8217;s seen and why, but doesn&#8217;t need the full back-and-forth discussion. Summarization compresses old context while preserving recent details.</p><p><strong>Trade-offs:</strong></p><p>&#9989; Balances memory efficiency with context preservation.</p><p>&#10060; Loses fine-grained details in compressed sections, and summarization itself costs tokens (though far fewer than keeping everything)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k2P4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k2P4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png 424w, https://substackcdn.com/image/fetch/$s_!k2P4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png 848w, https://substackcdn.com/image/fetch/$s_!k2P4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png 1272w, https://substackcdn.com/image/fetch/$s_!k2P4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k2P4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png" width="1456" height="1658" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1658,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:516265,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!k2P4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png 424w, https://substackcdn.com/image/fetch/$s_!k2P4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png 848w, https://substackcdn.com/image/fetch/$s_!k2P4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png 1272w, https://substackcdn.com/image/fetch/$s_!k2P4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0be04af1-1566-4d41-867d-6eaedf510590_1788x2036.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><blockquote><p>For the paper explorer, selective retention works best for papers while summarization makes the most sense for messages. This hybrid approach ensures both bounded memory and preserved context where it matters. You can find the complete implementation in the <a href="https://github.com/linafaik08/scientific-graph-agent">GitHub</a> repository.</p></blockquote></li></ol><h3>1.3 How Does Cache Avoid Redundant LLM Calls?</h3><p>Reducers solve memory growth, but there&#8217;s a complementary problem: computational waste. Agents often repeat the same operations, re-ranking identical papers, re-answering similar questions, and re-processing unchanged inputs. Every repetition burns tokens and time.</p><p><strong>Caching captures the results of expensive operations and reuses them when inputs match.</strong> </p><p>For the paper explorer, this means massive savings:</p><ul><li><p><strong>Clarifying similar queries:</strong> With a semantic cache, the agent would be able to return the same refined query with limited costs for queries similar to &#8220;Tell me about transformers&#8221; like &#8220;Explain transformer models&#8221;. </p></li><li><p><strong>Ranking papers:</strong> The cache would return stored relevance scores without re-evaluation for the same paper IDs and queries.</p></li><li><p><strong>Summarizing papers:</strong> The cache would return the existing summary for already parsed papers.</p></li></ul><p><strong>Semantic vs. Exact Caching</strong></p><ul><li><p><strong>Exact caching</strong> matches inputs byte-for-byte. It&#8217;s fast and reliable but brittle. Examples of mismatches:</p><ul><li><p>&#8220;Summarize this paper&#8221;</p></li><li><p>&#8220;Summarize this paper.&#8221; # extra period</p></li><li><p>&#8220; Summarize this paper&#8221; # extra space</p></li></ul></li><li><p><strong>Semantic caching</strong> matches inputs by meaning (for example, using embeddings and cosine similarity). Slightly slower to determine equivalence but far more robust for natural-language variants.  Examples of matches:</p><ul><li><p>&#8220;What are transformers in NLP?&#8221;</p></li><li><p>&#8220;Explain transformer architectures for natural language&#8221;</p></li><li><p>&#8220;Tell me about attention mechanisms in language models&#8221;</p></li></ul></li></ul><p><strong>Inside the Cache</strong></p><p>LangChain provides built-in caching at the LLM level through cache backends. When you make an LLM call, LangChain:</p><ol><li><p>Generates a cache key from the prompt, model parameters, and model name</p></li><li><p>Checks the cache for an existing result</p></li><li><p>Returns cached response if found, or calls the LLM and stores the result</p></li></ol><p>This process runs seamlessly under the hood, requiring no code modifications.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0t1H!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0t1H!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png 424w, https://substackcdn.com/image/fetch/$s_!0t1H!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png 848w, https://substackcdn.com/image/fetch/$s_!0t1H!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png 1272w, https://substackcdn.com/image/fetch/$s_!0t1H!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0t1H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png" width="444" height="385.0846153846154" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:902,&quot;width&quot;:1040,&quot;resizeWidth&quot;:444,&quot;bytes&quot;:199405,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0t1H!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png 424w, https://substackcdn.com/image/fetch/$s_!0t1H!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png 848w, https://substackcdn.com/image/fetch/$s_!0t1H!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png 1272w, https://substackcdn.com/image/fetch/$s_!0t1H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a42d69-578c-4f1b-8fd8-730683d3e593_1040x902.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>LangChain offers several cache backends, each with different tradeoffs in persistence, scalability, and setup complexity.</p><ol><li><p>In-memory cache (development)</p></li><li><p>SQLite cache (persistent, local)</p></li><li><p>Redis cache (production-ready)</p></li></ol><p><strong>1. In-Memory Cache (Development)</strong></p><p>It&#8217;s a cache that lives in RAM. It&#8217;s fast and simple to add, but everything vanishes when the app stops.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2HR4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2HR4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png 424w, https://substackcdn.com/image/fetch/$s_!2HR4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png 848w, https://substackcdn.com/image/fetch/$s_!2HR4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png 1272w, https://substackcdn.com/image/fetch/$s_!2HR4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2HR4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png" width="444" height="169.91538461538462" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:398,&quot;width&quot;:1040,&quot;resizeWidth&quot;:444,&quot;bytes&quot;:97624,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2HR4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png 424w, https://substackcdn.com/image/fetch/$s_!2HR4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png 848w, https://substackcdn.com/image/fetch/$s_!2HR4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png 1272w, https://substackcdn.com/image/fetch/$s_!2HR4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec38c1a-dbe3-4902-8896-c1442be9b879_1040x398.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>2. SQLite Cache (Persistent, Single-Instance)</strong></p><p>It&#8217;s a local database-backed cache that survives restarts. It&#8217;s perfect for single-instance tools.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yXDN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yXDN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png 424w, https://substackcdn.com/image/fetch/$s_!yXDN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png 848w, https://substackcdn.com/image/fetch/$s_!yXDN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png 1272w, https://substackcdn.com/image/fetch/$s_!yXDN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yXDN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png" width="540" height="179.3989983305509" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:398,&quot;width&quot;:1198,&quot;resizeWidth&quot;:540,&quot;bytes&quot;:107758,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yXDN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png 424w, https://substackcdn.com/image/fetch/$s_!yXDN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png 848w, https://substackcdn.com/image/fetch/$s_!yXDN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png 1272w, https://substackcdn.com/image/fetch/$s_!yXDN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eef2d89-603a-4afb-a4f3-93968a4fa2b8_1198x398.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>3. Redis Cache (Production, Distributed)</strong></p><p>It&#8217;s a distributed cache backed by Redis. It&#8217;s fast, concurrent, and shareable across servers.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GIWq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GIWq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png 424w, https://substackcdn.com/image/fetch/$s_!GIWq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png 848w, https://substackcdn.com/image/fetch/$s_!GIWq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png 1272w, https://substackcdn.com/image/fetch/$s_!GIWq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GIWq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png" width="470" height="217.82692307692307" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:482,&quot;width&quot;:1040,&quot;resizeWidth&quot;:470,&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="https://substackcdn.com/image/fetch/$s_!GIWq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png 424w, https://substackcdn.com/image/fetch/$s_!GIWq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png 848w, https://substackcdn.com/image/fetch/$s_!GIWq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png 1272w, https://substackcdn.com/image/fetch/$s_!GIWq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79512a7e-cf28-4127-9654-95825c1f7389_1040x482.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>For the paper explorer example, SQLite is a good starting point for development. When deploying multiple instances or sharing cache across users, Redis would be more appropriate.</p><p><strong>Semantic Caching in LangChain</strong></p><p>For semantic similarity matching, LangChain offers specialized cache implementations:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8I9N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8I9N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png 424w, https://substackcdn.com/image/fetch/$s_!8I9N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png 848w, https://substackcdn.com/image/fetch/$s_!8I9N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png 1272w, https://substackcdn.com/image/fetch/$s_!8I9N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8I9N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png" width="542" height="294.0734557595993" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/badc93ad-159b-4169-bf78-401224cd43de_1198x650.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:650,&quot;width&quot;:1198,&quot;resizeWidth&quot;:542,&quot;bytes&quot;:157009,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8I9N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png 424w, https://substackcdn.com/image/fetch/$s_!8I9N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png 848w, https://substackcdn.com/image/fetch/$s_!8I9N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png 1272w, https://substackcdn.com/image/fetch/$s_!8I9N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbadc93ad-159b-4169-bf78-401224cd43de_1198x650.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>When a query comes in, LangChain:</p><ol><li><p>Embeds the prompt using your chosen embedding model</p></li><li><p>Searches cached embeddings via vector similarity</p></li><li><p>Returns cached response if similarity exceeds the threshold</p></li><li><p>Stores new embedding and response if cache miss</p></li></ol><blockquote><p>Note: LangChain doesn&#8217;t provide built-in in-memory or SQLite semantic caches, but it can easily be implemented.</p></blockquote><h2>2. Persistent Dialogues: Threads, State, and Sessions</h2><p>Reducers and caches optimize individual state updates and computations. But production agents need something more: <strong>the ability to maintain coherent conversations across multiple interactions.</strong></p><p>When a user asks &#8220;What papers did you find?&#8221; then follows up with &#8220;Summarize the third one,&#8221; the agent needs to know which papers were retrieved and which one is &#8220;the third.&#8221; When a conversation crashes mid-analysis, the user shouldn&#8217;t have to start over. When multiple users interact with the same agent simultaneously, their conversations must remain separate and private.</p><p><strong>This is conversation continuity:</strong> the infrastructure that transforms stateless LLM calls into stateful dialogue systems.</p><h3>2.1 How Do Thread IDs Isolate Conversations?</h3><p>Every conversation needs an identity. In LangGraph, this identity is the <strong>thread ID,</strong> a unique identifier that isolates one conversation from another.</p><p>Think of threads like separate browser tabs. Each tab maintains its own history, state, and context. Actions in one tab don&#8217;t affect others. The same principle applies to agent conversations:</p><ul><li><p><strong>User A</strong> (thread: <code>user_a_session_123</code>) asks about quantum computing papers</p></li><li><p><strong>User B</strong> (thread: <code>user_b_session_456</code>) asks about climate change research</p></li><li><p>Both conversations run independently, never mixing context or state</p></li></ul><p><strong>Implementation is simple:</strong> Pass a thread ID in your configuration when invoking the graph.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fjTF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fjTF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png 424w, https://substackcdn.com/image/fetch/$s_!fjTF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png 848w, https://substackcdn.com/image/fetch/$s_!fjTF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png 1272w, https://substackcdn.com/image/fetch/$s_!fjTF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fjTF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png" width="1456" height="669" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:669,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:261319,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fjTF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png 424w, https://substackcdn.com/image/fetch/$s_!fjTF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png 848w, https://substackcdn.com/image/fetch/$s_!fjTF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png 1272w, https://substackcdn.com/image/fetch/$s_!fjTF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e77b0b-5b2b-489e-a8fc-eca2b09148fb_1688x776.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>What the thread ID enables:</strong></p><ul><li><p><strong>Isolation:</strong> Each conversation maintains separate state, messages, and context.</p></li><li><p><strong>Persistence:</strong> State survives between invocations, users can leave and return hours later.</p></li><li><p><strong>Continuity:</strong> Follow-up questions reference earlier messages without explicit context passing.</p></li><li><p><strong>Concurrency:</strong> Multiple conversations run simultaneously without interference.</p></li></ul><p><strong>Real-world thread ID patterns:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yBvI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yBvI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png 424w, https://substackcdn.com/image/fetch/$s_!yBvI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png 848w, https://substackcdn.com/image/fetch/$s_!yBvI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png 1272w, https://substackcdn.com/image/fetch/$s_!yBvI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yBvI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png" width="524" height="254.79725085910653" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:566,&quot;width&quot;:1164,&quot;resizeWidth&quot;:524,&quot;bytes&quot;:136514,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yBvI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png 424w, https://substackcdn.com/image/fetch/$s_!yBvI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png 848w, https://substackcdn.com/image/fetch/$s_!yBvI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png 1272w, https://substackcdn.com/image/fetch/$s_!yBvI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2efdd724-80dc-4e43-9381-9e70545906a3_1164x566.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>The thread ID doesn&#8217;t just label conversations. It&#8217;s the key that unlocks every checkpoint, message, and piece of state associated with that dialogue.</p><h3>2.2 How To Define An Efficient State Schema Design?</h3><p>Not all states should be visible everywhere. The paper explorer might track internal ranking scores, API rate limits, or retry counts, information crucial for workflow logic but irrelevant to the final output. Exposing everything creates noise. Hiding everything blocks debugging.</p><p><strong>LangGraph provides three schema patterns to control state visibility:</strong></p><ol><li><p>Public state</p></li><li><p>Private state</p></li></ol><p><strong>1. Public State: The Default</strong></p><p>This consists of designing a single schema shared across all nodes and exposed as both input and output. Every node sees and can modify every field. The entire state is returned as output. Simple, but sometimes too simple.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Cizq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Cizq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png 424w, https://substackcdn.com/image/fetch/$s_!Cizq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png 848w, https://substackcdn.com/image/fetch/$s_!Cizq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png 1272w, https://substackcdn.com/image/fetch/$s_!Cizq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Cizq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png" width="1456" height="886" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:886,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:297395,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Cizq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png 424w, https://substackcdn.com/image/fetch/$s_!Cizq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png 848w, https://substackcdn.com/image/fetch/$s_!Cizq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png 1272w, https://substackcdn.com/image/fetch/$s_!Cizq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4017aed-809c-4231-a9e8-9a8bb1460d35_1620x986.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>2. Private State: Node-to-Node Secrets</strong></p><p>Sometimes nodes need to exchange information that shouldn&#8217;t pollute the main schema. Consider the paper explorer workflow:</p><ul><li><p><strong>Clarifier Node:</strong> This node generates an optimized ArXiv search query (<code>refined_query</code>) which is just a technical transformation. For instance, users don&#8217;t need to see &#8220;transformer attention mechanism&#8221; when they ask &#8220;how do transformers work?&#8221;</p></li><li><p><strong>Researcher Node:</strong> This node uses the refined query to search, then immediately discards it as the papers are what really matter.</p></li><li><p><strong>Summarizer Node:</strong> This node only needs the final ranked papers, not the search query that found them</p></li></ul><p><strong>Private state lets nodes pass ephemeral working data without exposing it in the final output.</strong></p><p>Let&#8217;s build this concept step by step using a paper search workflow.</p><ul><li><p><strong>Step 1: Define Your Public Interface</strong></p><p>Start by defining what users provide and what they receive:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GMAG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GMAG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png 424w, https://substackcdn.com/image/fetch/$s_!GMAG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png 848w, https://substackcdn.com/image/fetch/$s_!GMAG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png 1272w, https://substackcdn.com/image/fetch/$s_!GMAG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GMAG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png" width="1456" height="702" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:702,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:323248,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GMAG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png 424w, https://substackcdn.com/image/fetch/$s_!GMAG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png 848w, https://substackcdn.com/image/fetch/$s_!GMAG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png 1272w, https://substackcdn.com/image/fetch/$s_!GMAG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17d2431c-4a3e-4965-b8e4-9aef9c74a205_1958x944.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>Key insight: Notice what&#8217;s <em>not</em> here: no internal counters, no refined queries, no technical scaffolding. Just the essentials.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ax5F!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ax5F!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png 424w, https://substackcdn.com/image/fetch/$s_!Ax5F!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png 848w, https://substackcdn.com/image/fetch/$s_!Ax5F!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png 1272w, https://substackcdn.com/image/fetch/$s_!Ax5F!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ax5F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png" width="1418" height="692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:692,&quot;width&quot;:1418,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:193940,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Ax5F!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png 424w, https://substackcdn.com/image/fetch/$s_!Ax5F!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png 848w, https://substackcdn.com/image/fetch/$s_!Ax5F!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png 1272w, https://substackcdn.com/image/fetch/$s_!Ax5F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc160b042-0d73-4907-b9e0-b57772ed75b7_1418x692.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>Think of <code>InternalState</code> as a &#8220;kitchen workspace&#8221;, it contains both the ingredients (input), the final dish (output), <em>and</em> all the prep bowls and measuring cups (internal fields).</p></li><li><p><strong>Step 2: Build Your Nodes</strong></p><p>Now let&#8217;s see how nodes use both public and private state:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!O1mL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!O1mL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png 424w, https://substackcdn.com/image/fetch/$s_!O1mL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png 848w, https://substackcdn.com/image/fetch/$s_!O1mL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png 1272w, https://substackcdn.com/image/fetch/$s_!O1mL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!O1mL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png" width="1350" height="1616" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1616,&quot;width&quot;:1350,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:423239,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!O1mL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png 424w, https://substackcdn.com/image/fetch/$s_!O1mL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png 848w, https://substackcdn.com/image/fetch/$s_!O1mL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png 1272w, https://substackcdn.com/image/fetch/$s_!O1mL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F398cabd4-c149-4775-987f-902f0844d50f_1350x1616.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div></li><li><p><strong>Step 3: Connect Everything</strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uYr6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uYr6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png 424w, https://substackcdn.com/image/fetch/$s_!uYr6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png 848w, https://substackcdn.com/image/fetch/$s_!uYr6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png 1272w, https://substackcdn.com/image/fetch/$s_!uYr6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uYr6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png" width="572" height="175.50906555090654" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:440,&quot;width&quot;:1434,&quot;resizeWidth&quot;:572,&quot;bytes&quot;:122625,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uYr6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png 424w, https://substackcdn.com/image/fetch/$s_!uYr6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png 848w, https://substackcdn.com/image/fetch/$s_!uYr6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png 1272w, https://substackcdn.com/image/fetch/$s_!uYr6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d739-9e9d-4bfd-a108-df91536ef991_1434x440.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div></li></ul><p>The user interface is clean and focused:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_Gqz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_Gqz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png 424w, https://substackcdn.com/image/fetch/$s_!_Gqz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png 848w, https://substackcdn.com/image/fetch/$s_!_Gqz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png 1272w, https://substackcdn.com/image/fetch/$s_!_Gqz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_Gqz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png" width="1456" height="1252" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1252,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:284458,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_Gqz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png 424w, https://substackcdn.com/image/fetch/$s_!_Gqz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png 848w, https://substackcdn.com/image/fetch/$s_!_Gqz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png 1272w, https://substackcdn.com/image/fetch/$s_!_Gqz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4381a26-c3aa-4300-a797-1d1cfabb0013_1586x1364.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>Private state is perfect for:</p><ul><li><p>Intermediate transformations that users don&#8217;t care about</p></li><li><p>Internal counters and flags</p></li><li><p>Raw technical data such as API response headers, performance metrics or internal timestamps</p></li></ul><p>They are not useful for:</p><ul><li><p>Debugging information: It&#8217;s better to keep these in public state during development (you can filter them out in production with <code>OutputState</code>)</p></li><li><p>Data needed by distant nodes: If a node 5 steps away needs a variable, it&#8217;s better to make it public. Private state should be short-lived (1-2 nodes)</p></li><li><p>User preferences: Configuration like <code>max_papers</code> or <code>llm_model</code> should be in <code>InternalState</code> for all nodes to access.</p></li></ul><h2>3. Checkpointers: Never Losing Progress</h2><p>Reducers manage memory growth. Caches skip redundant work. Thread IDs isolate conversations. But there&#8217;s one failure mode that none of these solve: what happens when something crashes mid-execution?</p><p>For instance, your research agent finds 8 relevant papers, summarizes 5 of them, then hits a rate limit. Without checkpointing, all progress will vanish. You must start over, re-searching the same papers, re-generating the same summaries. Every crash means wasted tokens, wasted time, and frustrated users.</p><p>Checkpointers eliminate this fragility. They automatically save your agent&#8217;s state after every step, creating a progress trail. When failures occur, the agent simply picks up where it left off, no data lost, no work repeated.</p><h3>3.1 How Does Checkpointing Work?</h3><p>Think of checkpointers as version control for agent execution. After each node completes, LangGraph captures a snapshot of the entire state and stores it persistently. Each snapshot includes the current values of all state fields, the conversation history, and metadata about which node just executed.</p><p>When you invoke the graph with a thread ID, LangGraph:</p><ol><li><p>Checks for the existing state associated with that thread</p></li><li><p>Loads the latest checkpoint if one exists</p></li><li><p>Resumes execution from the next node, not from scratch</p></li><li><p>Saves a new checkpoint after every node completes</p></li><li><p>Continues this pattern until the graph reaches an end state</p></li></ol><p>The key insight: With checkpointing, your agent becomes resumable by default.</p><h3>3.2 How To Implement Checkpointers?</h3><p>LangGraph provides three checkpointer backends, each trading simplicity for durability:</p><ol><li><p>MemorySaver</p></li><li><p>SQLite</p></li><li><p>Postgres</p></li></ol><p><strong>1. MemorySaver: Development and Testing</strong></p><p>The simplest option stores checkpoints in RAM. It&#8217;s perfect for local development and testing, but everything disappears when the process stops.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fwGZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fwGZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png 424w, https://substackcdn.com/image/fetch/$s_!fwGZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png 848w, https://substackcdn.com/image/fetch/$s_!fwGZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png 1272w, https://substackcdn.com/image/fetch/$s_!fwGZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fwGZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png" width="472" height="180.63076923076923" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:398,&quot;width&quot;:1040,&quot;resizeWidth&quot;:472,&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="https://substackcdn.com/image/fetch/$s_!fwGZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png 424w, https://substackcdn.com/image/fetch/$s_!fwGZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png 848w, https://substackcdn.com/image/fetch/$s_!fwGZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png 1272w, https://substackcdn.com/image/fetch/$s_!fwGZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02e4ef78-9361-4822-93d1-44091befbc52_1040x398.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>2. SQLite: Single-Instance Persistence</strong></p><p>SQLite provides durable storage with zero infrastructure. Checkpoints survive restarts, making it ideal for single-instance deployments, personal tools, or applications where multiple servers don&#8217;t need to share state.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PkT8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PkT8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png 424w, https://substackcdn.com/image/fetch/$s_!PkT8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png 848w, https://substackcdn.com/image/fetch/$s_!PkT8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png 1272w, https://substackcdn.com/image/fetch/$s_!PkT8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PkT8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png" width="524" height="303.8041074249605" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:734,&quot;width&quot;:1266,&quot;resizeWidth&quot;:524,&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="https://substackcdn.com/image/fetch/$s_!PkT8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png 424w, https://substackcdn.com/image/fetch/$s_!PkT8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png 848w, https://substackcdn.com/image/fetch/$s_!PkT8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png 1272w, https://substackcdn.com/image/fetch/$s_!PkT8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44b8749-91f1-4be5-a2cf-b448bb8dace4_1266x734.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>3. Postgres: Production-Scale Persistence</strong></p><p>For production systems with multiple instances, concurrent users, or distributed architectures, Postgres provides the durability and concurrency control needed. Multiple servers can safely read and write checkpoints without conflicts.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kSSp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kSSp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png 424w, https://substackcdn.com/image/fetch/$s_!kSSp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png 848w, https://substackcdn.com/image/fetch/$s_!kSSp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png 1272w, https://substackcdn.com/image/fetch/$s_!kSSp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kSSp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png" width="586" height="220.3213728549142" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:482,&quot;width&quot;:1282,&quot;resizeWidth&quot;:586,&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="https://substackcdn.com/image/fetch/$s_!kSSp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png 424w, https://substackcdn.com/image/fetch/$s_!kSSp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png 848w, https://substackcdn.com/image/fetch/$s_!kSSp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png 1272w, https://substackcdn.com/image/fetch/$s_!kSSp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e8807c8-eacd-4ac6-9512-ccd4aa36d94c_1282x482.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><h3>3.3 How To Resume from Failure?</h3><p>The real power of checkpointing emerges when things go wrong. With checkpoints enabled, your agent can recover from failures automatically by loading the last successful state and continuing execution.</p><p><strong>Example: Research agent hits rate limit</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9Xty!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9Xty!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png 424w, https://substackcdn.com/image/fetch/$s_!9Xty!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png 848w, https://substackcdn.com/image/fetch/$s_!9Xty!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png 1272w, https://substackcdn.com/image/fetch/$s_!9Xty!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9Xty!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png" width="1400" height="692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:692,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:190362,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9Xty!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png 424w, https://substackcdn.com/image/fetch/$s_!9Xty!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png 848w, https://substackcdn.com/image/fetch/$s_!9Xty!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png 1272w, https://substackcdn.com/image/fetch/$s_!9Xty!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652ab4e8-43ed-4b07-b39a-4a76e4203199_1400x692.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p><strong>What happened internally:</strong></p><ul><li><p><strong>First run:</strong> Clarifier ran, researcher found 8 papers, summarizer processed 5 papers (checkpoints saved after each node)</p></li><li><p><strong>Crash:</strong> Rate limit hit while processing paper 6</p></li><li><p><strong>Second run:</strong> Loaded checkpoint after paper 5 was summarized, resumed with paper 6, no repeated API calls or LLM invocations</p></li></ul><p>This pattern extends beyond crashes. Checkpointing enables human-in-the-loop workflows where agents pause for approval, long-running tasks that span hours or days, and multi-session conversations that persist indefinitely. More on this in the coming articles.</p><p><strong>How To Debug with Checkpoints?</strong></p><p>Checkpointers don&#8217;t just enable recovery, they create a complete execution history. You can inspect any previous state, understand how values changed, and debug issues by replaying the exact sequence of steps.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AK90!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AK90!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png 424w, https://substackcdn.com/image/fetch/$s_!AK90!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png 848w, https://substackcdn.com/image/fetch/$s_!AK90!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png 1272w, https://substackcdn.com/image/fetch/$s_!AK90!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AK90!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png" width="590" height="247.36296296296297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/90837231-ed30-4d5f-8baa-27255389f489_1350x566.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:566,&quot;width&quot;:1350,&quot;resizeWidth&quot;:590,&quot;bytes&quot;:159293,&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://aipractitioner.substack.com/i/177963794?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AK90!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png 424w, https://substackcdn.com/image/fetch/$s_!AK90!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png 848w, https://substackcdn.com/image/fetch/$s_!AK90!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png 1272w, https://substackcdn.com/image/fetch/$s_!AK90!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90837231-ed30-4d5f-8baa-27255389f489_1350x566.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent">repo</a></figcaption></figure></div><p>This visibility is crucial for:</p><ul><li><p>Understanding why the agent made specific decisions</p></li><li><p>Identifying which step introduced incorrect data</p></li><li><p>Comparing different execution paths for the same query</p></li><li><p>Building audit trails for compliance or debugging</p></li></ul><div><hr></div><h2>Key Takeaways</h2><p>&#10003; <strong>Reducers prevent memory overflow by controlling how state accumulates</strong>: Instead of endless growth, use truncation (keep last N items), selective retention (keep only highest-quality items), or summarization (compress old context) to maintain bounded memory while preserving essential context.</p><p>&#10003; <strong>Semantic caching eliminates redundant LLM calls by matching intent, not exact strings</strong>: Unlike exact caching that fails on trivial variations, semantic caching uses embeddings to recognize equivalent queries across different phrasings, dramatically reducing costs for repetitive operations.</p><p>&#10003; <strong>Thread IDs and checkpointers transform fragile demos into production-ready agents</strong>: Thread IDs isolate concurrent conversations while checkpointers save state after every node, enabling automatic recovery from failures without losing progress or repeating expensive work.</p><p>&#10003; <strong>Private state keeps interfaces clean by hiding implementation details</strong>: Separate InputState (user provides), OutputState (user receives), and InternalState (nodes share internally) to pass technical data between nodes without polluting final output.</p><div><hr></div><h2>References</h2><p>[1] LangChain Documentation. (2025). <a href="https://langchain-ai.github.io/langgraph/">LangGraph: Build resilient language agents as graphs</a>.</p><p>[2] LangChain Documentation. (2025). <a href="https://python.langchain.com/docs/get_started/introduction">LangChain: Building applications with LLMs through composability</a>.</p><p>[3] LangSmith Documentation. (2025). <a href="https://docs.smith.langchain.com/">LangSmith: Platform for debugging, testing, evaluating, and monitoring LLM applications</a>.</p><p>[4] LangGraph Documentation. (2025). <a href="https://langchain-ai.github.io/langgraph/reference/checkpoints/">Persistence and Memory: Checkpointer implementations</a>.</p><p>[5] LangChain Documentation. (2025). <a href="https://python.langchain.com/docs/modules/model_io/llms/llm_caching">Caching: LLM response caching strategies</a>.</p><p>[6] OpenAI Documentation. (2025). <a href="https://platform.openai.com/docs/">OpenAI Platform</a>.</p><p>[7] arXiv Documentation. (2025). <a href="https://arxiv.org/help/api/user-manual">arXiv API User&#8217;s Manual</a>.</p>]]></content:encoded></item><item><title><![CDATA[From Chains to Graphs: Smarter and Safer Agentic Systems with LangGraph (Part 1)]]></title><description><![CDATA[A Hands-on Introduction to Building Stateful, Graph-Based Workflows for Reliable AI Reasoning]]></description><link>https://aipractitioner.substack.com/p/from-chains-to-graphs-smarter-and</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/from-chains-to-graphs-smarter-and</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Tue, 28 Oct 2025 13:03:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SnQ2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SnQ2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SnQ2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png 424w, https://substackcdn.com/image/fetch/$s_!SnQ2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png 848w, https://substackcdn.com/image/fetch/$s_!SnQ2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png 1272w, https://substackcdn.com/image/fetch/$s_!SnQ2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SnQ2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png" width="1456" height="607" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:607,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1220053,&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://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SnQ2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png 424w, https://substackcdn.com/image/fetch/$s_!SnQ2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png 848w, https://substackcdn.com/image/fetch/$s_!SnQ2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png 1272w, https://substackcdn.com/image/fetch/$s_!SnQ2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8277c7c-621a-4044-baf9-8a72c2b1030f_2932x1222.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This article is also available as a podcast! If you&#8217;re on the go or just want to absorb the content in audio format, you can listen to the full episode below &#128071; The podcast is also available on <a href="https://open.spotify.com/show/6MROBKvrjx0Mey8tHud5LX">Spotify</a> and <a href="https://podcasts.apple.com/us/podcast/the-ai-practitioner-podcast/id1830285899">Apple Podcasts</a>. </em></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;4592c5c1-4c84-414f-912b-990a55d23c83&quot;,&quot;caption&quot;:&quot;Prefer reading instead? The full article is available here.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;PODCAST &#8212; From Chains to Graphs: Smarter and Safer Agentic Systems with LangGraph (Part 1)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:7177021,&quot;name&quot;:&quot;Lina Faik&quot;,&quot;bio&quot;:&quot;Lead AI Scientist bringing AI research to real-world impact across industries. Independent consultant, previously at Dataiku.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bdaf5e6-a6c6-48fe-80f6-3d69aaac1694_2256x2256.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-10-28T13:02:29.687Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/041787d9-ac28-40c6-97ed-b38282e9017e_2932x1222.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://aipractitioner.substack.com/p/podcast-from-chains-to-graphs-smarter&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:176825567,&quot;type&quot;:&quot;podcast&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4815372,&quot;publication_name&quot;:&quot;The AI Practitioner&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ivps!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p><strong>Consider an agent that answers complex scientific questions</strong> by retrieving papers from arXiv, cross-referencing findings, and synthesizing insights. It works perfectly, until an API fails, a token limit hits, or reasoning loops infinitely.</p><p>Linear chains can&#8217;t recover. No loops to retry. No branching to adapt. No state to resume from.</p><p><strong>LangGraph changes this.</strong> It models workflows as stateful graphs where each node is a reasoning step. State persists. Control flow adapts. Failures become recoverable.</p><p><strong>The result? </strong>Agents that don&#8217;t just execute, they reason iteratively, remember context across steps, and recover gracefully. Exactly what&#8217;s needed when the path forward isn&#8217;t predetermined.</p><h3>Objective</h3><p>This article focuses on <strong>building stateful, graph-based AI agents with LangGraph</strong> by progressively constructing a scientific research assistant that retrieves, analyzes, and synthesizes academic papers.</p><p>After reading this article, you will understand:</p><ul><li><p><strong>How to build graph architectures from the ground up</strong>&#8212;defining state schemas, creating node functions, and connecting them with edges to enable workflows that sequential chains cannot handle</p></li><li><p><strong>How to add intelligence through routing and agents</strong>&#8212;implementing conditional edges for dynamic decisions, binding tools for autonomous actions, and transforming simple chains into agentic nodes</p></li><li><p><strong>How to implement persistence and recovery patterns</strong>&#8212;using memory to prevent redundant work, checkpointing to resume from failures, and streaming to monitor agent execution in real-time</p></li></ul><blockquote><p><strong>Context:</strong> This article is Part 1 of a series on building production-grade agents with LangGraph. Future articles will explore advanced multi-agent orchestration patterns, deployment strategies, and scaling considerations for complex agentic systems.</p><p><strong>Prerequisites: </strong>Python programming experience and basic understanding of LLMs and prompt engineering. Familiarity with LangChain concepts (chains, models, prompts) is NOT required.</p><p><strong>Tools &amp; libraries: </strong><a href="https://www.langchain.com/langgraph">LangGraph</a>, <a href="https://www.langchain.com/">LangChain</a>, <a href="https://www.langchain.com/langsmith/observability">LangSmith</a>, <a href="https://openai.com/">OpenAI</a>, <a href="https://info.arxiv.org/help/api/index.html">arXiv API </a></p></blockquote><p>You can find the code <a href="https://github.com/linafaik08/scientific-graph-agent">here</a> on GitHub.</p><p><strong>Preview: </strong>Below is a demo of the graph-based research agent described in this article, showcasing iterative search, reasoning, and synthesis with proper citations.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FOOs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FOOs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 424w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 848w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 1272w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FOOs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif" width="800" height="433" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:433,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1871053,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FOOs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 424w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 848w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 1272w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Example response generated by the graph-based agent, combining multi-step retrieval and evidence-grounded synthesis</figcaption></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><p></p><div><hr></div><h2>1. The Research Problem: Why Linear Agents Can&#8217;t Think Like Scientists</h2><p>Before exploring graph-based agentic systems, let&#8217;s examine the problem that will serve as our guiding example throughout this article.</p><p>Imagine you want to build an AI research assistant capable of answering scientific questions by consulting actual research papers, retrieving them, analyzing their contents, and synthesizing evidence-based answers. A typical question would be: <em>&#8220;What are the recent advancements in using CRISPR for cancer immunotherapy?&#8221;</em> </p><p>At first, this seems simple enough for a single linear chain: query an API, summarize the papers, and generate an answer. Yet, scientific reasoning rarely follows a straight path. What happens when key references appear in papers not yet retrieved? When early results are too superficial, demanding refined searches? Or when new findings open unexpected research directions? A linear chain cannot handle these situations.</p><p>Graph-based reasoning solves this by reflecting how researchers actually think and work:</p><ul><li><p><strong>Non-linear exploration:</strong> It can search again after reading papers that reveal new directions.</p></li><li><p><strong>Conditional decisions:</strong> It can evaluate paper quality and determine whether to search more or synthesize findings.</p></li><li><p><strong>Iterative refinement:</strong>  It can loop back to search for specific details that emerged during analysis.</p></li><li><p><strong>State-aware branching:</strong> It can adapt the strategy based on the question type, with some requiring breadth and others demanding depth.</p></li></ul><p><strong>The Practical Implementation</strong></p><p>The scientific paper explorer presented in this article serves as a concise yet complete example of a graph-based research agent. It consists of three specialized nodes, each designed to perform a distinct cognitive function.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lv89!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lv89!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 424w, https://substackcdn.com/image/fetch/$s_!lv89!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 848w, https://substackcdn.com/image/fetch/$s_!lv89!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 1272w, https://substackcdn.com/image/fetch/$s_!lv89!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lv89!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png" width="552" height="442.92783505154637" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:934,&quot;width&quot;:1164,&quot;resizeWidth&quot;:552,&quot;bytes&quot;:262896,&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://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lv89!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 424w, https://substackcdn.com/image/fetch/$s_!lv89!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 848w, https://substackcdn.com/image/fetch/$s_!lv89!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 1272w, https://substackcdn.com/image/fetch/$s_!lv89!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332db5d9-7e7e-487a-8526-0433f80eca6d_1164x934.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Graph-Based Research Agent Architecture</figcaption></figure></div><p>To ensure robustness, the graph incorporates intelligent retry logic. When the researcher node retrieves fewer than three papers, the system automatically loops back to refine the query and search again, up to a configurable maximum iteration limit.</p><p>This simple structure already demonstrates the advantage of graph-based reasoning: the ability to adapt, revisit steps, and iteratively improve results without relying on a rigid linear chain.</p><h2>2. Graph Architecture: Designing the Backbone of Adaptive AI Agents</h2><h3>2.1 What Defines the Agent&#8217;s State?</h3><p>Every agent needs memory: a way to carry context from one reasoning step to another. In LangGraph, this is represented as a <strong>state object</strong>, often implemented through a <code>TypedDict </code>that defines what kind of data flows through the graph.</p><blockquote><p><strong>TypedDict</strong> is a Python feature (from the <code>typing</code> module) that lets you define dictionary types with specific keys and value types, providing type hints for dictionaries with a fixed structure.</p></blockquote><p>For our AI research assistant, the state is defined as follows: </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RZU9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RZU9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png 424w, https://substackcdn.com/image/fetch/$s_!RZU9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png 848w, https://substackcdn.com/image/fetch/$s_!RZU9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png 1272w, https://substackcdn.com/image/fetch/$s_!RZU9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RZU9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png" width="638" height="513.554945054945" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1172,&quot;width&quot;:1456,&quot;resizeWidth&quot;:638,&quot;bytes&quot;:365617,&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://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RZU9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png 424w, https://substackcdn.com/image/fetch/$s_!RZU9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png 848w, https://substackcdn.com/image/fetch/$s_!RZU9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png 1272w, https://substackcdn.com/image/fetch/$s_!RZU9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0920e4b9-901f-4831-a63a-7cceaf8c1223_1538x1238.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent/blob/main/src/agent_graph/state.py">repo</a></figcaption></figure></div><p>This state evolves through the reasoning process:</p><ul><li><p><code>query</code>: The user&#8217;s original scientific question</p></li><li><p><code>refined_query</code>: The optimized version used for the search</p></li><li><p><code>papers</code>: The list of retrieved results (metadata, abstracts, etc.)</p></li><li><p><code>summary</code>: The structured, synthesized output</p></li><li><p><code>iteration</code>: A safeguard against infinite loops</p></li><li><p><code>messages</code>: The full conversational trace (LangChain messages)</p></li></ul><p>Together, these elements capture both <em>content</em> and <em>context</em>, enabling the agent to reason iteratively while preserving history for monitoring and debugging.</p><blockquote><p>Notice the <code>Annotated[List[BaseMessage], add]</code> syntax on <code>messages</code>. This is a <strong>reducer annotation</strong> that tells LangGraph how to handle updates. Without a reducer, returning <code>{&#8221;messages&#8221;: [new_message]}</code> would replace the entire conversation history. But with the <code>add</code> reducer, it automatically appends new messages to the existing list, building up the conversation naturally without each node needing to manually read and concatenate. More on this in the comming articles.</p></blockquote><h3>2.2 How to Structure Tasks into Nodes?</h3><p>Once the <strong>state</strong> is defined, the next step is to design the <strong>nodes</strong>&#8212;the reasoning units that transform that state.</p><p>In LangGraph, each node is a Python function performing a distinct cognitive task. Think of them as the agent&#8217;s mental operations: clarifying a question, searching for information, analyzing findings, and deciding what to do next.</p><p>Each node is a function that:</p><ol><li><p>Takes the current <code>AgentState</code></p></li><li><p>Performs a reasoning step (e.g., refine query, fetch data, synthesize results)</p></li><li><p>Returns an updated version of the state</p></li></ol><p>This modular approach makes the workflow transparent, debuggable, and flexible.</p><p>Our research agent includes three main nodes:</p><ol><li><p><code>clarifier_node</code> &#8212; Refines the original question into a precise query</p></li><li><p><code>researcher_node</code> &#8212; Uses an ArXiv tool to fetch relevant papers</p></li><li><p><code>summarizer_node</code> &#8212; Summarizes the papers and decides whether to continue</p></li></ol><p>Here is an example of a node: the <code>clarifier_node </code>node</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7UtY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7UtY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png 424w, https://substackcdn.com/image/fetch/$s_!7UtY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png 848w, https://substackcdn.com/image/fetch/$s_!7UtY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png 1272w, https://substackcdn.com/image/fetch/$s_!7UtY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7UtY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png" width="1456" height="1581" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1581,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:556983,&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://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7UtY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png 424w, https://substackcdn.com/image/fetch/$s_!7UtY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png 848w, https://substackcdn.com/image/fetch/$s_!7UtY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png 1272w, https://substackcdn.com/image/fetch/$s_!7UtY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b9aa233-5a28-4079-8eed-791ed8a5c3fe_1980x2150.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent/blob/main/src/agent_graph/nodes.py">repo</a></figcaption></figure></div><p>This node extracts the user&#8217;s question from state, configures an LLM with specified parameters, and uses a specialized system prompt to transform natural language into precise ArXiv search terms. The refined query is then stored back into state along with the conversation history for downstream nodes.</p><p>Each node has a clear, single responsibility:</p><ul><li><p><strong>Clarifier</strong>: Transforms natural language into precise search terms</p></li><li><p><strong>Researcher</strong>: Handles external API interactions and data retrieval</p></li><li><p><strong>Summarizer</strong>: Analyzes content and makes strategic decisions about next steps</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!s4pU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!s4pU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png 424w, https://substackcdn.com/image/fetch/$s_!s4pU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png 848w, https://substackcdn.com/image/fetch/$s_!s4pU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png 1272w, https://substackcdn.com/image/fetch/$s_!s4pU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!s4pU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png" width="1456" height="389" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:389,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:103688,&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://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!s4pU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png 424w, https://substackcdn.com/image/fetch/$s_!s4pU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png 848w, https://substackcdn.com/image/fetch/$s_!s4pU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png 1272w, https://substackcdn.com/image/fetch/$s_!s4pU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde853e8a-02a3-46f3-8eb7-d706a35ad6ee_2074x554.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Table &#8212; Node Structure of the Scientific Paper Explorer</figcaption></figure></div><p>The beauty of this separation is modularity. Want to search PubMed instead of ArXiv? Replace the <code>researcher_node</code>. Need an additional quality-check step? Insert a new node between <code>researcher</code> and <code>summarizer</code>. The shared state ensures compatibility without rewriting the logic.</p><p>Together, these nodes form a self-consistent reasoning pipeline where every step is visible and testable.</p><h3>2.3 How to Connect Nodes into a Graph?</h3><p>With nodes defined, the final step involves linking them into a graph that defines the agent&#8217;s reasoning flow.</p><p>LangGraph uses a <code>StateGraph</code> to specify:</p><ul><li><p><strong>Nodes</strong>: The reasoning units</p></li><li><p><strong>Edges</strong>: Control flow between operations</p></li><li><p><strong>Conditional edges</strong>: Logic-based transitions (looping back if too few papers are found)</p></li></ul><p>This creates a structured yet flexible reasoning loop, ideal for research workflows where iterative exploration is essential.</p><p>For our AI research assistant, the graph is defined as follows: </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ABCg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ABCg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png 424w, https://substackcdn.com/image/fetch/$s_!ABCg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png 848w, https://substackcdn.com/image/fetch/$s_!ABCg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png 1272w, https://substackcdn.com/image/fetch/$s_!ABCg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ABCg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png" width="694" height="974.2692307692307" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2044,&quot;width&quot;:1456,&quot;resizeWidth&quot;:694,&quot;bytes&quot;:539761,&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://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ABCg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png 424w, https://substackcdn.com/image/fetch/$s_!ABCg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png 848w, https://substackcdn.com/image/fetch/$s_!ABCg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png 1272w, https://substackcdn.com/image/fetch/$s_!ABCg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39de26c-5f29-42ff-a26d-2534f7310d38_1634x2294.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Github <a href="https://github.com/linafaik08/scientific-graph-agent/blob/main/src/agent_graph/graph.py">repo</a></figcaption></figure></div><p>Graph construction proceeds in three steps: registering nodes, establishing connections, and implementing conditional logic.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3OTG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3OTG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png 424w, https://substackcdn.com/image/fetch/$s_!3OTG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png 848w, https://substackcdn.com/image/fetch/$s_!3OTG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png 1272w, https://substackcdn.com/image/fetch/$s_!3OTG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3OTG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png" width="525" height="170.44270833333334" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:374,&quot;width&quot;:1152,&quot;resizeWidth&quot;:525,&quot;bytes&quot;:81360,&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://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3OTG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png 424w, https://substackcdn.com/image/fetch/$s_!3OTG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png 848w, https://substackcdn.com/image/fetch/$s_!3OTG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png 1272w, https://substackcdn.com/image/fetch/$s_!3OTG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7411c914-54bc-4590-94d4-cf8f9f1b2f2f_1152x374.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ol><li><p><strong>Registering Nodes:</strong> First, each processing unit is registered as a named node in the workflow, representing a distinct phase in the agent&#8217;s pipeline: <code>workflow.add_node(&#8221;clarifier&#8221;, clarifier_node) workflow.add_node(&#8221;researcher&#8221;, researcher_node) workflow.add_node(&#8221;summarizer&#8221;, summarizer_node)</code></p></li><li><p><strong>Establishing Flow: </strong>Next, the execution path is defined. The clarifier serves as the entry point, with direct edges chaining the nodes together: <code>workflow.set_entry_point(&#8221;clarifier&#8221;)</code></p><p><code>workflow.add_edge(&#8221;clarifier&#8221;, &#8220;researcher&#8221;)</code></p><p><code>workflow.add_edge(&#8221;researcher&#8221;, &#8220;summarizer&#8221;)<br></code>This creates a linear progression where each stage feeds into the next.</p></li><li><p><strong>Implementing Conditional Logic:</strong> The critical intelligence comes from conditional edges. After the summarizer completes its analysis, the <code>should_continue</code> function determines the next action:<br><code>workflow.add_conditional_edges(</code></p><p><code>    &#8220;summarizer&#8221;,</code></p><p><code>    should_continue,</code></p><p><code>    {&#8220;researcher&#8221;: &#8220;researcher&#8221;,</code></p><p><code>      &#8220;end&#8221;: END}</code></p><p><code>  )</code></p><p>This establishes a feedback loop: when additional papers are needed, execution returns to the researcher node; otherwise, the workflow terminates. </p></li><li><p>Calling <code>workflow.compile()</code> produces an executable graph ready to process research queries with adaptive iteration based on result quality.</p></li></ol><blockquote><p>Note: The checkpointer enables persistence, allowing the graph to save state snapshots at each node execution. This supports advanced features like pausing execution, resuming from specific points, or implementing human-in-the-loop workflows. Future articles will explore these capabilities in depth.</p></blockquote><h2>3. Tracing, Debugging, and Monitoring: The Path to Reliable AI Agents</h2><h3>3.1 Why Agent Development Requires Dedicated Tooling?</h3><p>Building agents with LLMs is fundamentally different from traditional software development. The challenges that make specialized tooling essential include:</p><ul><li><p><strong>Non-deterministic behavior:</strong> LLMs are non-deterministic by nature, producing varied outputs even for similar inputs, making debugging and quality assurance more complex than traditional software. A prompt that works perfectly in testing might fail mysteriously in production. Without proper observability, developers are left guessing why an agent chose a particular path or generated unexpected output.</p></li><li><p><strong>Multi-step reasoning opacity:</strong> The opaque nature of LLMs can make debugging, monitoring, and performance optimization a formidable task. When an agent fails, the question isn&#8217;t just &#8220;what went wrong?&#8221; but &#8220;at which step in the reasoning process did it derail?&#8221;. Traditional debuggers with breakpoints can&#8217;t capture the cognitive flow of an agent that searches papers, analyzes findings, and decides whether to search again.</p></li><li><p><strong>State complexity across nodes:</strong> Agents traverse multiple nodes with intermediate states that need inspection. In the research agent example, the state evolves from an empty papers list, to populated papers, to extracted findings, to a final summary. Each transformation represents a potential failure point. Without visibility into state transitions, debugging becomes impossibly difficult.</p></li><li><p><strong>Iterative loops and conditional branching:</strong> Graph-based agents can loop back to previous nodes or branch based on conditions. The agent can interrupt at any time, run in debug mode where it pauses after each step, and developers can walk through step-by-step. Traditional linear debugging tools weren&#8217;t designed for workflows that might execute &#8220;search &#8594; analyze &#8594; search again &#8594; analyze &#8594; synthesize.&#8221;</p></li><li><p><strong>Production monitoring challenges:</strong> In production, there&#8217;s significantly more traffic, making it impractical to examine datapoints individually. Developers need aggregate metrics, anomaly detection, and the ability to drill down from high-level dashboards into specific problematic traces.</p></li></ul><p>These challenges demand tools purpose-built for agentic AI&#8212;tools that understand graph structures, state management, LLM calls, and the unique debugging needs of multi-step reasoning systems.</p><h3>3.2 How Does LangGraph Studio Enable Rapid Prototyping and Debugging?</h3><p>LangGraph Studio offers a new way to develop LLM applications, providing a specialized agent IDE for visualizing, interacting with, and debugging complex agentic applications. </p><p><strong>Visual Graph Representation</strong></p><p>Design workflows in a flowchart-style editor by connecting nodes and edges. The graph updates in real time as code changes, so structural issues become obvious: missing edges, incorrect routing, or unintended cycles that would be easy to miss in code.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FOOs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FOOs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 424w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 848w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 1272w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FOOs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif" width="800" height="433" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:433,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1871053,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!FOOs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 424w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 848w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 1272w, https://substackcdn.com/image/fetch/$s_!FOOs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F453c37be-3e88-48a2-aeb2-4f42194768f6_800x433.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Example response generated by the graph-based agent from LangGraph Studio</figcaption></figure></div><p><strong>Interactive State Inspection</strong></p><p>At any point, developers can interact with the state of the agent; if they don&#8217;t like what the agent responded with at a specific step, they can directly modify the response and then continue with that new response. </p><p>This is transformative for debugging: imagine the summarizer decides it needs more papers even though 5 papers were found.</p><ul><li><p><strong>Traditional debugging:</strong> Add print statements, restart the entire flow, hope to catch the issue.</p></li><li><p><strong>Studio debugging:</strong></p><ul><li><p>Pause execution at the summarizer node</p></li><li><p>Inspect the state: <code>{&#8221;papers&#8221;: [5 papers], &#8220;iteration&#8221;: 1, ...}</code></p></li><li><p>Notice the issue: papers have low relevance scores</p></li><li><p>Edit the state to inject better papers</p></li><li><p>Resume execution to test the hypothesis</p></li></ul></li></ul><p>This &#8220;time travel&#8221; debugging capability is invaluable for understanding agent behavior without repeatedly running expensive LLM calls.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mmN8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mmN8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png 424w, https://substackcdn.com/image/fetch/$s_!mmN8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png 848w, https://substackcdn.com/image/fetch/$s_!mmN8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png 1272w, https://substackcdn.com/image/fetch/$s_!mmN8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mmN8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png" width="1456" height="789" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:789,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:631426,&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://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mmN8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png 424w, https://substackcdn.com/image/fetch/$s_!mmN8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png 848w, https://substackcdn.com/image/fetch/$s_!mmN8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png 1272w, https://substackcdn.com/image/fetch/$s_!mmN8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad847d37-522d-4b94-9ef2-0e373d56d548_2932x1588.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Interactive State Inspection and Summarization Output in LangGraph Studio</figcaption></figure></div><p><strong>Real-Time Code Hot Reloading</strong></p><p>LangGraph Studio detects changes to the underlying code files, allowing developers to update prompts in their code editor and rerun nodes if an agent responds poorly, making it much easier to iterate on long-running agents. The workflow becomes:</p><ol><li><p>Run the agent in Studio</p></li><li><p>Notice that the clarifier node produces a poor query refinement</p></li><li><p>Edit the system prompt in <code>nodes.py</code></p></li><li><p>Studio detects the change and hot-reloads</p></li><li><p>Rerun just the clarifier node with the same input</p></li><li><p>Instantly see if the new prompt improves results</p></li></ol><p>No container rebuilds, no full restarts&#8212;just immediate iteration on prompts, logic, and LLM parameters.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X3lJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X3lJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png 424w, https://substackcdn.com/image/fetch/$s_!X3lJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png 848w, https://substackcdn.com/image/fetch/$s_!X3lJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png 1272w, https://substackcdn.com/image/fetch/$s_!X3lJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X3lJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png" width="1456" height="789" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:789,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:558372,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!X3lJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png 424w, https://substackcdn.com/image/fetch/$s_!X3lJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png 848w, https://substackcdn.com/image/fetch/$s_!X3lJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png 1272w, https://substackcdn.com/image/fetch/$s_!X3lJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8528f1e-94a1-4b6b-9456-995f9c978101_2932x1588.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Visual Graph Execution and Trace View in LangGraph Studio</figcaption></figure></div><h3>3.3 How Does LangSmith Provide Production Observability and Monitoring?</h3><p>LangSmith Observability gives complete visibility into agent behavior with tracing, real-time monitoring, alerting, and high-level insights into usage. </p><p>While Studio excels at local development, LangSmith is purpose-built for production environments where scale, reliability, and performance matter.</p><p>To get started with tracing, you only need to set one environment variable if already using LangChain or LangGraph.</p><p>For the research agent:</p><pre><code><code>LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=&#8221;XXX&#8221;
LANGCHAIN_PROJECT=scientific-graph-agent</code></code></pre><p><strong>End-to-End Trace Inspection</strong></p><p>Every invocation of the graph automatically generates a detailed trace capturing the entire reasoning flow, including the initial user query, each node execution (clarifier, researcher, summarizer), all LLM prompts and responses, tool calls such as ArXiv API searches, intermediate state updates, conditional edge decisions, and the final output with total execution time.</p><blockquote><p>A <strong>trace</strong> represents the complete end-to-end execution of a request, capturing every significant operation as a run within that trace. </p></blockquote><p>For the research agent, a single trace might look like:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cP0M!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cP0M!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif 424w, https://substackcdn.com/image/fetch/$s_!cP0M!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif 848w, https://substackcdn.com/image/fetch/$s_!cP0M!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif 1272w, https://substackcdn.com/image/fetch/$s_!cP0M!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cP0M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif" width="800" height="433" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:433,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2906939,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cP0M!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif 424w, https://substackcdn.com/image/fetch/$s_!cP0M!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif 848w, https://substackcdn.com/image/fetch/$s_!cP0M!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif 1272w, https://substackcdn.com/image/fetch/$s_!cP0M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f12b7c6-c3d9-4835-bb89-20902c02fe56_800x433.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Tracing in LangSmith</figcaption></figure></div><p>Developers can quickly debug and understand non-deterministic LLM app behavior with tracing, seeing what the agent is doing step by step, then fixing issues to improve latency and response quality. </p><p><strong>Production Monitoring Dashboards</strong></p><p>In production, with significantly more traffic, developers need tools to help with observability beyond examining individual datapoints. LangSmith provides monitoring charts tracking LLM-specific statistics like number of traces, feedback, time-to-first-token, costs, latency, and error rates over time.</p><p>For the research agent in production, monitor:</p><ul><li><p><strong>Throughput:</strong> How many research queries per hour?</p></li><li><p><strong>Latency:</strong> Average time from query to final summary</p></li><li><p><strong>Loop frequency:</strong> What percentage of runs trigger the &#8220;NEED_MORE_PAPERS&#8221; loop?</p></li><li><p><strong>Cost:</strong> Total tokens consumed across all LLM calls</p></li><li><p><strong>Error rate:</strong> How often does ArXiv search fail or summarization timeout?</p></li><li><p><strong>User feedback:</strong> Are summaries helpful? (via feedback API)</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bKr_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bKr_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif 424w, https://substackcdn.com/image/fetch/$s_!bKr_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif 848w, https://substackcdn.com/image/fetch/$s_!bKr_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif 1272w, https://substackcdn.com/image/fetch/$s_!bKr_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bKr_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif" width="800" height="433" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:433,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3023451,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://aipractitioner.substack.com/i/176807443?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bKr_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif 424w, https://substackcdn.com/image/fetch/$s_!bKr_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif 848w, https://substackcdn.com/image/fetch/$s_!bKr_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif 1272w, https://substackcdn.com/image/fetch/$s_!bKr_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcddcd266-432c-4ac6-8681-a0f1d1835551_800x433.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; LangSmith Dashboard</figcaption></figure></div><p><strong>A/B Testing and Metadata Grouping</strong></p><p>Developers can group monitoring charts by any metadata attribute and instantly get grouped charts over time, allowing experimentation with different LLMs or prompts and tracking their performance. </p><p>A typical example experiment for our research problem would be: does GPT-4 or Claude produce better research summaries?</p><p><strong>Interactive Drill-Down from Dashboards</strong></p><p>Developers can hover over a datapoint in the monitoring chart and click it to be led back to the runs table with a filtered view.</p><p>Imagine noticing a latency spike at 2 p.m. reaching eight seconds, three times the usual. Clicking that point reveals runs from the same window, sorted by delay. The slowest trace might show a six-second lag in the researcher node caused by a sluggish ArXiv API. This direct path from metric to root cause greatly speeds up debugging.<strong> </strong></p><p><strong>Zero-Latency Async Tracing</strong></p><p>LangSmith does not add any latency to applications. The LangSmith SDK uses a callback handler that sends traces to a trace collector running as an async, distributed process. In LangChain Python, LangSmith&#8217;s tracing is done in a background thread to avoid obstructing production applications.</p><p>Together, LangGraph Studio and LangSmith form a complete development lifecycle toolkit: Studio for rapid local iteration and visual debugging, LangSmith for production observability and performance optimization. This separation of concerns, development versus deployment, ensures agents can be built quickly and deployed confidently.</p><div><hr></div><h2>Key Takeaways</h2><p><strong>&#10003; Graph-based architectures fundamentally transform agent capabilities beyond linear chains:</strong> Unlike sequential chains that execute predetermined steps, graph-based systems enable non-linear exploration, conditional branching, iterative refinement, and state-aware decision-making. This is essential for complex workflows where the path forward isn&#8217;t predetermined.</p><p><strong>&#10003; State management creates persistent memory that enables true multi-step reasoning:</strong> TypedDict-based state schemas allow agents to carry context across nodes, track progress, maintain conversation history, and make informed decisions based on accumulated knowledge rather than treating each step in isolation.</p><p><strong>&#10003; Modular node architecture and conditional edges enable adaptive, self-correcting workflows:</strong> Single-responsibility nodes combined with routing functions create transparent reasoning pipelines that can autonomously decide next steps, loop back when needed, and adapt strategies based on intermediate results, all without brittle retry logic.</p><p><strong>&#10003; Production agents require specialized observability tools designed for non-deterministic AI systems:</strong> LangGraph Studio provides visual debugging, interactive state inspection, and hot-reloading for rapid development iteration, while LangSmith delivers end-to-end tracing, production monitoring dashboards, A/B testing capabilities, and zero-latency async tracking. Together, they address the unique challenges of multi-step LLM reasoning that traditional software monitoring cannot handle.</p><div><hr></div><h2>References</h2><p>[1] LangChain Documentation. (2025). <a href="https://python.langchain.com/docs/langgraph">LangGraph: Build resilient language agents as graphs. </a></p><p>[2] LangChain Documentation. (2025). <a href="https://python.langchain.com/docs/get_started/introduction">LangChain: Building applications with LLMs through composability</a>. </p><p>[3] LangSmith Documentation. (2025). <a href="https://docs.smith.langchain.com">LangSmith: Platform for debugging, testing, evaluating, and monitoring LLM applications</a>. </p><p>[4] LangGraph Studio Documentation. (2025). <a href="https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/">LangGraph Studio: A specialized IDE for developing LangGraph applications</a>. </p><p>[5] OpenAI API Documentation. (2025). <a href="https://platform.openai.com/docs">OpenAI Platform</a>.</p><p>[6] arXiv API Documentation. (2025). <a href="https://info.arxiv.org/help/api/index.html">arXiv API User&#8217;s Manual</a>.</p><p></p>]]></content:encoded></item><item><title><![CDATA[AgentOps: Operational Frameworks for LLM-Powered Agent Systems]]></title><description><![CDATA[A Practical Guide to Managing Production Agents with MLflow]]></description><link>https://aipractitioner.substack.com/p/agentops-operational-frameworks-for</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/agentops-operational-frameworks-for</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Tue, 07 Oct 2025 13:18:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_3S3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_3S3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_3S3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png 424w, https://substackcdn.com/image/fetch/$s_!_3S3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png 848w, https://substackcdn.com/image/fetch/$s_!_3S3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png 1272w, https://substackcdn.com/image/fetch/$s_!_3S3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_3S3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png" width="1456" height="602" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:602,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:678424,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_3S3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png 424w, https://substackcdn.com/image/fetch/$s_!_3S3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png 848w, https://substackcdn.com/image/fetch/$s_!_3S3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png 1272w, https://substackcdn.com/image/fetch/$s_!_3S3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f370aaf-9643-40a9-9887-eea87afa1a36_2238x926.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This article is also available as a podcast! If you&#8217;re on the go or just want to absorb the content in audio format, you can listen to the full episode below &#128071; The podcast is also available on <a href="https://open.spotify.com/show/6MROBKvrjx0Mey8tHud5LX">Spotify</a> and <a href="https://podcasts.apple.com/us/podcast/the-ai-practitioner-podcast/id1830285899">Apple Podcasts</a>. </em></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;10142bf3-8139-4ae8-864b-117a1061aa1a&quot;,&quot;caption&quot;:&quot;Prefer reading instead? The full article is available here.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;PODCAST &#8212; AgentOps: Operational Frameworks for LLM-Powered Agent Systems&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:7177021,&quot;name&quot;:&quot;Lina Faik&quot;,&quot;bio&quot;:&quot;Lead AI Scientist bringing AI research to real-world impact across industries. Independent consultant, previously at Dataiku.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bdaf5e6-a6c6-48fe-80f6-3d69aaac1694_2256x2256.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-10-07T16:30:10.884Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3012ee44-d77b-48dd-afff-aa32218ca362_2238x926.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://aipractitioner.substack.com/p/podcast-agentops-operational-frameworks&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:175259516,&quot;type&quot;:&quot;podcast&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4815372,&quot;publication_name&quot;:&quot;The AI Practitioner&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ivps!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>While traditional systems fail loudly with error codes, AI agents fail silently with confident nonsense.</p><p>The same prompt that generates brilliant analysis one moment can produce hallucinated data the next, all while monitoring dashboards show green. This fundamental shift from deterministic software to probabilistic reasoning systems demands a new operational paradigm: <strong>AgentOps</strong>.</p><h3>Objective</h3><p>This article focuses on <strong>bridging the gap between AgentOps theory and practice</strong>, demonstrating how to build truly observable AI agent systems. It is based on a <strong>real-world use case</strong>: a multi-agent investment brief generator that autonomously fetches market data, analyzes financials, monitors news, and synthesizes investment recommendations.</p><p>After reading this article, you will understand:</p><ol><li><p><strong>Why agentic systems require fundamentally different operations than traditional ML models?</strong> This includes unique failure modes, anomaly taxonomies, and the shift from deterministic to probabilistic debugging</p></li><li><p><strong>How does the AgentOps operational framework operate?</strong> This encompasses  monitoring, anomaly detection, root cause analysis, and iterative resolution strategies tailored for autonomous systems</p></li><li><p><strong>How to implement production-grade observability using MLflow?</strong> This relies on tracing, prompt management, and evaluation capabilities to instrument a four-agent pipeline with comprehensive cognitive state capture.</p></li></ol><blockquote><p><strong>Prerequisites <br></strong>- Basic understanding of LLMs and prompt engineering (familiar with concepts like tool calling)<br><br><strong>Tools &amp; Libraries</strong><br>- MLflow, for tracing, prompt management, and evaluation framework<br>- <strong>OpenAI API</strong> as LLM providers (principles apply to any LLM)</p></blockquote><p>You can find the code <a href="https://github.com/linafaik08/agentic-investor-brief">here</a> on GitHub.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>1. From MLOps to AgentOps: The New Operations Paradigm</h2><h3>1.1 Why Do Agent Systems Require Different Operations?</h3><p>Traditional machine learning operations (MLOps) are built around a straightforward paradigm: a model receives an input, generates a single prediction, and the process ends. This framework works well for static tasks such as identifying whether an image contains a cat or assessing the sentiment of a product review.</p><p>Agentic systems, however, break away from this model entirely. Rather than producing fixed outputs, agents operate through dynamic, iterative reasoning cycles that incorporate planning, tool usage, and memory.</p><p>This shift introduces <strong>non-deterministic behavior</strong>: the same input can yield different outputs due to the probabilistic nature of large language models (LLMs), even when model weights and parameters remain unchanged.</p><p>While traditional models behave consistently once deployed, an agent&#8217;s behavior unfolds dynamically in real time. It is shaped by the interaction between its LLM &#8220;brain&#8221;, prompt instructions, evolving memory, and the external tools it selects.</p><p>With LLM-powered agent systems, the paradigm moves <strong>from deploying a static prediction function to orchestrating a cognitive system</strong>, less like debugging a computation, and more like debugging a conversation.</p><h3>1.2 How Does the AgentOps Lifecycle Work?</h3><p>To meet the demands of such dynamic behavior, the AgentOps lifecycle extends the traditional DevOps framework to fit the realities of autonomous agents.</p><p>While both follow a similar four-stage structure&#8212;<strong>monitoring &#8594; anomaly detection &#8594; root cause analysis &#8594; resolution</strong> [1, 3], each phase must be reimagined to handle the probabilistic, iterative, and tool-augmented reasoning loops that define agent behavior.</p><p>Let&#8217;s dive deeper into each of these stages to understand how AgentOps adapts them for agentic systems.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!j5NU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j5NU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png 424w, https://substackcdn.com/image/fetch/$s_!j5NU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png 848w, https://substackcdn.com/image/fetch/$s_!j5NU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png 1272w, https://substackcdn.com/image/fetch/$s_!j5NU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j5NU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png" width="1456" height="780" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/acd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:780,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:479654,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!j5NU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png 424w, https://substackcdn.com/image/fetch/$s_!j5NU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png 848w, https://substackcdn.com/image/fetch/$s_!j5NU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png 1272w, https://substackcdn.com/image/fetch/$s_!j5NU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facd25021-346b-4f1b-adf8-a39d01ab60e4_2910x1558.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Traditional vs. Agent System Observability</figcaption></figure></div><p><strong>1. Monitoring: Capturing the Agent&#8217;s Cognitive State</strong></p><ul><li><p>Traditional MLOps monitors model metrics (accuracy, drift), data quality, and infrastructure (latency, throughput).</p></li><li><p>Agent systems require a fundamentally different approach: <strong>cognitive state traceability,</strong> capturing not just what an agent did, but why it made specific decisions [1, 3]. This means instrumenting the agent&#8217;s internal reasoning loop to record:</p><ul><li><p><strong>Beliefs and context</strong>: The agent&#8217;s current understanding of the world state, derived from initial inputs and accumulated observations. In the example of the investment agent, this includes known stock prices, market conditions, portfolio constraints, and task goals essentially its &#8220;investment thesis&#8221; at any given moment.</p></li><li><p><strong>Memory contents</strong>: Both short-term (the current context window with recent conversation history) and long-term memory (documents retrieved from vector databases, with their similarity scores and retrieval timestamps). For the investor agent, this might include retrieved earnings reports, analyst recommendations, or historical price data. This reveals whether the agent had access to correct information when making decisions.</p></li><li><p><strong>Reasoning traces</strong>: The explicit chain-of-thought that transforms beliefs into actions. This is the &#8220;inner monologue&#8221; showing step-by-step logic. In the context of the investor agent, this would materialize as follows: <em>&#8220;Given current market conditions, I should first check recent earnings... The earnings report shows revenue decline... Therefore I&#8217;ll downgrade my recommendation...&#8221;</em> Capturing this requires either prompting techniques (explicitly asking the LLM to show its reasoning) or model introspection (extracting hidden layer activations).</p></li><li><p><strong>Actions and observations</strong>: Every tool call with its exact parameters, the raw tool output (not summarized), and the agent&#8217;s interpretation of that output. For the investor agent: calling <code>get_stock_price</code>, receiving the price data, then interpreting whether it signals a buying opportunity. This creates an audit trail showing whether failures originated from bad tool selection, incorrect parameter formatting, or misinterpretation of valid results.</p></li><li><p><strong>Plan evolution</strong>: How the agent&#8217;s high-level strategy changes across execution steps. Did it follow its original plan? When and why did it deviate? For the investor agent, it might start planning to analyze tech stocks, but after discovering high volatility, pivot to defensive sectors instead. Tracking plan modifications helps identify planning anomalies versus valid adaptive behavior.</p></li></ul><p>This fine-grained telemetry allows for high-fidelity tracing of decision paths and facilitates root cause analysis when behaviors deviate.</p></li></ul><p><strong>2. Anomaly Detection: Identifying Failures Beyond Metrics</strong></p><ul><li><p>MLOps relies on quantitative thresholds to detect issues (performance degradation, distribution shifts, SLA breaches).</p></li><li><p>Agentic systems require semantic-level anomaly detection to identify hallucinated or fabricated outputs, invalid tool selections or tool misuse, gaps in memory recall or context drift, and failures in coordination between multiple agents.</p></li><li><p>Detection methods range from white-box techniques (analyzing model internals) to black-box approaches (validating outputs against external ground truth).</p></li></ul><p><strong>3. Root Cause Analysis (RCA): Diagnosing Multi-Layered Failures</strong></p><p>MLOps RCA traces failures through data quality issues, model degradation, and infrastructure dependencies.</p><p>For agents, failures may arise from three distinct layers:</p><ol><li><p><strong>System-level</strong>: Infrastructure issues, broken APIs, or latency in external services</p></li><li><p><strong>Model-level</strong>: Hallucinations, reasoning limitations, or knowledge gaps</p></li><li><p><strong>Orchestration-level</strong>: Poor prompt design, suboptimal task decomposition, or ineffective tool usage</p></li></ol><p>A single anomaly may result from compounding issues across these layers.</p><p><strong>4. Resolution: Iterative Fixes Requiring Longitudinal Validation</strong></p><ul><li><p>In conventional systems, fixes can often be verified immediately through tests or re-deployment.</p></li><li><p>Agent systems, by contrast, require <strong>multi-turn validation</strong>: fixes (e.g., updated prompts, new constraints, tool adjustments) must be tested across multiple interaction cycles.</p></li><li><p>Side effects may only emerge over time, especially in multi-agent setups or long-horizon tasks. Each resolution should be treated as an experimental intervention, requiring observation, measurement, and potential rollback if new failure modes arise.</p></li></ul><h2>2. Building Observable Agent Systems: Tools and Frameworks</h2><h3>2.1 What Actually Fails in Agent Systems? </h3><p>To build robust and observable agent systems, we first need to understand what can go wrong. Unlike traditional software, where failures often stem from deterministic bugs or infrastructure issues, agent systems introduce an entirely new class of failures rooted in probabilistic reasoning, dynamic decision-making, and evolving memory states.</p><p>Wang et al. [1] offer a useful starting point with a taxonomy that distinguishes between two broad categories of anomalies:</p><ul><li><p><strong>Intra-agent</strong> arising within a single agent</p></li><li><p><strong>Inter-agent</strong> emerging from coordination across agents or between agents and their environment</p></li></ul><p>This distinction is crucial, as each class of failure calls for distinct detection mechanisms and intervention strategies.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lxGR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lxGR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png 424w, https://substackcdn.com/image/fetch/$s_!lxGR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png 848w, https://substackcdn.com/image/fetch/$s_!lxGR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png 1272w, https://substackcdn.com/image/fetch/$s_!lxGR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lxGR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png" width="1456" height="881" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:881,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:553442,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lxGR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png 424w, https://substackcdn.com/image/fetch/$s_!lxGR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png 848w, https://substackcdn.com/image/fetch/$s_!lxGR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png 1272w, https://substackcdn.com/image/fetch/$s_!lxGR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8ea68c2-e7e8-4663-9b08-69f64b47a1fb_2724x1648.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Taxonomy of Anomalies in Agent Systems From [1]</figcaption></figure></div><p>Empirical results show that these failures are not rare edge cases. They are <strong>inherent</strong> to current systems. Even cutting-edge agent frameworks show task success rates ranging from <strong>33% to 95%</strong>, depending on complexity [2]. For example:</p><ul><li><p>On the <strong>SWE-bench</strong> coding benchmark: <strong>33.83%&#8211;75.20%</strong></p></li><li><p>In <strong>web navigation tasks</strong>: <strong>37.20%&#8211;95.60%</strong> [2]</p></li></ul><h3>2.2 What Should AgentOps Tools Monitor? </h3><p>Modern observability tools for agent systems must balance two competing demands: capturing sufficient detail to enable debugging while avoiding prohibitive storage and performance overhead. Dong et al. [3] propose a comprehensive monitoring taxonomy based on systematic analysis of 17 production observability platforms.</p><p>Their framework identifies seven core observability dimensions essential for production agent deployments, ordered by criticality: tracing, m<strong>onitoring, guardrails, evaluation, feedback, customization and prompt management</strong></p><ul><li><p><strong>Tracing</strong> enables LLM/agent tracing to capture each agent span, a single operation like one LLM call, tool invocation, or retrieval step. This includes the complete execution chain: retrieval operations, LLM calls, tool invocations, evaluation spans, and user feedback.</p><ul><li><p>For the investment agent, this would mean tracking the complete flow: fetching market data &#8594; retrieving earnings reports &#8594; analyzing financials &#8594; synthesizing recommendations.</p></li><li><p>This forms the foundation for understanding <strong>agent behavior and debugging</strong> issues in production.</p></li></ul></li><li><p><strong>Monitoring</strong> provides agent analytics dashboards to monitor diverse level and dimension statistics metrics about agents, along with LLM cost management and tracking to monitor token spend with foundation model providers.</p><ul><li><p>For the investment agent, this would track how often it calls expensive financial APIs, how many LLM tokens are used per investment brief, and success rates across different market conditions.</p></li><li><p>These capabilities are essential for <strong>operational visibility and cost control</strong>.</p></li></ul></li><li><p><strong>Guardrails</strong> implement predefined rules and constraints to limit agent actions, ensuring safe and predictable behavior, with fallback and escalation paths that provide safe defaults or redirect cases to human operators in ambiguous or risky scenarios.</p><ul><li><p>For the investment agent, guardrails might prevent recommendations without sufficient data sources, or escalate to human analysts when market volatility is extreme.</p></li><li><p><strong>Safety mechanisms</strong> are critical for production deployments.</p></li></ul></li><li><p><strong>Evaluation</strong> allows testing agents against benchmarks and leaderboards by creating datasets, defining metrics, running evaluations, and tracking results over time.</p><ul><li><p>This includes evaluating final responses, single-step evaluation to assess any agent step in isolation (e.g., whether it selects the appropriate tool), and trajectory evaluation to verify whether the agent took the expected path of tool calls to arrive at the final answer.</p></li><li><p>For the investment agent, this means verifying: did it fetch the correct financial data? Did it call the news monitoring tool appropriately? Did the final recommendation align with the analysis?</p></li></ul></li><li><p><strong>Feedback</strong> mechanisms collect both explicit feedback (directly prompting users for thumbs up or thumbs down ratings) and implicit feedback (measuring user behavior through time spent on page and click-through rate).</p><ul><li><p>For the investment agent, portfolio managers might rate the quality of investment briefs, while implicit signals show which recommendations led to actual trades. These enable continuous improvement loops.</p></li></ul></li><li><p><strong>Customization</strong> enables the provision, spawning, and deployment of customizable and scalable autonomous agents.</p><ul><li><p>Agent capabilities can be extended through toolkits from marketplace integrations, multiple vector databases to improve retrieval performance, and fine-tuned models for business-specific use cases. </p></li><li><p>The investment agent can be customized with specialized financial data providers (Bloomberg, Reuters), sector-specific analysis tools, or fine-tuned models trained on historical investment reports.</p></li></ul></li><li><p><strong>Prompt management</strong> supports versioning to track different prompt versions for A/B testing and optimizing agent performance.</p><ul><li><p>Prompt playground with model comparisons allows testing different prompts and models before deployment, while prompt injection detection identifies potential code injection and secret leaks.</p></li><li><p>For the investment agent, teams can A/B test different analysis frameworks (&#8221;value investing&#8221; vs &#8220;growth investing&#8221; prompts), compare models for financial reasoning quality, and detect attempts to manipulate recommendations through malicious inputs.</p></li></ul></li></ul><h3>2.3 How Do Current AgentOps Tools Compare Across Key Features?</h3><p>While the previous taxonomy defines what <em>should</em> be monitored in production agent systems, the natural question follows: to what extent do existing tools actually implement these capabilities? To answer this, Dong et al. [3] evaluated production AgentOps platforms against the seven dimensions they identified in their November 2024 study.</p><p>The table below presents our comparative analysis, revealing significant heterogeneity in feature coverage across the current tool landscape.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2G78!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2G78!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png 424w, https://substackcdn.com/image/fetch/$s_!2G78!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png 848w, https://substackcdn.com/image/fetch/$s_!2G78!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png 1272w, https://substackcdn.com/image/fetch/$s_!2G78!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2G78!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png" width="1456" height="913" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:913,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:278796,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2G78!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png 424w, https://substackcdn.com/image/fetch/$s_!2G78!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png 848w, https://substackcdn.com/image/fetch/$s_!2G78!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png 1272w, https://substackcdn.com/image/fetch/$s_!2G78!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa321e6ab-e825-412f-af9b-c73a409d93bf_2406x1508.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Table &#8212; Key Features of AgentOps relevant Tools From [3]</figcaption></figure></div><p><em>* Added by the author</em></p><p><strong>Note on tool coverage</strong>: The rapid evolution of the AgentOps ecosystem means that notable platforms may emerge or mature after any snapshot analysis. For instance, MLflow 3.0 introduced comprehensive GenAI capabilities in mid-2024, with agent-specific features continuing to evolve through late 2024 releases. The table represents the state of tools as documented in Dong et al.&#8217;s systematic mapping study conducted through November 2024.</p><h3>3. MLflow for AgentOps: A Practical Implementation</h3><p>Having established both the theoretical requirements for AgentOps and the current state of tool support, let&#8217;s now turn to practical implementation. This section demonstrates how MLflow&#8217;s capabilities address the operational challenges identified earlier through a real-world multi-agent system.</p><p>Initially developed for traditional machine learning experiment tracking, <strong>MLflow has matured into a robust AgentOps platform</strong>. Its latest release introduces key capabilities that address the operational challenges outlined in Sections 1 and 2:</p><ul><li><p><strong>Execution Tracing:</strong> It captures detailed records of agent actions, tool usage, and decision paths</p></li><li><p><strong>Prompt Management:</strong> It enables versioning, comparison, and lifecycle control of behavioral instructions</p></li><li><p><strong>Evaluation Frameworks:</strong> It supports continuous, automated quality assessments through customizable metrics</p></li></ul><p>These features provide the foundation for building, monitoring, and refining complex agentic systems.</p><p><strong>The Investment Brief Agent System</strong></p><p>To demonstrate these capabilities, consider a multi-agent system designed for generating structured investment briefs. The architecture includes four specialized agents, each responsible for a distinct analytical task:</p><ol><li><p><strong>Data Fetch Agent:</strong> Retrieves stock prices, financial data, and key performance indicators from external APIs</p></li><li><p><strong>Financial Analysis Agent:</strong> Computes valuation metrics, financial health scores, and historical trends</p></li><li><p><strong>News Monitoring Agent:</strong> Identifies and summarizes relevant market news and sentiment shifts</p></li><li><p><strong>Investment Reasoning Agent:</strong> Synthesizes structured and unstructured inputs into coherent investment recommendations</p></li></ol><p>This architecture exhibits common failure modes: hallucinated prices, API errors, context loss in long reports, and flawed synthesis, making comprehensive observability essential.</p><p>You can find the code <a href="https://github.com/linafaik08/agentic-investor-brief">here</a> on GitHub.</p><h3>3.1 How To Trace Agent Decision-Making? </h3><p>The first operational challenge is understanding <em>how</em> agents actually make decisions. Traditional application monitoring falls short here as logging &#8220;Service A called Service B&#8221; reveals little about why an agent chose a particular tool, what information it considered, or how it reasoned from inputs to conclusions.</p><p>MLflow&#8217;s tracing addresses this gap by capturing not just <em>what</em> agents do, but <em>why</em> they make specific decisions. Unlike traditional application tracing (Service A &#8594; Service B), agent tracing records <strong>cognitive flows</strong> using hierarchical spans [3, 4]:</p><p><strong>Understanding the Span Hierarchy</strong></p><p>Think of spans as nested containers that capture different levels of agent cognition, from high-level task execution down to individual model calls:</p><ul><li><p><strong>Agent span</strong> sits at the top, representing the complete task execution. It captures the agent&#8217;s role (e.g., &#8220;Financial Analyst&#8221;), persona (e.g., &#8220;conservative value investor&#8221;), and overall success metrics.</p></li><li><p><strong>Reasoning spans</strong> record individual thinking steps. For the Financial Analysis Agent, this might capture: &#8220;Given P/E ratio of 23.4 and industry average of 18.2, stock appears overvalued relative to peers.&#8221;</p></li><li><p><strong>Planning spans</strong> document action selection decisions. When the agent decides &#8220;I need current news sentiment before finalizing my recommendation,&#8221; the span records both the goal (assess sentiment) and constraints (only articles from last 30 days).</p></li><li><p><strong>Tool spans</strong> track external interactions. When calling a financial data API, the span captures not just the raw API response, but how the agent interpreted it: &#8220;Retrieved revenue growth of 15% YoY, indicating strong expansion.&#8221;</p></li><li><p><strong>LLM spans</strong> provide the finest granularity, recording every model inference with complete prompts, generation parameters (temperature, max tokens), and exact token counts for cost attribution.</p></li></ul><p>The figure below illustrates these concepts in practice. When a user asks &#8220;What are Amazon&#8217;s main revenue streams and which segment generates the highest profit margins?&#8221;, MLflow captures the complete cognitive flow:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rZpg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rZpg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png 424w, https://substackcdn.com/image/fetch/$s_!rZpg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png 848w, https://substackcdn.com/image/fetch/$s_!rZpg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png 1272w, https://substackcdn.com/image/fetch/$s_!rZpg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rZpg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png" width="1456" height="1105" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1105,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:711276,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rZpg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png 424w, https://substackcdn.com/image/fetch/$s_!rZpg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png 848w, https://substackcdn.com/image/fetch/$s_!rZpg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png 1272w, https://substackcdn.com/image/fetch/$s_!rZpg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a496a2d-05c2-460b-92d1-0d79a01c536a_2026x1538.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Trace Visualization of an Agent&#8217;s Reasoning and Tool Use in MLflow</figcaption></figure></div><p>With MLFlow, enabling comprehensive tracing requires just a single line of code. Consider this simple example:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z2kg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z2kg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png 424w, https://substackcdn.com/image/fetch/$s_!Z2kg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png 848w, https://substackcdn.com/image/fetch/$s_!Z2kg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png 1272w, https://substackcdn.com/image/fetch/$s_!Z2kg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z2kg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png" width="1406" height="806" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:806,&quot;width&quot;:1406,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:254605,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Z2kg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png 424w, https://substackcdn.com/image/fetch/$s_!Z2kg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png 848w, https://substackcdn.com/image/fetch/$s_!Z2kg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png 1272w, https://substackcdn.com/image/fetch/$s_!Z2kg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1553ef2-60f2-41fd-af13-9ef525712954_1406x806.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>3.2 How To Manage Prompts as Production Artifacts?</h3><p>Prompts control agent behavior, defining roles, boundaries, quality standards, and safety constraints. Yet unlike code, they&#8217;ve historically lacked version control and systematic testing. MLflow&#8217;s Prompt Registry treats prompts as <strong>versioned, production artifacts</strong> requiring engineering discipline [2, 4].</p><p><strong>Version Control and Rollback</strong></p><p>The registry stores complete version history with timestamps, authors, and change descriptions [4]. Each version links to performance metrics: success rates, quality scores, costs, and latency. This enables:</p><ul><li><p><strong>A/B testing</strong>: Run multiple prompt versions simultaneously on production traffic, comparing outcomes statistically to identify which performs best</p></li><li><p><strong>Instant rollback</strong>: When issues arise, revert to previous stable versions immediately (milliseconds, no redeployment)</p></li><li><p><strong>Performance tracking</strong>: Query &#8220;Which prompt achieved highest quality?&#8221; or &#8220;Most cost-efficient prompt maintaining 90%+ accuracy?&#8221;</p></li></ul><p><strong>Testing Gates for Production Promotion</strong></p><p>Before any prompt reaches production, it undergoes systematic validation [4]:</p><ul><li><p><strong>Regression testing</strong>: Verify performance against historical test cases to ensure the new version doesn&#8217;t reintroduce resolved issues</p></li><li><p><strong>Adversarial testing</strong>: Challenge the prompt with edge cases&#8212;missing data, contradictory information, ambiguous queries&#8212;to expose failure modes before they impact users</p></li><li><p><strong>Performance profiling</strong>: Measure token efficiency and response latency to catch prompts that sacrifice speed or cost-effectiveness for marginal quality gains</p></li></ul><p><strong>Operational Impact</strong></p><p>The registry transforms prompt changes from ad-hoc experiments into <strong>trackable, testable, reversible interventions</strong> with complete audit trails. When failures occur in production, operators can immediately determine whether issues correlate with recent prompt changes versus other factors (model updates, data quality, API failures). Teams naturally adopt code-like discipline: peer reviews for prompt changes, comprehensive documentation of intent and constraints, validation gates before promotion, and staged rollouts (10% of traffic &#8594; 50% &#8594; 100%)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!udmz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!udmz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png 424w, https://substackcdn.com/image/fetch/$s_!udmz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png 848w, https://substackcdn.com/image/fetch/$s_!udmz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png 1272w, https://substackcdn.com/image/fetch/$s_!udmz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!udmz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png" width="1456" height="868" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:868,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:380475,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!udmz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png 424w, https://substackcdn.com/image/fetch/$s_!udmz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png 848w, https://substackcdn.com/image/fetch/$s_!udmz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png 1272w, https://substackcdn.com/image/fetch/$s_!udmz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e86dacc-6b38-4d76-a55d-c2d27e882520_1728x1030.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; Comparison View of Prompt Versions in MLflow</figcaption></figure></div><p>The following code demonstrates how to register a versioned prompt template for the Financial Analysis Agent:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VhAI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VhAI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png 424w, https://substackcdn.com/image/fetch/$s_!VhAI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png 848w, https://substackcdn.com/image/fetch/$s_!VhAI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png 1272w, https://substackcdn.com/image/fetch/$s_!VhAI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VhAI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png" width="1362" height="698" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:698,&quot;width&quot;:1362,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:239844,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VhAI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png 424w, https://substackcdn.com/image/fetch/$s_!VhAI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png 848w, https://substackcdn.com/image/fetch/$s_!VhAI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png 1272w, https://substackcdn.com/image/fetch/$s_!VhAI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8d76c-b735-4d15-a516-adc2fb064792_1362x698.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>3.3 How To Evaluate Agent Quality Continuously?</h3><p>Traditional software either passes or fails tests. In contrast, agent systems operate in a gray area: the same prompt may yield dozens of plausible responses&#8212;none strictly &#8220;correct,&#8221; yet varying widely in quality.</p><p>To address this ambiguity, <strong>MLflow&#8217;s evaluation framework</strong> focuses on <strong>multi-dimensional quality assessment</strong> rather than binary correctness. This enables robust validation even under the non-deterministic behavior typical of LLM-based agents [2, 5].</p><p><strong>Evaluation Approaches</strong></p><p>MLflow supports three complementary evaluation strategies:</p><ul><li><p><strong>LLM-as-Judge Metrics</strong></p><p>Large language models act as evaluators, scoring outputs against structured rubrics. This approach captures nuanced attributes such as:</p><ul><li><p><strong>Answer correctness</strong> (factual accuracy)</p></li><li><p><strong>Semantic similarity</strong> (closeness to reference)</p></li><li><p><strong>Context relevance</strong> (appropriateness given prompt context)</p><p>These judges approximate human evaluation and support fine-grained quality analysis.</p></li></ul></li><li><p><strong>Heuristic Metrics</strong></p><p>These are rule-based, function-driven scores including Rouge/BLEU for text similarity, Flesch-Kincaid for readability, toxicity for safety, and latency/token_count for performance.</p></li><li><p><strong>Custom Scorers</strong></p><p>Developers can define tailored functions to validate tool usage patterns, constraint satisfaction, domain-specific correctness (e.g. financial ratios, legal disclaimers)</p></li></ul><p><strong>Tracking &amp; Iteration</strong></p><p>MLflow integrates evaluation tightly into experiment tracking:</p><ul><li><p><strong>Run-level Logging</strong>: All evaluation results are logged per run, enabling direct comparison across models, prompts, or agent strategies.</p></li><li><p><strong>Aggregate Agent Scores</strong>: System-level dashboards summarize quality, cost, and latency using metrics like <code>token_count</code>, <code>response_time</code>, and <code>score_distribution</code>.</p></li></ul><p><strong>Evaluation-Driven Development</strong></p><p>MLflow promotes a rigorous, feedback-driven development loop:</p><ol><li><p><strong>Establish baseline metrics</strong> on faithfulness, relevance, reasoning quality, etc.</p></li><li><p><strong>Identify failure patterns</strong> via traces and evaluation scores.</p></li><li><p><strong>Implement improvements</strong>, e.g. new prompts, tools, memory strategies.</p></li><li><p><strong>Re-evaluate</strong> to quantify impact and regressions.</p></li></ol><p>Traces capture multi-step behavior&#8212;including tool use, intermediate outputs, and decisions&#8212;enabling root cause analysis beyond final responses.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!STtS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!STtS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png 424w, https://substackcdn.com/image/fetch/$s_!STtS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png 848w, https://substackcdn.com/image/fetch/$s_!STtS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png 1272w, https://substackcdn.com/image/fetch/$s_!STtS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!STtS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png" width="1218" height="571" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:571,&quot;width&quot;:1218,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:97846,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!STtS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png 424w, https://substackcdn.com/image/fetch/$s_!STtS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png 848w, https://substackcdn.com/image/fetch/$s_!STtS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png 1272w, https://substackcdn.com/image/fetch/$s_!STtS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F513226a3-e27d-43f4-9f6e-593e90ad170b_1218x571.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure &#8212; GenAI Evaluation Dashboard in MLflow From [4]</figcaption></figure></div><p>The following code demonstrates how few lines of Python enable systematic quality validation with both correctness checking and custom safety criteria:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gcCM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gcCM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png 424w, https://substackcdn.com/image/fetch/$s_!gcCM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png 848w, https://substackcdn.com/image/fetch/$s_!gcCM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png 1272w, https://substackcdn.com/image/fetch/$s_!gcCM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gcCM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png" width="1456" height="1258" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1258,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:568917,&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://aipractitioner.substack.com/i/175258914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gcCM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png 424w, https://substackcdn.com/image/fetch/$s_!gcCM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png 848w, https://substackcdn.com/image/fetch/$s_!gcCM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png 1272w, https://substackcdn.com/image/fetch/$s_!gcCM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fee0713-0e8f-49fa-af02-fe764ed418c7_2100x1814.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Key Takeaways</h2><p>&#10003; <strong>AgentOps represents a fundamental paradigm shift from MLOps</strong>: Unlike traditional ML systems that produce single predictions, agent systems require monitoring <em>cognitive state,</em> capturing not just what agents did, but why they made specific decisions through reasoning traces, memory contents, and plan evolution.</p><p>&#10003; <strong>Agent failures are inherently different and more complex</strong>: While traditional systems fail deterministically with error codes, agents fail silently with confident hallucinations, tool misuse, and context drift. Current production systems show success rates ranging from only 33% to 95%, making robust observability critical.</p><p>&#10003; <strong>The AgentOps lifecycle extends DevOps to handle probabilistic reasoning</strong>: The four-stage framework (monitoring &#8594; anomaly detection &#8594; root cause analysis &#8594; resolution) must account for semantic-level failures across three distinct layers: system-level (infrastructure), model-level (hallucinations), and orchestration-level (prompt design).</p><p>&#10003; <strong>Seven core observability dimensions are essential for production agents</strong>: Tracing captures execution flows, monitoring provides operational visibility, guardrails ensure safety, evaluation validates quality, feedback enables improvement loops, customization extends capabilities, and prompt management treats prompts as versioned production artifacts.</p><p>&#10003; <strong>MLflow provides comprehensive AgentOps capabilities with minimal code</strong>: Hierarchical span tracing captures complete cognitive flows, the Prompt Registry enables version control with A/B testing and instant rollback, and the evaluation framework supports multi-dimensional quality assessment. This enables production-grade observability with just a few lines of Python.</p><div><hr></div><h3>References</h3><p><strong>[1]</strong> Wang, Z., Li, J., Zhou, Q., Si, H., Liu, Y., Li, J., Xie, G., Sun, F., Pei, D., &amp; Pei, C. (2025). <a href="https://arxiv.org/abs/2508.02121">A Survey on AgentOps: Categorization, Challenges, and Future Directions</a>. <em>arXiv preprint arXiv:2508.02121</em>. </p><p><strong>[2]</strong> Kreuzberger, D., K&#252;hl, N., &amp; Hirschl, S. (2023). <a href="https://arxiv.org/abs/2205.02302">Machine learning operations (MLOps): Overview, definition, and architecture</a>. <em>IEEE Access</em>, <em>11</em>, 31866-31879.</p><p><strong>[3]</strong> Dong, L., Lu, Q., &amp; Zhu, L. (2024). <a href="https://arxiv.org/abs/2411.05285">AgentOps: Enabling Observability of LLM Agents</a>. <em>arXiv preprint arXiv:2411.05285</em>.</p><p><strong>[4]</strong> <a href="https://mlflow.org/docs/latest/genai/">MLflow Documentation</a>. (2025).</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Balancing Conflicting Goals: A Practical Guide to Multi-Objective Optimization with Pymoo]]></title><description><![CDATA[A Deep Dive Into Solving Real-World Trade-Offs Using NSGA-II]]></description><link>https://aipractitioner.substack.com/p/balancing-conflicting-goals-a-practical</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/balancing-conflicting-goals-a-practical</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 31 Jul 2025 16:07:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!C7eJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!C7eJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!C7eJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png 424w, https://substackcdn.com/image/fetch/$s_!C7eJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png 848w, https://substackcdn.com/image/fetch/$s_!C7eJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png 1272w, https://substackcdn.com/image/fetch/$s_!C7eJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!C7eJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png" width="1456" height="603" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:603,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:502625,&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://aipractitioner.substack.com/i/169117228?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!C7eJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png 424w, https://substackcdn.com/image/fetch/$s_!C7eJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png 848w, https://substackcdn.com/image/fetch/$s_!C7eJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png 1272w, https://substackcdn.com/image/fetch/$s_!C7eJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb582ce4f-994c-481b-a71f-07e61cb81b9f_2236x926.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><p><em>This article is also available as a podcast! If you're on the go or just want to absorb the content in audio format, you can listen to the full episode below &#128071; The podcast is also available on <a href="https://open.spotify.com/show/6MROBKvrjx0Mey8tHud5LX">Spotify</a> and <a href="https://podcasts.apple.com/us/podcast/the-ai-practitioner-podcast/id1830285899">Apple Podcasts</a>. </em></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;8e8fa55d-1301-4c6f-8520-5500f3a6b503&quot;,&quot;caption&quot;:&quot;Prefer reading instead? The full article is available here.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;PODCAST &#8212; Balancing Conflicting Goals: A Practical Guide to Multi-Objective Optimization with Pymoo&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:7177021,&quot;name&quot;:&quot;Lina Faik&quot;,&quot;bio&quot;:&quot;Lead AI Scientist bringing AI research to real-world impact across industries. Independent consultant, previously at Dataiku.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bdaf5e6-a6c6-48fe-80f6-3d69aaac1694_2256x2256.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-07-31T16:03:55.871Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa75a345-7e2d-4e27-8ea2-a8227741f5d7_1456x603.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://aipractitioner.substack.com/p/podcast-balancing-conflicting-goals&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:169760559,&quot;type&quot;:&quot;podcast&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;The AI Practitioner&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ivps!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd008f4f7-a625-4156-98dc-df1fd3c14b2c_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>Real-world decisions often involve competing objectives. In supply chain management, for instance, increasing sales and minimizing overstock are two goals that frequently conflict. Traditional optimization approaches tend to merge these goals into a single objective by applying fixed weights&#8212;an approach that can oversimplify the problem and obscure critical trade-offs.</p><p><strong>Multi-objective optimization</strong> offers a more nuanced alternative. Rather than combining objectives into a single equation, it treats each one independently. This allows us to better capture the inherent tension between goals and explore a range of optimal trade-offs. The outcome is a <strong>Pareto front</strong>: a set of solutions where improving one objective necessarily comes at the expense of another. This empowers decision-makers to select the solution that best aligns with their current priorities&#8212;without being constrained by arbitrary weightings.</p><p>In this article, we show how to approach a two-objective problem using the Python library <strong>pymoo</strong>, with a focus on the widely adopted and robust <strong>Non-dominated Sorting Genetic Algorithm II (NSGA&#8209;II).</strong> [1]</p><p>The approach is illustrated with a real-world example: optimizing product dispatch across a network of retail locations.</p><h4>Objective</h4><p>After reading this article, you will understand:</p><ol><li><p>How can a real-world dispatch problem with conflicting objectives be properly modeled and solved?</p></li><li><p>What are the key mechanisms behind NSGA-II, and how does it address the challenge of balancing multiple objectives?</p></li><li><p>How can Multi-Criteria Decision Making (MCDM) methods be used to evaluate the trade-offs between solutions?</p></li></ol><blockquote><p>This article assumes a basic understanding of optimization concepts (such as objective functions and constraints) and some experience with Python programming.</p><p>All experiments were conducted using the Python libraries <strong><a href="https://pymoo.org/">pymoo</a></strong> and <a href="https://plotly.com/">plotly</a>.</p></blockquote><p>You can find the code here on <a href="https://github.com/linafaik08/multiobj-optimization-pymoo?tab=readme-ov-file">GitHub</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>1. The Problem at Hand: Boosting Sales Without Overstocking</h2><h3>1.1. Why simple dispatch strategies fall short in the real world?</h3><p>In theory, product dispatch in retail seems to be a straightforward task: distribute products to stores based on forecasted demand. In practice, however, na&#239;ve dispatch strategies often fail to deliver efficient and reliable outcomes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GOb6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GOb6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png 424w, https://substackcdn.com/image/fetch/$s_!GOb6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png 848w, https://substackcdn.com/image/fetch/$s_!GOb6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png 1272w, https://substackcdn.com/image/fetch/$s_!GOb6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GOb6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png" width="408" height="420.5153374233129" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:672,&quot;width&quot;:652,&quot;resizeWidth&quot;:408,&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="https://substackcdn.com/image/fetch/$s_!GOb6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png 424w, https://substackcdn.com/image/fetch/$s_!GOb6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png 848w, https://substackcdn.com/image/fetch/$s_!GOb6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png 1272w, https://substackcdn.com/image/fetch/$s_!GOb6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc42c6f7a-34a6-4a50-a926-9719c6d872ba_652x672.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Dispatch from a central warehouse to multiple retail stores</figcaption></figure></div><h4><strong>Common baseline</strong></h4><p>A common baseline strategy would be to send to each store as much as they are forecasted to sell. While it seems reasonable as we avoid overstocking and undersupply, it falls short for the main reasons:</p><ol><li><p><strong>It ignores uncertainty</strong>: Demand forecasts are never perfect. Some stores will sell more than expected, others less. Relying blindly on forecast values leads to lost sales or unused stock.</p></li></ol><blockquote><p>Example: A sudden storm hits a region. Stores there sell out of raincoats, while others are overstocked. A rigid dispatch plan would not catch that.</p></blockquote><ol><li><p><strong>It ignores trade-offs</strong>: In shortage scenarios, where total available stock is limited, allocating strictly by forecast does not account for priority, sales potential, or stock efficiency.</p></li></ol><blockquote><p>Example: A flagship store may need to always have products on shelves to protect brand image, even if its forecast is lower than smaller stores.</p></blockquote><h4><strong>Single-objective optimization</strong></h4><p>One might try to overcome this with a single-objective formulation to maximize, such as:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\alpha *Sales -\\beta*Overstock&quot;,&quot;id&quot;:&quot;KGVRMYSRBF&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>This scalarization reduces the problem to something a solver can optimize, but at the cost of:</p><ul><li><p>Choosing arbitrary weights (&#945;, &#946;), which strongly bias the result.</p></li><li><p>Losing interpretability as it is unclear how much one objective is being sacrificed for the other.</p></li><li><p>Finding only one solution, when there are multiple viable trade-offs.</p></li></ul><p>This is a core limitation that traditional methods like linear programming suffer from.</p><h4><strong>The extra hurdle: dealing with forecast uncertainty</strong></h4><p>Even with a good model, forecasting is never exact. Errors of &#177;10&#8211;20% are common in retail due to promotions, seasonality, and local events. A truly robust dispatch strategy must account for these uncertainties. This means not by blindly trusting forecasts, but by simulating multiple plausible scenarios and planning for what works on average, or under worst-case assumptions.</p><h3>1.2. How to account for competing objectives in dispatch problem formulation?</h3><p>To address the limitations of na&#239;ve and single-objective dispatch strategies, we need to acknowledge that retail dispatch is fundamentally a multi-objective problem. There is not a single &#8220;best&#8221; way to dispatch products but many viable trade-offs between competing goals.</p><p>The dispatch problem involves making the following decision: How many units should be sent to each store, given limited overall stock?</p><h4>Notations</h4><p>Let&#8217;s denote:</p><ul><li><p><em>x_i</em>: the number of units dispatched to store <em>i</em></p></li><li><p><em>d_i</em>: the demand forecast at store</p></li><li><p><em>S</em>: the total number of units available to dispatch</p></li></ul><p>Our two objectives are:</p><p>Objectives</p><p>For each product and on each day, the two objectives to optimize are:</p><ol><li><p><strong>Maximize expected sales</strong></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_1(x) = \\sum_i{min(x_i, d_i)}&quot;,&quot;id&quot;:&quot;CCZKDILCFP&quot;}" data-component-name="LatexBlockToDOM"></div><p></p></li><li><p><strong>Minimize expected overstock</strong></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_2(x) = \\sum_i{max(x_i-d_i,0)}&quot;,&quot;id&quot;:&quot;BNIWHRTTOA&quot;}" data-component-name="LatexBlockToDOM"></div></li></ol><h3>Contraints</h3><p>Subject to:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;0 &#8804; x_i&quot;,&quot;id&quot;:&quot;UYXLJQHOTK&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\sum_i x_i &#8804; S&quot;,&quot;id&quot;:&quot;RWACTWLGIN&quot;}" data-component-name="LatexBlockToDOM"></div><p>These constraints ensure that each store receives a non-negative quantity of products and that the total dispatch does not exceed the available stock</p><h4>Stochastic optimization</h4><p>In reality, demand forecasts are not fixed values, but rather estimates subject to error. Each forecast comes with uncertainty due to unpredictable factors like promotions, weather, local events, or competitor actions.</p><p>To handle this, we frame the problem as a <strong>stochastic optimization</strong> problem.</p><blockquote><p>Stochastic optimization refers to optimization problems where some of the inputs are uncertain or random. The goal is to find solutions that perform well on average, or under worst-case scenarios.</p></blockquote><p>Rather than relying on a single point forecast, the forecast is treated as a central estimate around which multiple demand scenarios are generated. These scenarios reflect realistic variations in demand.</p><p>One simple way to do this is to assume demand varies around the forecast according to a normal distribution, where the standard deviation is defined using historical forecast errors (e.g. &#177;15%). This transforms our view of demand from deterministic to probabilistic.</p><p>A more advanced and often more accurate approach involves using probabilistic forecasting models, including those based on machine learning. Unlike traditional models that output a single value, these models provide a full distribution or confidence interval, directly incorporating their own uncertainty into the forecast.</p><p>With these scenarios in hand whether sampled from a statistical distribution or learned from data, we can evaluate the performance of each candidate dispatch plan. For every scenario, we compute how many units would be sold (based on the realized demand) and how many would be left unsold, indicating overstock. By averaging the results over all scenarios, we obtain expected sales, a more realistic performance metric under uncertainty, and expected overstock, which captures the inefficiency of over-supplying.</p><p>This approach supports robust decision-making, ensuring that the dispatch plan performs reliably across a wide range of possible future outcomes, rather than being optimized for a single, potentially inaccurate forecast.</p><h3>1.3. Looking at the data: forecasts, inventory, and the challenge of allocation</h3><p>To make this problem concrete, we use a publicly available retail dataset from <a href="https://www.kaggle.com/datasets/anirudhchauhan/retail-store-inventory-forecasting-dataset/data">Kaggle</a>. It simulates a realistic inventory forecasting scenario in a multi-store retail setting and provides the essential building blocks for dispatch optimization.</p><p>The dataset includes daily records for multiple products and stores. Here are the key fields we rely on:</p><ul><li><p><strong>Date</strong>: Daily granularity, spanning a consistent time window across all stores and products.</p></li><li><p><strong>Store ID</strong> and <strong>Product ID</strong>: Unique identifiers for each store-product pair.</p></li><li><p><strong>Inventory Level</strong>: The stock available at the beginning of the day in each store.</p></li><li><p><strong>Demand Forecast</strong>: The predicted demand for the day, derived from past sales trends.</p></li></ul><p>To simplify the problem setup, it is assumed that the stock available for dispatch each day is equal to the total inventory across all stores. In other words, store inventories are treated as if they were pooled into a single centralized warehouse with no lead time. The core objective becomes determining how to redistribute this shared inventory across the stores to best meet daily demand.</p><p>To simulate shortage scenarios the total dispatchable stock is randomly reduced on certain days. This models real-world constraints such as supply chain disruptions, delayed replenishments, or capacity limitations. As a result, the optimization must make strategic trade-offs in allocating limited stock across competing demands.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uRyw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uRyw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png 424w, https://substackcdn.com/image/fetch/$s_!uRyw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png 848w, https://substackcdn.com/image/fetch/$s_!uRyw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png 1272w, https://substackcdn.com/image/fetch/$s_!uRyw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uRyw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png" width="1456" height="482" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:482,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!uRyw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png 424w, https://substackcdn.com/image/fetch/$s_!uRyw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png 848w, https://substackcdn.com/image/fetch/$s_!uRyw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png 1272w, https://substackcdn.com/image/fetch/$s_!uRyw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3178c832-bde1-4c1a-944a-0e293541a986_2000x662.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2 &#8211; Evolution of stock and demand for product P0006. Daily available units (orange) and demand forecast (green) are shown over time. Red dots indicate shortage events, where forecasted demand exceeds available stock. This highlights the variability of both supply and demand, and the importance of robust allocation strategies under uncertainty.</figcaption></figure></div><h2>2. Multi-Objective Optimization with NSGA-II: From Pareto Front to Practical Decision</h2><h3>2.1. How does NSGA-II find a diverse set of optimal trade-offs?</h3><p>In the early 2000s, most multi-objective optimization techniques relied on repeatedly solving single-objective formulations with different weightings to explore trade-offs. This approach was inefficient, highly sensitive to weight selection, and rarely resulted in a well-distributed set of Pareto-optimal solutions.</p><p>Recognizing these limitations, Deb et al. introduced NSGA-II (Non-dominated Sorting Genetic Algorithm II) in 2002 [1]. It quickly became one of the most widely used evolutionary algorithms for multi-objective optimization. It remains today a reference due to its speed, simplicity, and ability to discover well-spread solutions in a single run.</p><h4>NSGA-II: An evolutionary algorithm for multi-objective optimization</h4><p>NSGA-II belongs to the evolutionary algorithm (EA) family. Like all EAs, it evolves a population of candidate solutions over successive generations, using principles inspired by natural selection. NSGA-II is specifically designed for multi-objective optimization, where the goal is not to find a single best solution, but a set of <strong>non-dominated solutions</strong>.</p><blockquote><p>In a multi-objective problem, a solution is said to dominate another if it is no worse in all objectives and strictly better in at least one.</p><p><strong>Example</strong>: A warehouse has 200 units of a product.</p><p>&#10003; Solution A sends 120 to Store A (forecasted demand: 130) and 80 to Store B (forecast: 60). This leads to higher sales but more overstock.</p><p>&#10003; Solution B sends 100 to each. This leads to less overstock and slightly lower expected sales.</p><p>&#10003; Neither is strictly better, both are non-dominated.</p></blockquote><p>Each generation in NSGA-II follows three main steps, adapted for multi-objective problems:</p><ul><li><p><strong>Selection</strong>: NSGA-II selects parents using binary tournament selection, a simple yet effective method where two candidates are randomly chosen, and the more promising one is picked to reproduce. This mimics natural competition in evolutionary processes.</p></li></ul><blockquote><p>If Solution A leads to better sales with similar overstock than Solution B, it's selected for the next generation.</p></blockquote><ul><li><p><strong>Crossover</strong>: Selected parents undergo crossover (e.g., simulated binary crossover) to generate &#8220;offspring,&#8221; combining characteristics of both parents.</p></li></ul><blockquote><p>Two dispatch plans [120, 80] and [100, 100] may produce [110, 90].</p></blockquote><ul><li><p><strong>Mutation</strong>: Offspring are randomly mutated to maintain diversity and help explore new areas of the solution space.</p></li></ul><blockquote><p>[110, 90] mutates to [115, 85], shifting 5 units to better match changing forecasts.</p></blockquote><p>The resulting set of non-dominated solutions forms an approximation of the Pareto front, a curve (or surface) representing the best achievable compromises between conflicting objectives, such as increasing sales while reducing overstock.</p><h4>The three pillars of NSGA-II: Sorting, crowding, elitism</h4><p>NSGA-II introduced three important innovations over earlier multi-objective algorithms:</p><p><strong>1. Fast non-dominated sorting</strong></p><p>One of NSGA-II&#8217;s key innovations is a fast and hierarchical sorting algorithm to classify solutions based on Pareto dominance.NSGA-II uses this principle to organize the population into layers, or non-dominated fronts:</p><ul><li><p><strong>Front 1</strong> contains solutions not dominated by any other &#8212; these represent the current approximation of the Pareto front.</p></li><li><p><strong>Front 2</strong> contains solutions dominated only by those in Front 1.</p></li><li><p><strong>Front 3</strong> is dominated only by solutions in the first two fronts, and so on.</p></li></ul><p>This forms a hierarchical structure: each front reflects a decreasing level of dominance quality. The algorithm uses this structure to assign ranks to each solution, with lower ranks being preferred during selection.</p><p>In the original NSGA algorithm (1994), non-dominated sorting had a computational complexity of O(MN^3), which became a bottleneck for large populations. NSGA-II introduces an optimized method that reduces this to O(MN^2), where:</p><ul><li><p>N is the number of individuals in the population</p></li><li><p>M is the number of objectives</p></li></ul><p>This improvement is achieved by tracking the number of solutions that dominate each individual, and maintaining a list of individuals that each solution dominates</p><p>The sorting proceeds by iteratively building each front from solutions with zero domination count (i.e., currently non-dominated) and updating the domination counts of others. This approach avoids redundant comparisons and streamlines the entire process.</p><p>In simpler terms: instead of exhaustively comparing each solution with every other, NSGA-II efficiently builds up layers of dominance.</p><p>This hierarchical and efficient approach makes NSGA-II scalable and practical for solving real-world multi-objective problems with large search spaces, such as our dispatch optimization use case.</p><p><strong>2. Crowding Distance</strong></p><p>To maintain diversity, NSGA-II does not just select the best-ranked solutions, it also favors those that are less crowded in objective space. This ensures that the algorithm not only converges toward optimal solutions but also explores a wide range of trade-offs.</p><p>To do this, NSGA-II introduces the concept of crowding distance, a measure of how isolated a solution is compared to its neighbors within the same Pareto front. For each solution, the algorithm estimates the "space" around it by computing the normalized distance between its nearest neighbors along each objective.</p><p>Solutions with higher crowding distance are preferred during selection when multiple individuals have the same dominance rank. This pushes the algorithm to spread solutions across the Pareto front, avoiding premature convergence to any particular region.</p><blockquote><p>Imagine three candidate dispatch strategies:</p><p>A: 95% sales, 20% overstock</p><p>B: 96% sales, 21% overstock</p><p>C: 92% sales, 15% overstock</p><p>If A and B are very close in objective space, and C is farther apart, NSGA-II will likely prioritize C even if it&#8217;s slightly less optimal, because it provides a different perspective on the trade-off, and helps construct a more representative Pareto front.</p></blockquote><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XeUA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XeUA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png 424w, https://substackcdn.com/image/fetch/$s_!XeUA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png 848w, https://substackcdn.com/image/fetch/$s_!XeUA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png 1272w, https://substackcdn.com/image/fetch/$s_!XeUA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XeUA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png" width="366" height="284.736660929432" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:904,&quot;width&quot;:1162,&quot;resizeWidth&quot;:366,&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="https://substackcdn.com/image/fetch/$s_!XeUA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png 424w, https://substackcdn.com/image/fetch/$s_!XeUA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png 848w, https://substackcdn.com/image/fetch/$s_!XeUA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png 1272w, https://substackcdn.com/image/fetch/$s_!XeUA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00f43081-42e7-4f9c-9223-d480bfedb3f5_1162x904.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3 &#8211; Crowding distance estimation in NSGA-II, Source [1]</figcaption></figure></div><p><strong>Legend:</strong></p><ul><li><p><strong>f&#8321;, f&#8322;</strong>: Objective functions multi-optimization problem.</p></li><li><p><strong>Black circles</strong>: Non-dominated solutions on the current Pareto front.</p></li><li><p><strong>White circles</strong>: Dominated or non-selected solutions (not on the current front).</p></li><li><p><strong>i-1, i, i+1</strong>: Consecutive individuals on the same front, sorted by objective values.</p></li><li><p><strong>Cuboid</strong>: Represents the crowding region for individual <em>i</em>, bounded by its two neighbors (<em>i-1</em> and <em>i+1</em>). The crowding distance is computed as the perimeter (or volume in higher dimensions) of this cuboid.</p></li></ul><p>This crowding-based diversity mechanism eliminates the need for manually tuned niche parameters used in earlier algorithms (like the original NSGA), making NSGA-II both simpler to configure and more robust in practice.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hCMm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hCMm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png 424w, https://substackcdn.com/image/fetch/$s_!hCMm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png 848w, https://substackcdn.com/image/fetch/$s_!hCMm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png 1272w, https://substackcdn.com/image/fetch/$s_!hCMm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hCMm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png" width="560" height="319" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:319,&quot;width&quot;:560,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!hCMm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png 424w, https://substackcdn.com/image/fetch/$s_!hCMm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png 848w, https://substackcdn.com/image/fetch/$s_!hCMm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png 1272w, https://substackcdn.com/image/fetch/$s_!hCMm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fc8bd7-87f2-4b68-ab25-1baaebddcec0_560x319.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4 &#8212; NSGA-II selection procedure, Source [3]</figcaption></figure></div><ul><li><p><strong>P&#8348;</strong>: Parent population at generation <em>t</em>.</p></li><li><p><strong>Q&#8348;</strong>: Offspring population generated from <em>P&#8348;</em> using variation operators (e.g., crossover and mutation).</p></li><li><p><strong>R&#8348;</strong>: Combined population (<em>P&#8348;</em> &#8746; <em>Q&#8348;</em>), which is the input for non-dominated sorting.</p></li><li><p><strong>F&#8321;, F&#8322;, F&#8323;...</strong>: Fronts generated through non-dominated sorting. <em>F&#8321;</em> contains the best non-dominated solutions, followed by <em>F&#8322;</em>, and so on.</p></li><li><p><strong>Crowding Distance Sorting</strong>: Within each front, solutions are ranked based on crowding distance to maintain diversity.</p></li><li><p><strong>Rejected</strong>: Solutions that are not selected for the next generation due to rank or low crowding distance.</p></li><li><p><strong>P&#8348;&#8330;&#8321;</strong>: Next generation population selected from the best-ranked and most diverse solutions.</p></li></ul><p><strong>3. Elitism</strong></p><p>NSGA-II introduces elitism to ensure that the best solutions discovered so far are not lost in future generations, a key improvement over earlier algorithms like the original NSGA.</p><p>At each generation, the algorithm:</p><ol><li><p><strong>Merges</strong> parent and offspring populations,</p></li><li><p><strong>Sorts</strong> the combined population using non-dominated sorting and crowding distance,</p></li><li><p><strong>Selects</strong> the top individuals to carry forward.</p></li></ol><p>This guarantees that high-quality solutions remain in the population, even if new offspring don&#8217;t outperform them, helping the algorithm converge more reliably toward the Pareto front.</p><p>In a dispatch context, elitism ensures that a strong dispatch plan &#8212; say, one that achieves excellent sales with acceptable overstock &#8212; isn&#8217;t accidentally discarded as the algorithm evolves.</p><h3>2.2. How can Multi-Criteria Decision Making (MCDM) techniques guide final selection?</h3><p>NSGA-II returns a set of non-dominated solutions that represent trade-offs between objectives (e.g., maximizing sales vs. minimizing overstock).</p><p>However, in practice, decision-makers need to select a single solution to implement. This is where <strong>Multi-Criteria Decision Making (MCDM)</strong> techniques come in.</p><p>Two commonly used methods, both supported in <code>pymoo,</code> are the <strong>Augmented Scalarization Function (ASF)</strong> and the <strong>Pseudo-Weights</strong> approach. Each offers a different way to apply preferences and identify the most suitable dispatch plan.</p><h4>Augmented Scalarization Function (ASF)</h4><p>ASF selects the solution closest to the ideal point in objective space, based on a weight vector <em>w = (w_1, w_2)</em> that reflects the relative importance of each objective.</p><p>The ASF for a solution x with objective values <em>f(x)</em> is defined as:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;ASF(x) = max_i (\\frac{f_i(x)-z^*_i}{w_i})&quot;,&quot;id&quot;:&quot;AXJPZXHYQG&quot;}" data-component-name="LatexBlockToDOM"></div><p>Where:</p><ul><li><p><em>f_i(x)</em>: objective <em>i</em> value of solution <em>x</em></p></li><li><p><em>z</em>*: the ideal (best) value for each objective across the front</p></li><li><p><em>w_i</em>: weight assigned to objective <em>i</em></p></li></ul><p>This approach helps select a balanced solution that minimizes the worst deviation from the ideal.</p><h4><strong>Pseudo-Weights</strong></h4><p>Pseudo-weights, unlike ASF weights, are not specified by the user. Instead, they are derived from each solution itself, and represent the relative importance of each objective based on the solution&#8217;s position within the Pareto front.</p><p>For a solution x, with the objectives <em>f_i(x)</em>, the pseudo-weight <em>w_i(x)</em> is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;w_i(x) = \\frac{\\frac{f_i^{max}-f_i(x)}{f_i^{max}-f_i^{min}}}{\\sum^M_{m=1}\\frac{f_m^{max}-f_m(x)}{f_m^{max}-f_m^{min}}}&quot;,&quot;id&quot;:&quot;OEEDUVVBDV&quot;}" data-component-name="LatexBlockToDOM"></div><p>Where:</p><ul><li><p><em>f_i</em>(max), <em>f_i</em>(min): max and min values of objective <em>i</em> in the Pareto set</p></li><li><p><em>M</em>: is the total number of objectives.</p></li></ul><p>This yields a normalized weight vector for each solution, summing to 1, which reflects the solution&#8217;s implicit prioritization of the objectives, that is, which objective it has improved more relative to the others.</p><p>To use pseudo-weights in decision-making, we compute the pseudo-weight vector for each solution and compare it to a user-defined preference vector (e.g., 70% sales, 30% overstock). The solution whose pseudo-weight vector is most aligned with this preference &#8212; typically via cosine similarity or angle minimization is selected.</p><p>In essence, pseudo-weights allow you to find the solution on the Pareto front that already reflects your desired trade-off, without relying on geometric proximity to the ideal point as ASF does.</p><blockquote><p>Examples</p><p>Imagine three dispatch plans:</p><ul><li><p><strong>Solution A</strong>: 90 sales, 8 overstock</p></li><li><p><strong>Solution B</strong>: 88 sales, 5 overstock</p></li><li><p><strong>Solution C</strong>: 85 sales, 3 overstock</p></li></ul><p>Suppose your priority is to maximize sales while still keeping overstock under control &#8212; say, 80% importance on sales, 20% on overstock.</p><ul><li><p>ASF will select the solution closest to the ideal ([max sales = 90, min overstock = 3]), considering your weights. In this case, Solution A will likely be chosen, as it achieves the highest sales and its overstock is within a tolerable range.</p></li><li><p>Pseudo-weights, however, analyze each solution&#8217;s relative improvement across objectives. Solution C reduces overstock significantly compared to the others, but at the cost of substantial sales loss. Solution B offers a more balanced trade-off; a moderate drop in sales for a meaningful drop in overstock.</p></li></ul><p>In this case, pseudo-weights may favor Solution B, as it better matches the direction of your desired trade-off, even if it&#8217;s not closest to the ideal.</p></blockquote><h2>3. Practical Example: Dispatch Planning Using NSGA-II and MCDM Methods</h2><h3>3.1. How is NSGA-II applied to model the dispatch challenge?</h3><p>To define the dispatch problem, the <code>DispatchProblem</code> class is introduced to encapsulate the dispatch optimization logic. It inherits from <code>pymoo</code>'s <code>ElementwiseProblem</code>, which allows evaluating each solution (i.e., a dispatch plan across all stores) individually.</p><p>Upon initialization, we specify key attributes:</p><ul><li><p>The number of decision variables (<code>n_var</code>, one per store)</p></li><li><p>The number of objectives (<code>n_obj = 2</code>)</p></li><li><p>One constraint (<code>n_constr = 1</code>) ensuring that total dispatch does not exceed available stock</p></li><li><p>Lower (<code>xl</code>) and upper (<code>xu</code>) bounds for the decision variables</p></li></ul><p>The core of the class is the <code>_evaluate</code> method, which is called by <code>pymoo</code> for each candidate solution. In the code, the evaluation is delegated to either a deterministic or a stochastic function depending on whether demand uncertainty is enabled.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LC5Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LC5Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png 424w, https://substackcdn.com/image/fetch/$s_!LC5Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png 848w, https://substackcdn.com/image/fetch/$s_!LC5Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png 1272w, https://substackcdn.com/image/fetch/$s_!LC5Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LC5Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png" width="1456" height="2250" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/af6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2250,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!LC5Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png 424w, https://substackcdn.com/image/fetch/$s_!LC5Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png 848w, https://substackcdn.com/image/fetch/$s_!LC5Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png 1272w, https://substackcdn.com/image/fetch/$s_!LC5Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf6fdaea-ed0d-48c4-a5b5-42374b218500_1710x2642.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The logic is split into two methods depending on whether demand uncertainty is enabled:</p><ul><li><p><code>_evaluate_simple</code>: used in the deterministic case, where forecasts are assumed exact.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L4up!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L4up!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png 424w, https://substackcdn.com/image/fetch/$s_!L4up!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png 848w, https://substackcdn.com/image/fetch/$s_!L4up!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png 1272w, https://substackcdn.com/image/fetch/$s_!L4up!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L4up!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png" width="1215" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1215,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!L4up!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png 424w, https://substackcdn.com/image/fetch/$s_!L4up!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png 848w, https://substackcdn.com/image/fetch/$s_!L4up!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png 1272w, https://substackcdn.com/image/fetch/$s_!L4up!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a24ee9-2d73-42a6-ad99-662e2b12049a_1215x794.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><code>_evaluate_with_demand_uncertainty</code>: used when uncertainty is modeled by simulating multiple demand scenarios and evaluating expected outcomes.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iHcu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iHcu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png 424w, https://substackcdn.com/image/fetch/$s_!iHcu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png 848w, https://substackcdn.com/image/fetch/$s_!iHcu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png 1272w, https://substackcdn.com/image/fetch/$s_!iHcu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iHcu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png" width="1456" height="816" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:816,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!iHcu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png 424w, https://substackcdn.com/image/fetch/$s_!iHcu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png 848w, https://substackcdn.com/image/fetch/$s_!iHcu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png 1272w, https://substackcdn.com/image/fetch/$s_!iHcu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4d1cf9f-8ebb-4c47-bd27-3737004b4616_1556x872.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>3.2. What does a typical optimized dispatch plan look like?</h3><p>Once the dispatch problem is formulated, we use <strong>NSGA-II</strong> to explore and optimize possible dispatch plans under uncertainty.</p><p>We begin by defining the core components of the evolutionary search:</p><ul><li><p><code>FloatRandomSampling()</code> initializes a population of candidate dispatch plans with continuous random values.</p></li><li><p><code>SBX</code> (Simulated Binary Crossover) combines pairs of parent solutions to generate diverse offspring.</p></li><li><p><code>PM</code> (Polynomial Mutation) introduces subtle random variations to promote exploration and prevent premature convergence.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!V8SB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!V8SB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png 424w, https://substackcdn.com/image/fetch/$s_!V8SB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png 848w, https://substackcdn.com/image/fetch/$s_!V8SB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png 1272w, https://substackcdn.com/image/fetch/$s_!V8SB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!V8SB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png" width="1208" height="432" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:432,&quot;width&quot;:1208,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!V8SB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png 424w, https://substackcdn.com/image/fetch/$s_!V8SB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png 848w, https://substackcdn.com/image/fetch/$s_!V8SB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png 1272w, https://substackcdn.com/image/fetch/$s_!V8SB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e52c62d-ec05-43ac-a758-9d7a6c37b668_1208x432.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>These operators are passed into the <code>NSGA2</code> algorithm, which evolves a population of dispatch strategies over several generations:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Aur2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Aur2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png 424w, https://substackcdn.com/image/fetch/$s_!Aur2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png 848w, https://substackcdn.com/image/fetch/$s_!Aur2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png 1272w, https://substackcdn.com/image/fetch/$s_!Aur2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Aur2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png" width="1328" height="507" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:507,&quot;width&quot;:1328,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Aur2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png 424w, https://substackcdn.com/image/fetch/$s_!Aur2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png 848w, https://substackcdn.com/image/fetch/$s_!Aur2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png 1272w, https://substackcdn.com/image/fetch/$s_!Aur2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604ec362-4296-4f19-99c4-261890f4fe31_1328x507.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This configuration enables us to explore a wide range of dispatch strategies and ensures that redundant solutions are filtered out to maintain diversity across generations.</p><p>We then define the actual dispatch optimization problem. Here, demand is uncertain and evaluated through stochastic simulation using multiple scenarios.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NfyA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NfyA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png 424w, https://substackcdn.com/image/fetch/$s_!NfyA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png 848w, https://substackcdn.com/image/fetch/$s_!NfyA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png 1272w, https://substackcdn.com/image/fetch/$s_!NfyA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NfyA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png" width="1180" height="468" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:468,&quot;width&quot;:1180,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!NfyA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png 424w, https://substackcdn.com/image/fetch/$s_!NfyA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png 848w, https://substackcdn.com/image/fetch/$s_!NfyA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png 1272w, https://substackcdn.com/image/fetch/$s_!NfyA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cf9d254-e59d-4f0d-b7a4-3f2a96920121_1180x468.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This setup allows the optimizer to evaluate the robustness of a dispatch plan under uncertainty. Demand forecasts are assumed uncertain and simulated using 100 scenarios with 35% relative error.</p><p>Finally, pymoo's <code>minimize()</code> is used to run the optimization over 150 generations:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Gq1l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Gq1l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png 424w, https://substackcdn.com/image/fetch/$s_!Gq1l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png 848w, https://substackcdn.com/image/fetch/$s_!Gq1l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png 1272w, https://substackcdn.com/image/fetch/$s_!Gq1l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Gq1l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png" width="997" height="550" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:550,&quot;width&quot;:997,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Gq1l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png 424w, https://substackcdn.com/image/fetch/$s_!Gq1l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png 848w, https://substackcdn.com/image/fetch/$s_!Gq1l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png 1272w, https://substackcdn.com/image/fetch/$s_!Gq1l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19d14e4-00cd-468c-bac2-f7bd07ecc56d_997x550.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><code>pymoo</code> automatically tracks a range of performance indicators that can be visualized by setting <code>verbose=True</code></p><ul><li><p><code>n_gen</code> &#8211; generation number</p></li><li><p><code>n_eval</code> &#8211; number of function evaluations</p></li><li><p><code>n_nds</code> &#8211; number of non-dominated (Pareto optimal) solutions</p></li><li><p><code>cv_min</code> / <code>cv_avg</code> &#8211; minimum and average constraint violations</p></li><li><p><code>eps</code> &#8211; epsilon-progress indicator (convergence metric)</p></li><li><p><code>indicator</code>: <em>ideal</em>, <em>nadir</em>, and <em>f</em> are metrics describing the objective space</p></li></ul><p>These logs help you evaluate how well the algorithm is converging, whether the diversity is preserved, and how many valid trade-offs are found.</p><blockquote><p>&#128161; Tip: If the Pareto front stops improving or the log values plateau early, it may be a sign that your evolutionary settings (population size, mutation rate, number of scenarios) need to be adjusted.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iln1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iln1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png 424w, https://substackcdn.com/image/fetch/$s_!iln1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png 848w, https://substackcdn.com/image/fetch/$s_!iln1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png 1272w, https://substackcdn.com/image/fetch/$s_!iln1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iln1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png" width="1342" height="938" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:938,&quot;width&quot;:1342,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!iln1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png 424w, https://substackcdn.com/image/fetch/$s_!iln1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png 848w, https://substackcdn.com/image/fetch/$s_!iln1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png 1272w, https://substackcdn.com/image/fetch/$s_!iln1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b1cecc0-1b42-4cf7-a56a-1e30e9c85cf9_1342x938.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Table 1 &#8211; NSGA-II optimization progress across generations</figcaption></figure></div><p><strong>The table below shows the dispatch results for January 4th.</strong> The optimizer allocates the available 1154 units across stores in close alignment with forecasted demand, balancing sales performance with overstock risk. The sales figures confirm that the allocation respects both demand and capacity constraints.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AkY5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AkY5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png 424w, https://substackcdn.com/image/fetch/$s_!AkY5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png 848w, https://substackcdn.com/image/fetch/$s_!AkY5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png 1272w, https://substackcdn.com/image/fetch/$s_!AkY5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AkY5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png" width="1180" height="300" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:300,&quot;width&quot;:1180,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!AkY5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png 424w, https://substackcdn.com/image/fetch/$s_!AkY5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png 848w, https://substackcdn.com/image/fetch/$s_!AkY5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png 1272w, https://substackcdn.com/image/fetch/$s_!AkY5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef03557-8202-45a8-8985-9328601b0dcf_1180x300.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Table 2 &#8212; Dispatch plan and sales per store or January 4th</figcaption></figure></div><h3>3.3. How are trade-offs prioritized using ASF and Pseudo-Weights?</h3><p>In this first graph, we observe the full Pareto front returned by NSGA-II, plotted in the original objective space. The x-axis represents negative expected sales (since pymoo minimizes objectives), and the y-axis shows expected overstock in units. Each blue dot corresponds to a non-dominated solution.</p><ul><li><p>The green star marks the ideal point, representing perfect sales with zero overstock.</p></li><li><p>The red pentagon indicates the nadir point, the worst observed values on the front.</p></li></ul><p>Figure 5 illustrates the range of trade-offs discovered by the algorithm. As we move from left to right, we gain sales but incur more overstock, a classic optimization tension. It also gives a sense of how much room there is to maneuver between the two objectives.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xtD1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xtD1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png 424w, https://substackcdn.com/image/fetch/$s_!xtD1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png 848w, https://substackcdn.com/image/fetch/$s_!xtD1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png 1272w, https://substackcdn.com/image/fetch/$s_!xtD1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xtD1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png" width="1456" height="589" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:589,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!xtD1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png 424w, https://substackcdn.com/image/fetch/$s_!xtD1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png 848w, https://substackcdn.com/image/fetch/$s_!xtD1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png 1272w, https://substackcdn.com/image/fetch/$s_!xtD1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1438aee4-dbfa-43ea-8a7e-0fd026673622_1934x783.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 5 &#8212; Full Pareto front in the original objective space (negative expected sales vs. overstock). The ideal and nadir points illustrate the optimization boundaries.</figcaption></figure></div><p>Figure 6 builds on the first, highlighting two selected solutions:</p><ul><li><p>The red cross shows the solution chosen using the Augmented Scalarization Function (ASF), which minimizes the weighted distance to the ideal point. The weights assigned to the objectives are 70% for sales and 30% for overstock.</p></li><li><p>The orange cross shows the one selected using pseudo-weights, which aims to match the decision-maker&#8217;s preferred trade-off direction. The same weights are used.</p></li></ul><p>Here, we see that ASF selects a solution closer to the ideal in terms of raw distance, while the pseudo-weights approach picks a solution that sacrifices a bit more on overstock to preserve sales, offering a directional balance that might better reflect certain business goals.</p><p>This graph emphasizes how both methods provide valid but distinct interpretations of what makes a solution &#8220;best.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l8Ln!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l8Ln!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png 424w, https://substackcdn.com/image/fetch/$s_!l8Ln!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png 848w, https://substackcdn.com/image/fetch/$s_!l8Ln!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png 1272w, https://substackcdn.com/image/fetch/$s_!l8Ln!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l8Ln!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png" width="1456" height="595" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:595,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!l8Ln!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png 424w, https://substackcdn.com/image/fetch/$s_!l8Ln!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png 848w, https://substackcdn.com/image/fetch/$s_!l8Ln!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png 1272w, https://substackcdn.com/image/fetch/$s_!l8Ln!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3271db1-a9a9-4a84-9517-7e19691113de_1934x790.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 6 &#8212; ASF and Pseudo-Weights selections compared in raw objective space. ASF favors proximity to the ideal point, while Pseudo-Weights prioritize balanced trade-offs.</figcaption></figure></div><p>Finally, Figure 7 shows the same ASF and pseudo-weight solutions, but in a <strong>scaled objective space</strong> (both axes normalized between 0 and 1). This view helps remove bias due to differing units or magnitudes in the objectives.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!W2xY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!W2xY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png 424w, https://substackcdn.com/image/fetch/$s_!W2xY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png 848w, https://substackcdn.com/image/fetch/$s_!W2xY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png 1272w, https://substackcdn.com/image/fetch/$s_!W2xY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!W2xY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png" width="1456" height="571" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:571,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!W2xY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png 424w, https://substackcdn.com/image/fetch/$s_!W2xY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png 848w, https://substackcdn.com/image/fetch/$s_!W2xY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png 1272w, https://substackcdn.com/image/fetch/$s_!W2xY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32911d19-a9f3-4f34-9659-7c72b2e352c0_1934x759.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 7 &#8212; ASF vs. Pseudo-Weights selection in scaled objective space. Normalization makes differences in trade-off direction more visually interpretable.</figcaption></figure></div><div><hr></div><h2>Key Takeaways</h2><p>&#10003; Multi-objective optimization provides a powerful framework for addressing real-world trade-offs in dispatch planning, especially when goals like maximizing sales and minimizing overstock conflict.</p><p>&#10003; NSGA-II is well-suited for retail scenarios thanks to its ability to generate a diverse set of Pareto-optimal solutions in a single run, without needing to collapse objectives into a single weighted score.</p><p>&#10003; The implementation in <code>pymoo</code> makes it easy to handle both deterministic and uncertain demand through custom evaluation logic, making the approach robust to real-world variability.</p><p>&#10003; When it comes to selecting a final dispatch plan, Augmented Scalarization Function (ASF) and Pseudo-Weights offer two distinct perspectives: ASF favors proximity to the ideal point, while Pseudo-Weights emphasize solutions that match a preferred trade-off direction.</p><p>&#10003; Visualizing the Pareto front, both in raw and normalized form, is key to interpreting results and communicating choices to stakeholders. These plots make the trade-offs and selection rationale transparent and defensible.</p><div><hr></div><h3>References</h3><p>[1] K. Deb, A. Pratap, S. Agarwal and T. Meyarivan, <a href="https://ieeexplore.ieee.org/document/996017">"A fast and elitist multiobjective genetic algorithm: NSGA-II"</a> in IEEE Transactions on Evolutionary Computation</p><p>[2] <a href="https://www.kaggle.com/code/beshoyemad24/retail-store-inventory-forecastin-eda-prediction#Data-Modelling">Kaggle</a>, Retail Store Inventory Forecasting Dataset, A synthetic dataset for practicing inventory management and demand forecasting.</p><p>[3] Pymoo documentation, <a href="https://www.egr.msu.edu/coinlab/blankjul/pymoo-rc/algorithms/nsga2.html">NSGA-II: Non-dominated Sorting Genetic Algorithm</a></p>]]></content:encoded></item><item><title><![CDATA[Beyond Text: Leveraging LLMs for Time Series Forecasting (Part 2/2)]]></title><description><![CDATA[TimeGPT Explained: Principles, Implementation, and Use Cases]]></description><link>https://aipractitioner.substack.com/p/beyond-text-leveraging-llms-for-time-b93</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/beyond-text-leveraging-llms-for-time-b93</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Fri, 27 Jun 2025 15:31:18 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qyEn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qyEn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qyEn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png 424w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png 848w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png 1272w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qyEn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png" width="1456" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:688244,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qyEn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png 424w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png 848w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png 1272w, https://substackcdn.com/image/fetch/$s_!qyEn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F267d8b17-c6e3-4851-8704-443d06c9a06d_2010x828.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Foundation models have revolutionized NLP by handling tasks like translation, summarization, and reasoning with a single architecture and no task-specific retraining. Now, this paradigm is reaching time series forecasting, where models like TimeGPT, developed by Nixtla, are pushing beyond traditional statistical methods with architectures tailored for temporal data.</p><p>Unlike classic forecasting models which rely on domain-specific assumptions or handcrafted features, TimeGPT leverages the Transformer architecture to learn general temporal dynamics directly from large-scale time series corpora. Its strength lies in <strong>zero-shot or few-shot performance</strong>: it requires little to no historical context to generate accurate forecasts, even in unseen domains.</p><p>This article dives into TimeGPT, its design philosophy, forecasting abilities, and practical use in real-world scenarios like sales prediction. It explores its ease of use, performance, and how it compares to both classical and LLM-based approaches such as TimeLLM.</p><h3>Objective</h3><p>After reading this article, you will understand:</p><ol><li><p>What makes TimeGPT different from other forecasting models?</p></li><li><p>How to use TimeGPT in a zero-shot or few-shot setting for daily time series data?</p></li><li><p>How it performs on the M5 dataset compared to traditional and deep learning models?</p></li></ol><blockquote><p>This article is the second in a series on advanced time series modeling. If you haven&#8217;t already, check out the first part on TimeLLM, <em><strong><a href="https://aipractitioner.substack.com/p/beyond-text-leveraging-llms-for-time">Beyond Text: Leveraging LLMs for Time Series Forecasting (Part 1/2)</a></strong></em><strong>.</strong></p><p><strong>Prerequisites:</strong> No prior experience with LLMs or time series forecasting is required. Some familiarity with Python and pandas will help you follow the code examples.</p><p><strong>Tools &amp; libraries:</strong> The code used relies on nixtla ecosystem for accessing TimeGPT, pandas for data handling, and plotly for visualization. The dataset used is the M5 competition dataset featuring Walmart daily sales.</p></blockquote><p>You can find the code here on <a href="https://github.com/linafaik08/time-series-forecasting-models">GitHub</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><p></p><div><hr></div><h2>1. TimeGPT Explained: Foundation Models for Zero-Shot Time Series Forecasting</h2><h3>What makes TimeGPT different?</h3><p>TimeGPT is the first foundation model built specifically for time series forecasting. It delivers zero-shot predictions, meaning it can accurately forecast entirely new, unseen time series without any retraining or task-specific tuning. This contrasts sharply with traditional models, which typically require manual optimization and feature engineering for each new dataset. [<a href="https://arxiv.org/abs/2310.03589">1</a>]</p><p><strong>Key differentiators</strong>:</p><ul><li><p><strong>Zero-shot forecasting</strong>: TimeGPT can forecast without retraining or fine-tuning.</p></li><li><p><strong>Cross-domain generalization</strong>: It performs well across diverse areas such as finance, energy, healthcare, and IoT.</p></li><li><p><strong>Operational simplicity</strong>: Once the data is properly formatted, forecasting is reduced to a single call. No model selection, hyperparameter search, or manual tuning required.</p></li></ul><h3>How is TimeGPT built and trained?</h3><p>TimeGPT is not based on any existing large language model (LLM). But, it follows the same core training principle, which involves scaling up transformer architectures on large datasets, but it is specifically designed and trained for numerical time series data. [<a href="https://arxiv.org/abs/2310.03589">1</a>]</p><p><strong>Model architecture</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lYUP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lYUP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png 424w, https://substackcdn.com/image/fetch/$s_!lYUP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png 848w, https://substackcdn.com/image/fetch/$s_!lYUP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png 1272w, https://substackcdn.com/image/fetch/$s_!lYUP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lYUP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png" width="1346" height="514" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:514,&quot;width&quot;:1346,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:96454,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lYUP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png 424w, https://substackcdn.com/image/fetch/$s_!lYUP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png 848w, https://substackcdn.com/image/fetch/$s_!lYUP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png 1272w, https://substackcdn.com/image/fetch/$s_!lYUP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F943a0ada-e995-4b27-8957-87bf9e9c52bf_1346x514.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 1 &#8212; TimeGPT inference pipeline, source [<a href="https://arxiv.org/abs/2310.03589">1</a>]</figcaption></figure></div><p>TimeGPT is based on a Transformer encoder-decoder architecture adapted for time series forecasting. It is designed to handle time series of different frequencies, lengths, and structures, including varying seasonality, sparsity, and noise. It processes historical values and exogenous covariates, using positional encoding to retain temporal order. The model relies on multi-head attention, residual connections, and layer normalization to capture both short- and long-term dependencies. CNN layers are also included to extract local temporal patterns. A final linear layer projects the output to the forecast horizon, producing predictions along with uncertainty intervals. [<a href="https://arxiv.org/abs/2310.03589">1</a>]</p><p>However, the original article lacks key details about the model&#8217;s design, such as the number of layers, attention heads, and input window size. It also doesn&#8217;t specify how exogenous variables are integrated or whether the model uses causal masking and sequence-to-sequence or autoregressive decoding.</p><p><strong>Training Dataset</strong></p><p>TimeGPT was trained on over 100 billion data points from the largest publicly available time series dataset to date [<a href="https://arxiv.org/abs/2310.03589">1</a>], spanning domains like finance, healthcare, IoT, transport, weather, web traffic, and energy. The dataset includes mixed frequencies (hourly to monthly), varying noise levels, outliers, trends, and seasonality, and heterogeneous patterns across domains</p><p>Preprocessing was minimal, focusing on formatting and handling missing values while preserving raw signal variability to enhance robustness.</p><p>TimeGPT was trained in PyTorch over a few days on NVIDIA A10G GPUs using the Adam optimizer with learning rate decay and large batch sizes. [<a href="https://arxiv.org/abs/2310.03589">1</a>] In contrast, models like GPT-3 are trained for weeks on thousands of GPUs with more complex setups. While both use Transformers, TimeGPT remains lightweight and specialized for time series compared large, language-focused LLMs.</p><h3>How well does TimeGPT perform in practice?</h3><p>TimeGPT was evaluated in a true zero-shot setting&#8212;no fine-tuning, just direct inference on over 300,000 unseen time series. [<a href="https://arxiv.org/abs/2310.03589">1</a>]</p><p>Performance was measured using two normalized metrics: <strong>Relative Mean Absolute Error (rMAE)</strong> and <strong>Relative Root Mean Squared Error (rRMSE)</strong>. These scores are <em>relative</em> in the sense that they are normalized against the error of a seasonal naive baseline, which assumes each future value repeats the last observed value from the same season (e.g., predicting next January based on the previous January). A score of 1.0 indicates parity with this naive benchmark, while values below 1.0 reflect superior performance. This normalization enables consistent comparisons across datasets with different scales, units, and temporal patterns.</p><p><strong>Results</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-kwz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-kwz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png 424w, https://substackcdn.com/image/fetch/$s_!-kwz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png 848w, https://substackcdn.com/image/fetch/$s_!-kwz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png 1272w, https://substackcdn.com/image/fetch/$s_!-kwz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-kwz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png" width="1456" height="846" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:846,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:246265,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-kwz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png 424w, https://substackcdn.com/image/fetch/$s_!-kwz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png 848w, https://substackcdn.com/image/fetch/$s_!-kwz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png 1272w, https://substackcdn.com/image/fetch/$s_!-kwz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c4fa14d-ed9c-40d6-868a-da8bd3e94618_1814x1054.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Table 1 &#8212; Main performance results for TimeGPT with zero-shot inference, source [<a href="https://arxiv.org/abs/2310.03589">1</a>]</figcaption></figure></div><ul><li><p><strong>TimeGPT ranks 1st</strong> in 4 out of 8 metrics (rMAE and rRMSE across monthly and weekly frequencies), and is among the top 3 in all others. It demonstrates strong and consistent zero-shot performance across time scales.</p></li><li><p><strong>Monthly and Weekly Forecasts</strong>: TimeGPT clearly outperforms all other models, including specialized statistical (e.g. DOTheta) and deep learning methods (e.g. NHITS, TFT).</p></li><li><p><strong>Daily and Hourly Forecasts</strong>: While NHITS and LGBM are better on some hourly metrics, TimeGPT remains competitive and outperforms most traditional models.</p></li></ul><p>Overall, TimeGPT shows that a single, general-purpose model can match or surpass domain-tuned baselines, even without fine-tuning, validating its foundation model approach.</p><p><strong>Note</strong>:</p><ul><li><p>TimeGPT delivers rapid inference at just 0.6 milliseconds per time series. This is faster than most statistical models, even when parallelized.</p></li><li><p>TimeGPT can also be fine-tuned on specific domains to further improve accuracy.</p></li><li><p>It supports uncertainty quantification through conformal prediction, enabling reliable prediction intervals without relying on strong distributional assumptions.</p></li></ul><h2>2. Foundation Models in Action: Forecasting with TimeGPT and Nixtla</h2><h3>Use case: M5 store-level forecasting with TimeLLM and benchmarks</h3><p>This use case follows the same setup as described in the article <em><strong><a href="https://aipractitioner.substack.com/p/beyond-text-leveraging-llms-for-time">Beyond Text: Leveraging LLMs for Time Series Forecasting (Part 1/2)</a></strong></em>. Please refer to the article for a full description of the dataset, benchmark models, and experimental protocol.</p><p><strong>Problem Statement</strong></p><p>The task is to <strong>forecast daily store-level turnover over a 14-day horizon</strong> using historical sales data and external features such as calendar events from M5 dataset [<a href="https://www.kaggle.com/competitions/m5-forecasting-accuracy/data">14</a>]. Each store is modeled independently for the target variable, while shared temporal patterns are leveraged across series.</p><p><strong>Learning and Evaluation Framework</strong></p><p>The last 14 days of each store&#8217;s time series are held out as a test set. Models are trained on historical data only. Evaluation is performed using the Mean Absolute Percentage Error (MAPE).</p><p><strong>Evaluation strategy</strong></p><p>To assess the value of TimeGPT's architecture and feature integration, three progressively enriched configurations were tested:</p><ol><li><p><strong>TimeGPT (baseline)</strong>: The base <code>timegpt-1</code> model trained <strong>only on historical sales</strong>, with no additional features.</p></li><li><p><strong>TimeGPT (with date features)</strong>: The same model (<code>timegpt-1</code>) enriched with automatically extracted calendar features (e.g., day of week, holiday flags).</p></li><li><p><strong>TimeGPT (long horizon)</strong>: The <code>timegpt-1-long-horizon</code> variant, which uses a model architecture tailored for longer seasonal dependencies. Feature setup remains identical to the previous step.</p></li><li><p><strong>TimeGPT (with exogenous features)</strong>: This final configuration combines the long-horizon model with both calendar features and external event indicators (e.g., bank holiday flags) from the M5 dataset.</p></li></ol><p><strong>Benchmark Models</strong></p><ul><li><p>Statistical models: AutoARIMA, AutoETS, AutoCES, MSTL, Theta</p></li><li><p>Deep learning models: NHITS, NBEATS (trained with quantile loss and enriched with dynamic exogenous features)</p></li></ul><h3>How is TimeGPT used in practice with Nixtla libraries?</h3><p><strong>Prerequisite:</strong></p><p>Running TimeGPT requires access to the <a href="https://github.com/Nixtla/nixtla">Nixtla Python client</a>, along with an API key, which can be obtained by registering on <a href="https://nixtla.io/">nixtla.io</a>.</p><p>The input data must include:</p><ul><li><p>A timestamp column (<code>time_col</code>, e.g. <code>"ds"</code>)</p></li><li><p>A target column (<code>target_col</code>, e.g. <code>"y"</code>)</p></li><li><p>An identifier column for multiseries (<code>id_col</code>, e.g. <code>"unique_id"</code>)</p></li><li><p>Optionally, any exogenous variables for both historical and future periods</p></li></ul><p><strong>Example: forecasting with TimeGPT</strong></p><p>Here&#8217;s the code used in this benchmark to forecast a 14-day horizon using the <code>timegpt-1-long-horizon</code> model, fine-tuned on recent data. For full code and implementation details, see the <a href="https://github.com/linafaik08/time-series-forecasting-models">GitHub repository</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WwKC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WwKC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png 424w, https://substackcdn.com/image/fetch/$s_!WwKC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png 848w, https://substackcdn.com/image/fetch/$s_!WwKC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png 1272w, https://substackcdn.com/image/fetch/$s_!WwKC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WwKC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png" width="1249" height="822" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:822,&quot;width&quot;:1249,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:176811,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543d21af-ec4f-4b9e-b9aa-e25a71efb624_1304x878.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WwKC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png 424w, https://substackcdn.com/image/fetch/$s_!WwKC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png 848w, https://substackcdn.com/image/fetch/$s_!WwKC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png 1272w, https://substackcdn.com/image/fetch/$s_!WwKC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa00bedf1-ebef-46b8-9f66-b580f728d1b5_1249x822.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Key parameters explained</strong></p><ul><li><p><code>df</code> / <code>X_df</code>: Historical and future data, including exogenous variables if applicable.</p></li><li><p><code>h</code>: Forecast horizon (e.g., 14 for 14-day prediction).</p></li><li><p><code>finetune_steps</code> and <code>finetune_depth</code>: Enable model adaptation to recent trends; depth 3 is a moderate setting.</p></li><li><p><code>finetune_loss</code>: Loss used during finetuning (e.g., <code>"rmse"</code>).</p></li><li><p><code>model</code>: Use <code>"timegpt-1-long-horizon"</code> for multi-seasonal or longer horizons.</p></li><li><p><code>date_features</code>: Automatically extract calendar features (e.g., weekday, month).</p></li><li><p><code>level</code>: Confidence interval for probabilistic forecasting (e.g., 90%).</p></li></ul><p>For a complete reference of all parameters, see the <a href="https://www.nixtla.io/docs/getting-started-about_timegpt">official TimeGPT client documentation</a>.</p><h3>How does TimeLLM perform compared to benchmark models?</h3><p>TimeGPT outperforms both statistical and deep learning models on the M5 store-level forecasting task. The best configuration, combining a long-horizon architecture, calendar features, and external event indicators, achieves a MAPE of 6.2%, outperforming traditional baselines like AutoARIMA (9.2%) and advanced neural models like NHITS (7.8%).</p><p><strong>Mean MAPE comparison</strong></p><p>TimeGPT shows consistent improvements as feature complexity increases. The full configuration with exogenous features achieves the <strong>lowest average MAPE</strong>, while even the baseline version remains competitive with other modern models.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!P_0B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!P_0B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png 424w, https://substackcdn.com/image/fetch/$s_!P_0B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png 848w, https://substackcdn.com/image/fetch/$s_!P_0B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png 1272w, https://substackcdn.com/image/fetch/$s_!P_0B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!P_0B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png" width="1560" height="609" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:609,&quot;width&quot;:1560,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:125852,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90442562-7b29-44c4-b145-cc67277293ce_1560x706.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!P_0B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png 424w, https://substackcdn.com/image/fetch/$s_!P_0B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png 848w, https://substackcdn.com/image/fetch/$s_!P_0B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png 1272w, https://substackcdn.com/image/fetch/$s_!P_0B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf0b240-423d-4734-ad34-6ae382975f24_1560x609.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 2 &#8212; Average MAPE (%) by model on the M5 dataset...</figcaption></figure></div><p><strong>MAPE distribution across models</strong></p><p>MAPE distributions reveal that TimeGPT not only improves on average performance but also reduces error variability across stores. The most robust results are obtained with the full-featured model, while statistical methods exhibit wider and less consistent error ranges.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ATIY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ATIY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png 424w, https://substackcdn.com/image/fetch/$s_!ATIY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png 848w, https://substackcdn.com/image/fetch/$s_!ATIY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png 1272w, https://substackcdn.com/image/fetch/$s_!ATIY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ATIY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png" width="1946" height="717" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:717,&quot;width&quot;:1946,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:143748,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff7db24f-48cf-424f-bfa3-59b858d49eea_1946x840.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ATIY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png 424w, https://substackcdn.com/image/fetch/$s_!ATIY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png 848w, https://substackcdn.com/image/fetch/$s_!ATIY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png 1272w, https://substackcdn.com/image/fetch/$s_!ATIY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1290b98-f5f7-4cdf-9868-9995bed8d541_1946x717.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 3 &#8212; Distribution of MAPE across stores by model type. Each point represents one store. Narrower boxes indicate more stable performance.</figcaption></figure></div><p><strong>Forecast example with confidence interval</strong></p><p>An example forecast for store <code>WI_1</code> illustrates how TimeGPT captures weekly sales dynamics and aligns closely with the observed test values. The 90% prediction interval reflects the model&#8217;s calibrated uncertainty over the forecast window.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!owpZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!owpZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png 424w, https://substackcdn.com/image/fetch/$s_!owpZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png 848w, https://substackcdn.com/image/fetch/$s_!owpZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png 1272w, https://substackcdn.com/image/fetch/$s_!owpZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!owpZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png" width="1896" height="749" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:749,&quot;width&quot;:1896,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:165147,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff484b73f-4e7f-4367-bb4a-2565edad4f30_1896x862.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!owpZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png 424w, https://substackcdn.com/image/fetch/$s_!owpZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png 848w, https://substackcdn.com/image/fetch/$s_!owpZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png 1272w, https://substackcdn.com/image/fetch/$s_!owpZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e7d61a2-4c90-4d0a-b505-1e16fea647b3_1896x749.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 4 &#8212; Forecast with 90% confidence interval for store WI_1</figcaption></figure></div><h3>How interpretable is TimeGPT?</h3><p>While accuracy is key, explainability is critical for real-world adoption. TimeGPT delivers SHAP-based feature attributions, revealing which variables drive predictions, both overall and at each time step.</p><p><strong>Extracting SHAP values</strong></p><p>By enabling the <code>feature_contributions</code> argument, TimeGPT returns SHAP values alongside forecasts. These quantify how much each feature contributes to the predicted value compared to a base reference.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2nzl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2nzl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png 424w, https://substackcdn.com/image/fetch/$s_!2nzl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png 848w, https://substackcdn.com/image/fetch/$s_!2nzl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png 1272w, https://substackcdn.com/image/fetch/$s_!2nzl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2nzl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png" width="1268" height="780" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:780,&quot;width&quot;:1268,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:158077,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F345eeef6-552b-4d8e-83bc-80ca084d7ba1_1334x842.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2nzl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png 424w, https://substackcdn.com/image/fetch/$s_!2nzl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png 848w, https://substackcdn.com/image/fetch/$s_!2nzl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png 1272w, https://substackcdn.com/image/fetch/$s_!2nzl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53dddf16-ac6a-45e3-a28a-2f5d73cc75e3_1268x780.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">caption...</figcaption></figure></div><p>The SHAP values can then be accessed using:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tr7T!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tr7T!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png 424w, https://substackcdn.com/image/fetch/$s_!tr7T!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png 848w, https://substackcdn.com/image/fetch/$s_!tr7T!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png 1272w, https://substackcdn.com/image/fetch/$s_!tr7T!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tr7T!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png" width="532" height="130.0081799591002" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:239,&quot;width&quot;:978,&quot;resizeWidth&quot;:532,&quot;bytes&quot;:42752,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!tr7T!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png 424w, https://substackcdn.com/image/fetch/$s_!tr7T!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png 848w, https://substackcdn.com/image/fetch/$s_!tr7T!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png 1272w, https://substackcdn.com/image/fetch/$s_!tr7T!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b55bd1-f51e-476e-b0e7-90948087a584_978x239.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">caption...</figcaption></figure></div><p><strong>Global importance of features</strong></p><p>To understand which features generally drive model predictions, a bar plot of mean absolute SHAP values can be generated:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gbS4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gbS4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png 424w, https://substackcdn.com/image/fetch/$s_!gbS4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png 848w, https://substackcdn.com/image/fetch/$s_!gbS4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png 1272w, https://substackcdn.com/image/fetch/$s_!gbS4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gbS4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png" width="1438" height="751" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:751,&quot;width&quot;:1438,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:160203,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe72dc97e-926b-4051-992a-c9bee01baa1a_1492x806.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gbS4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png 424w, https://substackcdn.com/image/fetch/$s_!gbS4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png 848w, https://substackcdn.com/image/fetch/$s_!gbS4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png 1272w, https://substackcdn.com/image/fetch/$s_!gbS4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a0c782c-48ee-4228-af45-9964718a1fdb_1438x751.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">caption...</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RirG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RirG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png 424w, https://substackcdn.com/image/fetch/$s_!RirG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png 848w, https://substackcdn.com/image/fetch/$s_!RirG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png 1272w, https://substackcdn.com/image/fetch/$s_!RirG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RirG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png" width="524" height="325.70054945054943" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:905,&quot;width&quot;:1456,&quot;resizeWidth&quot;:524,&quot;bytes&quot;:184146,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RirG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png 424w, https://substackcdn.com/image/fetch/$s_!RirG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png 848w, https://substackcdn.com/image/fetch/$s_!RirG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png 1272w, https://substackcdn.com/image/fetch/$s_!RirG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04f4169e-8168-4d4e-8ffd-0cdd7351a31e_1622x1008.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 5 &#8212; Global feature importance</figcaption></figure></div><p>This bar chart ranks features by their average impact on the forecast. Features related to calendar structure and special events emerge as dominant drivers of sales volume across stores and dates.</p><p><strong>Local interpretation of a forecast</strong></p><p>To dive deeper, a waterfall plot can explain a single forecast by showing the additive effect of each input feature on the final predicted value.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wm-E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wm-E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png 424w, https://substackcdn.com/image/fetch/$s_!wm-E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png 848w, https://substackcdn.com/image/fetch/$s_!wm-E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png 1272w, https://substackcdn.com/image/fetch/$s_!wm-E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wm-E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png" width="595" height="360.9453405017921" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:677,&quot;width&quot;:1116,&quot;resizeWidth&quot;:595,&quot;bytes&quot;:148733,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!wm-E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png 424w, https://substackcdn.com/image/fetch/$s_!wm-E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png 848w, https://substackcdn.com/image/fetch/$s_!wm-E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png 1272w, https://substackcdn.com/image/fetch/$s_!wm-E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cc9a0d6-05ac-4114-9fbd-d1244aa5fabc_1116x677.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xtoh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xtoh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png 424w, https://substackcdn.com/image/fetch/$s_!xtoh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png 848w, https://substackcdn.com/image/fetch/$s_!xtoh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png 1272w, https://substackcdn.com/image/fetch/$s_!xtoh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xtoh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png" width="596" height="367.99725274725273" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:899,&quot;width&quot;:1456,&quot;resizeWidth&quot;:596,&quot;bytes&quot;:237328,&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://aipractitioner.substack.com/i/165606954?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xtoh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png 424w, https://substackcdn.com/image/fetch/$s_!xtoh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png 848w, https://substackcdn.com/image/fetch/$s_!xtoh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png 1272w, https://substackcdn.com/image/fetch/$s_!xtoh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39b39ae6-1b7c-46f8-a8f1-40e908625562_1740x1074.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 6 &#8212; Local forecast explanation</figcaption></figure></div><p>The waterfall plot breaks down how each feature shifts the model output from the base value to the final forecast. Positive and negative contributions are clearly distinguished, offering transparent reasoning behind individual predictions.</p><h1>Key Takeaways</h1><p>&#10003; <strong>TimeGPT brings foundation model capabilities to time series forecasting</strong></p><p>It enables accurate zero-shot and few-shot predictions across domains without the need for retraining or manual tuning, marking a shift from traditional, task-specific forecasting pipelines.</p><p>&#10003; <strong>Architecture and feature integration drive consistent gains</strong></p><p>TimeGPT's performance improves systematically with richer temporal structures (e.g., calendar features) and external signals, while maintaining simplicity of use through a single API call.</p><p>&#10003; <strong>Built-in explainability enhances trust and usability</strong></p><p>With native SHAP integration, TimeGPT not only predicts but also explains. This enables the interpretation of the influence of features on each forecast at both global and individual levels.</p><h1>References</h1><p>[1] A. Garza, C. Challu, M. Mergenthaler-Canseco (2023), <em><a href="https://arxiv.org/abs/2310.03589">TimeGPT-1: Foundation Model for Time Series Forecasting</a></em>, arXiv</p><p>[2] Wenlong Liao, Fernando Porte-Agel, Jiannong Fang, Christian Rehtanz, Shouxiang Wang, Dechang Yang, Zhe Yang, <a href="https://arxiv.org/abs/2404.04885">*TimeGPT in Load Forecasting: A Large Time Series Model Perspective</a>,* arXiv</p><p>[3] Congxi Xiao, Jingbo Zhou, Yixiong Xiao, Xinjiang Lu, Le Zhang, Hui Xiong, <em><a href="https://arxiv.org/abs/2503.04118">TimeFound: A Foundation Model for Time Series Forecasting</a></em>, arXiv</p><p>[4] Hua Tang, Chong Zhang, Mingyu Jin, Qinkai Yu, Zhenting Wang, Xiaobo Jin, Yongfeng Zhang, Mengnan Du, <em><a href="https://arxiv.org/abs/2402.10835">Time Series Forecasting with LLMs: Understanding and Enhancing Model Capabilities</a></em>, arXiv</p><p>[5] Jin, M., Wang, S., Ma, L., et al. (2023), <em><a href="https://arxiv.org/abs/2310.01728">Time-LLM: Time Series Forecasting by Reprogramming Large Language Models</a></em><strong>,</strong> arXiv</p><p>[6] Xiyuan Zhang, Ranak Roy Chowdhury, Rajesh K. Gupta, Jingbo Shang, <a href="https://arxiv.org/abs/2402.01801">Large Language Models for Time Series: A Survey</a>, arXiv</p><p>[7] C. Liu, S. Zhou, Q. Xu, H. Miao, C. Long, Z. Li, R. Zhao (2025), <em><a href="https://arxiv.org/abs/2505.02583?utm_source=tldrai">Towards Cross-Modality Modeling for Time Series Analytics: A Survey in the LLM Era</a></em>, arXiv</p><p>[8] T. Kim, J. Kim, Y. Tae, C. Park, J. Choi, J. Choo (2022), <a href="https://paperswithcode.com/paper/reversible-instance-normalization-for">*Reversible Instance Normalization for Accurate Time-Series Forecasting against Distribution Shift</a>,* ICLR 2022, Paper with code</p><p>[9] Nixtla, <em><a href="https://docs.nixtla.io/">TimeGPT-1 documentation</a></em></p><p>[10] Ming Jin, <em><a href="https://www.youtube.com/watch?v=6sFiNExS3nI">Time-LLM: Time Series Forecasting by Reprogramming Large Language Models</a></em>, MLLM Talk, Youtube</p><p>[11] Adrien Nav, <a href="https://www.youtube.com/watch?v=L-hRexVa32k">*TimeLLM - Time Series Forecasting Model</a><strong>,</strong>* Youtube</p><p>[12] Marco Peixeiro, <em><a href="https://medium.com/the-forecaster/time-llm-reprogram-an-llm-for-time-series-forecasting-e2558087b8ac">Time-LLM: Reprogram an LLM for Time Series Forecasting</a></em>, Medium</p><p>[13] S. Makridakis, E. Spiliotis, V. Assimakopoulos, <a href="https://www.sciencedirect.com/science/article/pii/S0169207021001874">*M5 accuracy competition: Results, findings, and conclusions</a>,* ScienceDirect</p><p>[14] Kaggle, <a href="https://www.kaggle.com/competitions/m5-forecasting-accuracy/data">M5 Forecasting</a></p><div><hr></div>]]></content:encoded></item><item><title><![CDATA[Beyond Text: Leveraging LLMs for Time Series Forecasting (Part 1/2)]]></title><description><![CDATA[A Deep Dive Into the Theoretical Foundations and Practical Implementation of LLM-Powered Time Series Forecasting]]></description><link>https://aipractitioner.substack.com/p/beyond-text-leveraging-llms-for-time</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/beyond-text-leveraging-llms-for-time</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 22 May 2025 08:30:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Xcz0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Xcz0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Xcz0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png 424w, https://substackcdn.com/image/fetch/$s_!Xcz0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png 848w, https://substackcdn.com/image/fetch/$s_!Xcz0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png 1272w, https://substackcdn.com/image/fetch/$s_!Xcz0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Xcz0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png" width="1456" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:275191,&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://aipractitioner.substack.com/i/164070335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Xcz0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png 424w, https://substackcdn.com/image/fetch/$s_!Xcz0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png 848w, https://substackcdn.com/image/fetch/$s_!Xcz0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png 1272w, https://substackcdn.com/image/fetch/$s_!Xcz0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9d88850-ad60-4b48-8184-7331d35ba540_2010x828.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Large Language Models (LLMs) have reshaped the AI landscape by enabling a single architecture to handle a wide range of tasks, often outperforming models built for specific problems. Their strength lies in generalization: trained on massive datasets with simple objectives, LLMs can tackle translation, question answering, reasoning, and more, all without task-specific tuning.</p><p>This flexibility has allowed LLMs to expand far beyond natural language processing. They now power applications in code generation, multimodal learning, and even computer vision, where they serve as universal backbones. </p><p><strong>A new frontier is emerging: time series forecasting. </strong>Traditionally dominated by specialized statistical models, forecasting is now being reimagined through foundation models trained on sequential patterns.</p><h3>Objective</h3><p>This article explores how Large Language Models (LLMs) can be applied to time series forecasting, with a particular focus on TimeLLM, a model that repurposes language modeling techniques for temporal data. It delves into both the theoretical foundations of TimeLLM and its practical implementation using the Nixtla ecosystem. The methodology is illustrated through a concrete use case: sales forecasting on the M5 competition dataset, which features daily Walmart sales data across thousands of items and stores.</p><p>After reading this article, you will understand:</p><ul><li><p>How does TimeLLM repurpose language models to tackle time series forecasting?</p></li><li><p>How performant is it compared to other classic approaches?</p></li><li><p>How can these models be applied in practice to deliver fast, accurate time series forecasts?</p></li></ul><blockquote><p>This article is the first in a series on advanced time series modeling. Be sure to explore the others for a complete understanding.</p><p><strong>Prerequisites:</strong> The article is designed to be accessible to readers without prior expertise in the subject.</p><p><strong>Tools &amp; libraries:</strong> The code uses the <code>nixtla</code> library for TimeLLM implementation and Plotly for interactive visualizations. Additional tools include <code>pandas</code> and <code>scikit-learn</code> for data handling and evaluation.</p></blockquote><p>You can find the code here on <a href="https://github.com/linafaik08/time-series-forecasting-models">GitHub</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>1. TimeLLM Explained: Repurposing Language Models for Temporal Forecasting</h2><h3>What is the core idea behind TimeLLM?</h3><p>LLMs are no longer confined to natural language. In fields like computer vision and code generation, they now serve as powerful general-purpose backbones, outperforming task-specific models. This cross-domain success raises a timely question for time series forecasting: can the pattern recognition and reasoning abilities of LLMs be harnessed for temporal data?</p><p>Time series and language share a sequential nature, but differ in structure and encoding. The key challenge is aligning these modalities to allow LLMs to process time series effectively, without modifying the models themselves.</p><p>This is the core idea behind TimeLLM, introduced in <em>&#8220;Time-LLM: Time Series Forecasting by Reprogramming Language Models&#8221;</em> [<a href="https://arxiv.org/abs/2505.02583?utm_source=tldrai">5</a>]. Rather than redesigning architectures, the authors reprogram the input: transforming time series into token sequences that resemble natural language prompts. This approach enables pretrained language models, like GPT-2, to be used directly for forecasting, leveraging their rich priors and generalization capabilities.</p><h3>How are time series reprogrammed into language-compatible formats?</h3><p>This process involves the following key steps:</p><ol><li><p><strong>Input Embedding:</strong> The first step is to convert continuous time series data into compact patch representations. Each time series is first normalized (zero mean, unit variance) using RevIN [<a href="https://www.youtube.com/watch?v=6sFiNExS3nI">8</a>], to handle distribution shifts. The time series is then segmented into patches, small overlapping or non-overlapping windows of consecutive values.</p></li></ol><blockquote><p><strong>Original series (T = 8):</strong> [95, 96, 97, 98, 100, 99, 98, 97]</p><p>Patch length (Lp) = 4</p><p><strong>Patches:</strong> <br>- Patch 1: [95, 96, 97, 98]<br>- Patch 2: [100, 99, 98, 97]</p><p>Emdedding dimension (dm) = 3</p><p><strong>Patches embedded:</strong> <br>- Patch 1: [0.2, 0.3, 0.4]<br>- Patch 2: [-0.3, -0.2, -0.1]</p><p>Each patch is linearly embedded into a vector of dimension <code>d&#8344;</code>. This results in patch embeddings.</p></blockquote><ol start="2"><li><p><strong>Patch Reprogramming:</strong> The next step involves aligning the structure of time series embeddings with the language model&#8217;s representation space. This is done by transforming each patch, which is a short segment of the series, into a combination of language-like representations. Instead of retraining the model, TimeLLM selects a small set of prototypes from the LLM&#8217;s existing vocabulary, words like &#8220;up&#8221;, &#8220;down&#8221;, or &#8220;steady&#8221; that reflect common time series patterns. Each patch is then matched to these prototypes. For example:</p><ul><li><p>A decreasing patch might become &#8220;short down&#8221;</p></li><li><p>A stable patch could be &#8220;steady flat&#8221;</p></li></ul><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CiJo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CiJo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png 424w, https://substackcdn.com/image/fetch/$s_!CiJo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png 848w, https://substackcdn.com/image/fetch/$s_!CiJo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png 1272w, https://substackcdn.com/image/fetch/$s_!CiJo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CiJo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png" width="395" height="286.35198135198135" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:622,&quot;width&quot;:858,&quot;resizeWidth&quot;:395,&quot;bytes&quot;:155371,&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://aipractitioner.substack.com/i/164070335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CiJo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png 424w, https://substackcdn.com/image/fetch/$s_!CiJo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png 848w, https://substackcdn.com/image/fetch/$s_!CiJo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png 1272w, https://substackcdn.com/image/fetch/$s_!CiJo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5dc2a59-29d6-4c3e-bcef-e5afb5f5f431_858x622.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Illustration of patch reprogramming, from the original paper [3]  </figcaption></figure></div><p>This transformation uses attention to choose the most relevant prototypes, converting numeric data into something the LLM can naturally process, just like a sentence. By rephrasing time series in this way, TimeLLM enables a frozen language model to perform forecasting without any architectural changes.</p></li></ol><blockquote><p><strong>Reprogrammed output:</strong> <br>- Patch 1: [0.2, 0.3, 0.4] &#8594; &#8220;steady up&#8221; <br>- Patch 2: [-0.3, -0.2, -0.1] &#8594; &#8220;slow down&#8221;</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ml9F!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ml9F!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png 424w, https://substackcdn.com/image/fetch/$s_!Ml9F!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png 848w, https://substackcdn.com/image/fetch/$s_!Ml9F!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png 1272w, https://substackcdn.com/image/fetch/$s_!Ml9F!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ml9F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png" width="1456" height="330" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa512fbe-3148-4594-afb3-41bc24130103_3904x884.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:330,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:229484,&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://aipractitioner.substack.com/i/164070335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ml9F!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png 424w, https://substackcdn.com/image/fetch/$s_!Ml9F!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png 848w, https://substackcdn.com/image/fetch/$s_!Ml9F!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png 1272w, https://substackcdn.com/image/fetch/$s_!Ml9F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa512fbe-3148-4594-afb3-41bc24130103_3904x884.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Figure 2 &#8212; Reprogrammed Patch Embeddings, inspired by the original paper [<a href="https://arxiv.org/abs/2310.01728">3</a>]</figcaption></figure></div><p><strong>3. Prompting:</strong> The next step consists of building a prompt that the LLM can process naturally. TimeLLM adopts the Prompt-as-Prefix (PaP) strategy instead of the Patch-as-Prefix approach, enabling better alignment with the model&#8217;s pretraining format.</p><ul><li><p><strong>Patch-as-Prefix:</strong> It translates the past values of the time series directly into natural language and appends a textual instruction asking the LLM to forecast. For example:</p></li></ul><blockquote><p>"Weekly sales were: 234.5, 238.0, 231.2, 229.8. Predict the next 3 values."</p></blockquote><ul><li><p>This method faces challenges:</p><ul><li><p>LLMs tokenize numbers in inconsistent ways (e.g., 238.0 might be split into ['2', '38', '.', '0'] depending on the tokenizer).</p></li><li><p>It lacks semantic structure and statistical grounding.</p></li><li><p>It&#8217;s hard to scale for long input sequences or high-precision forecasts.</p></li></ul></li><li><p><strong>Prompt-as-Prefix (PaP):</strong> It avoids these limitations by enriching the prompt with structured metadata and reprogrammed patch embeddings. It follows a format like:</p></li></ul><blockquote><p>The M5 dataset contains daily sales records for thousands of products sold across Walmart stores in the United States. Each record includes product-level sales, calendar information, and event markers. Below is the information about the input time series:</p><ul><li><p>[BEGIN DATA]</p></li><li><p>[Domain]: Daily sales of an individual product in a Walmart store.</p></li><li><p>[Instruction]: Predict the next &lt;H&gt; days of sales given the previous &lt;T&gt; days attached.</p></li><li><p>[Statistics]: The input has a minimum of &lt;min_value&gt;, a maximum of &lt;max_value&gt;, and a median of &lt;median_value&gt; The overall trend is &lt;upward or downward&gt;. The top five lags are &lt;lags&gt;. [END DATA]</p></li></ul></blockquote><ol start="4"><li><p><strong>Output Projection: </strong></p><p>We have seen how to structure and deliver temporal information to an LLM using reprogrammed patches and carefully designed prompts. But how is the model&#8217;s output transformed into usable forecasts? </p><p>After the prompt and patch embeddings are passed through the frozen LLM, the model generates a sequence of hidden representations. Only the final part, corresponding to the continuation of the sequence, is used for prediction. </p><p>The remaining outputs are then flattened and passed through a linear projection layer to convert them into real-valued forecasts. This final step completes the decoding process, transforming the LLM&#8217;s abstract representations back into interpretable, actionable time series predictions.</p></li></ol><p><strong>&#9888;&#65039; Important note:</strong> TimeLLM does not involve fine-tuning the LLM. The language model (e.g., GPT-2) remains entirely frozen during training. Its weights are not updated. Instead, forecasting is enabled by learning lightweight modules that reprogram the input (e.g., patch embeddings and prompts) into a format the LLM can process. This method bridges zero-shot-style forecasting and few-shot learning, leveraging the LLM&#8217;s pretrained reasoning capabilities without expensive retraining or parameter updates.</p><h3>How well does TimeLLM perform in practice compared to state-of-the-art models?</h3><p><strong>Learning frameworks</strong></p><p>The evaluation of Time-LLM was conducted across a comprehensive set of benchmarks and scenarios, including long-term and short-term forecasting, few-shot learning (with 5&#8211;10% of training data), and zero-shot cross-domain transfer.</p><p><strong>Datasets</strong></p><p>The model was tested on widely accepted datasets such as ETT (ETTh1, ETTm1, etc.), Weather, Traffic, Electricity (ECL), ILI, and M5, using standard metrics including Mean Squared Error (MSE) and Mean Absolute Error (MAE).</p><p><strong>Models</strong></p><p>It was compared against both classical and recent state-of-the-art models, including transformer-based baselines (PatchTST, FEDformer, Informer), as well as recent LLM-based methods (GPT4TS, LLMTime). Importantly, the comparisons followed unified evaluation protocols from prior works to ensure consistency.</p><p><strong>Results</strong></p><p>While the reported results show strong and consistent performance, especially in zero-shot and few-shot settings, the claim that <em>&#8220;Time-LLM consistently outperforms state-of-the-art forecasting methods by large margins&#8221;</em> should be interpreted with nuance.</p><ul><li><p>The margins are indeed substantial in specific low-data regimes, with reported improvements of up to 33% in MSE, and 14.2% average gain in zero-shot scenarios.</p></li><li><p>However, many of these gains are context-dependent: they are most pronounced when the training data is scarce, and less dominant under full supervision.</p></li><li><p>Additionally, while the LLM backbone is frozen, the reprogramming components are trained, which means the approach is not strictly zero-shot end-to-end.</p></li><li><p>Furthermore, model efficiency and scalability remain important trade-offs compared to domain-specific architectures optimized for speed and resource constraints.</p></li></ul><p>Thus, while the results validate the potential of LLMs in forecasting, they do not fully displace task-specific models in all conditions. This is further supported by the experimental results discussed in the following section.</p><h2>2. LLMs in Action: Implementing TimeLLM with Nixtla</h2><h3>Use case overview: M5 sales forecasting</h3><p><strong>About data</strong></p><p>To compare the performance of TimeLLM, the M5 dataset was used as a representative real-world benchmark [<a href="https://www.kaggle.com/competitions/m5-forecasting-accuracy/data">12</a>].</p><p>The data was aggregated per store to forecast daily turnover over a 14-day horizon for 10 stores, each with 1,990 observations. This setup simulates a common business case: making accurate short-term forecasts across multiple small time series with limited historical depth.</p><p>While the original M5 competition emphasized item-level forecasting with hierarchical reconciliation, several key takeaways are worth noting. The most impactful strategies included shared learning across related series, the integration of exogenous variables such as calendar events, and the strong performance of hybrid architectures. Hybrid architectures blend the structure of statistical methods with the adaptability of neural networks to capture both predictable patterns and complex dynamics. [<a href="https://www.sciencedirect.com/science/article/pii/S0169207021001874">11</a>]</p><p><strong>Problem statement</strong></p><p>The task involves predicting the next 14 days of store-level turnover based on historical sales and external event features. Each store's series is treated independently in terms of target values, but shared representations and temporal structures are leveraged where applicable.</p><p><strong>Learning and evaluation framework</strong></p><p>For evaluation, the last 14 days of each time series were held out as the test set to ensure models only learned from past data. This simple holdout strategy was preferred over cross-validation, which was less practical given the relatively short length of the series.</p><p>Model performance is evaluated using the Mean Absolute Percentage Error (MAPE), which provides a scale-independent measure of accuracy</p><p><strong>Benchmark models</strong></p><p>To contextualize TimeLLM&#8217;s performance, it was compared against two classes of models: traditional statistical methods and modern deep learning architectures.</p><p><strong>&#10004; Statistical Models</strong></p><ul><li><p><strong>AutoARIMA</strong>: Automatically selects ARIMA parameters using AIC minimization. It captures linear autoregressive patterns with integrated differencing and moving average components.</p></li><li><p><strong>AutoETS</strong>: Automatically fits an exponential smoothing model with components for level, trend, and seasonality. Particularly strong on short-term regular patterns.</p></li><li><p><strong>AutoCES</strong> (Complex Exponential Smoothing): A generalization of ETS (Error, Trend, Seasonality) designed to better handle nonlinearities and complex seasonality by modeling interactions of components multiplicatively or additively.</p></li><li><p><strong>MSTL</strong> (Multiple Seasonal-Trend decomposition using Loess): An extension of STL that supports multiple seasonal patterns (e.g., weekly and yearly) and smooths the trend nonparametrically. Especially effective on retail and web traffic series.</p></li><li><p><strong>Theta</strong>: A simple but powerful model that decomposes the series into theta lines and extrapolates using linear and exponential components. It was the winning model of the M3 forecasting competition.</p></li></ul><p><strong>&#10004; Deep Learning Models</strong></p><ul><li><p><strong>NHITS</strong>: An interpretable deep learning architecture that learns hierarchical residual blocks over varying temporal scales. It focuses on local level structures and performs well on long-horizon forecasting.</p></li><li><p><strong>NBEATS</strong>: A pure deep feedforward neural network architecture using backward and forward residual stacks. It does not require prior knowledge of seasonality or trend, making it versatile for various domains.</p></li></ul><p><strong>Note</strong>: Both deep learning models were trained using a quantile loss to support probabilistic forecasting, with a confidence level of 90%. In addition, they were enriched with dynamic exogenous variables such as holiday and event indicators, which are known to affect store-level turnover.</p><h3>How can TimeLLM be implemented using Nixtla's ecosystem?</h3><p>Nixtla provides a PyTorch Lightning-compatible implementation via the <code>neuralforecast</code> library, allowing data scientists to train TimeLLM models just like any other forecasting model.</p><p><strong>1. Forecasting Setup</strong></p><p>These parameters define how the historical input is structured before entering the LLM.</p><ul><li><p><code>h</code>: Forecast horizon (in our case 14 days).</p></li><li><p><code>input_size</code>: Number of past time steps the model looks at.</p></li><li><p><code>patch_len</code>: Length of each time series segment (patch).</p></li><li><p><code>stride</code>: Step size between patches (controls overlap).</p></li></ul><p><strong>2. LLM and Prompt Configuration</strong></p><p>Prompting allows better alignment between numerical patterns and the LLM's pretraining distribution.</p><ul><li><p><code>llm</code>: Pretrained language model to use (e.g. <code>'gpt2'</code>, <code>'gpt2-medium'</code>).</p></li><li><p><code>d_llm</code>: Dimensionality of the LLM&#8217;s hidden states (e.g. 768 for GPT2, 1024 for GPT2-medium).</p></li><li><p><code>prompt_prefix</code>: Optional natural-language prompt describing the forecasting task and data context.</p></li></ul><p><strong>3. Reprogramming Architecture</strong></p><p>These define how numeric input is transformed into text-like embeddings for the LLM.</p><ul><li><p><code>d_model</code>: Internal dimension for patch-to-prototype embedding.</p></li><li><p><code>d_ff</code>: Hidden dimension for the patch encoder&#8217;s feed-forward layers.</p></li><li><p><code>n_heads</code>: Number of attention heads in the cross-attention layer.</p></li><li><p><code>top_k</code>: Number of LLM token embeddings to use as prototypes.</p></li></ul><p><strong>4. Training Parameters</strong></p><p>These parameters control the learning process of the lightweight components surrounding the LLM.</p><ul><li><p><code>batch_size</code>, <code>valid_batch_size</code>, <code>windows_batch_size</code>: Batch sizes for training and validation.</p></li><li><p><code>learning_rate</code>: Learning rate for optimizing reprogramming layers (default: <code>1e-4</code>).</p></li><li><p><code>max_steps</code>: Maximum number of training iterations (e.g. 500&#8211;1000).</p></li><li><p><code>dropout</code>: Dropout probability for regularization.</p></li><li><p><code>loss</code>: Loss function (e.g. <code>MAE()</code>, <code>MQLoss(level=[90])</code>).</p></li><li><p><code>val_check_steps</code>: How often to evaluate on the validation set.</p></li></ul><p><strong>6. Additional Controls</strong></p><p>These offer extra flexibility and stability in training TimeLLM effectively.</p><ul><li><p><code>scaler_type</code>: Input normalization method (<code>'robust'</code>, <code>'minmax'</code>, etc.).</p></li><li><p><code>early_stop_patience_steps</code>: Stop training early if no improvement.</p></li><li><p><code>start_padding_enabled</code>: Allow left-padding for short sequences.</p></li><li><p><code>step_size</code>: Window stride for sampling training windows.</p></li><li><p><code>random_seed</code>: Seed for reproducibility.</p></li></ul><p>For more information, refer to the Nixlta documentation [<a href="https://nixtlaverse.nixtla.io/neuralforecast/models.timellm.html">7</a>].</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rbPb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rbPb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png 424w, https://substackcdn.com/image/fetch/$s_!rbPb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png 848w, https://substackcdn.com/image/fetch/$s_!rbPb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png 1272w, https://substackcdn.com/image/fetch/$s_!rbPb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rbPb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png" width="728" height="1010.9166666666666" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1733,&quot;width&quot;:1248,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:456793,&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://aipractitioner.substack.com/i/164070335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee1dbcde-fccb-4e71-a914-822ecbb7bbeb_1290x1778.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rbPb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png 424w, https://substackcdn.com/image/fetch/$s_!rbPb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png 848w, https://substackcdn.com/image/fetch/$s_!rbPb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png 1272w, https://substackcdn.com/image/fetch/$s_!rbPb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59bd2942-5488-436d-8b28-8d8ba7e38955_1248x1733.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3 &#8212; TimeLLM prompt configuration and model Initialization</figcaption></figure></div><p>Once the model is defined, it can be trained and used for forecasting through the <code>NeuralForecast</code> framework. The <code>fit()</code> method trains the model on historical data and calibrates 90% prediction intervals using conformal methods based on 10 past windows. The <code>predict()</code> function then produces both point forecasts and associated uncertainty intervals for the next 14 days.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!x7zf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!x7zf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png 424w, https://substackcdn.com/image/fetch/$s_!x7zf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png 848w, https://substackcdn.com/image/fetch/$s_!x7zf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png 1272w, https://substackcdn.com/image/fetch/$s_!x7zf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!x7zf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png" width="1223" height="1077" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1077,&quot;width&quot;:1223,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:220423,&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://aipractitioner.substack.com/i/164070335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a60e53-fec2-4f7f-b739-fc0590f06938_1276x1130.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!x7zf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png 424w, https://substackcdn.com/image/fetch/$s_!x7zf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png 848w, https://substackcdn.com/image/fetch/$s_!x7zf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png 1272w, https://substackcdn.com/image/fetch/$s_!x7zf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69ed1e98-d6c6-49f8-9527-7889a03b3087_1223x1077.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4 &#8212; Training and forecasting with TimeLLM using NeuralForecast</figcaption></figure></div><p>The code display logs that summarize the structure of the TimeLLM model at training time. The GPT-2 backbone (<code>llm</code>) is kept frozen (<code>eval</code> mode) with 124M non-trainable parameters, while the remaining 54M parameters are trainable and belong to the lightweight reprogramming modules. Most of the trainable parameters are concentrated in the <code>mapping_layer</code>, which transforms the LLM outputs into forecast-ready representations. Modules like <code>patch_embedding</code>, <code>reprogramming_layer</code>, and <code>output_projection</code> handle the transformation of time series patches into embeddings aligned with the LLM space. In total, the model includes 178M parameters and is compact enough (713 MB) to run comfortably on standard hardware.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sHpQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sHpQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png 424w, https://substackcdn.com/image/fetch/$s_!sHpQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png 848w, https://substackcdn.com/image/fetch/$s_!sHpQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png 1272w, https://substackcdn.com/image/fetch/$s_!sHpQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sHpQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png" width="489" height="320.57729941291586" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:670,&quot;width&quot;:1022,&quot;resizeWidth&quot;:489,&quot;bytes&quot;:119678,&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://aipractitioner.substack.com/i/164070335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sHpQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png 424w, https://substackcdn.com/image/fetch/$s_!sHpQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png 848w, https://substackcdn.com/image/fetch/$s_!sHpQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png 1272w, https://substackcdn.com/image/fetch/$s_!sHpQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4841979b-4e16-48e9-b853-4704624c4a8f_1022x670.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 5 &#8212; Model summary logs from TimeLLM training</figcaption></figure></div><h3>How well does TimeLLM perform?</h3><p><strong>Empirical results on store-level forecasting</strong></p><p>In the evaluation based on the M5 dataset (aggregated at store level, 14-day horizon), TimeLLM performed significantly worse than both classical and deep learning benchmarks. While NBEATS and NHITS achieved MAPE scores around 7-8%, and statistical models like AutoETS reached 8-9%, TimeLLM&#8217;s MAPE remained around 12.8%.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CjG2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CjG2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png 424w, https://substackcdn.com/image/fetch/$s_!CjG2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png 848w, https://substackcdn.com/image/fetch/$s_!CjG2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png 1272w, https://substackcdn.com/image/fetch/$s_!CjG2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CjG2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png" width="1456" height="610" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:610,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:100077,&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://aipractitioner.substack.com/i/164070335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CjG2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png 424w, https://substackcdn.com/image/fetch/$s_!CjG2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png 848w, https://substackcdn.com/image/fetch/$s_!CjG2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png 1272w, https://substackcdn.com/image/fetch/$s_!CjG2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0865bf89-8225-4e74-9448-7f4202cf213a_1580x662.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 6 &#8212; Mean Absolute Percentage Error (MAPE) comparison across models</figcaption></figure></div><p>Visually, TimeLLM&#8217;s forecasts appeared overly smooth, failing to reflect known seasonal dynamics such as weekend demand surges or event-driven peaks. The model&#8217;s output consistently regressed toward the historical average, suggesting it lacked responsiveness to calendar effects, even when these were included as binary flags in the input.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!feZt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!feZt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png 424w, https://substackcdn.com/image/fetch/$s_!feZt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png 848w, https://substackcdn.com/image/fetch/$s_!feZt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png 1272w, https://substackcdn.com/image/fetch/$s_!feZt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!feZt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png" width="1456" height="603" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:603,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:192154,&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://aipractitioner.substack.com/i/164070335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!feZt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png 424w, https://substackcdn.com/image/fetch/$s_!feZt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png 848w, https://substackcdn.com/image/fetch/$s_!feZt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png 1272w, https://substackcdn.com/image/fetch/$s_!feZt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd881b16-b72a-4c57-a4ad-5dba44c7ed67_1892x784.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 7 &#8212; Forecasting example for a single store: actual vs. predicted</figcaption></figure></div><p>This behavior resembled that of a na&#239;ve or exponentially smoothed baseline rather than a model designed for pattern-aware generalization. This outcome stands in sharp contrast to the high performance reported in the original TimeLLM paper.</p><p><strong>Understanding the discrepancy with the initial paper</strong></p><p>In the initial paper <em>&#8220;TIME-LLM: Time Series Forecasting by Reprogramming Large Language Models&#8221;</em> [<a href="https://arxiv.org/abs/2310.01728">3</a>], the model consistently outperforms deep learning and transformer-based methods across various long-range forecasting tasks. According to Table 12 [<a href="https://arxiv.org/abs/2310.01728">3</a>]:</p><ul><li><p>TimeLLM achieves the lowest SMAPE and MASE on quarterly and yearly data.</p></li><li><p>It ranks first in average OWA across benchmarks (0.86), outperforming PatchTST, FEDformer, and DLinear.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!J2e9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!J2e9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png 424w, https://substackcdn.com/image/fetch/$s_!J2e9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png 848w, https://substackcdn.com/image/fetch/$s_!J2e9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png 1272w, https://substackcdn.com/image/fetch/$s_!J2e9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!J2e9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png" width="1452" height="506" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:506,&quot;width&quot;:1452,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:436273,&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://aipractitioner.substack.com/i/164070335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!J2e9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png 424w, https://substackcdn.com/image/fetch/$s_!J2e9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png 848w, https://substackcdn.com/image/fetch/$s_!J2e9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png 1272w, https://substackcdn.com/image/fetch/$s_!J2e9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0daed484-9e4c-42c1-a7a4-0b5735ce5047_1452x506.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Table 1 &#8212; Full short-term time series forecasting results, from the oringal paper [<a href="https://arxiv.org/abs/2310.01728">3</a>]</figcaption></figure></div><p>However, these gains are observed in datasets with high trend/seasonal signal strength and input lengths ranging from 96 to 512 time steps, often evaluated in few-shot or zero-shot configurations.</p><p>Several design omissions likely contributed to the underperformance of TimeLLM in our experimentations:</p><ul><li><p><strong>Limited model capacity</strong>: The experimentations used GPT2-small (117M parameters), whereas the paper relies on large-scale LLMs like LLaMA-7B or GPT-4. Smaller models lack the abstraction capacity to generalize across complex time patterns.</p></li><li><p><strong>No structured prompt engineering</strong>: The prompt used described calendar effects in plain language but omitted statistical context such as trend slope, min/max, median, or autocorrelation lags. These elements are crucial in the original paper.</p></li><li><p><strong>Short input sequences</strong>: Input sizes in the original benchmarks ranged from 96 to 512 steps, whereas our setup used only 30&#8211;60, limiting the LLM&#8217;s ability to detect and reason over seasonal cycles.</p></li><li><p><strong>No decomposition or reformatting</strong>: The data was passed in raw numerical form without trend or seasonal decomposition, which removes useful inductive bias and prevents the LLM from focusing on meaningful variation.</p></li><li><p><strong>No input paraphrasing</strong>: As highlighted in <em>&#8220;Time Series Forecasting with LLMs: Understanding and Enhancing Model Capabilities&#8221;</em> [<a href="https://www.notion.so/Virtual-Env-Pipenv-89e76a975a384762ae9ddddb7e86e96d?pvs=21">2</a>], rephrasing inputs into natural language (e.g., &#8220;sales dropped from 180 to 140&#8221;) significantly improves performance. This step was not applied.</p></li><li><p><strong>Mismatch in learning regime</strong>: TimeLLM is designed for zero-or few-shot generalization. In our case, the model was trained on full-length data for just 40 steps. This is a misaligned setup for what is fundamentally a pretrained LLM.</p></li></ul><p>As a result, the model underperformed by a wide margin and did not demonstrate the generalization capabilities highlighted in the original paper.</p><p><strong>Broader Alignment with the Literature</strong></p><p>However, these findings are consistent with the limitations outlined in &#8221;<em>Time Series Forecasting with LLMs: Understanding and Enhancing Model Capabilities&#8221;</em> [<a href="https://www.notion.so/Virtual-Env-Pipenv-89e76a975a384762ae9ddddb7e86e96d?pvs=21">2</a>] which offer a more critical perspective. In that work, LLM-based methods, whether GPT-4, Gemini, or LLaMA-2, only performed competitively under highly structured conditions.</p><p>The authors observed:</p><ul><li><p><strong>Strong results</strong> only on datasets with high seasonal and trend strength (e.g., MonthlyMilk, AirPassengers)</p></li><li><p><strong>Poor generalization</strong> on short or irregular datasets (e.g., Sunspots, HeartRate), where MAPE often exceeded 300% (cf. Table 3 in the paper [<a href="https://www.notion.so/Virtual-Env-Pipenv-89e76a975a384762ae9ddddb7e86e96d?pvs=21">2</a>]).</p></li><li><p><strong>Significant gains</strong> only when input sequences were reformatted into natural language or when external statistical knowledge was included</p></li></ul><p>Our M5 setup aligns with these weaker cases: moderately seasonal, event-sensitive series with limited context and no prompt rephrasing. The absence of input-to-text transformation or decomposed statistics likely contributed to the lack of generalization. In particular, the model showed no capacity to recover or amplify signal from binary event indicators&#8212;an issue both papers identify when external knowledge is omitted.</p><div><hr></div><h2>Key Takeaways</h2><p>&#10004;&#65039; TimeLLM adapts frozen LLMs for time series forecasting by transforming numerical sequences into language-like prompts, allowing temporal predictions without modifying the core model.</p><p>&#10004;&#65039; The model shines in zero-shot and few-shot scenarios, with the original paper reporting up to 33% gains in MSE over state-of-the-art baselines when training data is limited.</p><p>&#10004;&#65039; The innovation lies in reprogramming, using patching and prompt engineering to align time series data with the LLM&#8217;s input expectations&#8212;no fine-tuning required.</p><p>&#10004;&#65039; However, TimeLLM is more resource-intensive than classical and even deep learning models. Despite not training the LLM, inference and training of the surrounding architecture still demand considerable compute and memory.</p><p><strong>Final thoughts: TimeLLM is a strong choice when data is scarce, flexibility is critical, or you need fast prototyping across domains. For production-grade or resource-constrained environments, leaner task-specific models often remain more efficient and accurate.</strong></p><div><hr></div><h1>References</h1><p>[1] Congxi Xiao, Jingbo Zhou, Yixiong Xiao, Xinjiang Lu, Le Zhang, Hui Xiong, <em><a href="https://arxiv.org/abs/2503.04118">TimeFound: A Foundation Model for Time Series Forecasting</a></em>, arXiv</p><p>[2] Hua Tang, Chong Zhang, Mingyu Jin, Qinkai Yu, Zhenting Wang, Xiaobo Jin, Yongfeng Zhang, Mengnan Du, <em><a href="https://arxiv.org/abs/2402.10835">Time Series Forecasting with LLMs: Understanding and Enhancing Model Capabilities</a></em>, arXiv</p><p>[3] Jin, M., Wang, S., Ma, L., et al. (2023), <em><a href="https://arxiv.org/abs/2310.01728">Time-LLM: Time Series Forecasting by Reprogramming Large Language Models</a></em><strong>,</strong> arXiv</p><p>[4] Xiyuan Zhang, Ranak Roy Chowdhury, Rajesh K. Gupta, Jingbo Shang, <a href="https://arxiv.org/abs/2402.01801">Large Language Models for Time Series: A Survey</a>, arXiv</p><p>[5] C. Liu, S. Zhou, Q. Xu, H. Miao, C. Long, Z. Li, R. Zhao (2025), <em><a href="https://arxiv.org/abs/2505.02583?utm_source=tldrai">Towards Cross-Modality Modeling for Time Series Analytics: A Survey in the LLM Era</a></em>, arXiv</p><p>[6] T. Kim, J. Kim, Y. Tae, C. Park, J. Choi, J. Choo (2022), <a href="https://paperswithcode.com/paper/reversible-instance-normalization-for">*Reversible Instance Normalization for Accurate Time-Series Forecasting against Distribution Shift</a>,* ICLR 2022, Paper with code</p><p>[7] Nixtla, <a href="https://nixtlaverse.nixtla.io/neuralforecast/models.timellm.html">TimeLLM documentation</a></p><p>[8] Ming Jin, <em><a href="https://www.youtube.com/watch?v=6sFiNExS3nI">Time-LLM: Time Series Forecasting by Reprogramming Large Language Models</a></em>, MLLM Talk, Youtube</p><p>[9] Adrien Nav, <a href="https://www.youtube.com/watch?v=L-hRexVa32k">*TimeLLM - Time Series Forecasting Model</a><strong>,</strong>* Youtube</p><p>[10] Marco Peixeiro, <em><a href="https://medium.com/the-forecaster/time-llm-reprogram-an-llm-for-time-series-forecasting-e2558087b8ac">Time-LLM: Reprogram an LLM for Time Series Forecasting</a></em>, Medium</p><p>[11] S. Makridakis, E. Spiliotis, V. Assimakopoulos, <a href="https://www.sciencedirect.com/science/article/pii/S0169207021001874">*M5 accuracy competition: Results, findings, and conclusions</a>,* ScienceDirect</p><p>[12] Kaggle, <a href="https://www.kaggle.com/competitions/m5-forecasting-accuracy/data">M5 Forecasting</a></p><div><hr></div>]]></content:encoded></item><item><title><![CDATA[From Text to Networks: The Revolutionary Impact of LLMs on Knowledge Graphs]]></title><description><![CDATA[A Step-by-Step Guide to Building and Leveraging Knowledge Graphs with LLMs]]></description><link>https://aipractitioner.substack.com/p/coming-soon</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/coming-soon</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 29 Aug 2024 15:38:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!wJEO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.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="https://substackcdn.com/image/fetch/$s_!wJEO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wJEO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wJEO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wJEO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wJEO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wJEO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg" width="728" height="302.7266666666667" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:499,&quot;width&quot;:1200,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wJEO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wJEO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wJEO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wJEO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816e8ff5-bd84-4cdd-8230-d13f2141bdd2_1200x499.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The rise of Large Language Models (LLMs) has revolutionized the way we extract information from text and interact with it. However, despite their impressive capabilities, LLMs face several inherent challenges, particularly in areas such as reasoning, consistency, and information&#8217;s contextual accuracy. These difficulties come from the probabilistic nature of LLMs, which can lead to hallucinations, lack of transparency, and challenges in handling structured data.</p><p>This is where Knowledge Graphs (KGs) come into play. By integrating LLMs with KGs, AI-generated knowledge can be significantly enhanced. Why? KGs provide a structured and interconnected representation of information, reflecting the relationships and entities in the real world. Unlike traditional databases, KGs can capture and reason about the complexities of human knowledge, ensuring that the outputs of LLMs come from a structured, verifiable knowledge base. This integration leads to more accurate, consistent, and contextually relevant outcomes.</p><p>Industries like healthcare, finance, and legal services can greatly benefit from knowledge graphs due to their need for precise and interpretable information.</p><h3><strong>Objective</strong></h3><p>The article delves into the innovative ways LLMs can be harnessed to build and leverage knowledge graphs.</p><p>After reading this article, you will understand:</p><ol><li><p>How to build a knowledge graph using LLMs</p></li><li><p>How LLMs can then leverage knowledge graphs to enhance their capabilities</p></li><li><p>What are the limitations and key considerations when integrating LLMs with knowledge graphs?</p></li></ol><blockquote><p><em>No prior knowledge is required to understand the article. The experimentations described in the article were carried out focus only the libraries <a href="https://www.llamaindex.ai/">llama-index</a>.</em></p></blockquote><p>You can find the code <a href="https://github.com/linafaik08/knowledge_graphs_llm">here</a> on GitHub.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>1. Navigating Knowledge Graphs &amp; LLMs Landscape</strong></h2><p>This section provides a comprehensive overview of the process involved in building and leveraging knowledge graphs with LLMs. It introduces the key concepts, terminology, and various approaches before delving into the specific methods in the following sections.</p><h3><strong>1.1. How does the process of developing and leveraging knowledge graphs unfold?</strong></h3><p>Figure 1 illustrates the overall workflow, consisting of two key steps:</p><ol><li><p>Knowledge graph extraction, along with the possible techniques detailed in Section 2. This step results in the creation of the knowledge graph.</p></li><li><p>Retrieval using one of the techniques outlined, which will be discussed an in-depth in Section 3. These techniques can be employed to answer queries.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RNw3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RNw3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png 424w, https://substackcdn.com/image/fetch/$s_!RNw3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png 848w, https://substackcdn.com/image/fetch/$s_!RNw3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png 1272w, https://substackcdn.com/image/fetch/$s_!RNw3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RNw3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png" width="1400" height="972" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:972,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!RNw3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png 424w, https://substackcdn.com/image/fetch/$s_!RNw3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png 848w, https://substackcdn.com/image/fetch/$s_!RNw3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png 1272w, https://substackcdn.com/image/fetch/$s_!RNw3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F022ceb49-b4ba-4fc5-9915-9308f228453c_1400x972.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 1 &#8212; Workflow</figcaption></figure></div><h3><strong>1.2. Refresher on knowledge graph terminology</strong></h3><p>In network terminology, a triplet refers to a fundamental unit of a knowledge graph. It consists of three elements: a subject (an entity), a relation (the connection between entities), and an object (another entity).</p><p>Nodes represent the entities (e.g., people, companies) within the network, while edges or links represent the relationships or interactions between these nodes.</p><p>Together, nodes and edges form a graph structure, where triplets define the specific connections within this network.</p><h3><strong>1.3. About Data</strong></h3><p>The data for the experiments is drawn from the Wikipedia <a href="https://en.wikipedia.org/wiki/Panama_Papers">page</a> on the Panama Papers scandal.</p><h2><strong>2. Building Knowledge Graphs: Extraction Methods Explored</strong></h2><p>The library llama-index proposes 4 main methods to extract a knowledge graph from a corpus of documents using LLMs:</p><ol><li><p>Schema-based extraction</p></li><li><p>Free-form extraction</p></li><li><p>Dynamic extraction</p></li><li><p>Implicit extraction</p></li></ol><p>Let&#8217;s delve into each of these methods.</p><h3><strong>2.1. Schema-based extraction</strong></h3><p>The main idea of this approach is to construct a graph based on a predefined network model. By specifying the desired entity types and their possible relationships, the LLM-based approach generates a network from the text, structured according to the specified model.</p><p><strong>&#128161; Example: </strong>In the Panama Papers scandal, we can establish a predefined structure where entities include companies, banks, or scandals, and relationships are defined as &#8216;involved&#8217; or &#8216;owns.&#8217; The schema-based extracted graph would then be expected to reveal connections such as &#8216;Person A owns Company B&#8217; or &#8216;Bank D is involved in Scandal E.&#8217;</p><p><strong>How to implement schema-based extraction in practice?</strong></p><p>Here&#8217;s a quick skeleton for implementing schema-based extraction in practice:</p><pre><code>from typing import Literal
from llama_index.core.indices.property_graph import SchemaLLMPathExtractor
from llama_index.core import PropertyGraphIndex
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI

# Define the possible entity types for the knowledge graph
entities = Literal["PERSON", "COMPANY", "COUNTRY", "BANK", "SCANDAL"]

# Define the possible relations between the entities in the knowledge graph
relations = Literal["OWNS", "LOCATED_IN", "INVOLVED_IN"]

# Define the schema that outlines which entities can have which relations
schema = {
    "PERSON": ["OWNS", "LOCATED_IN", "INVOLVED_IN"],
    "COMPANY": ["OWNS", "LOCATED_IN", "INVOLVED_IN"],
    "COUNTRY": ["LOCATED_IN"],
    "BANK": ["LOCATED_IN", "INVOLVED_IN"],
    "SCANDAL": ["INVOLVED_IN"],
}

# Create an instance of SchemaLLMPathExtractor to extract paths based on the defined schema
kg_extractor = SchemaLLMPathExtractor(
  llm=OpenAI(model=LLM_MODEL, temperature=TEMPERATURE), # Use OpenAI's language model with the specified parameters
  possible_entities=entities,  # Define the types of entities to extract
  possible_relations=relations,  # Define the types of relations to extract
  kg_validation_schema=schema,  # Use the predefined schema for validation
  strict=True,  # Enforce strict validation; only entities and relations defined in the schema will be allowed
)

# Create a PropertyGraphIndex from the provided documents, using the specified embedding model
index = PropertyGraphIndex.from_documents(
    documents,  # The input documents to be processed and indexed
    embed_model=OpenAIEmbedding(model_name=EMBEDDING_MODEL),  # Use OpenAI's embedding model for document representation
    show_progress=True,  # Display progress during indexing
    kg_extractors=[kg_extractor],  # Use the previously defined SchemaLLMPathExtractor for extracting knowledge graph paths
)

# Define the storage path for the keyword extractor
path_output_storage_kg_extractor = f"{path_output_storage}/{kw_extractor_name}/"

# Create the storage directory if it doesn't already exist
if not os.path.exists(path_output_storage_kg_extractor):
    os.makedirs(path_output_storage_kg_extractor)

# Persist the index's storage context to the specified directory
index.storage_context.persist(persist_dir=path_output_storage_kg_extractor)

# Save the knowledge graph as a NetworkX graph to an HTML file
index.property_graph_store.save_networkx_graph(name=f"{path_output}/kwnoledge_graphs_{kw_extractor_name}.html")</code></pre><blockquote><p><em>&#9888;&#65039; Note: In the </em><code>kg_extractors</code><em> argument of </em><code>PropertyGraphIndex</code><em>, multiple knowledge extractor instances can be added, enabling the combination of various extraction methods within a single network.</em></p></blockquote><p>Figure 2 displays a part of the schema-based extracted graph generated by the code. The nodes represent either a person, company, country, bank, or scandal, while the relationships are limited to ownership and involvement, as predefined in the code.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vh5i!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vh5i!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif 424w, https://substackcdn.com/image/fetch/$s_!vh5i!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif 848w, https://substackcdn.com/image/fetch/$s_!vh5i!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif 1272w, https://substackcdn.com/image/fetch/$s_!vh5i!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vh5i!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vh5i!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif 424w, https://substackcdn.com/image/fetch/$s_!vh5i!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif 848w, https://substackcdn.com/image/fetch/$s_!vh5i!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif 1272w, https://substackcdn.com/image/fetch/$s_!vh5i!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39a79edb-5d5c-4021-b0de-78eb6bf7507d_1614x1068.gif 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Fig 2 &#8212; Part of the schema-based extract graph</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xfG_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xfG_!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif 424w, https://substackcdn.com/image/fetch/$s_!xfG_!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif 848w, https://substackcdn.com/image/fetch/$s_!xfG_!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif 1272w, https://substackcdn.com/image/fetch/$s_!xfG_!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xfG_!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!xfG_!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif 424w, https://substackcdn.com/image/fetch/$s_!xfG_!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif 848w, https://substackcdn.com/image/fetch/$s_!xfG_!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif 1272w, https://substackcdn.com/image/fetch/$s_!xfG_!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bcc57b8-4a29-4ee8-845c-f9a860c08c37_1614x1068.gif 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>What is the method behind schema-based extraction?</strong></p><p><strong>&#10003; Text analysis:</strong> The extractor first analyzes the text content within each chunk using an LLM. This model interprets the text to identify potential entities (such as people, organizations, or locations) and relationships (such as ownership, location, or association) based on the provided schema.</p><p><strong>&#10003; Path extraction:</strong></p><ul><li><p>Using the schema as a guide, the tool extracts specific relationships between identified entities, forming triplets.</p></li><li><p>A triplet is a set of three components: a subject entity, a relationship, and an object entity (e.g., &#8220;Person X owns Company Y&#8221;).</p></li><li><p>The <code>max_triplets_per_chunk</code> parameter limits the number of triplets processed at a time, ensuring efficiency when handling large datasets.</p></li></ul><p><strong>&#10003; Validation:</strong> The extracted triplets are then validated against the schema to ensure they fit the predefined types of entities and relationships. If the schema is set to strict mode, only triplets that fully comply with the schema are retained.</p><p><strong>&#10003; Graph construction:</strong> The validated triplets are then used to construct or expand a knowledge graph. Each triplet adds nodes (entities) and edges (relationships) to the graph, gradually building a network that reflects the information extracted from the text.</p><p><strong>&#10003; Metadata integration:</strong> The tool can also incorporate metadata, which may include additional context or properties associated with entities and relationships (e.g., timestamps, source documents). This helps in enriching the graph with more detailed and relevant information.</p><h3><strong>2.2. Free-form extraction</strong></h3><p>Free-form extraction is a flexible method of extracting relationships, or &#8220;triples,&#8221; from text data. Contrary to the scheme-based extraction methods, it doesn't not rely on a predefined schema or structure but leverages the capabilities of a language model (LLM) to identify meaningful connections between entities on its own.</p><p><strong>&#128161; Example: </strong>In the context of the Panama Papers scandal, free-form extraction can analyze leaked documents to uncover hidden relationships between individuals, companies, and offshore entities. For instance, the model might extract triples such as &#8220;Company B is registered in Offshore Jurisdiction C&#8221;, or &#8220;Law Firm D manages Company B&#8221;. These connections, inferred from the context rather than explicitly stated, help build a knowledge graph that maps the complex network of entities involved in the scandal.</p><p><strong>How to implement free-form extraction in practice?</strong></p><pre><code>from llama_index.core.indices.property_graph import SimpleLLMPathExtractor
# Create an instance of SimpleLLMPathExtractor
kg_extractor = SimpleLLMPathExtractor(
    llm=OpenAI(model=LLM_MODEL, temperature=TEMPERATURE)
)</code></pre><p>Figure 3 presents a portion of the free-form extracted graph. Here, the relationships between nodes are more flexible, allowing for greater exploration. However, this flexibility involves a trade-off between the desire to explore and the need for a concise, essential-focused representation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fSUo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fSUo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png 424w, https://substackcdn.com/image/fetch/$s_!fSUo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png 848w, https://substackcdn.com/image/fetch/$s_!fSUo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png 1272w, https://substackcdn.com/image/fetch/$s_!fSUo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fSUo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png" width="450" height="510" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:510,&quot;width&quot;:450,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!fSUo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png 424w, https://substackcdn.com/image/fetch/$s_!fSUo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png 848w, https://substackcdn.com/image/fetch/$s_!fSUo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png 1272w, https://substackcdn.com/image/fetch/$s_!fSUo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3048baa-3c59-40c2-a2a6-5b46b43fc71b_450x510.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 3 &#8212;Part of the free-from extracted graph</figcaption></figure></div><p>Source: &#8220;Former Emir of Qatar Hamad bin Khalifa Al Thani owned Afrodille S.A., which had a bank account in Luxembourg and shares in two South African companies. Al Thani also held a majority of the shares in Rienne S.A. and Yalis S.A., holding a term deposit with the Bank of China in Luxembourg. &#8221; [<a href="https://en.wikipedia.org/wiki/Panama_Papers">3</a>]</p><p><strong>How does free-form extraction achieve its results?</strong></p><p><strong>&#10003; Input text analysis:</strong> The process begins with analyzing the input text from chunks. The content is passed through the language model, which uses a specific prompt to guide the extraction process. It generates potential triples. The extraction is controlled by the <code>max_paths_per_chunk</code> parameter, which limits the number of triples generated in each chunk. This ensures the process remains efficient and manageable, especially when handling large volumes of text.</p><p><strong>&#10003; Parsing:</strong> The output from the language model is then parsed by a function that extracts these triples from the raw text response.</p><p><strong>&#10003; Building the graph:</strong> The extracted triples are then used to create or update a knowledge graph. These nodes and edges are enriched with metadata, which can include additional information like the source of the data or timestamps.</p><h3><strong>2.3. Dynamic extraction</strong></h3><p>Dynamic extraction is similar to free-form extraction in its flexibility, but it introduces an initial structure that can evolve as the model processes more data.</p><p>While free-form extraction allows the model to interpret and extract relationships without any predefined structure, dynamic extraction starts with a basic ontology (ie. a set of initial entity types and relationships) that guides the extraction process.</p><p>This method not only extracts relationships but also encourages the discovery of new entity types and connections, expanding the ontology as needed.</p><p><strong>&#128161; Example: </strong>In the Panama Papers scandal, dynamic extraction might start with an initial ontology that includes entities like &#8220;Person,&#8221; &#8220;Company,&#8221; and &#8220;Offshore Account,&#8221; and relationships such as &#8220;owns&#8221; or &#8220;controls.&#8221; As the LLM processes leaked documents, it could discover new relationships like &#8220;facilitated by&#8221; (connecting a person to a law firm) or identify new entity types such as &#8220;shell company.&#8221; These discoveries would expand the original ontology, allowing the knowledge graph to capture a broader and more nuanced picture of the entities and their connections in the scandal.</p><p><strong>How to implement dynamic extraction in practice?</strong></p><pre><code>from llama_index.core.indices.property_graph import DynamicLLMPathExtractor
from llama_index.core import PropertyGraphIndex
from llama_index.llms.openai import OpenAI

# Define the possible entity types for the knowledge graph
entities = ["PERSON", "COMPANY", "COUNTRY", "BANK", "SCANDAL"]

# Define the possible relations between the entities in the knowledge graph
relations = ["OWNS", "LOCATED_IN", "INVOLVED_IN"]

# Create an instance of SimpleLLMPathExtractor
kg_extractor = DynamicLLMPathExtractor(
    llm=OpenAI(model=LLM_MODEL, temperature=TEMPERATURE),
    allowed_entity_types=entities,
    allowed_relation_types=relations,
    )# Define the possible entity types for the knowledge graph
entities = ["PERSON", "COMPANY", "COUNTRY", "BANK", "SCANDAL"]</code></pre><p>Figure 4 presents a segment of the resulting dynamic extracted graph. It demonstrates that the approach successfully identified relevant new entities and relationships, building upon the initial ones provided. This technique strikes an ideal balance between exploration and structure.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uONF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uONF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png 424w, https://substackcdn.com/image/fetch/$s_!uONF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png 848w, https://substackcdn.com/image/fetch/$s_!uONF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png 1272w, https://substackcdn.com/image/fetch/$s_!uONF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uONF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png" width="1456" height="703" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:703,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&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="https://substackcdn.com/image/fetch/$s_!uONF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png 424w, https://substackcdn.com/image/fetch/$s_!uONF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png 848w, https://substackcdn.com/image/fetch/$s_!uONF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png 1272w, https://substackcdn.com/image/fetch/$s_!uONF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d48ee1-1d09-452c-81f6-3d0c7495a43a_2000x965.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 4 &#8212; Part of the dynamic extracted graph</figcaption></figure></div><p><strong>How does the dynamic extraction method operate?</strong></p><p><strong>&#10003; Starting with an initial ontology</strong>: Unlike free-form extraction, which operates without a predefined schema, dynamic extraction begins with an initial ontology. This ontology includes basic entity types (e.g., &#8220;Person,&#8221; &#8220;Company&#8221;) and relationships (e.g., &#8220;owns,&#8221; &#8220;located in&#8221;). It serves as a starting point that the method can expand as it processes new data.</p><p><strong>&#10003; Guided LLM prompting</strong>: Similar to free-form extraction, dynamic extraction uses prompts to instruct the language model (LLM) on what to extract. However, the prompts in dynamic extraction not only guide the extraction of known entities and relationships but also encourage the LLM to identify and propose new ones.</p><p><strong>&#10003; Parsing and expanding the graph</strong>: The model&#8217;s output is parsed into triples (subject-relation-object) as in free-form extraction. However, in dynamic extraction, the process includes identifying and integrating new entity types or relationships.</p><p><strong>&#10003; Ontology Evolution</strong>: As the model processes more text, it continuously refines and expands the ontology.</p><h3><strong>2.4. Implicit extraction</strong></h3><p>The key idea of this method is to use inherent connections within the data to identify relationships between entities, even when these relationships are not explicitly mentioned. It infers connections based on the structure or context of the data, making it useful when relationships can be logically deduced rather than directly stated.</p><p><strong>&#128161; Example: </strong>Implicit extraction is most suited when analyzing a structured document with inherent relationships, such as a legal contract or a research paper with a clear hierarchy of sections, subsections, and references. In this case, the relationships between sections (e.g., &#8220;Chapter 1 is followed by Chapter 2&#8221;) or between references (e.g., &#8220;Section A cites Reference B&#8221;) are not explicitly labeled as relationships but can be inferred from the document&#8217;s structure. In that case, implicit extraction would automatically infer relationships like &#8220;Clause 1.1 is a subsection of Section 1&#8221; or &#8220;Clause 1.1 refers to Appendix A&#8221;.</p><p><strong>How to implement implicit extraction in practice?</strong></p><p>Here&#8217;s a quick skeleton for implementing implicit extraction in practice:</p><pre><code>from llama_index.core.indices.property_graph import ImplicitPathExtractor

# Create an instance of SimpleLLMPathExtractor
kg_extractor = ImplicitPathExtractor()</code></pre><p><strong>How is implicit extraction carried out?</strong></p><p><strong>&#10003; Node relationships:</strong> Each node in a graph can have various types of relationships with other nodes, such as being the parent of another node, being sequentially before or after another node, or referencing another node as a source. These relationships are typically stored within the node&#8217;s structure.</p><p><strong>&#10003; Edge extraction:</strong> The extractor scans through the list of nodes and examines these inherent relationships. For each node, it identifies connections to other nodes and creates corresponding edges (relations) between them. These edges are then labeled appropriately (e.g., &#8220;PARENT,&#8221; &#8220;CHILD,&#8221; &#8220;NEXT,&#8221; &#8220;PREVIOUS&#8221;) based on the type of relationship.</p><p><strong>&#10003; Metadata integration:</strong> During this process, the extractor can also integrate any relevant metadata associated with the nodes, such as timestamps or source information, into the relationships it creates. This enriches the graph with additional context, making the implicit connections more informative.</p><h2><strong>3. Empowering LLMs through Knowledge Graph Synergy</strong></h2><p>Once the graph is built, the challenge becomes how to effectively leverage it for LLM queries. The Llama-Index library currently offers four approaches, two of which are cypher-based.</p><ol><li><p>Vector context retriever</p></li><li><p>LLM synonym retriever</p></li><li><p>Text-to-cypher</p></li><li><p>Cypher template retriever</p></li></ol><blockquote><p><em>Cypher is a powerful query language used for interacting with graph databases, enabling precise retrieval and manipulation of graph data through pattern matching and other advanced querying techniques.&#8221;</em></p></blockquote><h3><strong>3.1. Vector context retriever</strong></h3><p>This approach retrieves nodes based on their semantic similarity to a given query, allowing for more precise and contextually appropriate search results.</p><p><strong>&#128161; Example:</strong> Imagine searching for information related to &#8220;offshore accounts&#8221; in a property graph built from the Panama Papers data. The vector context retriever would convert the query into a vector and find nodes in the graph that are semantically similar, such as nodes representing specific companies, individuals, or transactions linked to offshore accounts. It would then retrieve these nodes, along with any directly related entities (e.g., owners or connected banks), and return them sorted by relevance.</p><p><strong>How can the Vector Context Retriever be applied in practice?</strong></p><pre><code># Import necessary modules from the llama_index library
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI

# Import the VectorContextRetriever class from the property_graph module
from llama_index.core.indices.property_graph import VectorContextRetriever
# Create a sub-retriever using VectorContextRetriever
# This will use the property graph store and vector store from the loaded index
# The embed_model parameter specifies the model to be used for embedding queries (e.g., OpenAI's embedding model)
sub_retriever = VectorContextRetriever(
  index.property_graph_store, 
  vector_store=index.vector_store,
  embed_model=OpenAIEmbedding(model_name=EMBEDDING_MODEL),
)
# Create a retriever from the index using the previously defined sub-retriever
retriever = index.as_retriever(sub_retrievers=[sub_retriever])
# Initialize the query engine using the retriever
# The query engine will use the retriever(s) to process and return responses to queries
query_engine = index.as_query_engine(
    sub_retrievers=[retriever]
)
# Perform a query on the query engine to retrieve information about ICIJ's involvement in the Panama Papers scandal
print(
    query_engine.query(
    "How was the International Consortium of Investigative Journalists (ICIJ) involved in the Panama Papers scandal?"
    ).response
)</code></pre><p>Output:<br><em>The International Consortium of Investigative Journalists (ICIJ) helped organize the research and document review once S&#252;ddeutsche Zeitung realized the scale of the work required to validate the authenticity of the leaked data. The ICIJ enlisted reporters and resources from various media outlets to investigate individuals and organizations associated with Mossack Fonseca. Additionally, the ICIJ released the leaked documents from the Panama Papers scandal on its website after verifying the source and content.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pxDR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pxDR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png 424w, https://substackcdn.com/image/fetch/$s_!pxDR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png 848w, https://substackcdn.com/image/fetch/$s_!pxDR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png 1272w, https://substackcdn.com/image/fetch/$s_!pxDR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pxDR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png" width="1400" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!pxDR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png 424w, https://substackcdn.com/image/fetch/$s_!pxDR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png 848w, https://substackcdn.com/image/fetch/$s_!pxDR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png 1272w, https://substackcdn.com/image/fetch/$s_!pxDR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c464158-1e33-4691-a8fa-4d12c7b4a5d7_1400x971.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 4 &#8212; Supporting part of the knowledge graph used to answer the query</figcaption></figure></div><p><strong>How does the Vector Context Retriever retriever work?</strong></p><p><strong>&#10003; Embedding the query</strong>: When a query is submitted, the vector context retriever first converts the query into a vector representation using an embedding model. This vector captures the semantic meaning of the query, enabling the retriever to find similar content within the graph.</p><p><strong>&#10003; Vector store query</strong>: The retriever identifies the nodes whose vectors are most similar to the query vector, using a similarity measure (like cosine similarity). The number of top similar nodes to retrieve is controlled by the <code>similarity_top_k</code> parameter.</p><p><strong>&#10003; Node retrieval and path expansion</strong>: Once the most similar nodes are identified, the retriever can also explore relationships connected to these nodes based on the specified <code>path_depth</code>.</p><p><strong>&#10003; Similarity scoring</strong>: Each retrieved node is assigned a similarity score that reflects how closely it matches the query.</p><p><strong>&#10003; Final output</strong>: The retriever sorts the retrieved nodes by their similarity scores, optionally filters them based on the <code>similarity_score</code> threshold, and then returns the most relevant nodes and their associated relationships.</p><h3><strong>3.2. LLM synonym retriever</strong></h3><p>The LLM synonym retriever enhances the retrieval of information from a knowledge graph by expanding a user&#8217;s query with synonyms generated by an LLM.</p><p>This expansion allows the retriever to capture and return more relevant nodes from the graph, improving the accuracy of the search results.</p><p><strong>&#128161; Example: </strong>An investigator searching the Panama Papers graph for &#8220;offshore company&#8221; could use the LLM synonym retriever to expand the query with terms like &#8220;shell company&#8221; or &#8220;tax haven entity.&#8221; This broader search would uncover additional relevant nodes, such as companies involved in tax evasion, that might be missed with the original query alone, leading to a more thorough investigation.</p><p><strong>How to use the LLM synonym retriever in practice?</strong></p><pre><code># Import necessary modules from the llama_index library
from llama_index.core.indices.property_graph import LLMSynonymRetriever

sub_retriever = LLMSynonymRetriever(
    index.property_graph_store,  # The property graph store from the index is used as the data source
    llm=OpenAI(model=LLM_MODEL, temperature=TEMPERATURE),  # Initialize the LLM with specified model and temperature
    include_text=True,  # Include the source chunk text in the retrieved paths
    max_keywords=100,  # Maximum number of keywords to be considered for retrieval
    path_depth=5,  # Limit the depth of the search paths to 5 levels
)</code></pre><p><strong>What is the process behind the LLM synonym retriever?</strong></p><p><strong>&#10003; Query expansion with synonyms</strong>: When a query is submitted, the LLM synonym retriever first uses a language model to generate synonyms for the keywords in the query. This is done through a predefined prompt, which instructs the LLM to suggest alternative words or phrases similar to the original query terms.</p><p><strong>&#10003; Synonym integration</strong>: The synonyms generated by the LLM are then integrated into the query. This allows the LLM to carry out a broader search within the graph.</p><p><strong>&#10003; Graph retrieval</strong>:</p><ul><li><p>The expanded query is used to retrieve nodes from the graph. The retriever searches for nodes and relationships that match any of the terms in the expanded query.</p></li><li><p>The depth of the retrieval, or how far the search goes in terms of relationships (e.g., direct connections or further down the relationship chain), can be adjusted using the <code>path_depth</code> parameter.</p></li></ul><p><strong>&#10003; Parsing and matching</strong>: The output from the LLM is parsed into a format that can be used to identify relevant nodes in the graph.</p><p><strong>&#10003; Node scoring and retrieval</strong>: The matched nodes are scored based on their relevance to the original query and the relationships they hold within the graph. The retriever then returns a list of nodes with their associated scores, representing the most relevant entities and connections for the query.</p><h3><strong>3.3. Cypher-based retrievers</strong></h3><p>Llama-index offers two Cypher-based retrievers to leverage the capabilities of graph databases.</p><p>Here&#8217;s a brief overview without delving into the details:</p><ul><li><p>The TextToCypherRetriever operates by leveraging a graph store schema, an input query, and a prompt template for text-to-cypher conversion to generate and execute a cypher query.</p></li><li><p>The CypherTemplateRetriever offers a more controlled approach compared to the TextToCypherRetriever. Instead of allowing the LLM to generate any cypher statement freely, it uses a predefined cypher template, where the LLM fills in the specific details.</p></li></ul><div><hr></div><h2><strong>Key Takeaways</strong></h2><p>&#10003; Knowledge graphs not only improve the accuracy and contextual relevance of AI-generated knowledge but also serve as a powerful tool for industries that demand precise and interpretable information, such as healthcare, finance, and legal services.</p><p>&#10003; When selecting a method to build it with LLMs, it&#8217;s essential to consider the trade-off between exploration and structure. Dynamic extraction offers an excellent balance for those who need both flexibility and structure in their knowledge graph.</p><p>&#10003; For leveraging a knowledge graph, various techniques are available, with vector-based methods providing efficient retrieval.</p><p>&#10003; However, it&#8217;s important to acknowledge that the current version of Llama-Index has limitations in network analysis and handling complex graph structures. These capabilities would certainly improve as the synergies between knowledge graphs and LLMs are a hot topic!</p><div><hr></div><h2><strong>References</strong></h2><p><a href="https://docs.llamaindex.ai/en/latest/module_guides/indexing/lpg_index_guide/#default-llmsynonymretriever">[1] Llama index documentation</a></p><p><a href="https://www.llamaindex.ai/blog/introducing-the-property-graph-index-a-powerful-new-way-to-build-knowledge-graphs-with-llms">[2] Introducing the Property Graph Index: A Powerful New Way to Build Knowledge Graphs with LLMs</a></p><p><a href="https://en.wikipedia.org/wiki/Panama_Papers">[3] Panama Papers</a></p>]]></content:encoded></item><item><title><![CDATA[Beyond Predictions: Uplift Modeling & the Science of Influence (Part I)]]></title><description><![CDATA[Hands-On Approach to Uplift with Tree-Based Models]]></description><link>https://aipractitioner.substack.com/p/beyond-predictions-uplift-modeling</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/beyond-predictions-uplift-modeling</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Wed, 03 Jan 2024 18:55:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5Mxk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5Mxk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5Mxk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png 424w, https://substackcdn.com/image/fetch/$s_!5Mxk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png 848w, https://substackcdn.com/image/fetch/$s_!5Mxk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png 1272w, https://substackcdn.com/image/fetch/$s_!5Mxk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5Mxk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png" width="1400" height="578" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:578,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5Mxk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png 424w, https://substackcdn.com/image/fetch/$s_!5Mxk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png 848w, https://substackcdn.com/image/fetch/$s_!5Mxk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png 1272w, https://substackcdn.com/image/fetch/$s_!5Mxk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1dc67f7-90d9-4737-953d-f16f974591ab_1400x578.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Predictive analytics has long been a cornerstone of decision-making, but what if we told you there&#8217;s an alternative beyond forecasting? What if you could strategically influence the outcomes instead?</p><p>Uplift modeling holds this promise. It adds an interesting dynamic layer to traditional predictions by identifying individuals whose behavior can be influenced positively if they receive special treatments.</p><p>The application use cases are endless. In medicine, it would help identify patients for whom a medical treatment could improve their health. In retail, such a model allows for better targeting of customers for whom a promotion or personalized offering would be effective in retention.</p><h3><strong>Objective</strong></h3><p>This article is the first part of a series that explores the transformative potential of uplift modeling, shedding light on how it can reshape strategies in marketing, healthcare, and beyond. It focuses on uplift models based on decision trees and uses, as a case study, the prediction of customer conversion with the application of promotional offers</p><p>After reading this article, you will understand:</p><ol><li><p>What exactly is uplift modeling?</p></li><li><p>In what ways can decision trees be tailored for uplift modeling?</p></li><li><p>How to assess the performance of uplift models?</p></li></ol><blockquote><p><em>No prior knowledge is required to understand the article.<br>The experimentations described in the article were carried out using the libraries <a href="https://causalml.readthedocs.io/en/latest/causalml.html">scikit-uplift</a>, <a href="https://causalml.readthedocs.io/en/latest/causalml.html">causalml</a> and <a href="https://plotly.com/">plotly</a>. You can find the code <a href="https://medium.com/d3556fccc61f4ff995fbdef8f44b1d81?pvs=25">here</a> on GitHub.</em></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>1. Demystifying Uplift Modelling</strong></h2><h3><strong>1.1. Why uplift models?</strong></h3><p>The best way to understand the benefit of using uplift models is through an example. Imagine a scenario where a telecommunications company aims to reduce customer churn.</p><p>A &#8220;traditional&#8221; ML-based approach would consist of using a model trained on historical data to predict the likelihood of current customers to churn. This would help identify customers at risk and take proactive measures, such as offering tailored incentives or exclusive promotions.</p><ul><li><p>What if the customer is leaving regardless (for example, relocating to another country)?</p></li><li><p>And what if the promotional offer sent by mail or over the phone reinforces the customer&#8217;s urge to change operator?</p></li></ul><p>In such instances, even if the model accurately predicts their departure, the resulting actions may lead to wasted resources and expenses in communication. In the latter case, it could even contribute to an actual churn of customers who would have remained without action from the company.</p><p>This is where uplift modeling steps in, offering a more nuanced understanding of customer behavior. Its goal is not just to detect customers at risk but customers that will respond positively to a special treatment such as a promotion. Thus, businesses can accurately target the appropriate customers, streamlining resource allocation for optimal efficiency.</p><blockquote><p><em>Uplift modeling refers to the set of techniques used to model the incremental impact of an action or treatment on a customer outcome. Source [<a href="https://proceedings.mlr.press/v67/gutierrez17a/gutierrez17a.pdf">1</a>]</em></p></blockquote><h3><strong>1.2. What to expect from uplift models?</strong></h3><p>Uplift models categorize individuals into different classes based on their responses to treatment. The main classes typically include:</p><ol><li><p><strong>Persuadables:</strong> Individuals who are positively influenced by the treatment. Without the intervention, they are less likely to respond as desired. Persuadables represent the group that benefits most from targeted interventions.</p></li><li><p><strong>Sure Things:</strong> Individuals who respond positively to the treatment regardless of whether they receive it or not.</p></li><li><p><strong>Lost Causes:</strong> Individuals who are unlikely to respond positively to the treatment, even if they receive it. Identifying this group helps avoid unnecessary resource allocation, as interventions are unlikely to yield the desired outcome.</p></li><li><p><strong>Sleeping Dogs / Do-Not-Disturb:</strong> Individuals who respond negatively to the treatment, meaning the intervention might have a detrimental effect on their behavior. Recognizing this group is crucial to prevent inadvertently causing negative outcomes.</p></li></ol><p>This classification is summarized in Figure 1. It plays an essential role in uplift modeling.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Shzq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Shzq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png 424w, https://substackcdn.com/image/fetch/$s_!Shzq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png 848w, https://substackcdn.com/image/fetch/$s_!Shzq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png 1272w, https://substackcdn.com/image/fetch/$s_!Shzq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Shzq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png" width="752" height="457" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:457,&quot;width&quot;:752,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Shzq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png 424w, https://substackcdn.com/image/fetch/$s_!Shzq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png 848w, https://substackcdn.com/image/fetch/$s_!Shzq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png 1272w, https://substackcdn.com/image/fetch/$s_!Shzq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88d581a-03f3-45ff-8e12-e719ad9d47fd_752x457.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 1 &#8212; Classification related to uplift modeling, illustration by the author</figcaption></figure></div><h3><strong>1.3. What data do uplift models need for training?</strong></h3><p><strong>Data schema</strong></p><p>Before diving into the theory, let&#8217;s look at the data needed to train uplift models:</p><ul><li><p><strong>Feature columns</strong>: attributes or characteristics of the individuals or observations in the dataset that are used as input for the model.</p></li><li><p><strong>Treatment indicator</strong>: binary column that indicates whether a particular individual or observation has received a treatment or intervention.</p></li><li><p><strong>Target column</strong>: outcome variable that the model is designed to predict.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nb3a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nb3a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png 424w, https://substackcdn.com/image/fetch/$s_!nb3a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png 848w, https://substackcdn.com/image/fetch/$s_!nb3a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png 1272w, https://substackcdn.com/image/fetch/$s_!nb3a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nb3a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png" width="1322" height="397" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:397,&quot;width&quot;:1322,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!nb3a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png 424w, https://substackcdn.com/image/fetch/$s_!nb3a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png 848w, https://substackcdn.com/image/fetch/$s_!nb3a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png 1272w, https://substackcdn.com/image/fetch/$s_!nb3a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccb13888-3887-44dc-92d7-e5c4befab38f_1322x397.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 2 &#8212; Input data for uplift training, illustration by the author</figcaption></figure></div><p>The experimentations carried out for the purpose of this article are based on Criteo dataset [8]. It was built by gathering the results of several incrementality tests. These tests follow a specific randomized trial approach in which a randomly selected portion of the population is deliberately excluded from receiving targeted advertising. The target variable is <code>visit</code>.</p><p>A rough approach to get an idea of the impact of treatment is to calculate the average treatment effect (ATE), i.e. the difference in the occurrence of visits between instances with and without treatment. In the Criteo dataset, the ATE is equal to 1.034%.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pQCi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pQCi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png 424w, https://substackcdn.com/image/fetch/$s_!pQCi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png 848w, https://substackcdn.com/image/fetch/$s_!pQCi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png 1272w, https://substackcdn.com/image/fetch/$s_!pQCi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pQCi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png" width="1400" height="287" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:287,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!pQCi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png 424w, https://substackcdn.com/image/fetch/$s_!pQCi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png 848w, https://substackcdn.com/image/fetch/$s_!pQCi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png 1272w, https://substackcdn.com/image/fetch/$s_!pQCi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73c2914-88a0-4e7d-8fe0-380b832c43f6_1400x287.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Fig 3 &#8212; ATE on the Criteo dataset</figcaption></figure></div><p><strong>Hypothesis</strong></p><p>Behind these data lie several assumptions that must hold for the model to be trained properly. The main ones include:</p><ol><li><p><strong>Random Assignment Hypothesis:</strong> The treatment assignment is random or quasi-random, ensuring that any differences in outcomes are attributable to the treatment and not pre-existing biases.</p></li><li><p><strong>Unconfoundedness</strong>: The treatment assignment is not influenced by any other factors that may affect the potential outcome.</p></li><li><p><strong>Stable Unit Treatment Value Assumption (SUTVA):</strong> The treatment assignment of one individual does not affect the outcome of another individual.</p></li><li><p><strong>Positivity assumption:</strong> All individuals have a non-zero probability of receiving both the treatment and control conditions. Thus, there are no &#8220;unreachable&#8221; groups in the population.</p></li><li><p><strong>No Hidden Confounding Variables Hypothesis:</strong> All relevant variables influencing the outcome are measured and included in the model. There are no hidden confounding variables that are unaccounted for.</p></li><li><p><strong>Consistency</strong>: The treatment assignment is consistent across different populations and time periods. This means that the effect of the treatment on an individual unit is the same across different populations and periods.</p></li></ol><h2><strong>2. Tailoring Tree-Based Models for Uplift Modelling</strong></h2><h3><strong>2.1. How is uplift defined?</strong></h3><p>To assess the incremental benefits of applying a treatment (such as offering exclusive promotions in our previous example), we need to compute the difference in outcomes between receiving the treatment and not receiving it.</p><p>This difference is called the causal effect <a href="https://proceedings.mlr.press/v67/gutierrez17a/gutierrez17a.pdf">[1]</a> and can formulated as:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6xX8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6xX8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png 424w, https://substackcdn.com/image/fetch/$s_!6xX8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png 848w, https://substackcdn.com/image/fetch/$s_!6xX8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png 1272w, https://substackcdn.com/image/fetch/$s_!6xX8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6xX8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png" width="1150" height="120" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:120,&quot;width&quot;:1150,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!6xX8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png 424w, https://substackcdn.com/image/fetch/$s_!6xX8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png 848w, https://substackcdn.com/image/fetch/$s_!6xX8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png 1272w, https://substackcdn.com/image/fetch/$s_!6xX8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b69958-6155-4adf-a862-e83f7885eaa5_1150x120.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Where:</p><ul><li><p>W is equal to 1 if a person receives the treatment (treatment group), and 0 if he or she does not (control group)</p></li><li><p>Y is the outcome</p></li></ul><p>This definition raises a fundamental challenge: it is impossible to observe the outcomes of both scenarios simultaneously for the same individual.</p><p>Nevertheless, it is still possible to estimate the expected causal effect of the treatment for a subset of the population, called the Conditional Average Treatment Effect (CATE). It is expressed as:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gbOS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gbOS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png 424w, https://substackcdn.com/image/fetch/$s_!gbOS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png 848w, https://substackcdn.com/image/fetch/$s_!gbOS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png 1272w, https://substackcdn.com/image/fetch/$s_!gbOS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gbOS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png" width="1456" height="109" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:109,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!gbOS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png 424w, https://substackcdn.com/image/fetch/$s_!gbOS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png 848w, https://substackcdn.com/image/fetch/$s_!gbOS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png 1272w, https://substackcdn.com/image/fetch/$s_!gbOS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2534d1-a21c-4fe9-9cfa-d79a3a036645_1606x120.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Where X is the feature vector representing individual characteristics.</p><p>This estimation relies on the unconfoundedness assumption mentioned earlier, which translated to the assumption that the treatment assignment W is independent of the outcome Y given X. This condition holds when the treatment assignment is random conditional on X.</p><h3><strong>2.2. How are tree-based models adapted to uplift modeling?</strong></h3><p><strong>Concepts related to uplift trees</strong></p><p>Let&#8217;s start by uplift decision trees. They are very similar to conventional decision trees but with an important adjustment.</p><ul><li><p>Traditional decision trees are designed to maximize the accuracy of the predicted class probabilities. Their splitting criteria and pruning methods (Gini impurity or information gain, etc.) are adapted toward this objective.</p></li><li><p>On the other hand, uplift decision trees are intended to model the change in class probabilities caused by treatment, such as mailing an offer or treating a patient. Thus, the splitting criteria and pruning methods are designed to maximize the differences between treatment and control probabilities in the left and right subtrees.</p></li></ul><p>A perfect uplift decision tree would take the following form:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BxMR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BxMR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png 424w, https://substackcdn.com/image/fetch/$s_!BxMR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png 848w, https://substackcdn.com/image/fetch/$s_!BxMR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png 1272w, https://substackcdn.com/image/fetch/$s_!BxMR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BxMR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png" width="1456" height="855" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:855,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!BxMR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png 424w, https://substackcdn.com/image/fetch/$s_!BxMR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png 848w, https://substackcdn.com/image/fetch/$s_!BxMR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png 1272w, https://substackcdn.com/image/fetch/$s_!BxMR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89ceb226-6931-4f9b-a150-96fb741e8d34_1464x860.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 4&#8212; Uplift decision tree (perfect tree), illustration by the author</figcaption></figure></div><p>In that case, what splitting criteria should be used to maximize the differences between the treatment and control probabilities in the left and right subtrees?</p><p>P. Rzepakowski and S. Jaroszewicz introduced in <a href="https://www.researchgate.net/publication/241055513_Decision_trees_for_uplift_modeling_with_single_and_multiple_treatments">[2]</a> the following gain formulation for a given splitting choice (called test) A:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Kt4h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Kt4h!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png 424w, https://substackcdn.com/image/fetch/$s_!Kt4h!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png 848w, https://substackcdn.com/image/fetch/$s_!Kt4h!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png 1272w, https://substackcdn.com/image/fetch/$s_!Kt4h!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Kt4h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png" width="1280" height="100" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:100,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Kt4h!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png 424w, https://substackcdn.com/image/fetch/$s_!Kt4h!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png 848w, https://substackcdn.com/image/fetch/$s_!Kt4h!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png 1272w, https://substackcdn.com/image/fetch/$s_!Kt4h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2947c2d8-50a4-4efa-821e-c5e7e9ad2b24_1280x100.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Where:</p><ul><li><p><em>D(.)</em> is divergence measure</p></li><li><p><em>PT(Y) </em>and <em>PC(Y) </em>are the probability distribution of the outcome in respectively the treated group and control group</p></li></ul><p>For the divergence metrics, they mentioned Kullback, Euclidean, and Chi-Squared, defined as:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ShWD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ShWD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png 424w, https://substackcdn.com/image/fetch/$s_!ShWD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png 848w, https://substackcdn.com/image/fetch/$s_!ShWD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png 1272w, https://substackcdn.com/image/fetch/$s_!ShWD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ShWD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png" width="1106" height="238" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:238,&quot;width&quot;:1106,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ShWD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png 424w, https://substackcdn.com/image/fetch/$s_!ShWD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png 848w, https://substackcdn.com/image/fetch/$s_!ShWD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png 1272w, https://substackcdn.com/image/fetch/$s_!ShWD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b88e04e-c9e1-48fc-8774-1e5a59bcf260_1106x238.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>To illustrate the computation of divergence gain, let&#8217;s consider an example:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FVa_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FVa_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png 424w, https://substackcdn.com/image/fetch/$s_!FVa_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png 848w, https://substackcdn.com/image/fetch/$s_!FVa_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png 1272w, https://substackcdn.com/image/fetch/$s_!FVa_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FVa_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png" width="1456" height="836" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/abc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:836,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!FVa_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png 424w, https://substackcdn.com/image/fetch/$s_!FVa_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png 848w, https://substackcdn.com/image/fetch/$s_!FVa_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png 1272w, https://substackcdn.com/image/fetch/$s_!FVa_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabc40387-b3e8-4484-a321-b37f997e9cc8_1854x1064.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 5&#8212; Computation of probability divergence in uplift trees, illustration by the author</figcaption></figure></div><blockquote><p><em>Note that this model can model the causal effect of not just one but multiple treatments.</em></p></blockquote><p><strong>Training and inference process for tree-based uplift models</strong></p><p>Let&#8217;s summarize the steps to train an uplift decision tree to identify the stages at which the introduced concepts come into play.</p><p><strong>1. Building the uplift tree:</strong></p><ul><li><p><strong>Node splitting criteria:</strong> At each node, the algorithm calculates a measure of distribution divergence between the treatment and control groups. The algorithm chooses the feature and split point that maximize the distribution divergence, aiming to separate the treatment and control distributions.</p></li><li><p><strong>Recursive splitting:</strong> The tree-building process is recursive. At each node, the algorithm selects the best feature and split point based on the divergence gain and continues splitting until a stopping condition is met.</p></li></ul><p><strong>2. Stopping conditions:</strong> The algorithm typically stops when any of the specified conditions are satisfied:</p><ul><li><p><strong>Maximum depth:</strong> Limit the depth of the tree to prevent overfitting.</p></li><li><p><strong>Minimum samples per leaf:</strong> Set a threshold for the minimum number of samples required to create a leaf node.</p></li><li><p><strong>Minimum improvement in divergence:</strong> Stop splitting a node if the gain in class distribution divergence uplift improvement is below a certain threshold.</p></li></ul><p><strong>3. Pruning:</strong> After building the tree, prune branches that do not contribute significantly to the model performance. This helps prevent overfitting and improves generalization to new data.</p><p><strong>4. Uplift prediction:</strong></p><ul><li><p><strong>Leaf node assignment:</strong> For each observation, traverse the tree to determine the leaf node it falls into.</p></li><li><p><strong>Uplift score assignment:</strong> Calculate the predicted outcomes for the treatment and control groups separately at the leaf node. Assign the uplift score as the difference between the predicted outcomes for the treatment and control groups to capture the impact of the treatment on individual instances.</p></li></ul><p>Similar to traditional random forests, uplift random forests leverage ensemble learning to improve performance. The approach involves training multiple decision trees and aggregating their predictions.</p><h3><strong>2.3. Application</strong></h3><p>To whet your appetite, here is an example of code that trains an uplift model and makes predictions. It relies on the library developed by Uber, CausalML [<a href="https://causalml.readthedocs.io/en/latest/causalml.html">11</a>]. The evaluation of uplift models is discussed in the rest of the article.</p><p>The complete code is available <a href="https://github.com/linafaik08/uplift">here</a> on GitHub.</p><pre><code>from causalml.inference.tree import UpliftRandomForestClassifier
# model initialization
# more information about the parameters in the library doc
# https://causalml.readthedocs.io/en/latest/causalml.html#causalml.inference.tree.UpliftRandomForestClassifier

uplift_model = UpliftRandomForestClassifier(
    n_estimators = 10,
    max_depth = 5,
    min_samples_leaf = 10,
    min_samples_treatment = 3,
    n_reg = 10,
    normalization = True,
    evaluationFunction = "ED",
    control_name='control',
    honesty = False
)

# model training
uplift_model.fit(
    train_df[cols].values,
    treatment=train_df['treatment_group'].values,
    y=train_df[col_target].values
)

# model inference
uplift_model.predict(
  test_df[cols].values, 
  full_output=True)[uplift_model.classes_]

# finding the best treatment
pred_df["best_treatment_index"] = np.argmax(pred_df.values, axis=1)
pred_df["best_treatment"] = pred_df["best_treatment_index"].map(
    {i:c for i, c in enumerate(uplift_model.classes_)}
)</code></pre><p><strong>Potential issues</strong></p><p>One should be cautious about potential problems that can lead to an ill-trained model:</p><ul><li><p><strong>Treatment imbalance issue:</strong> This happens when the algorithm concentrates most if not all, treatment instances in one subtree. It violates the unconfoundedness assumption which is crucial to uplift modeling. This situation makes further splits challenging and may lead to an ill-trained model.</p></li><li><p><strong>Predisposition for selecting splits with numerous child nodes:</strong> Such splits may yield higher gains in training data but tend to overfit when extrapolated to the test data.</p></li></ul><p>To address these issues, normalization and regularization factors have been introduced in <a href="https://www.researchgate.net/publication/241055513_Decision_trees_for_uplift_modeling_with_single_and_multiple_treatments">[2]</a>.</p><h2><strong>3. Quantifying Uplift Models Performance</strong></h2><h3><strong>3.1. What are the common evaluation metrics?</strong></h3><p>Evaluating uplift models is significantly different from traditional machine learning. Why? Since it&#8217;s impossible to observe the effects of being treated and untreated on an individual simultaneously, there is no ground truth.</p><p><strong>Uplift by percentile</strong></p><p>A common alternative is to calculate the uplift by decile. This involves the following steps:</p><ol><li><p>Sort the individuals based on their predicted uplift scores in descending order</p></li><li><p>Divide the sorted dataset into percentiles containing a specific percentage of the population</p></li><li><p>Compute the uplift or response rate for each percentile by comparing the average in the treatment group with that in the control group within the percentile.</p></li></ol><pre><code>from sklift.metrics import uplift_by_percentile

uplift_by_perc_df =  uplift_by_percentile(
    test_df[col_target], 
    pred_df["uplift"],
    test_df["treatment_group"],
    strategy="overall", 
    total=False, 
    std=True, 
    bins=10
)

uplift_by_perc_df.head()</code></pre><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uyXu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uyXu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png 424w, https://substackcdn.com/image/fetch/$s_!uyXu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png 848w, https://substackcdn.com/image/fetch/$s_!uyXu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png 1272w, https://substackcdn.com/image/fetch/$s_!uyXu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uyXu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png" width="1400" height="252" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:252,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!uyXu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png 424w, https://substackcdn.com/image/fetch/$s_!uyXu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png 848w, https://substackcdn.com/image/fetch/$s_!uyXu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png 1272w, https://substackcdn.com/image/fetch/$s_!uyXu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e38de40-03f0-44fb-a19c-3f399e0c9e17_1400x252.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Fig 6&#8212; Table of uplift by percentile, illustration by the author</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UoT5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UoT5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png 424w, https://substackcdn.com/image/fetch/$s_!UoT5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png 848w, https://substackcdn.com/image/fetch/$s_!UoT5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png 1272w, https://substackcdn.com/image/fetch/$s_!UoT5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UoT5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png" width="1400" height="434" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:434,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!UoT5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png 424w, https://substackcdn.com/image/fetch/$s_!UoT5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png 848w, https://substackcdn.com/image/fetch/$s_!UoT5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png 1272w, https://substackcdn.com/image/fetch/$s_!UoT5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F782e93bd-46c2-44fd-b3a1-226c82e8f72a_1400x434.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 7&#8212; Response rates per percentile, illustration by the author</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nASB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nASB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png 424w, https://substackcdn.com/image/fetch/$s_!nASB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png 848w, https://substackcdn.com/image/fetch/$s_!nASB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png 1272w, https://substackcdn.com/image/fetch/$s_!nASB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nASB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png" width="1400" height="449" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:449,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!nASB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png 424w, https://substackcdn.com/image/fetch/$s_!nASB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png 848w, https://substackcdn.com/image/fetch/$s_!nASB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png 1272w, https://substackcdn.com/image/fetch/$s_!nASB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dff56c7-15e2-4ea9-98f5-cc7ac731dae6_1400x449.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 8&#8212; Uplift per percentile, illustration by the author</figcaption></figure></div><p>While this metric is straightforward, it does not allow comparison between models. What if one model performs better on the first decile but worse on the second decile compared to another model? Determining the best model is difficult in such cases. A simple idea is to calculate the cumulative uplift, but the approach still depends on the choice of decile size.</p><p><strong>Uplift curve &amp; AUUC</strong></p><p>Uplift curve is a widespread approach to evaluating uplift models. It does not rely on predefined percentiles leaving threshold setting up to the evaluator.</p><p>It consists of the following steps:</p><ol><li><p>Sort the individuals based on their predicted uplift scores in descending order</p></li><li><p>Compute the cumulative response rates for both the treatment group and the control group as we move down the sorted list. Thus, the cumulative response rate at each point is the fraction of responders in the group up to that point.</p></li></ol><p>Here&#8217;s the typical shape of an uplift curve: the x-axis denotes the percentage of individuals targeted (e.g., top 1%, top 5%), while the y-axis illustrates the disparity in cumulative response rates between the treatment and control groups.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OvpD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OvpD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png 424w, https://substackcdn.com/image/fetch/$s_!OvpD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png 848w, https://substackcdn.com/image/fetch/$s_!OvpD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png 1272w, https://substackcdn.com/image/fetch/$s_!OvpD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OvpD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png" width="1362" height="726" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:726,&quot;width&quot;:1362,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!OvpD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png 424w, https://substackcdn.com/image/fetch/$s_!OvpD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png 848w, https://substackcdn.com/image/fetch/$s_!OvpD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png 1272w, https://substackcdn.com/image/fetch/$s_!OvpD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2464aea1-c377-4cfb-9d90-f080e698fe14_1362x726.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 9 &#8212; Typical shape of uplift curves, illustration by the author</figcaption></figure></div><ul><li><p><strong>Increasing uplift curve:</strong> A steeper incline suggests that the model is effectively identifying individuals who respond positively to the treatment. This often occurs in the early stages of the curve (left side). The greater the uplift at the beginning, the more impactful the model is for a smaller percentage of the population.</p></li><li><p><strong>Sustained growth:</strong> If the uplift curve continues to rise on the right side, it indicates that is it still effective to target individuals even if the percentage of this population is large.</p></li><li><p><strong>Flattening uplift curve:</strong> As the curve progresses, it may reach a point where the uplift plateaus or starts to flatten. This suggests that the model&#8217;s effectiveness in identifying responders diminishes as a larger portion of the population is considered. The uplift becomes less pronounced.</p></li><li><p><strong>Decreasing uplift curve:</strong> Conversely, if the uplift curve is decreasing, it signals diminishing returns. This happens as the model targets more individuals.</p></li><li><p><strong>Baseline</strong>: It is obtained using uniform random assignment. It is increasing when the average treatment effect is positive which is often the case.</p></li></ul><p>The overall performance of the model can be assessed by calculating the Area Under the Uplift Curve (AUUC). A larger AUUC indicates a better-performing model across various percentages of the population.</p><pre><code>from sklift.metrics import uplift_auc_score

# Area Under Uplift Curve
# link to the library doc:
# https://www.uplift-modeling.com/en/latest/api/metrics/uplift_auc_score.html

uplift_auc = uplift_auc_score(
    y_true=test_df[col_target], 
    uplift=pred_df["uplift"],
    treatment=test_df["treatment_group"],
)</code></pre><p>Another option is to calculate the uplift at the top K or a specific percentage. This enables the selection of the best model, considering a constrained budget or resource allocation.</p><pre><code>from sklift.metrics import uplift_at_k

# Uplift@30%
# link to the library doc:
# https://www.uplift-modeling.com/en/latest/api/metrics/uplift_at_k.html

uplift_at_k_score = uplift_at_k(
    y_true=test_df[col_target], 
    uplift=pred_df["uplift"],
    treatment=test_df["treatment_group"],
    strategy='overall', k=0.3
)</code></pre><h3><strong>3.2. Application</strong></h3><p>The following section describes the experimentation carried out on Criteo dataset.</p><p><strong>Methodology</strong></p><ul><li><p>The dataset was divided into three subsets, maintaining an equal proportion of positive outcomes across each: one designated for training the model (constituting 70% of the total), another for testing (15%) to fine-tune hyperparameters, and a third for validation (15%) to facilitate model comparison.</p></li><li><p>Model hyper-parameters were finetuing using first the AUUC as the metrics then upflit &#224; 30%</p></li></ul><p>The performance of the model was compared to:</p><ul><li><p>A baseline involving random assignment.</p></li><li><p>A solo model [<a href="https://www.uplift-modeling.com/en/latest/user_guide/models/solo_model.html">10</a>] using a random forest as the estimator. This involves fitting a regular RF model with &#8216;treatment&#8217; as an additional feature. To estimate uplift for an observation, the model is used twice: once with the treatment flag set to 1 and the other with 0. Uplift is then obtained by subtracting the results.</p></li></ul><h3><strong>3.3. Results</strong></h3><p>This small experiment shows that the uplift model performs better than a solo model on the validation set: the AUUC is greater for the uplift model whose parameters have been fine-tuned to maximize upflit (in general rather than at 30%) on the test set.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v_DI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v_DI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png 424w, https://substackcdn.com/image/fetch/$s_!v_DI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png 848w, https://substackcdn.com/image/fetch/$s_!v_DI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png 1272w, https://substackcdn.com/image/fetch/$s_!v_DI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v_DI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png" width="1400" height="918" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:918,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!v_DI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png 424w, https://substackcdn.com/image/fetch/$s_!v_DI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png 848w, https://substackcdn.com/image/fetch/$s_!v_DI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png 1272w, https://substackcdn.com/image/fetch/$s_!v_DI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2be194a-0f8a-4ffb-9ff9-8b560e80b15b_1400x918.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 10 &#8212;Uplift curve from experimentations (note: legend refers to the metric for which the uplift models have been optimized), illustration by the author</figcaption></figure></div><p>Just as with the classic random forest, it is possible to visualize the most important variables for the uplift model.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LJFk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LJFk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png 424w, https://substackcdn.com/image/fetch/$s_!LJFk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png 848w, https://substackcdn.com/image/fetch/$s_!LJFk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png 1272w, https://substackcdn.com/image/fetch/$s_!LJFk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LJFk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png" width="1260" height="792" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:792,&quot;width&quot;:1260,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!LJFk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png 424w, https://substackcdn.com/image/fetch/$s_!LJFk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png 848w, https://substackcdn.com/image/fetch/$s_!LJFk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png 1272w, https://substackcdn.com/image/fetch/$s_!LJFk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa928f86-a35a-45d3-9a19-ea3841866498_1260x792.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fig 11 &#8212; Feature importance of the uplift random forest curve, illustration by the author</figcaption></figure></div><div><hr></div><h2><strong>Key Takeaways</strong></h2><p>&#10004;&#65039; Uplift modeling is a powerful analytical approach that aims to predict the incremental impact of a treatment or intervention on an individual&#8217;s behavior.</p><p>&#10004;&#65039; It is possible to adapt various machine learning techniques to uplift modeling, with random forests being a prime example. By adjusting the algorithm&#8217;s objective, one can capitalize on the inherent benefits of random forests, including good performance, robustness, interpretability, and easy implementation.</p><p>&#10004;&#65039; However, it is crucial to pay close attention to uplift modeling-specific assumptions. Rigorous checks are needed to ensure the model is well-trained.</p><p>&#10004;&#65039; Moreover, uplift modeling requires the interpretation of distinctive metrics, such as the uplift curve, which differ from traditional machine learning metrics. This is because there is no inherent ground truth for uplift by design.</p><p>&#10004;&#65039; Overall, uplift modeling goes beyond standard predictions. It provides insights into individuals who are likely to change their behavior if they receive a specific treatment, making it a powerful tool in reshaping strategies in marketing, healthcare, and beyond.&#8221;</p><div><hr></div><h2><strong>References</strong></h2><p>[1] P. Gutierrez, J.Y. G&#233;rardy, <em><a href="https://proceedings.mlr.press/v67/gutierrez17a/gutierrez17a.pdf">Causal Inference and Uplift Modeling, A review of the literature</a>,</em> 2016</p><p>[2] P. Rzepakowski, S. Jaroszewicz, <em><a href="https://www.researchgate.net/publication/241055513_Decision_trees_for_uplift_modeling_with_single_and_multiple_treatments">Decision trees for uplift modeling with single and multiple treatments</a></em>, 2011</p><p>[3] George Fei, <em><a href="https://www.aboutwayfair.com/tech-innovation/modeling-uplift-directly-uplift-decision-tree-with-kl-divergence-and-euclidean-distance-as-splitting-criteria">Modeling Uplift Directly: Uplift Decision Tree with KL Divergence and Euclidean Distance as Splitting Criteria,</a></em> 2019</p><p>[4] S. Athey, G.W. Imbens, <em><a href="https://arxiv.org/pdf/1504.01132.pdf">Recursive Partitioning for Heterogeneous Causal Effect</a>s</em>, 2015</p><p>[5] S. Athey and G.W. Imbens, <em><a href="https://gsb-faculty.stanford.edu/guido-w-imbens/files/2022/04/3350.pdf">Machine learning methods for estimating heterogeneous causal effects</a></em>, 2015</p><p>[6] Ivan Klimuk, <em><a href="https://www.youtube.com/watch?v=A6a1MbH4fFk&amp;ab_channel=DanskeBankLithuania">Uplift Modelling: Throw away your churn mode</a></em>, Danske Technight</p><p>[7] F. Moraes, H.M. Proen&#231;a, A. Kornilova, J. Albert, and D. Goldenberg, <em><a href="https://www.youtube.com/watch?v=OkWTEF3icFA&amp;ab_channel=FelipeMoraes">Uplift Modeling: From Causal Inference to Personalization</a></em>, 32nd ACM International Conference on Information and Knowledge Management (CIKM &#8216;23), 2023</p><p>[8] Jing Pan, <em><a href="https://www.youtube.com/watch?v=2J9j7peWQgI&amp;t=1154s&amp;ab_channel=DataConLA">Why start using uplift models for more efficient marketing campaigns</a></em>, Uber, 2020</p><p>[9] Kaggle, <em><a href="https://www.kaggle.com/datasets/arashnic/uplift-modeling">Uplift Modeling , Marketing Campaign Data</a></em>, Criteo Dataset</p><p>[10] <a href="https://www.uplift-modeling.com/en/latest/">scikit-uplift</a> documentation</p><p>[11] <a href="https://causalml.readthedocs.io/en/latest/about.html">CausalML</a> documentation</p>]]></content:encoded></item><item><title><![CDATA[Building Powerful Recommender Systems with Deep Learning]]></title><description><![CDATA[A Step-by-Step Implementation Using the PyTorch Library TorchRec]]></description><link>https://aipractitioner.substack.com/p/building-powerful-recommender-systems</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/building-powerful-recommender-systems</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Mon, 03 Jul 2023 18:06:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!oz9V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oz9V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oz9V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png 424w, https://substackcdn.com/image/fetch/$s_!oz9V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png 848w, https://substackcdn.com/image/fetch/$s_!oz9V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png 1272w, https://substackcdn.com/image/fetch/$s_!oz9V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oz9V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png" width="1200" height="499" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:499,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oz9V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png 424w, https://substackcdn.com/image/fetch/$s_!oz9V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png 848w, https://substackcdn.com/image/fetch/$s_!oz9V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png 1272w, https://substackcdn.com/image/fetch/$s_!oz9V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3417579-8b3d-49bd-839b-8fa7ef84c7ad_1200x499.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Recommending the right product to customers at the right time is a prevalent challenge across industries. For instance, bankers are constantly looking to suggest highly relevant services to their existing or potential customers. Retailers strive to recommend appealing products that meet customer tastes. Similarly, social networks aim to build captivating feeds to foster user adoption.</p><p>Despite being a widely explored use case, achieving satisfactory performance results remains arduous due to the unique nature of the problem. The main reasons include the presence of abundant categorical data, which often leads to scarcity issues, and the computational aspect of the use case, which poses scalability problems. It&#8217;s only recently that recommendation models have harnessed neural networks.</p><p>In this context, Meta has developed and made openly available a deep learning recommendation model (DRLM). The model is particularly remarkable for combining the principles of collaborative filtering and predictive analysis and being suitable for large-scale production.</p><h3><strong>Objective</strong></h3><p>The objective of this article is to guide you through a step-by-step implementation using the PyTorch library TorchRec, enabling you to effectively address your own recommendation use case.</p><p>After reading this article, you will understand:</p><ol><li><p>How does the DLRM model work?</p></li><li><p>What sets DLRM models apart and makes them powerful and scalable?</p></li><li><p>How can you implement your own recommendation system from end to end?</p></li></ol><blockquote><p><em>The article requires general knowledge of the recommender system problem and familiarity with the pytorch library. The experimentations described in the article were carried out using the libraries <a href="https://pytorch.org/torchrec/">TorchRec</a> and PyTorch. You can find the code <a href="https://github.com/linafaik08/recommender_systems_dlrm">here</a> on GitHub.</em></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>1. Decoding the DLRM Model</strong></h2><p>Let&#8217;s first dive into the complexities of the DLRM model and explore its underlying principles and mechanisms.</p><h3><strong>1.1. An Overview of the Model Design</strong></h3><p>To provide a more tangible illustration, let&#8217;s consider the scenario of an online retailer looking to create a personalized feed for every customer visiting their website.</p><p>In order to achieve this, the retailer can train a model that predicts the probability of a customer purchasing a particular product. This model assigns a score to each product for each individual customer, based on various factors. The feed is built by ranking the scores.</p><p>In this case, the model can learn from historical data that encompasses a range of information for each customer and product. This includes numerical variables like customer age and product price, as well as categorical characteristics such as product type, color, and more.</p><p>Here&#8217;s where the DLRM model excels: it possesses the remarkable ability to leverage both numerical and categorical variables, even when dealing with a large number of unique categories. This enables the model to comprehensively analyze and understand complex relationships between the features. To understand why, let&#8217;s take a look at the architecture model in Figure 1.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i74u!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i74u!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png 424w, https://substackcdn.com/image/fetch/$s_!i74u!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png 848w, https://substackcdn.com/image/fetch/$s_!i74u!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png 1272w, https://substackcdn.com/image/fetch/$s_!i74u!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i74u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png" width="1400" height="1338" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1338,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!i74u!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png 424w, https://substackcdn.com/image/fetch/$s_!i74u!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png 848w, https://substackcdn.com/image/fetch/$s_!i74u!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png 1272w, https://substackcdn.com/image/fetch/$s_!i74u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663084ce-7fc6-4970-a202-000b0567f32d_1400x1338.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; DLRM model architecture, illustration by the author, inspired from [5]</figcaption></figure></div><p><strong>Categorical features</strong></p><p>DLRM learns an embedding table for each categorial feature and uses them to map these variables to dense representations. Hence, each categorical feature is represented as a vector of the same length.</p><p><strong>Numerical features</strong></p><p>DLRM processes numerical features through an MLP, called bottom MLP. The output of this MLP has the same dimension as the previous embedding vectors.</p><p><strong>Pairwise interaction</strong></p><p>DLRM calculates the dot product between all pairs of embedding vectors and the processed numerical features This allows the model to include second-order feature interaction.</p><p><strong>Concatenation and final output</strong></p><p>DLRM concatenates these dot products with the processed numerical features and uses the results to feed another MLP, called the top MLP. The final probability is obtained by passing the output of this MLP to a sigmoid function.</p><h3><strong>1.2. The Model Implementation</strong></h3><p>While the potential of the model appears promising in theory, its practical implementation presents a computational hurdle.</p><p>Usually, recommendation use cases involve handling vast volumes of data. Using DLRM models, in particular, introduces an very large number of parameters, higher than common deep learning models. Consequently, this amplifies the computational demands associated with their implementation.</p><ol><li><p>The majority of parameters in DLRMs can be attributed to embeddings as they consist of multiple tables, each demanding a large memory. This makes DLRMs computationally demanding, both in terms of memory capacity and bandwidth.</p></li><li><p>Although the memory footprint of MLP parameters is smaller, they still require substantial computational resources.</p></li></ol><p>To mitigate the memory bottleneck, DLRM relies a unique combination of model parallelism for the embeddings and data parallelism for the MLPs.</p><h2><strong>2. From Concept to Implementation: A Step-by-Step Guide to Building Your Custom Recommendation System</strong></h2><p>This section provides a detailed step-by-step guide on how to implement your own recommendation system from start to finish.</p><h3><strong>2.1. Data Transformation and Batch Construction</strong></h3><p>The first step involves converting the data into tensors and organizing them into batches for input into the model.</p><p>To illustrate this process, let&#8217;s consider this dataframe as an example.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dr-R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dr-R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png 424w, https://substackcdn.com/image/fetch/$s_!dr-R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png 848w, https://substackcdn.com/image/fetch/$s_!dr-R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png 1272w, https://substackcdn.com/image/fetch/$s_!dr-R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dr-R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png" width="1400" height="392" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:392,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!dr-R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png 424w, https://substackcdn.com/image/fetch/$s_!dr-R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png 848w, https://substackcdn.com/image/fetch/$s_!dr-R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png 1272w, https://substackcdn.com/image/fetch/$s_!dr-R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0888e8b5-377c-4407-baec-b203e25bcb4a_1400x392.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>For sparse features, we need to concatenate the values into a single vector and compute the lengths. This can be accomplished using the <em>KeyedJaggedTensor.from_lengths_sync</em> function, which takes both elements as input. Here&#8217;s an example of the Python script:</p><pre><code>values = sample[cols_sparse].sum(axis=0).sum(axis=0)
values = torch.tensor(values).to(device)
# values = tensor([1, 0, 2, 0, 2, 2, 0, 2, 0, 1, 0, 1, 2, 0], device='cuda:0')

lengths = torch.tensor(
    pd.concat([sample[feat].apply(lambda x: len(x)) for feat in cols_sparse],
              axis=0).values,
    dtype=torch.int32
).to(self.device)
# lengths = tensor([1, 1, 1, 1, 1, 2, 3, 2, 2, 0], device='cuda:0', dtype=torch.int32)

sparse_features = KeyedJaggedTensor.from_lengths_sync(
  keys=cols_sparse,
  values=values,
  lengths=lengths
)</code></pre><p>For dense features and labels, the process is more straightforward. Here&#8217;s an example of the Python script:</p><pre><code>dense_features = torch.tensor(sample[cols_dense].values, dtype=torch.float32).to(device)
labels = torch.tensor(sample[col_label].values, dtype=torch.int32).to(device)</code></pre><p>By using the outputs from the previous steps, it becomes possible to construct a batch. Here&#8217;s an example of the Python script:</p><pre><code>batch = Batch(
  dense_features=dense_features,
  sparse_features=sparse_features,
  labels=labels,
).to(device)</code></pre><p>For a more comprehensive implementation, you can refer to the <a href="https://github.com/linafaik08/recommender_systems_dlrm/blob/main/src/batch.py">batch.py</a> file in the corresponding GitHub <a href="https://github.com/linafaik08/recommender_systems_dlrm/">repository</a>.</p><h3><strong>2.2. Model Initialization and Optimization Setup</strong></h3><p>The next step involves initializing the model, as demonstrated in the following Python code:</p><pre><code># Initialize the model and set up optimization

# Define the dimensionality of the embeddings used in the model
embedding_dim = 10

# Calculate the number of embeddings per feature
num_embeddings_per_feature = {c: len(v) for c, v in map_sparse.items()}

# Define the layer sizes for the dense architecture
dense_arch_layer_sizes = [512, 256, embedding_dim]

# Define the layer sizes for the overall architecture
over_arch_layer_sizes = [512, 512, 256, 1]

# Specify whether to use Adagrad optimizer or SGD optimizer
adagrad = False

# Set the epsilon value for Adagrad optimizer
eps = 1e-8

# Set the learning rate for optimization
learning_rate = 0.01

# Create a list of EmbeddingBagConfig objects for each sparse feature
eb_configs = [
    EmbeddingBagConfig(
        name=f"t_{feature_name}",
        embedding_dim=embedding_dim,
        num_embeddings=num_embeddings_per_feature[feature_name + '_enc'],
        feature_names=[feature_name + '_enc'],
    )
    for feature_idx, feature_name in enumerate(cols_sparse)
]

# Initialize the DLRM model with the embedding bag collection and architecture specifications
dlrm_model = DLRM(
    embedding_bag_collection=EmbeddingBagCollection(
        tables=eb_configs, device=device
    ),
    dense_in_features=len(cols_dense),
    dense_arch_layer_sizes=dense_arch_layer_sizes,
    over_arch_layer_sizes=over_arch_layer_sizes,
    dense_device=device,
)

# Create a DLRMTrain instance for handling training operations
train_model = DLRMTrain(dlrm_model).to(device)

# Choose the appropriate optimizer class for the embedding parameters
embedding_optimizer = torch.optim.Adagrad if adagrad else torch.optim.SGD

# Set the optimizer keyword arguments
optimizer_kwargs = {"lr": learning_rate}
if adagrad:
    optimizer_kwargs["eps"] = eps

# Apply the optimizer to the sparse architecture parameters
apply_optimizer_in_backward(
    optimizer_class=embedding_optimizer,
    params=train_model.model.sparse_arch.parameters(),
    optimizer_kwargs=optimizer_kwargs,
)

# Initialize the dense optimizer with the appropriate parameters
dense_optimizer = KeyedOptimizerWrapper(
    dict(in_backward_optimizer_filter(train_model.named_parameters())),
    optimizer_with_params(adagrad, learning_rate, eps),
)

# Create a CombinedOptimizer instance to handle optimization
optimizer = CombinedOptimizer([dense_optimizer])</code></pre><p>The model can then be trained and evaluated using the following code:</p><pre><code>loss, (loss2, logits, labels) = train_model(batch)</code></pre><p>For a more comprehensive implementation, you can refer to the <a href="https://github.com/linafaik08/recommender_systems_dlrm/blob/main/src/model.py">model.py</a> file in the corresponding GitHub <a href="https://github.com/linafaik08/recommender_systems_dlrm/">repository</a>.</p><div><hr></div><h2><strong>Key Takeaways</strong></h2><p>&#10004; The DLRM model presents a compelling approach to effectively combine numerical and categorical features using embeddings, enabling the model to capture intricate patterns and relationships.</p><p>&#10004; Although its architecture requires considerable computational resources, its implementation incorporates a unique combination of model parallelism and data parallelism, making the model scalable to production.</p><p>&#10004; However, due to limited data availability, the model&#8217;s performance has not been extensively tested across diverse real-world datasets. This raises uncertainty about its effectiveness in practical scenarios.</p><p>&#10004; Additionally, the model necessitates tuning a considerable number of parameters, further complicating the process.</p><p>&#10004; Considering this, simpler models like LGBM may offer comparable performance with easier implementation, tuning, and long-term maintenance, without the same computational overhead.</p><div><hr></div><h2><strong>References</strong></h2><p>[1] M Naumov &amp; al, <a href="https://arxiv.org/abs/1906.00091?fbclid=IwAR1yd08rme7ON-rIRO0IiooMJEtv0JBYyWPpLuAlli3zmPy2XmJP92UtM7k">Deep Learning Recommendation Model for Personalization and Recommendation Systems</a>, May 2019</p><p>[2] <a href="https://github.com/facebookresearch/dlrm?fbclid=IwAR1YrymUGB7IG8k2x7h4cw7JXRkdS8NcrITUUQ71K2GrbVE5CNxMFf2esFQ">Github repository</a> of the Facebook team&#8217;s initial implementation of the DLRM model available as open source</p><p>[3] DLRM: An advanced, open source deep learning recommendation model, Meta AI Blog, July 2019</p><p>[4] Pytorch library for modern production recommendation systems, <a href="https://pytorch.org/blog/introducing-torchrec/">torchec</a></p><p>[5] Vinh Nguyen, Tomasz Grel and Mengdi Huang, <a href="https://developer.nvidia.com/blog/optimizing-dlrm-on-nvidia-gpus/">Optimizing the Deep Learning Recommendation Model on NVIDIA GPUs</a>, June 2020</p>]]></content:encoded></item><item><title><![CDATA[Survival Analysis: Leveraging Deep Learning for Time-to-Event Forecasting (Part II)]]></title><description><![CDATA[Practical Application to Rehospitalization]]></description><link>https://aipractitioner.substack.com/p/survival-analysis-leveraging-deep</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/survival-analysis-leveraging-deep</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Fri, 21 Apr 2023 18:28:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!AhJo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.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="https://substackcdn.com/image/fetch/$s_!AhJo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AhJo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg 424w, https://substackcdn.com/image/fetch/$s_!AhJo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg 848w, https://substackcdn.com/image/fetch/$s_!AhJo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!AhJo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AhJo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg" width="1200" height="499" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:499,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AhJo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg 424w, https://substackcdn.com/image/fetch/$s_!AhJo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg 848w, https://substackcdn.com/image/fetch/$s_!AhJo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!AhJo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bfb4ae5-c5df-4c80-badd-78e0ead8228f_1200x499.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Survival models are great for predicting the time for an event to occur. These models can be used in a wide variety of use cases including predictive maintenance (forecasting when a machine is likely to break down), marketing analytics (anticipating customer churn), patient monitoring (predicting a patient is likely to be re-hospitalized), and much more.</p><p>By combining machine learning with survival models, the resulting models can benefit from the high predictive power of the former while retaining the framework and typical outputs of the latter (such as the survival probability or hazard curve over time). For more information, check out the first article of this series <a href="https://towardsdatascience.com/survival-analysis-predict-time-to-event-with-machine-learning-part-i-ba52f9ab9a46">here</a>.</p><p>However, in practice, ML-based survival models still require extensive feature engineering and thus prior business knowledge and intuition to lead to satisfying results. So, why not use deep learning models instead to bridge the gap?</p><h3><strong>Objective</strong></h3><p>This article focuses on how deep learning can be combined with the survival analysis framework to solve use cases such as predicting the likelihood of a patient being (re)hospitalized.</p><p>After reading this article, you will understand:</p><ol><li><p>How can deep learning be leveraged for survival analysis?</p></li><li><p>What are the common deep learning models in survival analysis and how do they work?</p></li><li><p>How can these models be applied concretely to hospitalization forecasting?</p></li></ol><blockquote><p><em>This article is the second part of the series around survival analysis. If you are not familiar with survival analysis, it is best to start by reading the first one <a href="https://towardsdatascience.com/survival-analysis-predict-time-to-event-with-machine-learning-part-i-ba52f9ab9a46">here</a>. The experimentations described in the article were carried out using the libraries <a href="https://scikit-survival.readthedocs.io/en/stable/">scikit-surviva</a>l, <a href="https://github.com/havakv/pycox">pycox</a>, and <a href="https://plotly.com/">plotly</a>. You can find the code here on <a href="https://github.com/linafaik08/survival_analysis">GitHub</a>.</em></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>1. Survival Analysis &amp; Deep Learning: How Can They Be Combined?</strong></h2><h3><strong>1.1. Problem statement</strong></h3><p>Let&#8217;s start by describing the problem at hand.</p><p>We are interested in predicting the likelihood that a given patient will be rehospitalized given the available information about his health status. More specifically, we would like to estimate this probability at different time points after the last visit. Such an estimate is essential to monitor patient health and mitigate their risk of relapse.</p><p>This is a typical survival analysis problem. The data consists of 3 elements:</p><p>Patient&#8217;s baseline data including:</p><ul><li><p>Demographics: age, gender, locality (rural or urban)</p></li><li><p>Patient history: smoking, alcohol, diabetes mellitus, hypertension, etc.</p></li><li><p>Laboratory results: hemoglobin, total lymphocyte count, platelets, glucose, urea, creatinine, etc.</p></li><li><p>More information about the source dataset <a href="https://www.kaggle.com/datasets/ashishsahani/hospital-admissions-data">here</a>.</p></li></ul><p>A time t and an event indicator &#948;&#8712;{0;1}:</p><ul><li><p>If the event occurs during the observation duration, t is equal to the time between the moment the data were collected and the moment the event (i.e., rehospitalization) is observed, In that case, &#948; = 1.</p></li><li><p>If not, t is equal to the time between the moment the data were collected and the last contact with the patient (e.g. end of study). In that case, &#948; = 0.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i7X-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i7X-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png 424w, https://substackcdn.com/image/fetch/$s_!i7X-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png 848w, https://substackcdn.com/image/fetch/$s_!i7X-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png 1272w, https://substackcdn.com/image/fetch/$s_!i7X-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i7X-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png" width="1356" height="702" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:702,&quot;width&quot;:1356,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!i7X-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png 424w, https://substackcdn.com/image/fetch/$s_!i7X-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png 848w, https://substackcdn.com/image/fetch/$s_!i7X-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png 1272w, https://substackcdn.com/image/fetch/$s_!i7X-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd2692cb-5c28-4412-959d-410a188bdf76_1356x702.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Survival analysis data, illustration by the author. Note: patients A, and C are censored.</figcaption></figure></div><p>&#9888;&#65039; With this description, why use survival analysis methods when the problem is so similar to a regression task? The initial paper gives a pretty good explanation of the main reason:</p><blockquote><p><em>&#8220;If one chooses to use standard regression methods, the right-censored data becomes a type of missing data. It is usually removed or imputed, which may introduce bias into the model. Therefore, modeling right-censored data requires special attention, hence the use of a survival model.&#8221; Source [<a href="https://bmcmedresmethodol.biomedcentral.com/articles/10.1186/s12874-018-0482-1">2</a>]</em></p></blockquote><h3><strong>1.2. DeepSurv</strong></h3><p><strong>Approach</strong></p><p>Let&#8217;s move on to the theoretical part with a little refresher on the hazard function.</p><blockquote><p><em>&#8220;The hazard function is the probability an individual will not survive an extra infinitesimal amount of time &#948;, given they have already survived up to time t. Thus, a greater hazard signifies a greater risk of death.&#8221;</em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XVXc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XVXc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png 424w, https://substackcdn.com/image/fetch/$s_!XVXc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png 848w, https://substackcdn.com/image/fetch/$s_!XVXc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png 1272w, https://substackcdn.com/image/fetch/$s_!XVXc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XVXc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png" width="1340" height="170" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:170,&quot;width&quot;:1340,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XVXc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png 424w, https://substackcdn.com/image/fetch/$s_!XVXc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png 848w, https://substackcdn.com/image/fetch/$s_!XVXc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png 1272w, https://substackcdn.com/image/fetch/$s_!XVXc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49af77f-fe20-447d-83b9-35a00c7ff848_1340x170.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><blockquote><p><em>Source [<a href="https://bmcmedresmethodol.biomedcentral.com/articles/10.1186/s12874-018-0482-1">2</a>]</em></p></blockquote><p>Similar to the Cox proportional hazards (CPH) model, DeepSurv is based on the assumption that the hazard function is the product of the 2 functions:</p><ul><li><p><strong>the baseline hazard function:</strong> &#955;_0(t)</p></li><li><p><strong>the risk score</strong>, r(x)=exp(h(x)). It models how the hazard function varies from the baseline for a given individual given the observed covariates.</p></li></ul><p>More on CPH models in the <a href="https://towardsdatascience.com/survival-analysis-predict-time-to-event-with-machine-learning-part-i-ba52f9ab9a46">first article</a> of this series.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D9FX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D9FX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png 424w, https://substackcdn.com/image/fetch/$s_!D9FX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png 848w, https://substackcdn.com/image/fetch/$s_!D9FX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png 1272w, https://substackcdn.com/image/fetch/$s_!D9FX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D9FX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png" width="1400" height="359" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:359,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!D9FX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png 424w, https://substackcdn.com/image/fetch/$s_!D9FX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png 848w, https://substackcdn.com/image/fetch/$s_!D9FX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png 1272w, https://substackcdn.com/image/fetch/$s_!D9FX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ca7965f-e76e-4d35-a2d8-8e30ab688df2_1400x359.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The function h(x) is commonly referred to as the <strong>log-risk function</strong>. And this is precisely the function that the Deep Surv model aims at modeling.</p><p>In fact, CPH models assume that <em>h(x)</em> is a linear function: h(x) = &#946; . x. Fitting the model consists thus in computing the weights <em>&#946;</em> to optimize the objective function. However, the linear proportional hazards assumption does not hold in many applications. This justifies the need for a more complex non-linear model that is ideally capable of handling large volumes of data.</p><p><strong>Architecture</strong></p><p>In this context, how can the DeepSurv model provide a better alternative? Let&#8217;s start by describing it. According to the original paper, it&#8217;s a &#8220;deep feed-forward neural network which predicts the effects of a patient&#8217;s covariates on their hazard rate parameterized by the weights of the network &#952;.&#8221; [<a href="https://bmcmedresmethodol.biomedcentral.com/articles/10.1186/s12874-018-0482-1">2</a>]</p><p>How does it work?</p><blockquote><p><em>&#8227; The input to the network is the baseline data x.</em></p><p><em>&#8227; The network propagates the inputs through a number of hidden layers with weights &#952;. The hidden layers consist of fully-connected nonlinear activation functions followed by dropout.</em></p><p><em>&#8227; The final layer is a single node that performs a linear combination of the hidden features. The output of the network is taken as the predicted log-risk function.</em></p><p><em>Source [<a href="https://bmcmedresmethodol.biomedcentral.com/articles/10.1186/s12874-018-0482-1">2</a>]</em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mI2t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mI2t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png 424w, https://substackcdn.com/image/fetch/$s_!mI2t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png 848w, https://substackcdn.com/image/fetch/$s_!mI2t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png 1272w, https://substackcdn.com/image/fetch/$s_!mI2t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mI2t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png" width="1400" height="948" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:948,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mI2t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png 424w, https://substackcdn.com/image/fetch/$s_!mI2t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png 848w, https://substackcdn.com/image/fetch/$s_!mI2t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png 1272w, https://substackcdn.com/image/fetch/$s_!mI2t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffff7c664-225a-470b-93e0-9ace2bf47c10_1400x948.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2 &#8212; DeepSurv architecture, illustration by the author, inspired by source [<a href="https://www.researchgate.net/publication/323409041_DeepSurv_Personalized_treatment_recommender_system_using_a_Cox_proportional_hazards_deep_neural_network">2</a>]</figcaption></figure></div><p>As a result of this architecture, the model is very flexible. Hyperparametric search techniques are typically used to determine the number of hidden layers, the number of nodes in each layer, the dropout probability and other settings.</p><p>What about the objective function to optimize?</p><ul><li><p>CPH models are trained to optimize the Cox partial likelihood. It consists of calculating for each patient <em>i</em> at time <em>Ti</em> the probability that the event has happened, considering all the individuals still at risk at time <em>Ti</em>, and then multiplying all these probabilities together. You can find the exact mathematical formula here [<a href="https://bmcmedresmethodol.biomedcentral.com/articles/10.1186/s12874-018-0482-1">2</a>].</p></li><li><p>Similarly, the objective function of DeepSurv is the log-negative mean of the same partial likelihood with an additional part that serves to regularize the network weights. [<a href="https://bmcmedresmethodol.biomedcentral.com/articles/10.1186/s12874-018-0482-1">2</a>]</p></li></ul><p><strong>Code sample</strong></p><p>Here is a small code snippet to get an idea of how this type of model is implemented using the <a href="https://github.com/havakv/pycox">pycox</a> library. The complete code can be found in the notebook examples of the library <a href="https://nbviewer.org/github/havakv/pycox/blob/master/examples/cox-ph.ipynb">here</a> [6].</p><pre><code># Step 1: Neural net
# simple MLP with two hidden layers, ReLU activations, batch norm and dropout

in_features = x_train.shape[1]
num_nodes = [32, 32]
out_features = 1
batch_norm = True
dropout = 0.1
output_bias = False

net = tt.practical.MLPVanilla(in_features, num_nodes, out_features, batch_norm,
                              dropout, output_bias=output_bias)

model = CoxPH(net, tt.optim.Adam)


# Step 2: Model training

batch_size = 256
epochs = 512
callbacks = [tt.callbacks.EarlyStopping()]
verbose = True

model.optimizer.set_lr(0.01)

log = model.fit(x_train, y_train, batch_size, epochs, callbacks, verbose,
                val_data=val, val_batch_size=batch_size)


# Step 3: Prediction

_ = model.compute_baseline_hazards()
surv = model.predict_surv_df(x_test)


# Step 4: Evaluation

ev = EvalSurv(surv, durations_test, events_test, censor_surv='km')
ev.concordance_td()</code></pre><h3><strong>1.3. DeepHit</strong></h3><p><strong>Approach</strong></p><p>Instead of making strong assumptions about the distribution of survival times, what if we could train a deep neural network that would learn them directly?</p><p>This is the case with the DeepHit model. In particular, it brings two significant improvements over previous approaches:</p><ul><li><p>It does not rely on any assumptions about the underlying stochastic process. Thus, the network learns to model the evolution over time of the relationship between the covariates and the risk.</p></li><li><p>It can handle competing risks (e.g., simultaneously modeling the risks of being rehospitalized and dying) through a multi-task learning architecture.</p></li></ul><p><strong>Architecture</strong></p><p>As described here [<a href="https://humboldt-wi.github.io/blog/research/information_systems_1920/group2_survivalanalysis/">3</a>], DeepHits follows the common architecture of multi-task learning models. It consists of two main parts:</p><ol><li><p>A shared subnetwork, where the model learns from the data a general representation useful for all the tasks.</p></li><li><p>Task-specific subnetworks, where the model learns more task-specific representations.</p></li></ol><p>However, the architecture of the DeepHit model differs from typical multi-task learning models in two aspects:</p><ul><li><p>It includes a residual connection between the inital covariates and the input of the task-specific sub-networks.</p></li><li><p>It uses only one softmax output layer. Thanks to this, the model does not learn the marginal distribution of competing events but the joint distribution.</p></li></ul><p>The figures below show the case where the model is trained simultaneously on two tasks.</p><p>The output of the DeepHit model is a vector <em>y</em> for every subject. It gives the probability that the subject will experience the event k &#8712; [1, 2] for every timestamp <em>t</em> within the observation time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QzCu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QzCu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png 424w, https://substackcdn.com/image/fetch/$s_!QzCu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png 848w, https://substackcdn.com/image/fetch/$s_!QzCu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png 1272w, https://substackcdn.com/image/fetch/$s_!QzCu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QzCu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png" width="1400" height="753" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:753,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!QzCu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png 424w, https://substackcdn.com/image/fetch/$s_!QzCu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png 848w, https://substackcdn.com/image/fetch/$s_!QzCu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png 1272w, https://substackcdn.com/image/fetch/$s_!QzCu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f6faf4c-494d-4f21-8730-53bd31bd696e_1400x753.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3 &#8212; DeepHit architecture, illustration by the author, inspired by source [<a href="https://www.semanticscholar.org/paper/DeepHit%3A-A-Deep-Learning-Approach-to-Survival-With-Lee-Zame/803a7b26bdc0feafbf45bc5d57c2bc3f55b6f8fc#references">4</a>]</figcaption></figure></div><p></p><h2><strong>2. Use Case Application: How Do These Models Perform in Practice?</strong></h2><h3><strong>2.1. Methodology</strong></h3><p><strong>Data</strong></p><p>The data set was divided into three parts: a training set (60% of the data), a validation set (20%), and a test set (20%). The training and validation sets were used to optimize the neural networks during training and the test set for final evaluation.</p><p><strong>Benchmark</strong></p><p>The performance of the deep learning models was compared to a benchmark of models including CoxPH and ML-based survival models (Gradient Boosting and SVM). More information on these models is available in the first <a href="https://towardsdatascience.com/survival-analysis-predict-time-to-event-with-machine-learning-part-i-ba52f9ab9a46">article</a> of the series.</p><p><strong>Metrics</strong></p><p>Two metrics were used to evaluate the models:</p><ul><li><p>Concordance index (C-index): it measures the capability of the model to provide a reliable ranking of survival times based on individual risk scores. It is computed as the proportion of concordant pairs in a dataset.</p></li><li><p>Brier score: It&#8217;s a time-dependent extension of the mean squared error to right censored data. In other words, it represents the average squared distance between the observed survival status and the predicted survival probability.</p></li></ul><h3><strong>2.2. Results</strong></h3><p>In terms of C-index, the performance of the deep learning models is considerably better than that of the ML-based survival analysis models. Moreover, there is almost no difference between the performance of Deep Surval and Deep Hit models.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ke2C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ke2C!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png 424w, https://substackcdn.com/image/fetch/$s_!ke2C!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png 848w, https://substackcdn.com/image/fetch/$s_!ke2C!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png 1272w, https://substackcdn.com/image/fetch/$s_!ke2C!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ke2C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png" width="1400" height="524" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:524,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ke2C!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png 424w, https://substackcdn.com/image/fetch/$s_!ke2C!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png 848w, https://substackcdn.com/image/fetch/$s_!ke2C!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png 1272w, https://substackcdn.com/image/fetch/$s_!ke2C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22e65b6d-17f0-4828-ba0d-b3bbd7e3222c_1400x524.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4 &#8212; C-Index of models on the train and test sets</figcaption></figure></div><p>In terms of Brier score, the Deep Surv model stands out from the others.</p><ul><li><p>When examining the curve of the Brier score as a function of time, the curve of the Deep Surv model is lower than the others, which reflects a better accuracy.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Fk-2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Fk-2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png 424w, https://substackcdn.com/image/fetch/$s_!Fk-2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png 848w, https://substackcdn.com/image/fetch/$s_!Fk-2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png 1272w, https://substackcdn.com/image/fetch/$s_!Fk-2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Fk-2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png" width="1400" height="515" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:515,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Fk-2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png 424w, https://substackcdn.com/image/fetch/$s_!Fk-2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png 848w, https://substackcdn.com/image/fetch/$s_!Fk-2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png 1272w, https://substackcdn.com/image/fetch/$s_!Fk-2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb469ed47-8b48-4e31-a025-8d362c4a1843_1400x515.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 5&#8212; Brier score on the test set</figcaption></figure></div><ul><li><p>This observation is confirmed when considering the integration of the score over the same time interval.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WMeq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WMeq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png 424w, https://substackcdn.com/image/fetch/$s_!WMeq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png 848w, https://substackcdn.com/image/fetch/$s_!WMeq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png 1272w, https://substackcdn.com/image/fetch/$s_!WMeq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WMeq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png" width="1400" height="654" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:654,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!WMeq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png 424w, https://substackcdn.com/image/fetch/$s_!WMeq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png 848w, https://substackcdn.com/image/fetch/$s_!WMeq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png 1272w, https://substackcdn.com/image/fetch/$s_!WMeq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1535601-5d56-4f0a-90e3-679aef8ac288_1400x654.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 6 &#8212; Integrated Brier score on the test set</figcaption></figure></div><blockquote><p><em>Note that the Brier wasn&#8217;t computed for the SVM as this score is only applicable for models that are able to estimate a survival function.</em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!C-37!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!C-37!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png 424w, https://substackcdn.com/image/fetch/$s_!C-37!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png 848w, https://substackcdn.com/image/fetch/$s_!C-37!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png 1272w, https://substackcdn.com/image/fetch/$s_!C-37!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!C-37!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png" width="1400" height="522" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:522,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!C-37!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png 424w, https://substackcdn.com/image/fetch/$s_!C-37!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png 848w, https://substackcdn.com/image/fetch/$s_!C-37!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png 1272w, https://substackcdn.com/image/fetch/$s_!C-37!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7c790f-01c4-44b4-8156-e60097c8e5aa_1400x522.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 7&#8212; Survival curves of randomly selected patients using DeepSurv Model</figcaption></figure></div><p>Finally, deep learning models can be used for survival analysis as well as statistical models. Here, for instance, we can see the survival curve of randomly selected patients. Such outputs can bring many benefits, in particular allowing a more effective follow-up of the patients that are the most at risk.</p><div><hr></div><h2><strong>Key Takeaways</strong></h2><p>&#10004;&#65039; Survival models are very useful for predicting the time it takes for an event to occur.</p><p>&#10004;&#65039; They can help address many use cases by providing a learning framework and techniques as well as useful outputs such as the probability of survival or the hazard curve over time.</p><p>&#10004;&#65039; They are even indispensable in this type of uses cases to exploit all the data including the censored observations (when the event does not occur during the observation period for example).</p><p>&#10004;&#65039; ML-based survival models tend to perform better than statistical models (more information <a href="https://towardsdatascience.com/survival-analysis-predict-time-to-event-with-machine-learning-part-i-ba52f9ab9a46">here</a>). However, they require high-quality feature engineering based on solid business intuition to achieve satisfactory results.</p><p>&#10004;&#65039; This is where Deep Learning can bridge the gap. Deep learning-based survival models like DeepSurv or DeepHit have the potential to perform better with less effort!</p><p>&#10004;&#65039; Nevertheless, these models are not without drawbacks. They require a large database for training and require fine-tuning multiple hyperparameters.</p><div><hr></div><h2><strong>References</strong></h2><p>[1] Bollepalli, S.C.; Sahani, A.K.; Aslam, N.; Mohan, B.; Kulkarni, K.; Goyal, A.; Singh, B.; Singh, G.; Mittal, A.; Tandon, R.; Chhabra, S.T.; Wander, G.S.; Armoundas, A.A. <a href="https://doi.org/10.3390/diagnostics12020241">An Optimized Machine Learning Model Accurately Predicts In-Hospital Outcomes at Admission to a Cardiac Unit</a>. Diagnostics 2022, 12, 241.</p><p>[2] Katzman, J., Shaham, U., Bates, J., Cloninger, A., Jiang, T., &amp; Kluger, Y. (2016). <a href="https://doi.org/10.1186/s12874-018-0482-1">DeepSurv: Personalized Treatment Recommender System Using A Cox Proportional Hazards Deep Neural Network</a>, ArXiv</p><p>[3] Laura L&#246;schmann, Daria Smorodina, <a href="https://humboldt-wi.github.io/blog/research/information_systems_1920/group2_survivalanalysis/">Deep Learning for Survival Analysis</a>, Seminar information systems (WS19/20), February 6, 2020</p><p>[4] Lee, Changhee et al. <a href="https://www.semanticscholar.org/paper/DeepHit%3A-A-Deep-Learning-Approach-to-Survival-With-Lee-Zame/803a7b26bdc0feafbf45bc5d57c2bc3f55b6f8fc#references">DeepHit: A Deep Learning Approach to Survival Analysis With Competing Risks.</a> AAAI Conference on Artificial Intelligence (2018).</p><p>[5] Wikipedia, <em><a href="https://en.wikipedia.org/wiki/Proportional_hazards_model">Proportional hazards model</a></em></p><p>[6] <a href="https://github.com/havakv/pycox">Pycox library</a></p>]]></content:encoded></item><item><title><![CDATA[Survival Analysis: Predict Time-To-Event With Machine Learning (Part I)]]></title><description><![CDATA[Practical Application to Customer Churn Prediction]]></description><link>https://aipractitioner.substack.com/p/survival-analysis-predict-time-to</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/survival-analysis-predict-time-to</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 09 Feb 2023 19:24:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!BJ3i!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.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="https://substackcdn.com/image/fetch/$s_!BJ3i!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BJ3i!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg 424w, https://substackcdn.com/image/fetch/$s_!BJ3i!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg 848w, https://substackcdn.com/image/fetch/$s_!BJ3i!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!BJ3i!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BJ3i!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg" width="1200" height="499" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:499,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BJ3i!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg 424w, https://substackcdn.com/image/fetch/$s_!BJ3i!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg 848w, https://substackcdn.com/image/fetch/$s_!BJ3i!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!BJ3i!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94b97307-551a-4acf-81d7-53c5802b731b_1200x499.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Predicting the probability of an event occurring is good, predicting the time remaining before an event occurs is even better!</p><p>Take the example of customer churn. What if, instead of predicting the probability of a customer leaving the company in the next months, you could predict this probability at several time points over the next months? The benefits of such an approach are immediate. It would allow you to anticipate and prioritize your marketing actions more effectively in time and, ultimately, reduce the churn rate.</p><p>This falls exactly in the field of <strong>survival analysis</strong>, also called time-to-event analysis. It refers to a learning framework and a set of techniques that can be used to estimate the time it takes for an event of interest to occur based on observations.</p><p>The name of survival analysis comes from the typical use case where it was first applied: predicting time to death for clinical research. However, one should not be misled by its name: it is not limited to the medical field, but can be applied to use cases in multiple industries. And with the recent advances in data science, survival analysis has reemerged leaving the world of classical statistics to include more advanced methods in machine learning.</p><h3><strong>Objective</strong></h3><p>This article focuses on how machine learning can be combined with survival analysis framework to solve use cases such as predicting churn.</p><p>After reading this article, you will understand:</p><ol><li><p>What is survival analysis all about?</p></li><li><p>What are the main survival models and how do they work?</p></li><li><p>How can these models be applied concretely to churn prediction?</p></li></ol><blockquote><p><em>This article is the first part of the series around survival analysis. No prior knowledge is required to understand the article. The experimentations described in the article were carried out using the libraries <a href="https://scikit-survival.readthedocs.io/en/stable/install.html">scikit-survival</a> and <a href="https://plotly.com/">plotly</a>. You can find the code <a href="https://github.com/linafaik08/survival_analysis/">here</a> on GitHub.</em></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>1. What is Survival Analysis About?</strong></h2><h3><strong>1.1. Problem statement</strong></h3><p>At first glance, survival analysis may appear to be just another regression problem since the goal is to predict when an event is likely to occur (a continuous variable). However, the problem has a twist: a part of the training data may be partially observed &#8212; it is censored.</p><p>To illustrate this, let&#8217;s take the example of a company that offers services on a subscription basis. The company wants to predict for each customer that reaches out to the support the probability of unsubscribing over time. During the period in which the data was collected:</p><ul><li><p>Customer A did not unsubscribe before the end of the study.</p></li><li><p>Customers B and D canceled their subscriptions after a few months.</p></li><li><p>Customer C has decided to restrict access to its data from the platform.</p></li></ul><p>In this case, the records of customers A and C are <strong>censored</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y_ZI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y_ZI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png 424w, https://substackcdn.com/image/fetch/$s_!Y_ZI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png 848w, https://substackcdn.com/image/fetch/$s_!Y_ZI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png 1272w, https://substackcdn.com/image/fetch/$s_!Y_ZI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y_ZI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png" width="1400" height="733" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bce61000-de10-4f25-95e1-817a2a79c664_1400x733.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:733,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Y_ZI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png 424w, https://substackcdn.com/image/fetch/$s_!Y_ZI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png 848w, https://substackcdn.com/image/fetch/$s_!Y_ZI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png 1272w, https://substackcdn.com/image/fetch/$s_!Y_ZI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbce61000-de10-4f25-95e1-817a2a79c664_1400x733.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Survival analysis data, illustration by the author</figcaption></figure></div><p>More formally, each observation contains a set of covariates <em>X = (x_1, &#8230;, x_n),</em> the time <em>t</em> when the event occurred, or the censoring time <em>c&gt;0</em>. Let&#8217;s introduce an event indicator &#948;&#8712;{0;1}. The observable time y of a right-censored sample is then defined as:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!B73W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B73W!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png 424w, https://substackcdn.com/image/fetch/$s_!B73W!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png 848w, https://substackcdn.com/image/fetch/$s_!B73W!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png 1272w, https://substackcdn.com/image/fetch/$s_!B73W!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B73W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png" width="1280" height="196" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:196,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!B73W!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png 424w, https://substackcdn.com/image/fetch/$s_!B73W!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png 848w, https://substackcdn.com/image/fetch/$s_!B73W!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png 1272w, https://substackcdn.com/image/fetch/$s_!B73W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc33801d-3513-4052-ad27-b382ad3ecaa5_1280x196.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>In our case of churn prediction, the data consists of the customer&#8217;s support contact history. Each observation contains information about:</p><ul><li><p>the interaction: the date, the reason for the call (sign-up/support), and the channel (email/phone).</p></li><li><p>the customer: age and gender.</p></li><li><p>subscription: product, price, billing cycle (monthly/annual), sign-up.</p></li></ul><p>The data was enriched with additional features including the number of times the customer has contacted the company in the past, the duration since the customer subscribed, and cyclical date-related features.</p><h3><strong>1.2. Use cases</strong></h3><p>Survival analysis can be used for a wide range of applications where the goal is to predict the time between two events. Here are few other examples:</p><ul><li><p><strong>Predictive maintenance:</strong> Forecast when the machine is likely to break down after it has been turned on. Data can be censored if the machines had to stop due to external factors (fire alarms, etc.)</p></li><li><p><strong>Patient monitoring: </strong>Predict when a patient is likely to be re-hospitalized since their first diagnosis or hospitalization. Data may be censored if the patient has left the geographic scope of the study.</p></li><li><p><strong>Marketing analytics: </strong>Predict when a prospect might convert since the first call. Data may be censored if the person has died during the observation period.</p></li><li><p><strong>Economics: </strong>Forecast the time it takes for a laid-off person to find a job. Data may be censored if a person drops out of the study.</p></li></ul><h2><strong>2. What Are Common Approaches to Tackle Survival Use Cases?</strong></h2><h3><strong>2.1. Kaplan &#8212; Meier estimator</strong></h3><p>One of the most simple approaches to this problem is to use the Kaplan-Meier estimator. This is a non-parametric method that focuses on approximating the survival function. Let&#8217;s start by discussing the fundamental underlying theories before examining the results of the application case.</p><p><strong>Survival function</strong></p><p>The survival function <em>S(t)</em> represents the probability that a subject survives beyond time <em>t</em> or, in a similar way, the probability that the duration is at least equal to <em>t</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!reOC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!reOC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png 424w, https://substackcdn.com/image/fetch/$s_!reOC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png 848w, https://substackcdn.com/image/fetch/$s_!reOC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png 1272w, https://substackcdn.com/image/fetch/$s_!reOC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!reOC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png" width="1400" height="149" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:149,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!reOC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png 424w, https://substackcdn.com/image/fetch/$s_!reOC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png 848w, https://substackcdn.com/image/fetch/$s_!reOC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png 1272w, https://substackcdn.com/image/fetch/$s_!reOC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7272eccf-77d2-4561-894e-bb4ca3bd76c3_1400x149.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>where <em>T</em> is the random lifespan taken from the study population.</p><p><em>S</em> starts with 1 at time <em>t=0</em> since no subject has yet experienced the event at the beginning. It decreases and tends to 0 as everyone is likely to experience the event of interest at some point.</p><p><strong>Kaplan-Meier estimator</strong></p><p>To approximate the survival function, the Kaplan-Meier model breaks the estimation into small steps. For each interval, the probability is computed as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9zdg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9zdg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png 424w, https://substackcdn.com/image/fetch/$s_!9zdg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png 848w, https://substackcdn.com/image/fetch/$s_!9zdg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png 1272w, https://substackcdn.com/image/fetch/$s_!9zdg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9zdg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png" width="1400" height="131" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:131,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9zdg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png 424w, https://substackcdn.com/image/fetch/$s_!9zdg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png 848w, https://substackcdn.com/image/fetch/$s_!9zdg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png 1272w, https://substackcdn.com/image/fetch/$s_!9zdg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016a3419-85bf-4a81-979e-0c0df74c52b4_1400x131.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>where <em>n_i</em> is the number of individuals who are at risk at time point <em>t_i</em> and <em>d_i</em> the number of individuals that experienced the event at time <em>t_i</em>.</p><p>It is a very simple method that does not take into account covariates.</p><ul><li><p>It can be used as a naive baseline.</p></li><li><p>It can also serve as a data exploration method. In this case, it provides an overview of the survival function for the whole population or helps in comparing certain groups between them.</p></li></ul><p>For example, in our case study, we might compare the estimate depending on the subscription billing cycle. The graph below confirms the intuition that customers with a monthly subscription are more volatile. They tend to churn more often and faster during the first years after their subscription.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JCjX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JCjX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png 424w, https://substackcdn.com/image/fetch/$s_!JCjX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png 848w, https://substackcdn.com/image/fetch/$s_!JCjX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png 1272w, https://substackcdn.com/image/fetch/$s_!JCjX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JCjX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png" width="1400" height="511" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:511,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!JCjX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png 424w, https://substackcdn.com/image/fetch/$s_!JCjX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png 848w, https://substackcdn.com/image/fetch/$s_!JCjX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png 1272w, https://substackcdn.com/image/fetch/$s_!JCjX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6b8dea1-20dd-4ca6-8f63-49c73f2c531a_1400x511.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2 &#8212; Survival function estimated by the Kaplan-Meier model</figcaption></figure></div><h3><strong>2.2. Cox proportional hazards model</strong></h3><p>The most widely used estimator is certainly the Cox proportional hazards (Cox PH) model. It is easy to implement, takes covariates into account and provides interpretable results. It is a semi-parametric method that aims at modeling the hazard function.</p><p><strong>Hazard function</strong></p><p>The hazard function <em>h(t)</em> represents the probability of the death event occurring at time <em>t</em>, given that the subject did not experience the death event until time <em>t</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!e9-B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!e9-B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png 424w, https://substackcdn.com/image/fetch/$s_!e9-B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png 848w, https://substackcdn.com/image/fetch/$s_!e9-B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png 1272w, https://substackcdn.com/image/fetch/$s_!e9-B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!e9-B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png" width="1328" height="166" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:166,&quot;width&quot;:1328,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!e9-B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png 424w, https://substackcdn.com/image/fetch/$s_!e9-B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png 848w, https://substackcdn.com/image/fetch/$s_!e9-B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png 1272w, https://substackcdn.com/image/fetch/$s_!e9-B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98df23d3-471b-4aa2-97d1-9f53d09f95db_1328x166.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Therefore, the hazard function is useful in finding the periods that are the safest or riskiest with respect to the occurrence of the event.</p><p><strong>Cox proportional hazards</strong></p><p>CoxPH models the hazard function as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZqB8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZqB8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png 424w, https://substackcdn.com/image/fetch/$s_!ZqB8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png 848w, https://substackcdn.com/image/fetch/$s_!ZqB8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png 1272w, https://substackcdn.com/image/fetch/$s_!ZqB8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZqB8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png" width="1156" height="384" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:384,&quot;width&quot;:1156,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ZqB8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png 424w, https://substackcdn.com/image/fetch/$s_!ZqB8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png 848w, https://substackcdn.com/image/fetch/$s_!ZqB8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png 1272w, https://substackcdn.com/image/fetch/$s_!ZqB8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4740cc07-878a-47bf-9278-2a41dde00f5c_1156x384.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Illustration by the author</figcaption></figure></div><p>The model consists of 2 parts:</p><ul><li><p><strong>the baseline hazard:</strong> it describes how the risk evolves through time.</p></li><li><p><strong>the hazard ratio:</strong> it models the effect of the explanatory covariates on the risk.</p></li></ul><p>With this parametric function, the model relies on a strong proportionality assumption: at a given point in time, the hazard functions for a subject remain proportional with the same ratio with respect to the baseline or to another subject.</p><ul><li><p>For example, if a customer has a risk of churn at an initial observation that is twice as low as another customer, then for all subsequent time observations, the risk of churn remains twice as low.</p></li></ul><p><strong>Application</strong></p><p>The outputs of the model are highly interpretable.</p><p>At the<strong> instance level</strong>, the model provides for each observation:</p><ul><li><p><strong>A</strong> <strong>risk score</strong>: the higher the risk, the more likely the customer is to unsubscribe.</p></li><li><p><strong>A</strong> <strong>survival function</strong>: it enables analysts to assess the probability of surviving at least to a point <em>t</em> over time. For instance, the graph below shows that customer 2 is most likely to churn in the first few days, while customers 1, 3, and 4 are not at risk.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4uw4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4uw4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png 424w, https://substackcdn.com/image/fetch/$s_!4uw4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png 848w, https://substackcdn.com/image/fetch/$s_!4uw4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png 1272w, https://substackcdn.com/image/fetch/$s_!4uw4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4uw4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png" width="1400" height="537" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:537,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!4uw4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png 424w, https://substackcdn.com/image/fetch/$s_!4uw4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png 848w, https://substackcdn.com/image/fetch/$s_!4uw4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png 1272w, https://substackcdn.com/image/fetch/$s_!4uw4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8dc070c-31dc-49fe-b747-840f275dc186_1400x537.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3 &#8212; Survival function of 5 randomly selected clients</figcaption></figure></div><ul><li><p><strong>A hazard function:</strong> it serves the same purpose. The chart below confirms the previous conclusion.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!P2BA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!P2BA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png 424w, https://substackcdn.com/image/fetch/$s_!P2BA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png 848w, https://substackcdn.com/image/fetch/$s_!P2BA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png 1272w, https://substackcdn.com/image/fetch/$s_!P2BA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!P2BA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png" width="1400" height="544" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:544,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!P2BA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png 424w, https://substackcdn.com/image/fetch/$s_!P2BA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png 848w, https://substackcdn.com/image/fetch/$s_!P2BA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png 1272w, https://substackcdn.com/image/fetch/$s_!P2BA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b67c698-3d26-49f3-a6b1-55dad76c36e9_1400x544.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4 &#8212; Cumulative hazard function of 5 randomly selected clients</figcaption></figure></div><p>At the global level, the model can be explained through its coefficients (see formula above). For a positive coefficient, the higher it is, the stronger the impact on the risk of churn.</p><p>For example, the graph below shows that the model generally considers contacting assistance for support reasons as a risk factor for churn.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0ksG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0ksG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png 424w, https://substackcdn.com/image/fetch/$s_!0ksG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png 848w, https://substackcdn.com/image/fetch/$s_!0ksG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png 1272w, https://substackcdn.com/image/fetch/$s_!0ksG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0ksG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png" width="1068" height="862" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:862,&quot;width&quot;:1068,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0ksG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png 424w, https://substackcdn.com/image/fetch/$s_!0ksG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png 848w, https://substackcdn.com/image/fetch/$s_!0ksG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png 1272w, https://substackcdn.com/image/fetch/$s_!0ksG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe101df1c-9801-4ef0-b8f9-1fca97ba82c2_1068x862.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 5&#8212; Coefficients obtained by the Cox PH model</figcaption></figure></div><h2><strong>3. How Is Machine Learning Leveraged for Survival Analysis?</strong></h2><h3><strong>3.1. Machine learning-based survival models</strong></h3><p>Let&#8217;s start by walking through the fundamentals behind ML models for survival analysis before comparing their performance in our case study around churn prediction.</p><h4><strong>Random Survival Forests</strong></h4><p>Just as standard <a href="https://en.wikipedia.org/wiki/Random_forest">Random Forests</a>, Random Survival Forest consists in training a number of survival trees on various sub-samples (often drawn with replacement) of the dataset and using averaging for more accurate prediction and limited over-fitting.</p><p>The main difference lies in the metric used to assess the quality of a split: <a href="https://en.wikipedia.org/wiki/Logrank_test">log-rank</a> which is typically used when comparing survival curves among two or more groups.</p><p>More information about the model can be found <a href="https://scikit-survival.readthedocs.io/en/stable/api/generated/sksurv.ensemble.RandomSurvivalForest.html">here</a>.</p><h4><strong>Gradient Boosting Survival Analysis</strong></h4><p>Gradient Boosting when applied to survival analysis is also very similar: it consists in combining in an additive manner the predictions of multiple base learners to obtain a powerful overall model. The base learners, also called weak learners, are often very simple models. It differs from Random Forests as the survival trees are not trained independently but sequentially in a greedy stagewise fashion.</p><p>The model is a very versatile framework: it can optimize many loss functions including:</p><ul><li><p>Partial likelihood loss of Cox&#8217;s proportional hazards model</p></li><li><p>Squared regression loss</p></li><li><p>Inverse probability of censoring weighted least squares error.<br>This loss allows the model to accelerate or decelerate the time to an event by a constant factor. It is known as the Accelerated Failure Time (AFT). It contrasts with the Cox proportional hazards model where only the features influence the hazard function.</p></li></ul><p>More information about the model can be found <a href="https://scikit-survival.readthedocs.io/en/stable/api/generated/sksurv.ensemble.GradientBoostingSurvivalAnalysis.html">here</a>.</p><h3><strong>3.3. Survival Support Vector Machine</strong></h3><p><a href="https://en.wikipedia.org/wiki/Support_vector_machine">Survival Support Vector Machine</a> (SVM) can also be extended to survival analysis. It is also a very versatile model as it can account for complex, non-linear relationships between features and survival via the so-called kernel trick.</p><p>However, its predictions cannot be easily related to the standard quantities of survival analysis, that is, the survival function and the cumulative hazard function.</p><p>More information about the model can be found <a href="https://scikit-survival.readthedocs.io/en/stable/api/generated/sksurv.svm.FastKernelSurvivalSVM.html">here</a>.</p><h3><strong>3.2. Comparison</strong></h3><h4><strong>Methodology</strong></h4><p>In order to compare the performance of the models, the initial dataset containing approximately 320,000 observations was divided into two sets: a training set (70%) and a validation set (30%) with the same censoring distribution. The models were trained and fine-tuned using 5-fold cross-validation. They were then evaluated on the validation set.</p><h4><strong>Concordance index</strong></h4><p>The most frequently used evaluation metric is the concordance index, also referred to as the c-index. It measures the capability of the model to provide a reliable ranking of survival times based on individual risk scores. It is computed as the proportion of concordant pairs in a dataset.</p><p>More specifically, let&#8217;s consider two observations <em>(i,j)</em>:</p><ul><li><p>First, to be comparable, the observation with lower time needs to have experienced the event.</p></li><li><p>Second, if comparable, it is concordant if the risk estimated by the survival model is higher for individuals with shorter survival times.</p></li></ul><p>The graph below shows the results of the models on the 5-cross tests and the validation set. Gradient Boosting is the best-performing model with a concordance index of approximately 0.70 for both the 5-cross tests and the validation sets.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0J_P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0J_P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png 424w, https://substackcdn.com/image/fetch/$s_!0J_P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png 848w, https://substackcdn.com/image/fetch/$s_!0J_P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png 1272w, https://substackcdn.com/image/fetch/$s_!0J_P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0J_P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png" width="1400" height="519" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:519,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0J_P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png 424w, https://substackcdn.com/image/fetch/$s_!0J_P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png 848w, https://substackcdn.com/image/fetch/$s_!0J_P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png 1272w, https://substackcdn.com/image/fetch/$s_!0J_P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4a619c0-26d3-4b23-a624-e26e8fc74eb5_1400x519.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 6&#8212; Concordance index of the models</figcaption></figure></div><p>The concordance index is easy to calculate and interpret. However, it suffers from two major drawbacks:</p><ol><li><p>It tends to be too favorable with an increasing amount of censoring. An alternative consists of using the inverse probability of censoring weights. The censoring distribution is obtained from a Kaplan-Meier estimator applied to the training data.</p></li><li><p>It is not very useful when the main goal is to measure performance over a specific period of time (e.g. predicting churn in the first year of subscription).</p></li></ol><p>The second drawback can be overcome by using other metrics such as cumulative/dynamic AUC.</p><h4><strong>Cumulative/dynamic AUC</strong></h4><p>The well-known receiver operating characteristic curve (ROC curve) can be extended to censored survival times. The idea is to consider several points in time. At each point, we consider separately:</p><ul><li><p>the cumulative cases: all individuals who have experienced the event before or at time <em>t.</em></p></li><li><p>the dynamic controls: individuals who will experience an event after time.</p></li></ul><p>We can then evaluate the model on its ability to distinguish subjects who will experience an event over time (sensitivity) from those who will not (specificity).</p><p>With this method, it is possible to evaluate the estimator only on the time points that are most important in the context (e.g. the two first years).</p><p>The graph below shows the results of the models on the validation set. Gradient Boosting is again the best-performing model with an average AUC over the 2-year period of around 0.80. Although Random Forest and Cox PH perform similarly on average, they lag far behind Gradient Boosting over the first few months of subscription.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZbE5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZbE5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png 424w, https://substackcdn.com/image/fetch/$s_!ZbE5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png 848w, https://substackcdn.com/image/fetch/$s_!ZbE5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png 1272w, https://substackcdn.com/image/fetch/$s_!ZbE5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZbE5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png" width="1400" height="493" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:493,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ZbE5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png 424w, https://substackcdn.com/image/fetch/$s_!ZbE5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png 848w, https://substackcdn.com/image/fetch/$s_!ZbE5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png 1272w, https://substackcdn.com/image/fetch/$s_!ZbE5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57802dd5-0b05-4ea7-bbd4-2e661f50b05d_1400x493.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 7&#8212; AUC of models over time on the validation set</figcaption></figure></div><div><hr></div><h2><strong>Key Takeaways</strong></h2><p>&#10004;&#65039; Survival analysis refers to a learning framework and a set of techniques that can be used to estimate the time it takes for an event of interest to occur based on observations.</p><p>&#10004;&#65039; It&#8217;s more than a simple regression predictive problem as part of the training data may be partially observed &#8212; it is censored.</p><p>&#10004;&#65039; Common machine learning models such as Random Forest, Gradient Boosting or SVM can be extended to survival analysis, resulting in better-performing and still interpretable models.</p><p>&#10004;&#65039; Combining the survival analysis framework with the predictive power of machine learning can bring significant business value to a wide range of applications, including predictive maintenance, patient monitoring, marketing analytics, economics, etc.</p><div><hr></div><h2><strong>References</strong></h2><p>[1] <a href="https://scikit-survival.readthedocs.io/en/stable/user_guide/00-introduction.html">Introduction to Survival Analysis with scikit-survival</a></p><p>[2] Scikit survival <a href="https://scikit-survival.readthedocs.io/en/stable/">documentation</a></p><p>[3] Wikipedia, <a href="https://en.wikipedia.org/wiki/Proportional_hazards_model">Proportional hazards model</a></p><p>[4] Wikipedia, <a href="https://en.wikipedia.org/wiki/Kendall_rank_correlation_coefficient">Kendall rank correlation coefficient</a></p><p>[5] Laura L&#246;schmann, Daria Smorodina, <a href="https://humboldt-wi.github.io/blog/research/information_systems_1920/group2_survivalanalysis/">Deep Learning for Survival Analysis</a>, Humboldt University, February 2020</p>]]></content:encoded></item><item><title><![CDATA[Graph Neural Networks: Graph Classification (Part III)]]></title><description><![CDATA[When It Comes to Labeling Whole Graphs, Not Just Nodes]]></description><link>https://aipractitioner.substack.com/p/graph-neural-networks-graph-classification</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/graph-neural-networks-graph-classification</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 01 Sep 2022 18:51:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!q5w9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.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="https://substackcdn.com/image/fetch/$s_!q5w9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!q5w9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!q5w9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!q5w9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!q5w9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!q5w9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg" width="1400" height="584" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:584,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!q5w9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!q5w9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!q5w9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!q5w9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f55b910-8f54-4c26-ab5e-633ae84a93fb_1400x584.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Many real-life situations can be modeled as graphs, but turning the relational structure of these graphs into valuable information that can help solve complex tasks is a real challenge.</p><p>Take the example of <strong>drug discovery</strong>. In the early stages of drug development, scientists need to screen large libraries often composed of hundreds of thousands of compounds (drug candidates) against targets (biological events). This requires the use of an arsenal of tools such as robotics, data processing and control software, and sensitive detectors [<a href="https://www.sciencedirect.com/referencework/9780123864550/encyclopedia-of-toxicology">1</a>]. Such approaches can be very time consuming and expensive, with a very low hit rate (a typical hit rate is less than 1% in most assays!).</p><p>And, yet, the molecules' atomic composition and arrangement can already tell us a lot about their biological behavior.</p><h3><strong>Objective</strong></h3><p>This article focuses on using <strong>graph neural networks for graph classification</strong>. It also explores <strong>explainability</strong> techniques for these models.</p><p>As an illustration, we will develop a use case <strong>predicting the toxicity of a molecule. </strong>We&#8217;ll use its representation as a graph where the nodes are atoms connected by edges corresponding to chemical bonds.</p><p>After reading this article, you will understand:</p><ol><li><p>How GNN models can be applied to graph classification tasks</p></li><li><p>How edge features can be included in graph-based models</p></li><li><p>The techniques used to explain GNN model predictions</p></li></ol><blockquote><p><em>This is the third and last part of the series that aims to provide a comprehensive overview of the most common applications of GNN to real-world problems. The first two parts focused on <a href="https://medium.com/data-from-the-trenches/graph-neural-networks-merging-deep-learning-with-graphs-part-i-57694ca5be">node classification</a> and <a href="https://medium.com/data-from-the-trenches/graphical-neural-networks-link-prediction-part-ii-c60f6d97fd97">link prediction</a>, respectively.</em></p><p><em>The article assumes minimal knowledge of GNNs and no knowledge of chemistry is required!</em></p><p><em>The experimentations described in the article were carried out using <a href="https://pytorch-geometric.readthedocs.io/en/latest/">PyTorch Geometric</a>, <a href="https://www.rdkit.org/">RDKit</a>, <a href="https://plotly.com/python/">Plotly</a>, and <a href="https://pypi.org/project/py3Dmol/">py3Dmol</a>. You can find the code <a href="https://github.com/linafaik08/graph_neural_networks/blob/main/3_graph_classification.ipynb">here</a> on GitHub.</em></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>1. What Is Drug Discovery?</strong></h2><p>One of the most recent popular tasks in graph classification is <strong>molecular property prediction</strong>. It consists of using the representation of molecules as graphs to infer molecular properties so, in our case, whether the molecule is toxic or not.</p><h3><strong>1.1. From the Representation of Molecules to the Graph</strong></h3><p>The dataset used for the experiments contains graphs of 7,831 molecules. It comes from <a href="https://moleculenet.org/datasets-1">MoleculeNet</a> (Tox-21) with a node and edge enrichment introduced by the <a href="https://ogb.stanford.edu/">Open Graph Benchmark</a>.</p><p>Let&#8217;s take a look at what information is available through an example.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wap8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wap8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png 424w, https://substackcdn.com/image/fetch/$s_!wap8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png 848w, https://substackcdn.com/image/fetch/$s_!wap8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png 1272w, https://substackcdn.com/image/fetch/$s_!wap8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wap8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png" width="392" height="161" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:161,&quot;width&quot;:392,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 1&#8202;&#8212;&#8202;Representation of a molecule from the dataset&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="Figure 1&#8202;&#8212;&#8202;Representation of a molecule from the dataset" title="Figure 1&#8202;&#8212;&#8202;Representation of a molecule from the dataset" srcset="https://substackcdn.com/image/fetch/$s_!wap8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png 424w, https://substackcdn.com/image/fetch/$s_!wap8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png 848w, https://substackcdn.com/image/fetch/$s_!wap8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png 1272w, https://substackcdn.com/image/fetch/$s_!wap8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7827896c-b9b2-458f-8c57-534dbedbbc74_392x161.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Representation of a molecule from the dataset</figcaption></figure></div><p>Converting this into a graph consists mainly of representing each atom by a node and replacing the bonds with edges. These nodes and edges are further enriched with various features to avoid losing valuable information such as the name of the atom or the type of bond. In total, input node features are nine-dimensional and edge features three-dimensional.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OVW6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OVW6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png 424w, https://substackcdn.com/image/fetch/$s_!OVW6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png 848w, https://substackcdn.com/image/fetch/$s_!OVW6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png 1272w, https://substackcdn.com/image/fetch/$s_!OVW6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OVW6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png" width="1400" height="749" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:749,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 2- Representation of the molecule as a graph&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="Figure 2- Representation of the molecule as a graph" title="Figure 2- Representation of the molecule as a graph" srcset="https://substackcdn.com/image/fetch/$s_!OVW6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png 424w, https://substackcdn.com/image/fetch/$s_!OVW6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png 848w, https://substackcdn.com/image/fetch/$s_!OVW6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png 1272w, https://substackcdn.com/image/fetch/$s_!OVW6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac5ceacf-7b4a-40db-930f-247701a3118e_1400x749.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2&#8212; Representation of the molecule as a graph</figcaption></figure></div><p><strong>What are the node features?</strong></p><ul><li><p><a href="https://en.wikipedia.org/wiki/Atomic_number">Atomic number</a>: Number of protons in the nucleus of an atom. It&#8217;s characteristic of a chemical element and determines its place in the periodic table.</p></li><li><p><a href="https://en.wikipedia.org/wiki/Chirality_(chemistry)">Chirality</a>: A molecule is chiral if it is distinguishable from its mirror image by any combination of rotations, translations, and some conformational changes. Different types of chirality exist depending on the molecule and the arrangement of the atoms.</p></li><li><p>Degree: Number of directly-bonded neighbors of the atom.</p></li><li><p><a href="https://en.wikipedia.org/wiki/Formal_charge">Formal charge</a>: Charge assigned to an atom. It reflects the electron count associated with the atom compared to the isolated neutral atom.</p></li><li><p>Number of H: Total number of hydrogen atoms on the atom.</p></li><li><p><a href="https://en.wikipedia.org/wiki/Radical_(chemistry)">Number of radical e</a>: Number of unpaired electrons of the atom.</p></li><li><p><a href="https://en.wikipedia.org/wiki/Orbital_hybridisation">Hybridization</a>: Atom&#8217;s hybridization.</p></li><li><p><a href="https://en.wikipedia.org/wiki/Aromatic_compound">Is aromatic</a>: Whether it is included in a cyclic structure with pi bonds. This type of structure tends to be very stable in comparison with other geometric arrangements of the same atoms.</p></li><li><p><a href="https://en.wikipedia.org/wiki/Ring_(chemistry)">Is in ring</a>: Whether it is included in a ring (a simple cycle of atoms and bonds in a molecule).</p></li></ul><p>Edge features:</p><ul><li><p><a href="https://en.wikipedia.org/wiki/Chemical_bond">Bond type</a>: Whether the bond is single, double, triple, or aromatic.</p></li><li><p><a href="https://en.wikipedia.org/wiki/Stereoisomerism">Stereo configuration</a> of the bond.</p></li><li><p><a href="https://en.wikipedia.org/wiki/Conjugated_system">Is conjugated</a>: Whether or not the bond is considered to be conjugated.</p></li></ul><h3><strong>1.2. What&#8217;s Our target?</strong></h3><p>The dataset contains the outcomes of 12 different toxicological experiments in the form of binary labels (active/inactive).</p><p>The data, as it is, poses two main challenges:</p><ul><li><p>Small dataset: The number of labeled molecules varies depending on the experiment.</p></li><li><p>Unbalanced targets: The percentage of active molecules is very low, up to 3% as shown in the figure below.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!b3Ej!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b3Ej!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png 424w, https://substackcdn.com/image/fetch/$s_!b3Ej!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png 848w, https://substackcdn.com/image/fetch/$s_!b3Ej!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png 1272w, https://substackcdn.com/image/fetch/$s_!b3Ej!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b3Ej!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png" width="1400" height="476" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:476,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 3&#8202;&#8212;&#8202;Number of labeled graphs and percentage of positive outcomes for each experiment&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="Figure 3&#8202;&#8212;&#8202;Number of labeled graphs and percentage of positive outcomes for each experiment" title="Figure 3&#8202;&#8212;&#8202;Number of labeled graphs and percentage of positive outcomes for each experiment" srcset="https://substackcdn.com/image/fetch/$s_!b3Ej!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png 424w, https://substackcdn.com/image/fetch/$s_!b3Ej!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png 848w, https://substackcdn.com/image/fetch/$s_!b3Ej!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png 1272w, https://substackcdn.com/image/fetch/$s_!b3Ej!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88b88e45-be49-45b7-964e-880cf09c0f7f_1400x476.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3 &#8212; Number of labeled graphs and percentage of positive outcomes for each experiment</figcaption></figure></div><h2><strong>2. GNN for Graph Classification: How Does It Work?</strong></h2><p>Before diving into how GNN works for graph classification, here is a refresher on the three different types of supervised tasks for graph-based models.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2yoH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2yoH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png 424w, https://substackcdn.com/image/fetch/$s_!2yoH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png 848w, https://substackcdn.com/image/fetch/$s_!2yoH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!2yoH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2yoH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png" width="1400" height="1168" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1977c270-5278-486a-b06c-c1968424777f_1400x1168.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1168,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 4&#8202;&#8212;&#8202;The different supervised tasks for graph data, illustration by Lina Faik&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="Figure 4&#8202;&#8212;&#8202;The different supervised tasks for graph data, illustration by Lina Faik" title="Figure 4&#8202;&#8212;&#8202;The different supervised tasks for graph data, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!2yoH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png 424w, https://substackcdn.com/image/fetch/$s_!2yoH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png 848w, https://substackcdn.com/image/fetch/$s_!2yoH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!2yoH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1977c270-5278-486a-b06c-c1968424777f_1400x1168.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4 &#8212; The different supervised tasks for graph data, illustration by Lina Faik</figcaption></figure></div><h3><strong>2.1. The GNN Approach</strong></h3><p>So far, we have seen in the previous articles of the series that GNNs are able to classify nodes or predict links within a network by learning an <strong>embedding of nodes</strong>. These embeddings are low-dimensional vectors that summarize the position of nodes in the network as well as the structure of their local neighborhood.</p><p><strong>How can this approach be extended to classify whole graphs and not just nodes?</strong></p><p>The idea remains the same: GNNs learn to <strong>embed entire graphs </strong>based on the structural properties of these graphs.</p><p><strong>Learning From Multiple Graphs at Once</strong></p><p>As graphs tend to be small, it&#8217;s better to use <strong>batches of graphs</strong> instead of individual graphs before inputting them into a GNN.</p><p>In NLP or computer vision, this is typically done by rescaling or padding each element into a set of equally-sized shapes. For graphs, those approaches are not feasible. Instead, we can:</p><ul><li><p>Stack adjacency matrices in a diagonal manner leading to a large graph with multiple isolated subgraphs.</p></li><li><p>Concatenate node features and the target.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ziJG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ziJG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png 424w, https://substackcdn.com/image/fetch/$s_!ziJG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png 848w, https://substackcdn.com/image/fetch/$s_!ziJG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png 1272w, https://substackcdn.com/image/fetch/$s_!ziJG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ziJG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png" width="1400" height="699" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:699,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 5 -Mini-batching of graphs, illustration by Lina Faik, inspired by [2]&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="Figure 5 -Mini-batching of graphs, illustration by Lina Faik, inspired by [2]" title="Figure 5 -Mini-batching of graphs, illustration by Lina Faik, inspired by [2]" srcset="https://substackcdn.com/image/fetch/$s_!ziJG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png 424w, https://substackcdn.com/image/fetch/$s_!ziJG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png 848w, https://substackcdn.com/image/fetch/$s_!ziJG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png 1272w, https://substackcdn.com/image/fetch/$s_!ziJG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c0c5f53-c0db-406c-b7c3-94df596cd0b3_1400x699.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 5 &#8212;Mini-batching of graphs, illustration by Lina Faik, inspired by [<a href="https://colab.research.google.com/drive/1I8a0DfQ3fI7Njc62__mVXUlcAleUclnb?usp=sharing">2</a>]</figcaption></figure></div><p>This approach is the one implemented in PyTorch. It has two main advantages:</p><ol><li><p>It does not require changing GNN operators using a message passing scheme as, by construction, messages are not exchanged between two nodes of different graphs.</p></li><li><p>There is no risk of having a computational or memory overload since the adjacency matrices are saved sparsely (only the non-zero entries which correspond to the edges are kept).</p></li></ol><p><strong>Model Architecture</strong></p><p>The model learns to classify graphs using three main steps:</p><ol><li><p>Embed nodes using several rounds of message passing.</p></li><li><p>Aggregate these node embeddings into a single graph embedding (called readout layer). In the code below, the average of node embeddings is used (<a href="https://medium.com/r?url=https%3A%2F%2Fpytorch-geometric.readthedocs.io%2Fen%2Flatest%2Fmodules%2Fnn.html%23torch_geometric.nn.pool.global_mean_pool">global mean pool</a>).</p></li><li><p>Train a classifier based on graph embeddings.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L-wl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L-wl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png 424w, https://substackcdn.com/image/fetch/$s_!L-wl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png 848w, https://substackcdn.com/image/fetch/$s_!L-wl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png 1272w, https://substackcdn.com/image/fetch/$s_!L-wl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L-wl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png" width="1400" height="693" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:693,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 6&#8202;&#8212;&#8202;GNN model architecture, illustration by Lina Faik&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="Figure 6&#8202;&#8212;&#8202;GNN model architecture, illustration by Lina Faik" title="Figure 6&#8202;&#8212;&#8202;GNN model architecture, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!L-wl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png 424w, https://substackcdn.com/image/fetch/$s_!L-wl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png 848w, https://substackcdn.com/image/fetch/$s_!L-wl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png 1272w, https://substackcdn.com/image/fetch/$s_!L-wl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87f83e06-da41-4325-8315-6b3502750bfd_1400x693.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 6 &#8212; GNN model architecture, illustration by Lina Faik</figcaption></figure></div><p>You can find below the code used.</p><p><strong>What About Edge Features?</strong></p><p>The type of bond that links two atoms in a given molecule holds valuable information about the molecule such as its stability, its reactivity, the presence of some chemically organic functional groups, etc. Therefore, including this feature has the potential to improve model performance.</p><p><strong>But how can edge features be used when training the model?</strong></p><p>If we take the example of GCN, it can easily be done by replacing the zeros and ones of the adjacency matrix with the edge weights, as illustrated in Figure 7. In this context, each message-passing iteration through the GCN updates the hidden embedding of nodes based on the aggregated and now weighted information of their neighborhood.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xM7Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xM7Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png 424w, https://substackcdn.com/image/fetch/$s_!xM7Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png 848w, https://substackcdn.com/image/fetch/$s_!xM7Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png 1272w, https://substackcdn.com/image/fetch/$s_!xM7Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xM7Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png" width="1400" height="1371" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1371,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 7&#8202;&#8212;&#8202;Including edge weights in a GNN model via the adjacency matrix, illustration by Lina Faik&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="Figure 7&#8202;&#8212;&#8202;Including edge weights in a GNN model via the adjacency matrix, illustration by Lina Faik" title="Figure 7&#8202;&#8212;&#8202;Including edge weights in a GNN model via the adjacency matrix, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!xM7Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png 424w, https://substackcdn.com/image/fetch/$s_!xM7Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png 848w, https://substackcdn.com/image/fetch/$s_!xM7Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png 1272w, https://substackcdn.com/image/fetch/$s_!xM7Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f2c15fd-e079-4273-ae48-de9f536ddfca_1400x1371.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 7 &#8212; Including edge weights in a GNN model via the adjacency matrix, illustration by Lina Faik</figcaption></figure></div><p>Other more sophisticated approaches to include the weights or categorical features of features exist. For more information, you can watch this short video <a href="https://www.youtube.com/watch?v=mdWQYYapvR8">here</a> from DeepFindr which gives a large overview of the possibilities.</p><h3><strong>2.2. Application to the Detection of Toxic Molecules</strong></h3><p><strong>Methodology</strong></p><p><strong>Target.</strong> As seen in the first section, the molecules are labeled depending on the experiment. For this reason, each experiment outcome is taken as an individual classification task.</p><p><strong>Train / Test sets.</strong> The data is divided into two datasets: a training set, which contains around 70% of the total number of graphs, and a test set that contains the rest of the graph. This split is randomly done three times for each model.</p><p><strong>Model evaluation.</strong> The models are trained using cross-entropy loss with class weights. They are evaluated according to the mean accuracy measured on the test sets, as well as other common classification metrics.</p><p><strong>Hyperparameters.</strong> For each target, multiple parameters are tested such as the type and number of GNN convolutions used for node embedding (e.g., GCN, GAT, etc.), the latent dimension of node embedding, and the learning rate.</p><p><strong>Features.</strong> Node features are all used when training the model. Concerning the edge features, the possibility of using the type of bonds (single, double, or triple) was also tested.</p><p><strong>Results</strong></p><p>The results show satisfactory accuracy on average. However, the accuracy depends to a large extent on the number of labeled molecules (the higher the better) and the percentage of positive outcomes (the lower the worse).</p><p>As for the hyperparameters, the best combination also differs depending on the target. Hence, it is difficult to draw a general rule.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3imM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3imM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png 424w, https://substackcdn.com/image/fetch/$s_!3imM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png 848w, https://substackcdn.com/image/fetch/$s_!3imM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png 1272w, https://substackcdn.com/image/fetch/$s_!3imM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3imM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png" width="1400" height="509" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:509,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 8&#8202;&#8212;&#8202;Accuracy of models on test set depending on the target (experiment)&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="Figure 8&#8202;&#8212;&#8202;Accuracy of models on test set depending on the target (experiment)" title="Figure 8&#8202;&#8212;&#8202;Accuracy of models on test set depending on the target (experiment)" srcset="https://substackcdn.com/image/fetch/$s_!3imM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png 424w, https://substackcdn.com/image/fetch/$s_!3imM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png 848w, https://substackcdn.com/image/fetch/$s_!3imM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png 1272w, https://substackcdn.com/image/fetch/$s_!3imM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ed88e18-ac30-44c5-b05b-881d834eb04c_1400x509.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 8 &#8212; Accuracy of models on test set depending on the target (experiment)</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kGQo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kGQo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png 424w, https://substackcdn.com/image/fetch/$s_!kGQo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png 848w, https://substackcdn.com/image/fetch/$s_!kGQo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png 1272w, https://substackcdn.com/image/fetch/$s_!kGQo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kGQo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png" width="1272" height="796" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:796,&quot;width&quot;:1272,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 9&#8202;&#8212;&#8202;Accuracy of models on test set vs. % positive class, a large dot size means a high number of labeled graphs for the experiment&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="Figure 9&#8202;&#8212;&#8202;Accuracy of models on test set vs. % positive class, a large dot size means a high number of labeled graphs for the experiment" title="Figure 9&#8202;&#8212;&#8202;Accuracy of models on test set vs. % positive class, a large dot size means a high number of labeled graphs for the experiment" srcset="https://substackcdn.com/image/fetch/$s_!kGQo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png 424w, https://substackcdn.com/image/fetch/$s_!kGQo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png 848w, https://substackcdn.com/image/fetch/$s_!kGQo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png 1272w, https://substackcdn.com/image/fetch/$s_!kGQo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e39897b-3890-4315-8627-bbb5473513b5_1272x796.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 9 &#8212; Accuracy of models on test set vs. % positive class, a large dot size means a high number of labeled graphs for the experiment</figcaption></figure></div><h2><strong>3. What About Explainability for GNN?</strong></h2><h3><strong>3.1. A Quick Overview of Approaches</strong></h3><p>Getting good performance is one thing, but having confidence in the prediction to take action is another. To trust the prediction of a model, one can examine the reasons why the model generated it. Sometimes, these explanations can be more important than the results themselves as they reveal the hidden patterns that the model has detected and better guide the decision-making.</p><p>For graphs, explicability is about three questions:</p><ul><li><p>Which nodes and features were relevant to making the prediction?</p></li><li><p>How relevant were they?</p></li><li><p>How relevant were the node and edge features of the graph?</p></li></ul><p><strong>What approaches are used to answer these questions?</strong></p><p>The paper [<a href="https://arxiv.org/abs/2012.15445">5</a>] contains a survey of current methods of GNN explicability. It classifies them in this tree which gives a good overview of the different types of approaches.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VbFI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VbFI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png 424w, https://substackcdn.com/image/fetch/$s_!VbFI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png 848w, https://substackcdn.com/image/fetch/$s_!VbFI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png 1272w, https://substackcdn.com/image/fetch/$s_!VbFI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VbFI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png" width="1400" height="359" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:359,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 10&#8202;&#8212;&#8202;Classification of the explainability approaches for graphs, illustration by Lina Faik, inspired by [5]&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="Figure 10&#8202;&#8212;&#8202;Classification of the explainability approaches for graphs, illustration by Lina Faik, inspired by [5]" title="Figure 10&#8202;&#8212;&#8202;Classification of the explainability approaches for graphs, illustration by Lina Faik, inspired by [5]" srcset="https://substackcdn.com/image/fetch/$s_!VbFI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png 424w, https://substackcdn.com/image/fetch/$s_!VbFI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png 848w, https://substackcdn.com/image/fetch/$s_!VbFI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png 1272w, https://substackcdn.com/image/fetch/$s_!VbFI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aabf905-e59e-400f-9e65-c92eef6aa645_1400x359.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 10 &#8212; Classification of the explainability approaches for graphs, illustration by Lina Faik, inspired by [<a href="https://arxiv.org/abs/2012.15445">5</a>]</figcaption></figure></div><p>First, it is important to distinguish between:</p><ul><li><p><strong>Instance-level methods</strong>, that provide explanations at the level of individual predictions</p></li><li><p><strong>Model-level approaches</strong>, that give explanations at the level of the whole model</p></li></ul><p>Let&#8217;s explore explanations at the instance level:</p><ul><li><p><strong>Gradient or features-based methods: </strong>They rely on the gradients or hidden feature maps to approximate input importance. Gradients-based approaches compute the gradients of target prediction with respect to input features by back-propagation whereas feature-based methods map the hidden features to the input space via interpolation to measure importance scores. In this context, larger gradients or feature values mean higher importance.</p></li><li><p><strong>Perturbation-based methods: </strong>They examine the variation in the model predictions with respect to different input perturbations. This is done by masking nodes or edges and observing the results for instance. Intuitively, predictions remain the same when important input information is kept.</p></li><li><p><strong>Decomposition methods: </strong>They decompose prediction into the input space. Layer by layer the output is transferred back until the input layer is reached. The values then indicate which of the inputs had the highest importance on the outputs.</p></li><li><p><strong>Surrogate: </strong>Train a simple and interpretable surrogate model to approximate the predictions of the model in the neighboring area of the input.</p></li></ul><h3><strong>3.2. Application of GNNExplainer to the Use Case</strong></h3><p>GNNExplainer falls into the category of perturbation-based methods.</p><p>Without going into technical details, it basically consists of learning soft masks for edges and node features. To do so, it starts by randomly initializing soft masks and combining them with the original graph via element-wise multiplications. Then, the masks are optimized by maximizing the mutual information between the predictions of the original graph and the predictions of the newly obtained graph.</p><p>More information is available in the original paper [<a href="https://arxiv.org/abs/1903.03894">6</a>].</p><p>Figure 11 shows the explanations obtained for a molecule of the test set. The more the links between the atoms tend towards the red, the more they played an important role in the prediction.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZnzW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZnzW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png 424w, https://substackcdn.com/image/fetch/$s_!ZnzW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png 848w, https://substackcdn.com/image/fetch/$s_!ZnzW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png 1272w, https://substackcdn.com/image/fetch/$s_!ZnzW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZnzW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png" width="916" height="348" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:348,&quot;width&quot;:916,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ZnzW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png 424w, https://substackcdn.com/image/fetch/$s_!ZnzW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png 848w, https://substackcdn.com/image/fetch/$s_!ZnzW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png 1272w, https://substackcdn.com/image/fetch/$s_!ZnzW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb34130b-80eb-432e-b08b-83f27931f2e5_916x348.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AIcr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AIcr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png 424w, https://substackcdn.com/image/fetch/$s_!AIcr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png 848w, https://substackcdn.com/image/fetch/$s_!AIcr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png 1272w, https://substackcdn.com/image/fetch/$s_!AIcr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AIcr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png" width="918" height="590" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:590,&quot;width&quot;:918,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!AIcr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png 424w, https://substackcdn.com/image/fetch/$s_!AIcr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png 848w, https://substackcdn.com/image/fetch/$s_!AIcr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png 1272w, https://substackcdn.com/image/fetch/$s_!AIcr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1c0a1fc-354a-46c2-b0ef-735c44f57e3a_918x590.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 11 &#8212; Explanations obtained for a given prediction using GNNExplainer</figcaption></figure></div><p>Strong knowledge of organic chemistry is needed to investigate the consistency of the results. However, one might note that the presence of SO2 was detected as important. This is the formula of sulfur dioxide which is a chemical compound known to be toxic.</p><div><hr></div><h2><strong>Key Takeaways</strong></h2><p>&#10004; Graph Neural Networks, GNNs, can be used to classify entire graphs. The idea is similar to node classification or link prediction: <strong>learning an embedding of graphs</strong> (instead of nodes) using the structural properties of these graphs.</p><p>&#10004; When it comes to understanding the outcome of a model for a given instance, many approaches exist. They can rely on the gradient or features, use perturbation techniques, decompose the outcome, or use surrogate models.</p><p>&#10004; &#65039;The real-life applications are multiple. This article was about the detection of the toxicity of molecules. Predicting other molecular properties lends itself well to this graph-based approach.</p><p>&#10004; &#65039;However, biology is not the only industry. It can be used for instance in the retail industry: this <a href="https://medium.com/stanford-cs224w/buy-this-session-based-recommendation-using-sr-gnn-d3415e393722">article</a> explains how GNNs can be applied to generate recommendations based on the graph of users&#8217; sessions.</p><div><hr></div><h2><strong>References</strong></h2><p>[1] M.S. Attene-Ramos et al., <a href="https://www.sciencedirect.com/referencework/9780123864550/encyclopedia-of-toxicology">Encyclopedia of Toxicology (Third Edition)</a>, 2014</p><p>[2] <a href="https://pytorch-geometric.readthedocs.io/en/latest/notes/colabs.html">Pytorch Geometric tutorials</a>, <a href="https://colab.research.google.com/drive/1I8a0DfQ3fI7Njc62__mVXUlcAleUclnb?usp=sharing">Graph Classification</a></p><p>[3] Tong Ying Shun, John S. Lazo, Elizabeth R. Sharlow, Paul A. Johnston, <em><a href="https://journals.sagepub.com/doi/10.1177/1087057110389039?url_ver=Z39.88-2003&amp;rfr_id=ori%3Arid%3Acrossref.org&amp;rfr_dat=cr_pub++0pubmed">Identifying Actives from HTS Data Sets: Practical Approaches for the Selection of an Appropriate HTS Data-Processing Method and Quality Control Review</a></em>. J. Biomol. Screen. 2010</p><p>[4] Evan N. Feinberg, et al, <em><a href="https://arxiv.org/abs/1703.00564">MoleculeNet: A Benchmark for Molecular Machine Learning, Zhenqin Wu, Bharath Ramsundar</a></em>, March 2017</p><p>[5] Hao Yuan, Haiyang Yu, Shurui Gui, Shuiwang Ji,<em> <a href="https://arxiv.org/abs/2012.15445">Explainability in Graph Neural Networks: A Taxonomic Survey</a></em>, December 2020</p><p>[<a href="https://arxiv.org/abs/1903.03894">6</a>] Rex Ying, Dylan Bourgeois, Jiaxuan You, Marinka Zitnik, Jure Leskovec, <em><a href="https://arxiv.org/abs/1903.03894">GNNExplainer: Generating Explanations for Graph Neural Networks</a></em>, March 2019</p><p>[7] <a href="http://web.stanford.edu/class/cs224w/">CS224W: Machine Learning with Graphs</a>, Standford</p>]]></content:encoded></item><item><title><![CDATA[Graph Neural Networks: Link Prediction (Part II)]]></title><description><![CDATA[When It Comes to Forecasting Connections Within a Network]]></description><link>https://aipractitioner.substack.com/p/graph-neural-networks-link-prediction</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/graph-neural-networks-link-prediction</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 07 Jul 2022 18:44:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zgxq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.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="https://substackcdn.com/image/fetch/$s_!zgxq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zgxq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zgxq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zgxq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zgxq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zgxq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg" width="1400" height="584" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:584,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zgxq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zgxq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zgxq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zgxq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e698a-5def-4b5c-b354-fee86617582d_1400x584.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As many real-world problems can naturally be modeled as a network of nodes and edges, Graphical Neural Networks (GNNs) provide a powerful approach to solve them. By leveraging this inherent structure, they can learn more efficiently and solve complex problems where standard machine learning algorithms fail.</p><p>In this context, the <a href="https://medium.com/data-from-the-trenches/graph-neural-networks-merging-deep-learning-with-graphs-part-i-57694ca5be">first article</a> of this series on GNNs discusses the benefits of such models when it comes to classifying entities in a network or predicting a continuous attribute.</p><p><strong>But what if the task to be solved is about predicting the existence of a relationship between entities or a characteristic of this relationship?</strong></p><p>Real-life examples are abundant:</p><ul><li><p>Retailers are interested in predicting the satisfaction score that consumers would give to their products in order to improve their recommendation tool.</p></li><li><p>Social networks would find it useful to predict the likelihood that two users connect to improve their suggestions and ultimately help each of them expand your network.</p></li><li><p>Chemists study the existence of interactions between molecules in order to discover new drugs or to avoid unexpected side effects when taking several drugs.</p></li></ul><p>The previous article only considers homogeneous graphs, that is, graphs with a single type of node. <strong>What if the network contains different types of entities?</strong> For instance, in their modeling, retailers need to account for customers and products as different types of nodes, social networks users and content, etc. This type of graph is commonly called a heterogeneous graph.</p><h3><strong>Objective</strong></h3><p>This article focuses on building GNN models for link prediction tasks for heterogeneous graphs.</p><p>To illustrate these concepts, I rely on the use case of recommendation. More specifically, predict the rating that users will give to a movie. I also discuss the benefits of using graph-based models by comparing them to a more traditional approach, collaborative filtering.</p><p>After reading this article, you will understand:</p><ol><li><p>What is SAGEGraph and to what extent does it improve the GCN approach?</p></li><li><p>How is link prediction performed using GNNs models?</p></li><li><p>How can GNNs models be applied to real-world problems?</p></li></ol><blockquote><p><em>This article is the second part of three-part series that aims to provide a comprehensive overview of the most common applications of GNN models to real-world problems. While the second focuses on link prediction, the two others tackle respectively node classification and graph classification.</em></p><p><em>This article assumes minimal knowledge of GNNs (you can refer to the <a href="https://medium.com/data-from-the-trenches/graph-neural-networks-merging-deep-learning-with-graphs-part-i-57694ca5be">first article</a> of the series). The experimentations described in the article were carried out using the libraries <a href="https://pytorch-geometric.readthedocs.io/en/latest/">PyTorch Geometric</a>, <a href="https://surprise.readthedocs.io/en/stable/">Surprise</a>, and <a href="https://plotly.com/python/">Plotly</a>.</em></p></blockquote><p>You can find the code <a href="https://github.com/linafaik08/graph_neural_networks/blob/main/2_link_prediction.ipynb">here</a> on GitHub.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>1. Link Prediction Model: What&#8217;s Under the Hood?</strong></h2><p>Before getting into the use case, let&#8217;s start with some theory.</p><p>First, we introduce the GNN layer used, GraphSAGE. Then, we show how the GNN model can be extended to deal with heterogeneous graphs. Finally, we discuss possible approaches that use node embeddings for link prediction.</p><h3><strong>1.1. GraphSAGE</strong></h3><p>A first natural question is: <strong>Why shift from standard GCN to GraphSAGE?</strong></p><p>GCNs suffer from several issues caused by their very learning framework:</p><ol><li><p><strong>Difficulties in learning from large networks: </strong>GCNs require the presence of all the nodes during the training of the embeddings. This does not allow the model to be trained in batches.</p></li><li><p><strong>Difficulties to generalize to unseen nodes: </strong>GCNs assumes a single fixed graph. But, in many real-world applications, the embeddings of unseen nodes need to be quickly generated (e.g., posts on Twitter, videos on YouTube, etc.)</p></li></ol><p>As a result, GCNs are not very practical, limited in terms of memory when handling large networks, and even not suitable for some cases.</p><p>GraphSAGE overcomes the previous challenges while relying on the same mathematical principles as GCNs. It provides a general inductive framework that is able to generate node embeddings for new nodes.</p><p>Introduced by the paper <em>Inductive Representation Learning on Large Graphs</em> [<a href="https://arxiv.org/pdf/1706.02216.pdf">1</a>] in 2017, GraphSAGE, which stands for Graph SAmpling and AggreGatE, has made a significant contribution to the GNN research area.</p><p><strong>So how does GraphSAGE work concretely?</strong></p><p>Rather than training individual embeddings for each node, the model learns a function that generates embeddings by sampling and aggregating the features of the local neighborhood of a node.</p><p>At each iteration, the model follows two different steps:</p><ol><li><p><strong>Sample</strong>: Instead of using the entire neighborhood of a given node, the model uniformly samples a fixed-size set of neighbors.</p></li><li><p><strong>Aggregate</strong>: Nodes aggregate information from their local neighbors as shown in the equation below. In the original paper [<a href="https://arxiv.org/pdf/1706.02216.pdf">1</a>], three aggregation functions are considered:</p></li></ol><ul><li><p><strong>Mean aggregator:<br></strong>It consists in taking the average of the vectors of the neighboring nodes.<br>Simple and efficient, this approach has led to good performances in the experiments carried out in the research paper. It is the one that has been retained in the application below.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FUbY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FUbY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png 424w, https://substackcdn.com/image/fetch/$s_!FUbY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png 848w, https://substackcdn.com/image/fetch/$s_!FUbY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png 1272w, https://substackcdn.com/image/fetch/$s_!FUbY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FUbY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png" width="1334" height="78" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:78,&quot;width&quot;:1334,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;mean aggregator&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="mean aggregator" title="mean aggregator" srcset="https://substackcdn.com/image/fetch/$s_!FUbY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png 424w, https://substackcdn.com/image/fetch/$s_!FUbY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png 848w, https://substackcdn.com/image/fetch/$s_!FUbY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png 1272w, https://substackcdn.com/image/fetch/$s_!FUbY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff160b837-281d-480d-9b0a-bd68d0c05e19_1334x78.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ul><li><p><strong>LSTM aggregator:<br></strong>This aggregator has the potential to benefit from the greater expressive capabilities of the LTSMs architecture. To adapt it to graphs that have no natural order, the aggregator is applied to a random permutation of the node&#8217;s neighbors.</p></li><li><p><strong>Pooling aggregator:<br></strong>It consists in feeding a fully connected neural network with the vector of each neighbor. After this transformation, a maximum pooling operation per element is applied to aggregate the information on all the neighbors.<br>It has yielded very good results in the experiments with the paper.</p></li></ul><p>These steps are repeated for all nodes K times (usually K= 2 is enough). Therefore, as these steps are repeated for all nodes, nodes gradually acquire more and more information from more distant areas of the graph. The figure below illustrates the process for K=2.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EJDr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EJDr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png 424w, https://substackcdn.com/image/fetch/$s_!EJDr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png 848w, https://substackcdn.com/image/fetch/$s_!EJDr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png 1272w, https://substackcdn.com/image/fetch/$s_!EJDr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EJDr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png" width="1400" height="487" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df78a501-4185-4526-a888-5cf1b33410a1_1400x487.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:487,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 1&#8202;&#8212;&#8202;Illustration of GraphSAGE approach, illustration by Lina Faik, inspired by [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="Figure 1&#8202;&#8212;&#8202;Illustration of GraphSAGE approach, illustration by Lina Faik, inspired by [1]" title="Figure 1&#8202;&#8212;&#8202;Illustration of GraphSAGE approach, illustration by Lina Faik, inspired by [1]" srcset="https://substackcdn.com/image/fetch/$s_!EJDr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png 424w, https://substackcdn.com/image/fetch/$s_!EJDr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png 848w, https://substackcdn.com/image/fetch/$s_!EJDr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png 1272w, https://substackcdn.com/image/fetch/$s_!EJDr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf78a501-4185-4526-a888-5cf1b33410a1_1400x487.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Illustration of GraphSAGE approach, illustration by Lina Faik, inspired by [<a href="https://arxiv.org/pdf/1706.02216.pdf">1</a>]</figcaption></figure></div><p>Note that the weights used in the aggregation step are not specific to a node but only specific to iteration <em>k</em>. Therefore, they are shared by all the neighborhoods making generalization to unseen nodes possible.</p><p><strong>To sum up, you can consider GraphSAGE as a GCN with subsampled neighbors.</strong></p><h3><strong>1.2. Heterogeneous Graphs</strong></h3><p>Consider movie recommendations, as illustrated in the figure below.</p><p><strong>Goal</strong>: Predict the rating that a given user is likely to give to the most recent movies. This prediction would then be used to suggest the most relevant movie.</p><p><strong>Modeling</strong>: The problem can be modeled as a graph with two types of nodes: one representing users and the other movies. A user node is linked to the movie node if the user has rated the movie and is labeled with the rating.</p><p><strong>Task</strong>: Under this modeling, the problem becomes a link prediction task where the goal is to predict the label (rating) of a link between a user node and a movie node.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fv7u!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fv7u!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png 424w, https://substackcdn.com/image/fetch/$s_!fv7u!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png 848w, https://substackcdn.com/image/fetch/$s_!fv7u!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png 1272w, https://substackcdn.com/image/fetch/$s_!fv7u!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fv7u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png" width="1400" height="1319" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1319,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 2&#8202;&#8212;&#8202;Modeling the recommendation problem as a link prediction task, illustration by Lina Faik&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="Figure 2&#8202;&#8212;&#8202;Modeling the recommendation problem as a link prediction task, illustration by Lina Faik" title="Figure 2&#8202;&#8212;&#8202;Modeling the recommendation problem as a link prediction task, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!fv7u!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png 424w, https://substackcdn.com/image/fetch/$s_!fv7u!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png 848w, https://substackcdn.com/image/fetch/$s_!fv7u!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png 1272w, https://substackcdn.com/image/fetch/$s_!fv7u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70858e9d-7990-4dde-a4e9-bb6fe00163e2_1400x1319.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2 &#8212; Modeling the recommendation problem as a link prediction task, illustration by Lina Faik</figcaption></figure></div><p>In this context, the GNN model needs to be able to simultaneously learn embeddings for the user and movie nodes.</p><p>To do this, one solution would be to take the GNN model compatible with a homogeneous graph and duplicate the message functions to work on each edge type individually. This process is detailed in the following figure.</p><blockquote><p><em>This is the default architecture implemented in PyTorch Geometric. More precisely, the library provides an automatic converter that transforms any GNN model into a model compatible with heterogeneous graphs. The library also allows to build GNNs for heterogeneous graphs from scratch with custom heterogenous message and update functions. More information can be found <a href="https://pytorch-geometric.readthedocs.io/en/latest/notes/heterogeneous.html">here</a>.</em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5KRE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5KRE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png 424w, https://substackcdn.com/image/fetch/$s_!5KRE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png 848w, https://substackcdn.com/image/fetch/$s_!5KRE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png 1272w, https://substackcdn.com/image/fetch/$s_!5KRE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5KRE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png" width="1400" height="1038" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1038,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 3- Conversion of a regular GNN model to a GNN model adapted to heterogeneous graphs, illustration by Lina Faik, inspired by [3]&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="Figure 3- Conversion of a regular GNN model to a GNN model adapted to heterogeneous graphs, illustration by Lina Faik, inspired by [3]" title="Figure 3- Conversion of a regular GNN model to a GNN model adapted to heterogeneous graphs, illustration by Lina Faik, inspired by [3]" srcset="https://substackcdn.com/image/fetch/$s_!5KRE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png 424w, https://substackcdn.com/image/fetch/$s_!5KRE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png 848w, https://substackcdn.com/image/fetch/$s_!5KRE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png 1272w, https://substackcdn.com/image/fetch/$s_!5KRE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710af2d2-d687-47b6-ad97-7adb2236c86f_1400x1038.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3&#8212; Conversion of a regular GNN model to a GNN model adapted to heterogeneous graphs, illustration by Lina Faik, inspired by [<a href="https://pytorch-geometric.readthedocs.io/en/latest/notes/heterogeneous.html">3</a>]</figcaption></figure></div><h3><strong>1.3. Link Prediction</strong></h3><p>The previous model allows us to train a model capable of generating the embedding of two nodes of different types.</p><p><strong>How can these embeddings be used for link prediction?</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4oWc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4oWc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png 424w, https://substackcdn.com/image/fetch/$s_!4oWc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png 848w, https://substackcdn.com/image/fetch/$s_!4oWc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png 1272w, https://substackcdn.com/image/fetch/$s_!4oWc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4oWc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png" width="1400" height="764" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:764,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 4&#8202;&#8212;&#8202;Modeling the recommendation problem as a link prediction task, illustration by Lina Faik&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="Figure 4&#8202;&#8212;&#8202;Modeling the recommendation problem as a link prediction task, illustration by Lina Faik" title="Figure 4&#8202;&#8212;&#8202;Modeling the recommendation problem as a link prediction task, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!4oWc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png 424w, https://substackcdn.com/image/fetch/$s_!4oWc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png 848w, https://substackcdn.com/image/fetch/$s_!4oWc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png 1272w, https://substackcdn.com/image/fetch/$s_!4oWc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43df6bfe-06d1-4c06-832a-af25826fec28_1400x764.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4 &#8212; Modeling the recommendation problem as a link prediction task, illustration by Lina Faik</figcaption></figure></div><p>There are two options:</p><p><strong>Option 1.</strong> Train an additional linear model that takes (as an input) the concatenation of the user and movie embeddings to predict the rating. This is the approach implemented in the application part below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TM76!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TM76!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png 424w, https://substackcdn.com/image/fetch/$s_!TM76!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png 848w, https://substackcdn.com/image/fetch/$s_!TM76!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png 1272w, https://substackcdn.com/image/fetch/$s_!TM76!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TM76!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png" width="1400" height="659" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:659,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 5&#8202;&#8212;&#8202;From node embeddings to link prediction (option 1), illustration by Lina Faik&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="Figure 5&#8202;&#8212;&#8202;From node embeddings to link prediction (option 1), illustration by Lina Faik" title="Figure 5&#8202;&#8212;&#8202;From node embeddings to link prediction (option 1), illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!TM76!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png 424w, https://substackcdn.com/image/fetch/$s_!TM76!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png 848w, https://substackcdn.com/image/fetch/$s_!TM76!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png 1272w, https://substackcdn.com/image/fetch/$s_!TM76!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65358b61-733c-4fed-ba37-0b3cb75e25f0_1400x659.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 5 &#8212; From node embeddings to link prediction (option 1), illustration by Lina Faik</figcaption></figure></div><p><strong>Option 2.</strong> The other alternative consists of either:</p><ul><li><p>Computing a simple dot product, provided that the dimensions of both embeddings are the same and that the output is one-dimensional (e.g., predict whether the link exists or not):</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sJp0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sJp0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png 424w, https://substackcdn.com/image/fetch/$s_!sJp0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png 848w, https://substackcdn.com/image/fetch/$s_!sJp0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png 1272w, https://substackcdn.com/image/fetch/$s_!sJp0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sJp0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png" width="1120" height="84" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/be707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:84,&quot;width&quot;:1120,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;simple dot product computation&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="simple dot product computation" title="simple dot product computation" srcset="https://substackcdn.com/image/fetch/$s_!sJp0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png 424w, https://substackcdn.com/image/fetch/$s_!sJp0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png 848w, https://substackcdn.com/image/fetch/$s_!sJp0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png 1272w, https://substackcdn.com/image/fetch/$s_!sJp0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe707be7-251f-4d09-8bca-711b48d65ad5_1120x84.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ul><li><p>Learning a trainable matrix <em>W = (W&#185;, &#8230;, W^k)</em> so that:</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qy1Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qy1Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png 424w, https://substackcdn.com/image/fetch/$s_!Qy1Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png 848w, https://substackcdn.com/image/fetch/$s_!Qy1Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png 1272w, https://substackcdn.com/image/fetch/$s_!Qy1Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qy1Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png" width="1198" height="76" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:76,&quot;width&quot;:1198,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;learning a trainable matrix&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="learning a trainable matrix" title="learning a trainable matrix" srcset="https://substackcdn.com/image/fetch/$s_!Qy1Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png 424w, https://substackcdn.com/image/fetch/$s_!Qy1Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png 848w, https://substackcdn.com/image/fetch/$s_!Qy1Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png 1272w, https://substackcdn.com/image/fetch/$s_!Qy1Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d20e250-c0d8-4898-87d5-d8b115af938c_1198x76.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>You can find here the final code of the GNN model:</p><h2><strong>2. Application to Recommender Systems</strong></h2><p>This section describes the methodology used and discussed the results.</p><h3><strong>2.1. Methodology</strong></h3><p>&#10004;&#65039; <strong>Data</strong></p><p>The data consists of the heterogeneous rating dataset, assembled by GroupLens Research from the <a href="https://movielens.org/">MovieLens website</a>. It contains two types of nodes: &#8220;user&#8221; and &#8220;movie.&#8221; A user node is linked to a movie node if he has rated the movie. The link is then labeled with the rating he gave.</p><p>Here is a short description of the data:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OrIw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OrIw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png 424w, https://substackcdn.com/image/fetch/$s_!OrIw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png 848w, https://substackcdn.com/image/fetch/$s_!OrIw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png 1272w, https://substackcdn.com/image/fetch/$s_!OrIw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OrIw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png" width="1400" height="448" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:448,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;description of the data&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="description of the data" title="description of the data" srcset="https://substackcdn.com/image/fetch/$s_!OrIw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png 424w, https://substackcdn.com/image/fetch/$s_!OrIw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png 848w, https://substackcdn.com/image/fetch/$s_!OrIw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png 1272w, https://substackcdn.com/image/fetch/$s_!OrIw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb90913b-ef89-4d6e-a9c9-3554ce331cdd_1400x448.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>&#10004;&#65039; Model evaluation</strong></p><p>As shown in Figure 5, users tend to give ratings between 3 and 4 more frequently than other ratings. To this into account when training and evaluating the model, a weight is associated with each rating as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Jb4R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jb4R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png 424w, https://substackcdn.com/image/fetch/$s_!Jb4R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png 848w, https://substackcdn.com/image/fetch/$s_!Jb4R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png 1272w, https://substackcdn.com/image/fetch/$s_!Jb4R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Jb4R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png" width="990" height="134" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:134,&quot;width&quot;:990,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;model evaluation formula&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="model evaluation formula" title="model evaluation formula" srcset="https://substackcdn.com/image/fetch/$s_!Jb4R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png 424w, https://substackcdn.com/image/fetch/$s_!Jb4R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png 848w, https://substackcdn.com/image/fetch/$s_!Jb4R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png 1272w, https://substackcdn.com/image/fetch/$s_!Jb4R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d7209f-565b-43eb-999d-f4f2c8f7dc30_990x134.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>where <em>c_k </em>is the number of occurrences of the rating <em>k</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7ZWS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7ZWS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png 424w, https://substackcdn.com/image/fetch/$s_!7ZWS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png 848w, https://substackcdn.com/image/fetch/$s_!7ZWS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png 1272w, https://substackcdn.com/image/fetch/$s_!7ZWS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7ZWS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png" width="1400" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:608,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 6&#8202;&#8212;&#8202;Distribution of the ratings and associated weights, illustration by Lina Faik&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="Figure 6&#8202;&#8212;&#8202;Distribution of the ratings and associated weights, illustration by Lina Faik" title="Figure 6&#8202;&#8212;&#8202;Distribution of the ratings and associated weights, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!7ZWS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png 424w, https://substackcdn.com/image/fetch/$s_!7ZWS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png 848w, https://substackcdn.com/image/fetch/$s_!7ZWS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png 1272w, https://substackcdn.com/image/fetch/$s_!7ZWS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F879280f3-d70c-4f49-b168-795bbb12f354_1400x608.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 6 &#8212; Distribution of the ratings and associated weights, illustration by Lina Faik</figcaption></figure></div><p>In this context, the RMSE is weighted as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dOMw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dOMw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png 424w, https://substackcdn.com/image/fetch/$s_!dOMw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png 848w, https://substackcdn.com/image/fetch/$s_!dOMw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png 1272w, https://substackcdn.com/image/fetch/$s_!dOMw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dOMw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png" width="1036" height="154" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:154,&quot;width&quot;:1036,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;RMSE weighted&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="RMSE weighted" title="RMSE weighted" srcset="https://substackcdn.com/image/fetch/$s_!dOMw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png 424w, https://substackcdn.com/image/fetch/$s_!dOMw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png 848w, https://substackcdn.com/image/fetch/$s_!dOMw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png 1272w, https://substackcdn.com/image/fetch/$s_!dOMw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb833ddca-d2b0-4f27-9734-5fe1494d76af_1036x154.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>&#10004;&#65039; Learning framework</strong></p><p>The data is divided into three:</p><ul><li><p>Training set (80%)</p></li><li><p>Validation set (20%) used to choose the best combination of the model hyperparameters</p></li><li><p>Test set (10%) used to compare the performance of the models</p></li></ul><p>In order to measure the robustness of the results, the splitting was repeated five times. The graphs show the mean and the variance of the values.</p><h3><strong>2.2. Benchmark</strong></h3><p>Using this methodology, two different GNN models were tested, one using SAGEConv and the other GATConv.</p><p>To assess the performance of those graph-based models, the results are compared with a na&#239;ve algorithm and <strong>collaborative filtering</strong> standard models either based on KNN or matrix factorization.</p><p><strong>1. A na&#239;ve algorithm:</strong> It draws random values from a normal distribution whose parameters &#956; and &#963;, are the ratings mean and standard deviation.</p><p><strong>2. KNN-based algorithms</strong></p><ul><li><p>It consists of computing the similarities between users (or movies) based on the ratings they previously gave (or received).</p></li><li><p>The rating a user would give to a movie is then predicted as a weighted average of the ratings of the <em>K</em> most similar users (or movies) as follows:</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ik5X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ik5X!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png 424w, https://substackcdn.com/image/fetch/$s_!ik5X!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png 848w, https://substackcdn.com/image/fetch/$s_!ik5X!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png 1272w, https://substackcdn.com/image/fetch/$s_!ik5X!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ik5X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png" width="1004" height="194" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:194,&quot;width&quot;:1004,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The rating a user would give to a movie is then predicted as a weighted average of the ratings of the K most similar users (or movies)&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="The rating a user would give to a movie is then predicted as a weighted average of the ratings of the K most similar users (or movies)" title="The rating a user would give to a movie is then predicted as a weighted average of the ratings of the K most similar users (or movies)" srcset="https://substackcdn.com/image/fetch/$s_!ik5X!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png 424w, https://substackcdn.com/image/fetch/$s_!ik5X!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png 848w, https://substackcdn.com/image/fetch/$s_!ik5X!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png 1272w, https://substackcdn.com/image/fetch/$s_!ik5X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6152cd51-f07c-4dc3-bd9d-b6d18a166cd9_1004x194.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ul><li><p>Other variants of this model exist as well. For more information about the implementation, you can read the library doc about <a href="https://surprise.readthedocs.io/en/stable/knn_inspired.html">KNN-based algorithms</a> and <a href="https://surprise.readthedocs.io/en/stable/similarities.html">similarity metrics</a>.</p></li></ul><p><strong>3. Matrix factorization-based algorithms: Singular Value Decomposition (SVD)</strong></p><ul><li><p>The model relies on a double-entry matrix representation of the problem: The rows correspond to the users, the columns to the movies, and the values are the ratings that the users have attributed to the movies.</p></li><li><p>The model is then used to shrink the space dimension and thus reduce the number of features. In order words, they manage to map each user and each movie into a smaller dimensional latent space.</p></li><li><p>The algorithm minimizes then a loss function which is the square error difference between the product of the user and movie new vectors and the true rating. Regularization terms can be also added to avoid overfitting issues.</p></li></ul><p>For more information about the implementation, you can read the library documentation about <a href="https://surprise.readthedocs.io/en/stable/matrix_factorization.html#surprise.prediction_algorithms.matrix_factorization.SVD">SVD</a> and <a href="https://surprise.readthedocs.io/en/stable/matrix_factorization.html#surprise.prediction_algorithms.matrix_factorization.SVDpp">SVD++</a>.</p><h3><strong>2.3. Results</strong></h3><p>The results are presented below. For the sake of readability, only the best variants of each model were kept: <a href="https://surprise.readthedocs.io/en/stable/knn_inspired.html#surprise.prediction_algorithms.knns.KNNWithZScore">KNN with Zcore</a> for the KNN-based model and <a href="https://surprise.readthedocs.io/en/stable/matrix_factorization.html#surprise.prediction_algorithms.matrix_factorization.SVD">SVD</a> for matrix factorization-based algorithms.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cHTZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cHTZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png 424w, https://substackcdn.com/image/fetch/$s_!cHTZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png 848w, https://substackcdn.com/image/fetch/$s_!cHTZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png 1272w, https://substackcdn.com/image/fetch/$s_!cHTZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cHTZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png" width="1400" height="497" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a9977cdf-c540-4638-826a-938131aaa238_1400x497.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:497,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!cHTZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png 424w, https://substackcdn.com/image/fetch/$s_!cHTZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png 848w, https://substackcdn.com/image/fetch/$s_!cHTZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png 1272w, https://substackcdn.com/image/fetch/$s_!cHTZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9977cdf-c540-4638-826a-938131aaa238_1400x497.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 7 &#8212; Performance of the models in terms of weighted RMSE</figcaption></figure></div><p>The results show that graph-based models perform better than SVD. SVD tends to overfit the data and is therefore not able to generalize well.</p><p>Note also that there are no significant differences between GAT and GraphSAGE convolutions. The main reason is that GAT learns to give more or less weight to the neighbors of each node and is therefore somehow similar to the sampling strategy of GraphSAGE.</p><p>Nevertheless, GATs have also several issues compared GraphSAGE as mentioned in the first section. Among them is the fact that they are a full-batch model, they need to be trained on the whole dataset. Moreover, the attention weights are specific to each node which prevent GATs from generalizing to unseen nodes.</p><div><hr></div><h2><strong>3. Key Takeaways</strong></h2><p>&#10004;&#65039; GraphSAGE convolutions provide a general inductive framework that relies on the same mathematical principles as GCNs but with a sampling mechanism. This enables GraphSAGE to efficiently generate node embeddings on large graphs or / and fast-evolving graphs.</p><p>&#10004;&#65039; Working with heterogeneous graphs brings an additional layer of complexity. A solution would be to take the GNN model used for homogeneous graphs and duplicate the message functions to work on each edge type individually as shown in Figure 3.</p><p>&#10004;&#65039; Link prediction refers to the task of predicting the existence or a characteristic of the relationship between entities within a network. To do so using a graph-based model, one option is to train a linear model that takes as input the concatenation of embeddings.</p><p>&#10004;&#65039; The application to the use case of movie recommendation shows that graph-based models perform better than the well-established collaborative filtering approach, SVD.</p><div><hr></div><h2><strong>References</strong></h2><p>[1] W. Hamilton et al., <a href="https://arxiv.org/pdf/1706.02216.pdf">Inductive Representation Learning on Large Graphs</a>, Stanford University, 2018</p><p>[2] W. Hamilton, <em><a href="https://www.cs.mcgill.ca/~wlh/grl_book/files/GRL_Book.pdf">Graph Representation Learning</a></em>, McGill University, 2020</p><p>[3] Pytorch Geometric, <a href="https://pytorch-geometric.readthedocs.io/en/latest/notes/heterogeneous.html">Heterogeneous Graph Learning,</a></p><p>[3] Z. Wu et al., <em><a href="https://arxiv.org/abs/1901.00596">A Comprehensive Survey on Graph Neural Networks</a></em>, January 2019</p><p>[4] <a href="http://web.stanford.edu/class/cs224w/">CS224W: Machine Learning with Graphs</a>, Standford</p>]]></content:encoded></item><item><title><![CDATA[Graph Neural Networks: Merging Deep Learning With Graphs (Part I)]]></title><description><![CDATA[When It Comes to Node Classification]]></description><link>https://aipractitioner.substack.com/p/graph-neural-networks-merging-deep</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/graph-neural-networks-merging-deep</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 28 Apr 2022 18:40:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-ew4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.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="https://substackcdn.com/image/fetch/$s_!-ew4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-ew4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-ew4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-ew4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-ew4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-ew4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg" width="1400" height="584" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:584,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-ew4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-ew4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-ew4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-ew4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23d6adb8-a4f3-4b36-9e75-c9dab2a01fc2_1400x584.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Recently, <strong>Graph Neural Networks (GNNs)</strong> have received a lot of attention. From marketing to social science to biology, they have been widely promoted as the new way of learning &#8220;smartly&#8221; from data. It&#8217;s more than a trend, though, as many research papers have proven that they can actually lead to more accurate and robust models.</p><p>What could possibly explain this? This is certainly due to their ability to combine graphical representation learning (which is used today for a wider variety of use cases) with the predictive power of deep learning models.</p><h3><strong>Objective</strong></h3><p>This article is the first part of three-part series that aims to provide a comprehensive overview of the most common applications of GNN models to real-world problems.</p><p>While the first focuses on node classification, the two others tackle link prediction and graph classification, respectively.</p><p>After reading this article, you will understand:</p><ol><li><p>What is graphical representation learning all about?</p></li><li><p>What are the main mechanisms hidden under GNNs models?</p></li><li><p>How can they be applied to real-world classification problems?</p></li></ol><blockquote><p><em>The experimentations described in the article were carried out using the libraries <a href="https://pytorch-geometric.readthedocs.io/en/latest/">PyTorch Geometric</a>, <a href="https://networkx.org/">NetworkX</a>, <a href="https://igraph.org/python/">igraph</a>, and <a href="https://plotly.com/python/">Plotly</a>.</em></p></blockquote><p>You can find the code <a href="https://github.com/linafaik08/graph_neural_networks/">here</a> on GitHub.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>1. Graphical Representation Learning: What Is It All About?</strong></h2><h3><strong>1.1. Motivation</strong></h3><p>The first question you are likely to ask yourself is why and when should you consider graphical representation learning to solve your use case?</p><p>Graphs provide a simple yet powerful tool to describe complex systems. In simple terms, it consists of representing a problem as a set of objects (nodes) along with a set of interactions (edges) between pairs of these objects.</p><p>Yet, the number of applications where data is represented in the form of graphs is important. Here are some examples:</p><ul><li><p><strong>Recommender Systems:</strong> In e-commerce, you can represent interactions between users and products graphically and use this knowledge to make more relevant personalized recommendations.</p></li><li><p><strong>Social Networks:</strong> By using a graph to describe the relationship between users, you can train a model to detect fake accounts.</p></li><li><p><strong>Transport</strong>: Networks can be visualized as a graph and used as inputs by models to accurately forecast traffic speed, volume, or density.</p></li><li><p><strong>Chemistry:</strong> Molecules are usually modeled as graphs. By using this representation, you can predict their bioactivity for drug discovery purposes.</p></li></ul><h3><strong>1.2. Benefits</strong></h3><p>The second question you might consider is: What do graph-based models bring to the table compared to &#8220;traditional&#8221; approaches?</p><p>The key advantage of using a graphical representation of a problem lies in its ability to represent both information about the points and relationships between nodes.</p><blockquote><p><em>To put it more concretely, let&#8217;s consider the case where you would like to classify products sold in a store. You would probably gather information about the products (description, price, brand, etc.) and use it as input to train a model. But what if this information is non-existent or too poor to build a robust model?</em></p><p><em>In this context, you can leverage the graphical aspect of the problem. Each product can be represented as a node and each pair of products frequently bought together can be linked. A graph-based model is then likely to perform better than a &#8220;traditional&#8221; machine learning algorithm, as it would learn not only from information about products but also from the relationships between them. In fact, instead of considering each product independently, it would leverage this additional information to detect valuable patterns.</em></p></blockquote><h3><strong>1.3. Prediction Tasks on Graphs</strong></h3><p>Before going further, it is important to distinguish between three main types of tasks for which graph-based models can be used for:</p><p><strong>Node-level tasks: Node classification and regression</strong></p><ul><li><p><strong>Goal</strong>: Predict a label, type, category, or attribute of a node.</p></li><li><p><strong>Example</strong>: Given a large social network with millions of users, detect fake accounts.</p></li></ul><p><strong>Edge-level tasks: Link prediction</strong></p><ul><li><p><strong>Goal</strong>: Given a set of nodes and an incomplete set of edges between these nodes, infer the missing edges.</p></li><li><p><strong>Example</strong>: Predict biological interactions between proteins.</p></li></ul><p><strong>Graph-level tasks: Graph classification, regression, and clustering</strong></p><ul><li><p><strong>Goal</strong>: Carry a classification, regression, or clustering task over entire graphs.</p></li><li><p><strong>Example</strong>: Given a graph representing the structure of a molecule, predict molecules&#8217; toxicity.</p></li></ul><p>In the rest of the article, I will focus on node classification.</p><h2><strong>2. Node Classification With GNN: What Performance Should You Expect?</strong></h2><h3><strong>2.1. Description of the Use Case</strong></h3><p>Imagine that you run a large online knowledge-sharing platform such as Wikipedia. Every day, thousands of scientific articles are published.</p><p>To help your readers easily navigate the platform and find the content they are interested in, you need to make sure that each article is classified into the right category quickly after its publication.</p><p>In this context, the problem can be modeled as a graph where each node represents an article and has as an attribute an embedding of the content. Two articles are linked if one of them contains a link to the other. The goal is to predict the category of new articles.</p><p>This is thus a typical node classification task!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nX_D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nX_D!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png 424w, https://substackcdn.com/image/fetch/$s_!nX_D!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png 848w, https://substackcdn.com/image/fetch/$s_!nX_D!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png 1272w, https://substackcdn.com/image/fetch/$s_!nX_D!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nX_D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png" width="1400" height="748" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:748,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 1&#8202;&#8212;&#8202;Graphical representation of the use case, illustration by Lina Faik&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="Figure 1&#8202;&#8212;&#8202;Graphical representation of the use case, illustration by Lina Faik" title="Figure 1&#8202;&#8212;&#8202;Graphical representation of the use case, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!nX_D!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png 424w, https://substackcdn.com/image/fetch/$s_!nX_D!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png 848w, https://substackcdn.com/image/fetch/$s_!nX_D!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png 1272w, https://substackcdn.com/image/fetch/$s_!nX_D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa91768c7-4532-491f-ae53-9415de96bd9b_1400x748.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Graphical representation of the use case, illustration by Lina Faik</figcaption></figure></div><p>The dataset I will be using for experiments is <em>Wiki-CS </em>from the paper <em><a href="https://arxiv.org/abs/2007.02901">Wiki-CS: A Wikipedia-Based Benchmark for Graph Neural Networks</a>. </em>It consists of nodes corresponding to computer science articles, with edges based on hyperlinks and 10 classes that represent different branches of the field. You can download it using PyTorch datasets <a href="https://pytorch-geometric.readthedocs.io/en/latest/_modules/torch_geometric/datasets/wikics.html">here</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E0F-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E0F-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png 424w, https://substackcdn.com/image/fetch/$s_!E0F-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png 848w, https://substackcdn.com/image/fetch/$s_!E0F-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png 1272w, https://substackcdn.com/image/fetch/$s_!E0F-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E0F-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png" width="1144" height="1006" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1006,&quot;width&quot;:1144,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 2&#8202;&#8212;&#8202;Projection of a subset of the graph, illustration by Lina Faik&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="Figure 2&#8202;&#8212;&#8202;Projection of a subset of the graph, illustration by Lina Faik" title="Figure 2&#8202;&#8212;&#8202;Projection of a subset of the graph, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!E0F-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png 424w, https://substackcdn.com/image/fetch/$s_!E0F-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png 848w, https://substackcdn.com/image/fetch/$s_!E0F-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png 1272w, https://substackcdn.com/image/fetch/$s_!E0F-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38bae4d8-d3ad-4e0b-b781-48e86ae873b5_1144x1006.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2 &#8212; Projection of a subset of the graph, illustration by Lina Faik</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HTFP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HTFP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png 424w, https://substackcdn.com/image/fetch/$s_!HTFP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png 848w, https://substackcdn.com/image/fetch/$s_!HTFP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png 1272w, https://substackcdn.com/image/fetch/$s_!HTFP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HTFP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png" width="1282" height="444" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:444,&quot;width&quot;:1282,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 3&#8202;&#8212;&#8202;Basic information and statistics about the graph, illustration by Lina Faik&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="Figure 3&#8202;&#8212;&#8202;Basic information and statistics about the graph, illustration by Lina Faik" title="Figure 3&#8202;&#8212;&#8202;Basic information and statistics about the graph, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!HTFP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png 424w, https://substackcdn.com/image/fetch/$s_!HTFP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png 848w, https://substackcdn.com/image/fetch/$s_!HTFP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png 1272w, https://substackcdn.com/image/fetch/$s_!HTFP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6271a5b-b6e8-4bdf-8c18-092ba28ba281_1282x444.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3 &#8212; Basic information and statistics about the graph, illustration by Lina Faik</figcaption></figure></div><p><strong>Challenges</strong></p><p>The nature of graph data poses a real challenge to existing deep learning models. Why?</p><ul><li><p><strong>Non-Euclidean data.</strong> The usual deep learning toolbox does not apply directly to graph data. For instance, convolutional neural networks (CNNs) need grid-structured inputs such as images, while recurrent neural networks (RNNs) require sequences such as text.</p></li><li><p><strong>Variable shapes.</strong> Graphs are by nature irregular: They have different numbers of nodes, and nodes may have different numbers of neighbors. This makes operations that are easily computed in the other domains more difficult to apply in the graph domain.</p></li><li><p><strong>Permutation invariance:</strong> Operations applied to graph data must be permutation-invariant, i.e. independent of the order of neighbor nodes, as there is no specific way to order them.</p></li><li><p><strong>Internal dependence.</strong> One of the core assumptions of existing ML models is that instances are independent of each other. However, for graph data, this assumption is no longer valid as each instance (node) is related to others by links of various types, such as citations, friendships, and interactions.</p></li></ul><p>These challenges motivate the need to introduce a new kind of deep learning architecture to apply deep learning methods over graphs.</p><blockquote><p><em>It is also worth mentioning that the &#8216;traditional&#8217; approach from ML models to learn from graph data is to include additional features that characterize the instance within the graph. These can be features like the nodes&#8217; degree, their centrality, etc. You can read my article on <a href="https://towardsdatascience.com/fraud-detection-with-graph-analytics-2678e817b69e">fraud detection</a> in which I applied such an approach. However, the feasibility and the success of such approaches are highly dependent on the use case (e.g., in some cases, the class of nodes may have no correlation with how central it is in the graph).</em></p></blockquote><h3><strong>2.2. Graph Convolutional Networks (GCN)</strong></h3><p><strong>What are the key concepts of the model?</strong></p><p>The goal of a <strong>Graph Neural Network (GNN)</strong> model is to use all the information about the graph, namely nodes&#8217; features and the connection between them, to learn a new representation for each of the nodes called <strong>node embeddings</strong>.</p><p>These node embeddings are low-dimensional vectors that summarize nodes&#8217; positions in the graph and the structure of their local graph neighborhood. The embeddings can then be directly used to classify nodes.</p><p>To do so, GNNs rely on a message-passing framework. At each iteration, every node aggregates information from its local neighborhood.</p><ul><li><p>So after the first iteration (k = 1), every node embedding contains information from its 1-hop neighborhood, i.e., its immediate graph neighbors.</p></li><li><p>After the second iteration (k = 2), every node embedding contains information from its 2-hop neighborhood, i.e. nodes that can be reached by a path of length 2 in the graph.</p></li><li><p>etc.</p></li></ul><p>As these iterations progress, each node embedding contains more and more information from further reaches of the graph.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ROLg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ROLg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png 424w, https://substackcdn.com/image/fetch/$s_!ROLg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png 848w, https://substackcdn.com/image/fetch/$s_!ROLg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png 1272w, https://substackcdn.com/image/fetch/$s_!ROLg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ROLg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png" width="1400" height="1254" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1254,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 4&#8202;&#8212;&#8202;GNN overall structure, illustration by Lina Faik&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="Figure 4&#8202;&#8212;&#8202;GNN overall structure, illustration by Lina Faik" title="Figure 4&#8202;&#8212;&#8202;GNN overall structure, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!ROLg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png 424w, https://substackcdn.com/image/fetch/$s_!ROLg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png 848w, https://substackcdn.com/image/fetch/$s_!ROLg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png 1272w, https://substackcdn.com/image/fetch/$s_!ROLg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66001b5a-b7ee-496f-bf79-e31f725a2a45_1400x1254.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4 &#8212; GNN overall structure, illustration by Lina Faik</figcaption></figure></div><p><strong>What kind of &#8220;information&#8221; does a node embedding actually encode?</strong></p><ul><li><p>Structural information about the graph (e.g., degrees of all the nodes in their k-hop neighborhood).</p></li><li><p>Feature-based information about the nodes&#8217; k-hop neighborhood.</p></li></ul><blockquote><p><em>One common issue with GNNs is <strong>over-smoothing</strong>: After multiple iterations of message passing, the representations for all the nodes in the graph can become very similar to one another. Natural ways to avoid this issue include maintaining a low number of layers or using skip connections.</em></p></blockquote><p><strong>What is the message passing framework about?</strong></p><p>What is a message-passage layer composed of? How are embeddings updated at each iteration? During each message-passing iteration in a GNN, a hidden embedding <em>h_u</em> corresponding to each node u is updated according to information aggregated from u&#8217;s graph neighborhood N(u). The figure below illustrates the first iteration.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oN-r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oN-r!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png 424w, https://substackcdn.com/image/fetch/$s_!oN-r!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png 848w, https://substackcdn.com/image/fetch/$s_!oN-r!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png 1272w, https://substackcdn.com/image/fetch/$s_!oN-r!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oN-r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png" width="1400" height="1285" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1285,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 5&#8202;&#8212;&#8202;Illustration of a message passing layer, illustration by Lina Faik&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="Figure 5&#8202;&#8212;&#8202;Illustration of a message passing layer, illustration by Lina Faik" title="Figure 5&#8202;&#8212;&#8202;Illustration of a message passing layer, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!oN-r!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png 424w, https://substackcdn.com/image/fetch/$s_!oN-r!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png 848w, https://substackcdn.com/image/fetch/$s_!oN-r!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png 1272w, https://substackcdn.com/image/fetch/$s_!oN-r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb948c455-f44f-4d70-96a7-840cc1a388f5_1400x1285.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 5 &#8212; Illustration of a message passing layer, illustration by Lina Faik</figcaption></figure></div><p>The message-passing update is expressed as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yon3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yon3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png 424w, https://substackcdn.com/image/fetch/$s_!yon3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png 848w, https://substackcdn.com/image/fetch/$s_!yon3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png 1272w, https://substackcdn.com/image/fetch/$s_!yon3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yon3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png" width="1400" height="474" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:474,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 6&#8202;&#8212;&#8202;Message passing function, illustration by Lina Faik&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="Figure 6&#8202;&#8212;&#8202;Message passing function, illustration by Lina Faik" title="Figure 6&#8202;&#8212;&#8202;Message passing function, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!yon3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png 424w, https://substackcdn.com/image/fetch/$s_!yon3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png 848w, https://substackcdn.com/image/fetch/$s_!yon3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png 1272w, https://substackcdn.com/image/fetch/$s_!yon3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F640db188-0455-4c8c-ba69-362e13f111e6_1400x474.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 6 &#8212; Message passing function, illustration by Lina Faik</figcaption></figure></div><p>The UPDATE and AGGREGATE functions vary depending on the model. For instance, GCN models rely on a symmetric-normalized aggregation as well as a self-loop update approach as shown in the previous figure.</p><p>What is the intuition behind this type of normalization?<strong> </strong>It provides more importance to neighborhood nodes that are not very connected (low degree). This is relevant for use cases such as the classification of pages as highly connected nodes tend to discuss very broad and general topics. Thus, they do not provide information that is truly useful for classifying the nodes to which they are linked.</p><blockquote><p><em>GCN approach has proved to be one of the most popular and effective baselines for GNN architectures. How do they relate to the concept of convolution? Just as CNNs aggregate feature information from spatially-defined patches in an image, GNNs aggregate information based on local graph neighborhoods. The figure below illustrates the analogy.</em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JeCw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JeCw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png 424w, https://substackcdn.com/image/fetch/$s_!JeCw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png 848w, https://substackcdn.com/image/fetch/$s_!JeCw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png 1272w, https://substackcdn.com/image/fetch/$s_!JeCw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JeCw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png" width="730" height="366" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:366,&quot;width&quot;:730,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 7&#8202;&#8212;&#8202;Analogy between convolutions and the GNN approach, Source [2]&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="Figure 7&#8202;&#8212;&#8202;Analogy between convolutions and the GNN approach, Source [2]" title="Figure 7&#8202;&#8212;&#8202;Analogy between convolutions and the GNN approach, Source [2]" srcset="https://substackcdn.com/image/fetch/$s_!JeCw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png 424w, https://substackcdn.com/image/fetch/$s_!JeCw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png 848w, https://substackcdn.com/image/fetch/$s_!JeCw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png 1272w, https://substackcdn.com/image/fetch/$s_!JeCw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391fb83c-626f-4408-bb8c-f325b28f0370_730x366.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 7 &#8212; Analogy between convolutions and the GNN approach, Source [<a href="https://arxiv.org/abs/1901.00596">2</a>]</figcaption></figure></div><p><strong>How does the model perform compared to a &#8220;traditional&#8221; classifier?</strong></p><p>To compare the performance of this approach to traditional machine learning models, I implemented a GCN-based model and compared it to a random forest classifier.</p><p>As shown in the code below, the GCN is composed of two graph convolutional layers with a non-linear transformation between them and a final softmax layer for multi-class classification.</p><p>The figure below shows the learning curves during the training.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NN3f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NN3f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png 424w, https://substackcdn.com/image/fetch/$s_!NN3f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png 848w, https://substackcdn.com/image/fetch/$s_!NN3f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png 1272w, https://substackcdn.com/image/fetch/$s_!NN3f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NN3f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png" width="1400" height="623" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:623,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 8&#8202;&#8212;&#8202;Evolution of the AUC during the training over the epochs&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="Figure 8&#8202;&#8212;&#8202;Evolution of the AUC during the training over the epochs" title="Figure 8&#8202;&#8212;&#8202;Evolution of the AUC during the training over the epochs" srcset="https://substackcdn.com/image/fetch/$s_!NN3f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png 424w, https://substackcdn.com/image/fetch/$s_!NN3f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png 848w, https://substackcdn.com/image/fetch/$s_!NN3f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png 1272w, https://substackcdn.com/image/fetch/$s_!NN3f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F031af858-0079-4f9f-9648-87233b1e2fc9_1400x623.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 8 &#8212; Evolution of the AUC during the training over the epochs</figcaption></figure></div><p>It is also possible to visualize the evolution of the embeddings as the model is training using t-SNE algorithm as represented in the figure below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZHhL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZHhL!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif 424w, https://substackcdn.com/image/fetch/$s_!ZHhL!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif 848w, https://substackcdn.com/image/fetch/$s_!ZHhL!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif 1272w, https://substackcdn.com/image/fetch/$s_!ZHhL!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZHhL!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif" width="700" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:700,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 9&#8202;&#8212;&#8202;Evolution of the embeddings during the training&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="Figure 9&#8202;&#8212;&#8202;Evolution of the embeddings during the training" title="Figure 9&#8202;&#8212;&#8202;Evolution of the embeddings during the training" srcset="https://substackcdn.com/image/fetch/$s_!ZHhL!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif 424w, https://substackcdn.com/image/fetch/$s_!ZHhL!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif 848w, https://substackcdn.com/image/fetch/$s_!ZHhL!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif 1272w, https://substackcdn.com/image/fetch/$s_!ZHhL!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde4e20a-3833-48d3-9066-c3a46541881d_700x500.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 9 &#8212; Evolution of the embeddings during the training</figcaption></figure></div><p><strong>Train / Validation sets. </strong>So far, the model is trained and tested on only one split of the initial data. However, the choice of the training split can significantly impact model performance when it comes to node classification. Luckily, the WikiCS dataset provides 20 different training splits, each consisting of 5% of nodes from each class. To ensure a robust comparison, I trained and tested each model on every split.</p><p><strong>Hyperparameters</strong>. I also tested different combinations of hyperparameters for each model. For more information, you can refer to the code <a href="https://github.com/linafaik08/graph_neural_networks/blob/main/1_node_classification.ipynb">here</a>.</p><p><strong>Features. </strong>To take the comparison further, I also enriched the dataset used by the random forest by adding graph-related features. These features include nodes degree, triangles, square clustering, clustering, eigenvector centrality, and page rank. For more information about these metrics, you can refer to my previous article <a href="https://towardsdatascience.com/fraud-detection-with-graph-analytics-2678e817b69e">here</a>.</p><p>As shown in the figure below, GCN tends to learn more efficiently from the data and outperforms the random forest classifier on the validation set. Enriching the dataset by adding graph-related features provides a relatively small improvement in the performance of random forest.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1tZ-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1tZ-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png 424w, https://substackcdn.com/image/fetch/$s_!1tZ-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png 848w, https://substackcdn.com/image/fetch/$s_!1tZ-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png 1272w, https://substackcdn.com/image/fetch/$s_!1tZ-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1tZ-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png" width="1400" height="593" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:593,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 10&#8202;&#8212;&#8202;Performance of models on the train/validation sets in terms of AUC&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="Figure 10&#8202;&#8212;&#8202;Performance of models on the train/validation sets in terms of AUC" title="Figure 10&#8202;&#8212;&#8202;Performance of models on the train/validation sets in terms of AUC" srcset="https://substackcdn.com/image/fetch/$s_!1tZ-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png 424w, https://substackcdn.com/image/fetch/$s_!1tZ-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png 848w, https://substackcdn.com/image/fetch/$s_!1tZ-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png 1272w, https://substackcdn.com/image/fetch/$s_!1tZ-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F22b1d784-de50-418a-b0af-14e1603abc4e_1400x593.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 10 &#8212; Performance of models on the train/validation sets in terms of AUC</figcaption></figure></div><h3><strong>2.3. Graph Attention Network (GAT)</strong></h3><p><strong>What are the key concepts behind the model?</strong></p><p>GCN models rely on a symmetric-normalized aggregation function that favors nodes depending on their degree. But what if the model could also learn what weight to give to each neighbor during the aggregation step? This can be done by including attention mechanisms in the learning process of the GNN.</p><p>The first GNN model to apply attention was <a href="https://arxiv.org/abs/1710.10903">Velickovic et al. [2018]</a>&#8217;s Graph Attention Network (GAT), which uses attention weights to define the weighted sum of the neighbors:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lakw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lakw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png 424w, https://substackcdn.com/image/fetch/$s_!lakw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png 848w, https://substackcdn.com/image/fetch/$s_!lakw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png 1272w, https://substackcdn.com/image/fetch/$s_!lakw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lakw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png" width="1360" height="328" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:328,&quot;width&quot;:1360,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Graph Attention Network (GAT)&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="Graph Attention Network (GAT)" title="Graph Attention Network (GAT)" srcset="https://substackcdn.com/image/fetch/$s_!lakw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png 424w, https://substackcdn.com/image/fetch/$s_!lakw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png 848w, https://substackcdn.com/image/fetch/$s_!lakw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png 1272w, https://substackcdn.com/image/fetch/$s_!lakw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc80cb225-28b4-4294-9543-d9eea1dbcdce_1360x328.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>For more about attention, you can read this <a href="https://medium.com/data-from-the-trenches/the-transformer-the-model-c921e43574e3">article</a> from DFTT.</p><p><strong>How does the model perform?</strong></p><p>The figure below presents the final results. It turns out that the GAT models lead to similar results as GCN for this use case.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Nl7P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Nl7P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png 424w, https://substackcdn.com/image/fetch/$s_!Nl7P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png 848w, https://substackcdn.com/image/fetch/$s_!Nl7P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png 1272w, https://substackcdn.com/image/fetch/$s_!Nl7P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Nl7P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png" width="1400" height="490" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/722ff422-c299-4122-a9be-ae7884865069_1400x490.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:490,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 11&#8202;&#8212;&#8202;Performance of models on the train/validation sets in terms of AUC&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="Figure 11&#8202;&#8212;&#8202;Performance of models on the train/validation sets in terms of AUC" title="Figure 11&#8202;&#8212;&#8202;Performance of models on the train/validation sets in terms of AUC" srcset="https://substackcdn.com/image/fetch/$s_!Nl7P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png 424w, https://substackcdn.com/image/fetch/$s_!Nl7P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png 848w, https://substackcdn.com/image/fetch/$s_!Nl7P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png 1272w, https://substackcdn.com/image/fetch/$s_!Nl7P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722ff422-c299-4122-a9be-ae7884865069_1400x490.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 11 &#8212; Performance of models on the train/validation sets in terms of AUC</figcaption></figure></div><div><hr></div><h2><strong>3. Key Takeaways</strong></h2><p>GNN frameworks offer a powerful approach by allowing models to learn patterns from graphs that are typically undetectable by traditional ML models. This comparison illustrates the improvement that a simple GCN or GAT model can bring to node classification.</p><p>However, depending on the use case and the data that you have, you might opt for one approach over another when carrying out your node classification task:</p><ul><li><p><strong>Availability of data. </strong>Node features (such as the content of the pages) may not be available in other uses cases. And graph-based features that usually reflect nodes&#8217; centrality may not be correlated to the label to predict at all! Thus, graph-based models remain the only relevant option.</p></li><li><p><strong>Computing time. </strong>GNNs are more expensive than traditional approaches. They take a longer time to be trained. You may be forced to make a trade-off between performance and cost.</p></li><li><p><strong>Explainability</strong>. The interpretation of the GNN results may not be as straightforward as other models. There are some local approaches that provide an understanding of the reasons that influenced a prediction. But decision trees might be more useful to understand the model as a whole for instance even if it means losing a little in terms of performance.</p></li></ul><div><hr></div><h2><strong>References</strong></h2><p>[1] W. Hamilton, <em><a href="https://www.cs.mcgill.ca/~wlh/grl_book/files/GRL_Book.pdf">Graph Representation Learning</a></em>, McGill University, 2020</p><p>[2] Z. Wu et al., <em><a href="https://arxiv.org/abs/1901.00596">A Comprehensive Survey on Graph Neural Networks</a></em>, January 2019</p><p>[3] P. Mernyei, C. Cangea, <a href="https://arxiv.org/abs/2007.02901">Wiki-CS: A Wikipedia-Based Benchmark for Graph Neural Networks</a>, July 2020</p><p>[4] <a href="http://web.stanford.edu/class/cs224w/">CS224W: Machine Learning with Graphs</a>, Standford</p><p>[5] P. Veli&#269;kovi&#263; et al., <a href="https://arxiv.org/abs/1710.10903">Graph Attention Networks</a>, October 2017</p>]]></content:encoded></item><item><title><![CDATA[Can Deep Learning Change the Game for Time Series Forecasting? (Part II)]]></title><description><![CDATA[Comparing MQ Forecasters & Transformers to ML to Find Out]]></description><link>https://aipractitioner.substack.com/p/can-deep-learning-change-the-game</link><guid isPermaLink="false">https://aipractitioner.substack.com/p/can-deep-learning-change-the-game</guid><dc:creator><![CDATA[Lina Faik]]></dc:creator><pubDate>Thu, 18 Nov 2021 20:06:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-Za4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.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="https://substackcdn.com/image/fetch/$s_!-Za4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-Za4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-Za4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-Za4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-Za4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-Za4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg" width="1400" height="584" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:584,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-Za4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-Za4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-Za4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-Za4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f691ca8-be66-483c-a320-9e24b9a54ade_1400x584.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The encoder-decoder framework is undoubtedly one of the most popular concepts in deep learning. Widely used to solve sophisticated tasks such as machine translation, image captioning, and text summarization, it has led to great breakthroughs.</p><p>However, when it comes to time series forecasting, the encoder-decoder framework has generated less noise. And yet, the recently emerged models that rely on this architecture have led to more accurate forecasts than classic approaches. They have also proven to be a more scalable solution from a business perspective.</p><p>Among them, two have stood out for their performance and scalability: the <strong>Multi-Quantile Recurrent Forecaster </strong>that comes in two flavors (<strong>MQ-RNN and MQ-CNN)</strong> and <strong>Transformers</strong>. Although they both share the same overall architecture, they rely on completely different approaches. Let&#8217;s deep dive into their mechanisms!</p><h3><strong>Objective</strong></h3><p>The goal of this article is to expose the key principles of these models.</p><p>It is the continuation of a two-part series (<a href="https://medium.com/data-from-the-trenches/deep-learning-for-time-series-forecasting-is-it-worth-it-bfc95a1c9de4">here&#8217;s part one</a>) that aims to provide a comprehensive overview of the state-of-the-art deep learning models for time series forecasting. After reading this series, you will understand:</p><ol><li><p>What are the key common concepts of deep learning models used for time series forecasting?</p></li><li><p>How do these models differ from one another?</p></li><li><p>To what extent do they provide better results in terms of forecasting accuracy and computing time?</p></li></ol><p>As an illustrative use case, I will rely on the example of the <strong>prediction of daily stock market prices </strong>of several companies from different industries<strong> over a time window of 30 days.</strong> This will provide an opportunity to evaluate and compare the performance of the approaches exposed in two articles on a concrete use case based on different criteria.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://aipractitioner.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="https://aipractitioner.substack.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>1. Deep Learning Models</strong></h2><h3><strong>1.1. Multi-Quantile Recurrent Forecaster (MQ-RNN &amp; MQ-CNN)</strong></h3><p>Multi-Quantile Forecasters (MQ Forecasters) rely on a Seq2Seq architecture with Context, also referred to as <em>Seq2SeqC</em>, with some slight differences. Let&#8217;s first start by describing the <em>Seq2SeqC</em> architecture before diving into the model&#8217;s specificities.</p><p><strong>What Is a </strong><em><strong>Seq2SeqC</strong></em><strong> Architecture?</strong></p><p>Figure 1 illustrates the <em>Seq2SeqC</em> architecture as introduced in [1]. It consists of three major components: an encoder, an intermediate vector, and a decoder.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g1Sq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g1Sq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png 424w, https://substackcdn.com/image/fetch/$s_!g1Sq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png 848w, https://substackcdn.com/image/fetch/$s_!g1Sq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png 1272w, https://substackcdn.com/image/fetch/$s_!g1Sq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g1Sq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png" width="1400" height="674" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:674,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 1&#8202;&#8212;&#8202;Seq2Seq architecture with context (Seq2SeqC) as proposed by [1], adapted from [2], illustration by Lina Faik&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="Figure 1&#8202;&#8212;&#8202;Seq2Seq architecture with context (Seq2SeqC) as proposed by [1], adapted from [2], illustration by Lina Faik" title="Figure 1&#8202;&#8212;&#8202;Seq2Seq architecture with context (Seq2SeqC) as proposed by [1], adapted from [2], illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!g1Sq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png 424w, https://substackcdn.com/image/fetch/$s_!g1Sq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png 848w, https://substackcdn.com/image/fetch/$s_!g1Sq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png 1272w, https://substackcdn.com/image/fetch/$s_!g1Sq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe126eb5c-0873-4373-bb6f-70c8de43a4a4_1400x674.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1 &#8212; Seq2Seq architecture with Context (<em>Seq2SeqC</em>) as proposed by [1], adapted from [2], illustration by Lina Faik</figcaption></figure></div><ol><li><p><strong>Encoder</strong>. It encapsulates a stack of recurrent units such as LSTM. It takes a single element from the input <em>y</em> and covariants <em>x</em> and outputs a hidden state <em>h</em>.</p></li><li><p><strong>Encoder or Context Vector.</strong> It is the final hidden state of the encoder and thus encodes all of the information from the input data.</p></li><li><p><strong>Decoder.</strong> It also encapsulates a stack of recurrent units. It takes the encoder vector as its first hidden state and the past value of y. At every step, the decoder estimates the likelihood <em>p(y|&#952;)</em> that depends on the parameters <em>&#952;</em> of a given distribution. For instance, in the case of a Gaussian likelihood, these parameters consist of &#956; and &#963;.</p></li></ol><p>Both the encoder and decoder, parameterized by &#952;, are trained jointly to optimize the log-likelihood<strong> </strong>computed over the time horizon.</p><p><em>This approach is very similar to DeepAR whose encoder and decoder have the same architecture and share the same weights. More information about this model is provided <a href="https://medium.com/data-from-the-trenches/deep-learning-for-time-series-forecasting-is-it-worth-it-bfc95a1c9de4">here</a>.</em></p><p><strong>How Do MQ Forecasters Differ?</strong></p><p>Although MQ Forecasters&#8217; architecture is very similar to <em>Seq2SeqC</em>, it differs from it on multiple levels:<strong> the loss function, the training scheme, and the neural networks used in the decoder.</strong></p><p>Figure 2 summarizes the architecture of MQ-RNN that will be explained in this section.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LWTp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LWTp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png 424w, https://substackcdn.com/image/fetch/$s_!LWTp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png 848w, https://substackcdn.com/image/fetch/$s_!LWTp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png 1272w, https://substackcdn.com/image/fetch/$s_!LWTp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LWTp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png" width="1400" height="599" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:599,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 2&#8202;&#8212;&#8202;MQ-RNN adapted from [2], illustration by Lina Faik&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="Figure 2&#8202;&#8212;&#8202;MQ-RNN adapted from [2], illustration by Lina Faik" title="Figure 2&#8202;&#8212;&#8202;MQ-RNN adapted from [2], illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!LWTp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png 424w, https://substackcdn.com/image/fetch/$s_!LWTp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png 848w, https://substackcdn.com/image/fetch/$s_!LWTp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png 1272w, https://substackcdn.com/image/fetch/$s_!LWTp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3d6d9d4-e6c2-4e0f-a744-43d26da55df2_1400x599.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2 &#8212; MQ-RNN adapted from [2], illustration by Lina Faik</figcaption></figure></div><ul><li><p><strong>Quantile Loss function:</strong></p></li></ul><p>Instead of learning a probability distribution and maximizing the log-likelihood, the model minimizes a quantile loss function <em>L</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XdM7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XdM7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png 424w, https://substackcdn.com/image/fetch/$s_!XdM7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png 848w, https://substackcdn.com/image/fetch/$s_!XdM7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png 1272w, https://substackcdn.com/image/fetch/$s_!XdM7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XdM7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png" width="580" height="77.39864864864865" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:158,&quot;width&quot;:1184,&quot;resizeWidth&quot;:580,&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="https://substackcdn.com/image/fetch/$s_!XdM7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png 424w, https://substackcdn.com/image/fetch/$s_!XdM7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png 848w, https://substackcdn.com/image/fetch/$s_!XdM7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png 1272w, https://substackcdn.com/image/fetch/$s_!XdM7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb5107b3-352d-40b4-9b83-cdceb9579535_1184x158.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><blockquote><p><em><strong>What is the intuition behind a quantile loss?</strong></em></p><p><em>The quantile loss function allows the weight associated with over-predictions to be varied compared to under-predictions. What does it mean? Let&#8217;s suppose q&gt;0.5. The loss has a higher value if the model over-predicts then if it under-predicts.</em></p><p><em>The use of a quantile loss has two main benefits. First, it helps assess the uncertainty of the model predictions, as quantiles can provide an upper and lower bound for forecasts. Second, it makes possible to take into account a difference in costs between under- and over-prediction. For instance, in the retail industry, overestimating the demand leads to storage costs, while underestimating the demand is associated to the lost sale opportunity.</em></p></blockquote><p>In this context, the model is trained to minimize the total loss which is computed over all time horizons including all quantiles:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HIfZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HIfZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png 424w, https://substackcdn.com/image/fetch/$s_!HIfZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png 848w, https://substackcdn.com/image/fetch/$s_!HIfZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png 1272w, https://substackcdn.com/image/fetch/$s_!HIfZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HIfZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png" width="1262" height="90" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:90,&quot;width&quot;:1262,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;total loss over all time horizons&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="total loss over all time horizons" title="total loss over all time horizons" srcset="https://substackcdn.com/image/fetch/$s_!HIfZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png 424w, https://substackcdn.com/image/fetch/$s_!HIfZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png 848w, https://substackcdn.com/image/fetch/$s_!HIfZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png 1272w, https://substackcdn.com/image/fetch/$s_!HIfZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff2ba4c-7a18-4c34-8e40-54767e4b783e_1262x90.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>What does the quantile loss bring compared to the other approach? This approach has two main advantages:</p><ol><li><p>It doesn&#8217;t make any assumptions on the distributions. There is no need to suppose a certain distribution <em>p(y|&#952;)</em> for which the model learns to find the parameters &#952;.</p></li><li><p>It produces accurate probabilistic forecasts with prediction intervals. This allows us to know how confident the model is of its predictions and assess the risk associated with them.</p></li></ol><ul><li><p><strong>Training Scheme</strong></p></li></ul><p>During training, the time sequence is forked. This means that there is a decoder that corresponds to each recurrent layer (time point) and they all share the same weights.</p><p>Therefore, at each time point, the loss is computed using the multi-horizon forecasts and the corresponding targets. Then, one back-propagation-through-time gathers the multi-horizon error gradients of different time points in only one pass over the sample.</p><p>Thanks to this framework, the model is able to learn more efficiently by using all information in one shot. This allows for a reduction of the training time and a stabilization of the learning as well as a boost in the performance.</p><ul><li><p><strong>Decoder Architecture</strong></p></li></ul><p>Instead of using a <a href="https://en.wikipedia.org/wiki/Long_short-term_memory">Long Short-Term Memory</a> (LSTM) as the recursive decoder, MQ-RNN uses two <a href="https://en.wikipedia.org/wiki/Multilayer_perceptron">Multi-Layer perceptron</a> (MLPs): global and local MLPs.</p><ol><li><p><strong>The global MLP:</strong> It summarizes the encoder output and all future covariants into two contexts:</p></li></ol><ul><li><p><strong>Time-dependent contexts</strong> <em>c_{t+k}</em> for each of the K future points</p></li><li><p><strong>Time-independent context</strong> <em>c_{a}</em> that captures common information</p></li></ul><p>You might wonder what would be the benefits of having two contexts and if they are not redundant. Actually, the time-dependent context is different from the other one. It carries information about the model awareness of the temporal distance between a forecast starting point and a specific horizon.</p><p><strong>2. The local MLP:</strong> This network is specific to each horizon. It uses the future covariants and the two contexts from the global MLP to output all the required quantiles for that specific future time step.</p><p>At this stage, you might wonder why we are using MLPs instead of LSTMs. Since the parameters of the local MLP are shared across horizons, you might even be tempted to replace the MLPs with LSTMs.This is actually unnecessary and expensive as the temporal aspect of information is captured in the time-dependent context.</p><p><strong>What About MQ-CNN?</strong></p><p>The key difference between MQ-RNN and MQ-CNN lies in the choice of the neural network used in the encoder.</p><p>In the initial version of MQ-RNN, the encoder consists of LSTMs. These networks are known for their ability to avoid the RNN issues of vanishing or exploding gradients and expand the long-term memory capacity. However, it is also possible to replace them for better performance.</p><p>The alternatives include:</p><ul><li><p><strong>Recurrent networks: </strong>NARX RNN [3] or LSTMs for which lagged values of the time series are provided.</p></li><li><p><strong>Non-recurrent network: </strong>Dilated causal 1D convolution layers. Since higher-level layers can reach far into the past summary, they represent another good alternative to LSTMs. This version of the model is known as MQ-CNN. And in the original paper, it has led to excellent forecasting results.</p></li></ul><p><em>The idea of using this type of network was inspired by WaveNet which is famous for its impressive capacities of processing and generating audio sequences. The model consists of a stack of dilated causal 1D convolution layers. More information about WaveNet <a href="https://deepmind.com/blog/article/wavenet-generative-model-raw-audio">here</a>.</em></p><blockquote><p><em><strong>But what is a dilated causal 1D convolution layer?</strong></em></p><p><em><strong><a href="https://paperswithcode.com/method/causal-convolution">Causal Convolution</a>:</strong> It is a convolution designed so as the model only receives at a time point the past inputs. This is particularly used when dealing with temporal input data as it ensures the model is trained to respect the ordering of the input data.</em></p><p><em><strong><a href="https://paperswithcode.com/method/dilated-causal-convolution">Dilated</a></strong><a href="https://paperswithcode.com/method/dilated-causal-convolution"> </a><strong><a href="https://paperswithcode.com/method/dilated-causal-convolution">Causal Convolution</a>:</strong> It is a causal convolution for which the network is allowed to skip input values with a certain step.</em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ND4B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ND4B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png 424w, https://substackcdn.com/image/fetch/$s_!ND4B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png 848w, https://substackcdn.com/image/fetch/$s_!ND4B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png 1272w, https://substackcdn.com/image/fetch/$s_!ND4B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ND4B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png" width="1400" height="510" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:510,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 3&#8202;&#8212;&#8202;Causal Convolution (left), Dilated Causal Convolution (right) [4]&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="Figure 3&#8202;&#8212;&#8202;Causal Convolution (left), Dilated Causal Convolution (right) [4]" title="Figure 3&#8202;&#8212;&#8202;Causal Convolution (left), Dilated Causal Convolution (right) [4]" srcset="https://substackcdn.com/image/fetch/$s_!ND4B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png 424w, https://substackcdn.com/image/fetch/$s_!ND4B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png 848w, https://substackcdn.com/image/fetch/$s_!ND4B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png 1272w, https://substackcdn.com/image/fetch/$s_!ND4B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F396be5f8-c5cd-46b7-aab7-5dc6b3a36312_1400x510.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3 &#8212; <a href="https://paperswithcode.com/method/causal-convolution">Causal Convolution</a> (left), <a href="https://paperswithcode.com/method/dilated-causal-convolution">Dilated Causal Convolution</a> (right) [4]</figcaption></figure></div><h3><strong>1.2. Transformer-Based Models</strong></h3><p>Originally introduced in <em>Attention Is All You Need</em> [5], Transformers have outperformed previous approaches in tasks such as translation and text summarization image captioning and are now widely used. More information about Transformers can be found in our previous <a href="https://medium.com/data-from-the-trenches/the-transformer-the-model-c921e43574e3">article</a>.</p><p><strong>How Does a Transformer-Based Model Differ From Other Models?</strong></p><p>If, in theory, RNN-based models are able to keep important information in memory while processing the input data, in practice this is not the case: they tend to forget as they process long sequences.</p><p>In contrast, Transformers&#8217; architecture enables models to propagate very important information over long sequences and thus better capture the long-term seasonal behaviors and dependencies. How? Transformer-based models do not process data in any specific order. Their architecture does not include any RNN-like networks, they rely on self-attention mechanisms to learn dependencies in the sequence.</p><blockquote><p><em>For instance, a model trained to translate a sentence from one language to another would not necessarily process the beginning of the sentence before the end. Instead, it will use the context that reflects the relative importance of each of the input sentences.</em></p><p><em>Similarly, a model trained to forecast stock prices based on the data of the past week would not necessarily process past prices in order. For instance, it might first start with the data of the last Friday before last Monday. The context would help the model account for the day of the week, vacations, etc.</em></p></blockquote><p>Relying only on attention mechanisms has not only led to better performance but also a reduction of training time. In fact, as the model is now able to process calculations at the same time rather than in sequential steps, it can parallelize the calculations.</p><p><strong>How Does a Transformer-Based Model Work in Practice?</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rcz-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rcz-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png 424w, https://substackcdn.com/image/fetch/$s_!rcz-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png 848w, https://substackcdn.com/image/fetch/$s_!rcz-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png 1272w, https://substackcdn.com/image/fetch/$s_!rcz-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rcz-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png" width="1400" height="778" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:778,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 4- Architecture of Transformer-based forecasting model, illustration by Lina Faik&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="Figure 4- Architecture of Transformer-based forecasting model, illustration by Lina Faik" title="Figure 4- Architecture of Transformer-based forecasting model, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!rcz-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png 424w, https://substackcdn.com/image/fetch/$s_!rcz-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png 848w, https://substackcdn.com/image/fetch/$s_!rcz-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png 1272w, https://substackcdn.com/image/fetch/$s_!rcz-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbf41ac5-41a3-4ee2-a978-dca290e4312a_1400x778.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4&#8212; Architecture of Transformer-based forecasting model, illustration by Lina Faik</figcaption></figure></div><p>A Transformer-based model is composed of two components.</p><p><strong>Encoder</strong>. It encapsulates an input layer and a positional encoding layer that maps the input time series data to a vector. The resulting vectors are transferred to self-attention and feed-forward layers with pre- and post-process blocks in between.</p><p><strong>Decoder.</strong> It is composed of an input layer and decoder layers that are similar to those of the encoder. The decoder also includes an output layer to map the output of the last decoder layer to the target time sequence.</p><p>There is one element worth mentioning: in order to make predictions one step at a time using only previous data points, the model uses a one-position offset between the decoder and target output and a look-ahead mask. What does this mean? It implies that all data points that come after the data point currently being predicted are masked, which prevents the model from cheating.</p><h2><strong>2. The Traditional Machine Learning Approach</strong></h2><p>What about standard machine learning (ML) algorithms such as random forests, XGBoost, ridge, and lasso?</p><h3><strong>2.1. How Can ML Models Be Used for Time Series Forecasts?</strong></h3><p>The first step is to build the dataset from which the model will learn. Usually, the model learns to predict future values based on recent history. Therefore, features mostly consist of lagged values or aggregation such as rolling means, rolling sum, etc.</p><p>Figure 5 illustrates the transformation of raw data to a training dataset for one-step prediction. In this example, the model would learn to forecast future values using all the lagged values.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qfH_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qfH_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png 424w, https://substackcdn.com/image/fetch/$s_!qfH_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png 848w, https://substackcdn.com/image/fetch/$s_!qfH_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png 1272w, https://substackcdn.com/image/fetch/$s_!qfH_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qfH_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png" width="1302" height="422" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:422,&quot;width&quot;:1302,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 5- Building the training dataset, illustration by Lina Faik&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="Figure 5- Building the training dataset, illustration by Lina Faik" title="Figure 5- Building the training dataset, illustration by Lina Faik" srcset="https://substackcdn.com/image/fetch/$s_!qfH_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png 424w, https://substackcdn.com/image/fetch/$s_!qfH_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png 848w, https://substackcdn.com/image/fetch/$s_!qfH_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png 1272w, https://substackcdn.com/image/fetch/$s_!qfH_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe93d40fa-68c3-47b0-b57d-588bea139cd2_1302x422.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 5&#8212; Building the training dataset, illustration by Lina Faik</figcaption></figure></div><p>Note that it is also possible to add more features related to the date in the training dataset. These features include holidays flags, yearly or weekly seasonality components. For more information, <a href="https://heartbeat.fritz.ai/feature-engineering-techniques-handle-date-time-and-mixed-variables-with-python-4fc97285dc14">here</a> is an interesting article explaining how such features can be computed.</p><p>Moreover, as the training set can contain data from multiple time series, it is possible to add features specific to items and thus enable the model to leverage cross-learning benefits. In the case of stock prediction, these features can be information related to the company such as its industry, its earnings, or financial ratios.</p><h3><strong>2.2. What Feature Engineering Is Required for Multi-Step Forecasting?</strong></h3><p>However, the prediction for a longer period of time requires more complex feature engineering. Why?</p><p>Imagine we want to build a model that is able to make predictions using all the available data, including <em>lag t-1</em> or features that are computed using <em>lag t-1</em>. In this case, when predicting <em>day+2</em>, these features will be missing since the model has also to predict <em>day+1</em>.</p><p>There are two options to deal with this gap:</p><ol><li><p><strong>Recursive learning.</strong> The model can use its last prediction. However, this means that it will learn based on data containing errors from previous predictions and thus quickly accumulate mistakes. Such an approach has great chances to lead to unstable models producing totally inaccurate forecasts.</p></li><li><p><strong>Multiple models.</strong> The other option would be to build separate models for every time step. In this context, when predicting <em>day+1</em>, we would use a model that is able to make predictions at time <em>t</em> using all lags or related features. When predicting <em>day+2</em>, we would use a model that is able to make predictions at time <em>t</em> using all lags except <em>lag t-1</em> or all features except those computed from using lag <em>t-1</em>. However, this approach would mean that 30 models need to be trained to make forecasts over the next month! And every model has to be chosen among the available algorithms and its parameters carefully fine-tuned. Therefore, this approach can be very computationally expensive and labor-intensive.</p></li></ol><p>As a good compromise, we consider building one model per week as described in the figure below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vDNq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vDNq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png 424w, https://substackcdn.com/image/fetch/$s_!vDNq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png 848w, https://substackcdn.com/image/fetch/$s_!vDNq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png 1272w, https://substackcdn.com/image/fetch/$s_!vDNq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vDNq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png" width="1400" height="841" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:841,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!vDNq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png 424w, https://substackcdn.com/image/fetch/$s_!vDNq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png 848w, https://substackcdn.com/image/fetch/$s_!vDNq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png 1272w, https://substackcdn.com/image/fetch/$s_!vDNq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23a9c559-ce47-4585-9a52-6c047509045d_1400x841.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 6 &#8212; Learning Framework for an ML approach, illustration by Lina Faik</figcaption></figure></div><h2><strong>3. Application to Stock Forecasting</strong></h2><h3><strong>3.1. Scope</strong></h3><p>The objective of this section is to compare the performance of the models presented above with other approaches in terms of both accuracy and computing time.</p><p>It is a continuation of the use case presented in the previous <a href="https://medium.com/data-from-the-trenches/deep-learning-for-time-series-forecasting-is-it-worth-it-bfc95a1c9de4">article</a>. Here is a short recap of the main elements that are needed to understand the use case:</p><p><strong>Task:</strong> Predict the daily stock prices of large companies over the next 30 days.</p><p><strong>Dataset</strong>: Daily stock price of 100 companies randomly chosen from the S&amp;P index over a period of 10 years. Information about the company is also included (<em>Market Cap, EBITDA, Price/Earnings, Dividend Yield, etc.)</em></p><p><strong>Learning Framework: </strong>The dataset is split into two: a training dataset and a validation dataset containing the last 30 days&#8217; prices. The experimentation includes 3 different scenarios:</p><ol><li><p><strong>Baseline:</strong> Only prices are given to the model.</p></li><li><p><strong>Date Features: </strong>Features related to the date are used by the model to take into account weekly, monthly, and yearly seasonality effects.</p></li><li><p><strong>Date Features and Covariants</strong>: In addition to price and date features, the model is trained using the covariants described above.</p></li></ol><p><strong>Metrics</strong>. <a href="https://en.wikipedia.org/wiki/Root-mean-square_deviation">RMSE</a>, <a href="https://en.wikipedia.org/wiki/Mean_absolute_percentage_error">MAPE</a> and, training time.</p><h3><strong>3.2. Results</strong></h3><p>In the rest of this section, you will see my key findings as I explored the results:</p><ol><li><p><strong>The Transformer performs better in terms of accuracy. </strong>Figure 7 compares the results of the different approaches on the test set.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4rh2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4rh2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png 424w, https://substackcdn.com/image/fetch/$s_!4rh2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png 848w, https://substackcdn.com/image/fetch/$s_!4rh2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png 1272w, https://substackcdn.com/image/fetch/$s_!4rh2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4rh2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png" width="1400" height="686" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:686,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 7&#8202;&#8212;&#8202;Results on the test set (expressed as an average over all time series)&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="Figure 7&#8202;&#8212;&#8202;Results on the test set (expressed as an average over all time series)" title="Figure 7&#8202;&#8212;&#8202;Results on the test set (expressed as an average over all time series)" srcset="https://substackcdn.com/image/fetch/$s_!4rh2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png 424w, https://substackcdn.com/image/fetch/$s_!4rh2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png 848w, https://substackcdn.com/image/fetch/$s_!4rh2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png 1272w, https://substackcdn.com/image/fetch/$s_!4rh2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e1c80dc-02a0-46e7-8f87-df07a7b69ce4_1400x686.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 7 &#8212; Results on the test set (expressed as an average over all time series)</figcaption></figure></div><p><em>Note: Figure 7 presents only averages. In reality, there is a wide disparity of results depending on the company.</em></p><p><strong>2. The ML approach also produces accurate forecasts.</strong> Nevertheless, implementing the learning framework is labor intensive as it requires several feature engineering steps and hyper-parameters tuning. Figure 8 contains the results of the different approaches on the validation set<strong> </strong>(i.e., the last 30 days).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Tjad!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Tjad!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png 424w, https://substackcdn.com/image/fetch/$s_!Tjad!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png 848w, https://substackcdn.com/image/fetch/$s_!Tjad!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png 1272w, https://substackcdn.com/image/fetch/$s_!Tjad!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Tjad!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png" width="1400" height="699" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:699,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 8&#8202;&#8212;&#8202;Results on the validation set (expressed as an average over all time series)&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="Figure 8&#8202;&#8212;&#8202;Results on the validation set (expressed as an average over all time series)" title="Figure 8&#8202;&#8212;&#8202;Results on the validation set (expressed as an average over all time series)" srcset="https://substackcdn.com/image/fetch/$s_!Tjad!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png 424w, https://substackcdn.com/image/fetch/$s_!Tjad!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png 848w, https://substackcdn.com/image/fetch/$s_!Tjad!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png 1272w, https://substackcdn.com/image/fetch/$s_!Tjad!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee045e14-d5bd-41fe-942f-1f9c804ced5c_1400x699.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 8 &#8212; Results on the validation set (expressed as an average over all time series)</figcaption></figure></div><p><em>Note: It is worth mentioning that Figure 8 compares the ML approach with other approaches using only one task, i.e. predicting the last 30 days. To properly compare the models and measure the significance of models cores, it is necessary to test them on several points (cf. References).</em></p><p>3. <strong>The performance of most models is consistent across forecasting time.</strong></p><p>As 30 days represents a long period of time for financial markets, it&#8217;s not something to be taken for granted! Table 3 shows the performance of the model depending on the forecasts horizon. For instance, the DeepAR model (baseline) shows a decrease in results for distant time horizons.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4Xe-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4Xe-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png 424w, https://substackcdn.com/image/fetch/$s_!4Xe-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png 848w, https://substackcdn.com/image/fetch/$s_!4Xe-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png 1272w, https://substackcdn.com/image/fetch/$s_!4Xe-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4Xe-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png" width="1400" height="623" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:623,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Figure 9&#8202;&#8212;&#8202;Results on the validation set depending on the forecast horizon (expressed as an average over all time series)&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="Figure 9&#8202;&#8212;&#8202;Results on the validation set depending on the forecast horizon (expressed as an average over all time series)" title="Figure 9&#8202;&#8212;&#8202;Results on the validation set depending on the forecast horizon (expressed as an average over all time series)" srcset="https://substackcdn.com/image/fetch/$s_!4Xe-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png 424w, https://substackcdn.com/image/fetch/$s_!4Xe-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png 848w, https://substackcdn.com/image/fetch/$s_!4Xe-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png 1272w, https://substackcdn.com/image/fetch/$s_!4Xe-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67f2ebf-0db1-4340-8198-c1e43c3bbbee_1400x623.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 9 &#8212; Results on the validation set depending on the forecast horizon (expressed as an average over all time series)</figcaption></figure></div><div><hr></div><h2><strong>Key Takeaways</strong></h2><p><strong>Deep Learning vs. Other Approaches: The Final Verdict</strong></p><p>Through this two-part series, it appears that forecasting time series using deep learning has many advantages:</p><ul><li><p><strong>Improved</strong> <strong>forecast accuracy. </strong>By learning global models from related time series, they are able to capture complex patterns and leverage cross-learning between related time series. As a result, the accuracy is higher than state-of-the-art forecasting methods</p></li><li><p><strong>Less pre-processing steps and feature engineering. </strong>Many research papers have shown that these models work on a wide variety of datasets with little or no hyperparameter tuning. This applies also to datasets of medium size with around one hundred time series.</p></li><li><p><strong>No manual intervention during the training phase. </strong>Contrary to ML frameworks, deep learning models do not require any specific data pre-processing, feature engineering, or model hand-picking.</p></li><li><p><strong>Possibility to include exogenous variables. </strong>Contrary to classic statistical methods, deep learning models can include exogenous variables as input variables.</p></li><li><p><strong>Reduction of computing time. </strong>The architecture of deep learning models enables them to learn and forecast many time series simultaneously.</p></li></ul><p>For all these reasons, deep learning models are <strong>much more scalable</strong> than other approaches and meet better business constraints in terms of <strong>both accuracy and computation time.</strong></p><div><hr></div><h2><strong>References</strong></h2><p><em>The experimentations presented above have been carried out in <a href="https://www.dataiku.com/product/">Dataiku</a> using the plugins <a href="https://www.dataiku.com/product/plugins/timeseries-preparation/">time series preparation</a> and <a href="https://www.dataiku.com/product/plugins/timeseries-forecast/">time series Forecast</a> in addition to Python code. The trained models are based on the library <a href="https://ts.gluon.ai/">GluonTS</a> except for AutoArima which is based on the Python library <a href="https://alkaline-ml.com/pmdarima/0.9.0/modules/generated/pyramid.arima.ARIMA.html">pyramid</a>.</em></p><p>[1] Cho et al. <a href="https://arxiv.org/pdf/1406.1078.pdf">Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation</a>, September 2014</p><p>[2] Wen et al., <a href="https://arxiv.org/abs/1711.11053">A Multi-Horizon Quantile Recurrent Forecaster</a>, June 2018</p><p>[3] R. DiPietro et al., <a href="https://arxiv.org/abs/1702.07805">Analyzing and Exploiting NARX Recurrent Neural Networks for Long-Term Dependencies</a>, February 2017.</p><p>[4] Oord et al., <a href="https://arxiv.org/abs/1609.03499v2">WaveNet: A Generative Model for Raw Audio</a>, September 2016</p><p>[5] A. Vaswani, N. Shazeer, et al. <a href="https://arxiv.org/abs/1706.03762">Attention Is All You Need</a>, Jun 2017</p><p>[6] N. Wu, B. Green, et al. <a href="https://arxiv.org/abs/2001.08317">Deep Transformer Models for Time Series Forecasting: The Influenza Prevalence Case</a>, Jan 2020</p><p>[7] J. Alammar, <a href="https://jalammar.github.io/illustrated-transformer/">The Illustrated Transformer</a>, June 2018</p><p>[8] N. Klingenbrunn, <a href="https://medium.com/mlearning-ai/transformer-implementation-for-time-series-forecasting-a9db2db5c820">Transformers for Time-series Forecasting</a>, February 2019</p>]]></content:encoded></item></channel></rss>