<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: viraj gubbewad</title>
    <description>The latest articles on DEV Community by viraj gubbewad (@viraj_gubbewad_a01f4197e0).</description>
    <link>https://dev.to/viraj_gubbewad_a01f4197e0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4231558%2F66a13b00-1872-4866-8d75-042e9259d047.png</url>
      <title>DEV Community: viraj gubbewad</title>
      <link>https://dev.to/viraj_gubbewad_a01f4197e0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viraj_gubbewad_a01f4197e0"/>
    <language>en</language>
    <item>
      <title>My Analytics Agent Stopped Repeating Its Wrong Guesses With Hindsight</title>
      <dc:creator>viraj gubbewad</dc:creator>
      <pubDate>Sat, 07 Nov 2026 06:37:01 +0000</pubDate>
      <link>https://dev.to/viraj_gubbewad_a01f4197e0/my-analytics-agent-stopped-repeating-its-wrong-guesses-with-hindsight-4ho3</link>
      <guid>https://dev.to/viraj_gubbewad_a01f4197e0/my-analytics-agent-stopped-repeating-its-wrong-guesses-with-hindsight-4ho3</guid>
      <description>&lt;h1&gt;
  
  
  My Analytics Agent Stopped Repeating Its Wrong Guesses With Hindsight
&lt;/h1&gt;

&lt;p&gt;Every Monday morning, someone in leadership asks why a regional revenue metric dropped, and an analyst spends two hours checking the exact same five tables in the exact same order. When we first wired an LLM tool-calling agent to automate root-cause investigations, it had an infuriating habit: it treated every single alert like its first day on the job.&lt;/p&gt;

&lt;p&gt;If the South region experienced three consecutive pricing-tier drops over three weeks, a stateless agent would still burn time querying holiday calendars, competitor promo trackers, and warehouse stockout logs before checking pricing. Worse, if the Monday morning ETL sync stalled at 02:00 UTC, the agent would panic over incomplete tables and report a fake revenue collapse. And no matter how many times the Finance Head asked for a single-line summary with the exact dollar variance, the next session returned a multi-paragraph essay.&lt;/p&gt;

&lt;p&gt;To fix this, we built &lt;strong&gt;WhyDesk&lt;/strong&gt;—an autonomous metric investigation system powered by FastAPI, Groq tool-calling, and the &lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight GitHub repository&lt;/a&gt;. Instead of treating memory as a passive chat log, we used &lt;a href="https://vectorize.io/what-is-agent-memory" rel="noopener noreferrer"&gt;Vectorize agent memory&lt;/a&gt; to dynamically reorder diagnostic tool execution, skip low-probability checks, flag flaky data pipelines before trusting raw numbers, and enforce stakeholder-specific output formatting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the System Does and How It Hangs Together
&lt;/h2&gt;

&lt;p&gt;WhyDesk sits between business stakeholders (&lt;code&gt;Finance Head&lt;/code&gt; and &lt;code&gt;Senior Analyst&lt;/code&gt;) and five deterministic diagnostic tools that inspect weekly regional performance across &lt;code&gt;South&lt;/code&gt;, &lt;code&gt;North&lt;/code&gt;, &lt;code&gt;West&lt;/code&gt;, and &lt;code&gt;East&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;check_holiday_calendar&lt;/code&gt;: Audits regional banking holidays and seasonal B2B checkout dips.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;check_competitor_promos&lt;/code&gt;: Scans market intelligence feeds for aggressive rival discounting.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;check_inventory_stockouts&lt;/code&gt;: Inspects warehouse SKU depletion and unfulfilled hardware bundle backlogs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;check_pricing_changes&lt;/code&gt;: Audits contract repricing, partner promo codes, discount overrides, and unit ACV shifts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;check_etl_pipeline&lt;/code&gt;: Verifies warehouse sync completion, job timestamps, and missing row counts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When an investigation request arrives at &lt;code&gt;POST /api/investigate&lt;/code&gt;, WhyDesk does not immediately hand the five tool schemas to the LLM. Instead, it executes a four-stage loop built around the primitives described in &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;what Hindsight does&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Query + Stakeholder Role
       │
       ▼
1. Hindsight Recall (world, experience, observation) + Reflect
       │
       ▼
2. Memory-Driven Tool Planner (Groq qwen/qwen3-32b -&amp;gt; openai/gpt-oss-120b -&amp;gt; llama-3.3-70b-versatile)
   [Reorders diagnostic tools &amp;amp; enables early stopping once root cause + clean ETL are verified]
       │
       ▼
3. Deterministic Tool Execution + Numeric Grounding Verification
       │
       ▼
4. Synchronous Hindsight Retain (Confirmed cause, ruled-out theories, pipeline reliability, format rule)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9bvtypqcsexoutj10aqx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9bvtypqcsexoutj10aqx.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Technical Story: Turning Memory Into Tool Execution Order
&lt;/h2&gt;

&lt;p&gt;Most agent implementations stuff retrieved text chunks into a prompt and hope the model changes its behavior. In data analysis, passive context is not enough. We needed institutional memory to govern &lt;strong&gt;which diagnostic tools run first&lt;/strong&gt;, &lt;strong&gt;which tools get skipped&lt;/strong&gt;, and &lt;strong&gt;how the final answer is shaped&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We organized our Hindsight memory bank (&lt;code&gt;whydesk-bank&lt;/code&gt;) around three memory types and configured the bank disposition with high skepticism and literalism (&lt;code&gt;skepticism: 4&lt;/code&gt;, &lt;code&gt;literalism: 4&lt;/code&gt;, &lt;code&gt;empathy: 2&lt;/code&gt;) so confirmed metric verdicts always outweigh unverified guesses:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;World facts (&lt;code&gt;world&lt;/code&gt;)&lt;/strong&gt;: Confirmed historical root causes and explicitly falsified hypotheses for a region or product line (for example, &lt;em&gt;"In W10 and W12 for the South region, revenue drops were caused by pricing configuration changes; holiday and competitor promo hypotheses were ruled out"&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational experiences (&lt;code&gt;experience&lt;/code&gt;)&lt;/strong&gt;: Lessons learned about data source reliability (for example, &lt;em&gt;"Monday revenue drops in W11 were false alarms caused by an &lt;code&gt;etl_sales_sync&lt;/code&gt; warehouse stall; always verify ETL pipeline status before trusting Monday numbers"&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stakeholder observations (&lt;code&gt;observation&lt;/code&gt;)&lt;/strong&gt;: Reporting rules per persona (for example, &lt;em&gt;"Stakeholder 'Finance Head' strictly requires a 1-line summary with the exact dollar impact"&lt;/em&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Pre-Investigation Recall and Reflection (&lt;code&gt;backend/memory.py&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Before calling Groq, &lt;code&gt;WhyDeskMemory.recall_context()&lt;/code&gt; queries Hindsight across all three memory types and runs &lt;code&gt;reflect()&lt;/code&gt; to synthesize a tactical plan for the current investigation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;recall_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stakeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Past metric investigations for region &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, reliable vs unreliable data sources, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ruled out causes, and formatting preferences for stakeholder &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stakeholder&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Question: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;recall_resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;world&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;experience&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;observation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;budget&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;memories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;world&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;context&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;context&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recall_resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;reflect_resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reflect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Based on past investigations in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; and stakeholder &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stakeholder&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1) Which diagnostic tools should run first? &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2) Which hypotheses were repeatedly ruled out? &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3) Any data pipeline traps to check first? &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4) How should the final response for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stakeholder&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; be formatted?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;budget&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;memories&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reflection&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reflect_resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Memory-Driven Tool Ordering and Early Stopping (&lt;code&gt;backend/agent.py&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Rather than hardcoding regional rules in Python, &lt;code&gt;backend/agent.py&lt;/code&gt; derives the diagnostic execution queue strictly from the recalled memory text and reflection output. On a cold start (&lt;code&gt;0&lt;/code&gt; recalled memories) or when the user switches the UI toggle to &lt;strong&gt;Memory off&lt;/strong&gt;, the agent runs all five tools in the default baseline sequence (&lt;code&gt;check_holiday_calendar&lt;/code&gt; -&amp;gt; &lt;code&gt;check_competitor_promos&lt;/code&gt; -&amp;gt; &lt;code&gt;check_inventory_stockouts&lt;/code&gt; -&amp;gt; &lt;code&gt;check_pricing_changes&lt;/code&gt; -&amp;gt; &lt;code&gt;check_etl_pipeline&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;When &lt;strong&gt;Memory on&lt;/strong&gt; is active and Hindsight returns prior investigations, the planner scores each diagnostic tool based on recalled pipeline warnings, historical regional root causes, and previously ruled-out checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;derive_tool_order_from_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reflection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;combined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reflection&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DEFAULT_TOOL_ORDER&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;priority_scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;DEFAULT_TOOL_ORDER&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;etl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pipeline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sync&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lag&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;priority_scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_etl_pipeline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pricing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;discount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;promo code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;repricing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;priority_scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_pricing_changes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stockout&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inventory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;priority_scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_inventory_stockouts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ruled out&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;holiday&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;priority_scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_holiday_calendar&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ruled out&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;competitor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;priority_scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_competitor_promos&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;DEFAULT_TOOL_ORDER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;priority_scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;DEFAULT_TOOL_ORDER&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the prioritized tools run, the agent checks whether the warehouse ETL sync is verified clean and a primary anomaly (&lt;code&gt;status == "anomaly_detected"&lt;/code&gt;) has been isolated. When both conditions are met under memory-guided execution, the loop stops early and skips the remaining low-probability checks.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Synchronous Post-Investigation Retention (&lt;code&gt;backend/memory.py&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;In an interactive analytics workflow, an analyst often runs follow-up investigations seconds apart. If memory ingestion happens asynchronously in the background, the very next query might miss the finding that was just confirmed. We set &lt;code&gt;retain_async=False&lt;/code&gt; on every &lt;code&gt;client.retain()&lt;/code&gt; call so verdicts, pipeline notes, and stakeholder preferences are immediately searchable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;In &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;week&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; for the &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; region, the confirmed root cause of the revenue anomaly &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;was &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;confirmed_cause&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (Impact: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dollar_impact&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;). &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ruled-out hypotheses: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ruled_out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ruled_out&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;None&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;investigation_verdict:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;region&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;week&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;week&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;verdict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;confirmed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;retain_async&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Concrete Results: 5-Run Progression and Memory On vs. Off
&lt;/h2&gt;

&lt;p&gt;To verify that every behavioral change comes strictly from stored memories, we ran a five-investigation progression starting from an empty memory bank:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Scenario &amp;amp; Stakeholder&lt;/th&gt;
&lt;th&gt;Recalled Memories&lt;/th&gt;
&lt;th&gt;Tools Executed (In Order)&lt;/th&gt;
&lt;th&gt;Tools Count&lt;/th&gt;
&lt;th&gt;Result &amp;amp; Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Run 1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;W10 South&lt;/code&gt; (-18%) — &lt;em&gt;Finance Head&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;0&lt;/code&gt; (Cold Start)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;holiday&lt;/code&gt; -&amp;gt; &lt;code&gt;competitor&lt;/code&gt; -&amp;gt; &lt;code&gt;inventory&lt;/code&gt; -&amp;gt; &lt;code&gt;pricing&lt;/code&gt; -&amp;gt; &lt;code&gt;etl&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5 / 5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Finds 20% discount tier (-$42,500). Retains verdict + Finance Head's 1-line rule.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Run 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;W11-Mon South&lt;/code&gt; (-64%) — &lt;em&gt;Senior Analyst&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pricing&lt;/code&gt; -&amp;gt; &lt;code&gt;etl&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2 / 5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Discovers &lt;code&gt;etl_sales_sync&lt;/code&gt; stalled at 02:00 UTC ($0 real loss). Retains ETL lag warning.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Run 3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;W11 North&lt;/code&gt; (-24%) — &lt;em&gt;Senior Analyst&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;etl&lt;/code&gt; -&amp;gt; &lt;code&gt;pricing&lt;/code&gt; -&amp;gt; &lt;code&gt;inventory&lt;/code&gt; -&amp;gt; &lt;code&gt;competitor&lt;/code&gt; -&amp;gt; &lt;code&gt;holiday&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5 / 5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Confirms &lt;code&gt;ENT-GATEWAY-02&lt;/code&gt; stockout (-$31,200); explicitly rules out competitor promo &amp;amp; holiday.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Run 4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;W12 South&lt;/code&gt; (-15%) — &lt;em&gt;Senior Analyst&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;etl&lt;/code&gt; -&amp;gt; &lt;code&gt;pricing&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2 / 5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verifies ETL clean first, then catches reactivated &lt;code&gt;SOUTH-Q1-25&lt;/code&gt; promo (-$36,800).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Run 5 (Memory ON)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;W13 South&lt;/code&gt; (-19%) — &lt;em&gt;Finance Head&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;check_etl_pipeline&lt;/code&gt; -&amp;gt; &lt;code&gt;check_pricing_changes&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;2 / 5&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Skips &lt;code&gt;holiday&lt;/code&gt;, &lt;code&gt;competitor&lt;/code&gt;, and &lt;code&gt;inventory&lt;/code&gt;. Returns strict 1-line executive summary.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Run 5 (Memory OFF)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;W13 South&lt;/code&gt; (-19%) — &lt;em&gt;Finance Head&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;0&lt;/code&gt; (Bypassed)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;holiday&lt;/code&gt; -&amp;gt; &lt;code&gt;competitor&lt;/code&gt; -&amp;gt; &lt;code&gt;inventory&lt;/code&gt; -&amp;gt; &lt;code&gt;pricing&lt;/code&gt; -&amp;gt; &lt;code&gt;etl&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;5 / 5&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reverts to running all 5 checks blindly and returns a generic multi-paragraph breakdown.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw27dr0nsdzybgjrsdolt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw27dr0nsdzybgjrsdolt.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;Run 5 with Memory ON&lt;/strong&gt;, WhyDesk recalls the two prior South pricing anomalies, the W11 Monday ETL stall warning, and the Finance Head formatting preference. It checks &lt;code&gt;check_etl_pipeline&lt;/code&gt; first, checks &lt;code&gt;check_pricing_changes&lt;/code&gt; second, skips the three ruled-out checks, and outputs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;W13 South revenue dropped 19% (-$47,900 WoW) due to a regional reseller contract repricing that reduced unit ACV; ETL sync verified clean.&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Synchronous retention (&lt;code&gt;retain_async=False&lt;/code&gt;) eliminates race conditions in sequential debugging&lt;/strong&gt;: When analysts run back-to-back diagnostic queries, waiting for synchronous indexing guarantees that a pipeline warning discovered in one turn immediately protects the next turn.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retaining falsified hypotheses is just as valuable as retaining root causes&lt;/strong&gt;: Explicitly recording that competitor promos and holidays were ruled out in a region gives the planner the signal it needs to deprioritize noisy checks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM tool-calling needs deterministic schema repair and numeric validation&lt;/strong&gt;: Fast inference models occasionally emit malformed tool call payloads or round currency figures in prose. Adding a fallback chain (&lt;code&gt;qwen/qwen3-32b&lt;/code&gt; -&amp;gt; &lt;code&gt;openai/gpt-oss-120b&lt;/code&gt; -&amp;gt; &lt;code&gt;llama-3.3-70b-versatile&lt;/code&gt;) and verifying that every dollar figure in the final response matches the raw tool output kept financial reporting accurate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate data-pipeline health from domain anomalies&lt;/strong&gt;: Storing ETL stalls as &lt;code&gt;experience&lt;/code&gt; memories forced the agent to verify data freshness before blaming pricing or sales execution.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
