<?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: Boda Venkata Hari kiran</title>
    <description>The latest articles on DEV Community by Boda Venkata Hari kiran (@hari8679).</description>
    <link>https://dev.to/hari8679</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%2F4148392%2Fa539b37e-aca9-4d75-9695-b7116095c422.png</url>
      <title>DEV Community: Boda Venkata Hari kiran</title>
      <link>https://dev.to/hari8679</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hari8679"/>
    <language>en</language>
    <item>
      <title>I Taught an On-Call Agent to Remember Mistakes with Hindsight</title>
      <dc:creator>Boda Venkata Hari kiran</dc:creator>
      <pubDate>Tue, 29 Sep 2026 03:13:58 +0000</pubDate>
      <link>https://dev.to/hari8679/i-taught-an-on-call-agent-to-remember-its-own-mistakes-3hb0</link>
      <guid>https://dev.to/hari8679/i-taught-an-on-call-agent-to-remember-its-own-mistakes-3hb0</guid>
      <description>&lt;p&gt;At 2 AM, when a database connection pool exhausts itself for the third time this quarter, the last thing anyone wants is an AI assistant that gives the same generic advice it gave the first two times — including the fix that already failed twice.&lt;/p&gt;

&lt;p&gt;That's the problem I set out to fix with &lt;strong&gt;IncidentMind&lt;/strong&gt;, an on-call incident response agent that doesn't just analyze what's happening right now — it remembers every incident it has seen before, and critically, it remembers which fixes worked and which ones didn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it actually does
&lt;/h2&gt;

&lt;p&gt;IncidentMind takes an incident alert and error log as input — the kind of thing that lands in a Slack channel or PagerDuty ping — and returns a root cause analysis, a ranked list of fix steps, and an estimated urgency and resolution time. Nothing unusual so far; plenty of tools do that with a single LLM call.&lt;/p&gt;

&lt;p&gt;What makes it different is what happens &lt;em&gt;before&lt;/em&gt; that LLM call. Every incoming incident first gets run through &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight&lt;/a&gt;, a persistent memory layer, which searches for similar past incidents and — this is the part I care about — searches separately for records of which fixes worked and which ones failed. Both sets of results get folded into the prompt before the model ever sees the current incident.&lt;/p&gt;

&lt;p&gt;The practical effect: if a database connection pool exhausted itself last month and the team's first instinct — restart the service — didn't fix it, the agent doesn't suggest a restart again. It says so explicitly, citing the incident it's remembering from.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core technical story: retain, then recall, then validate
&lt;/h2&gt;

&lt;p&gt;The architecture is deliberately boring in the right places. A Streamlit front end collects the incident text. A thin wrapper module talks to &lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight's API&lt;/a&gt; for retain and recall calls. Groq serves the LLM inference (&lt;code&gt;openai/gpt-oss-120b&lt;/code&gt;, with a fallback model if the primary is rate-limited).&lt;/p&gt;

&lt;p&gt;The interesting part is the memory schema. I store two separate kinds of memory per incident, not one:&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="c1"&gt;# The incident itself — what happened, and how it was ultimately resolved
&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incidentmind-v1&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INCIDENT MEMORY&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Service: payments-api&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Root cause: DB pool exhaustion...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;document_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incident-INC-001&lt;/span&gt;&lt;span class="sh"&gt;"&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;service&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;payments-api&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;outcome&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;worked&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;tags&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;incident&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;payments-api&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;worked&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="c1"&gt;# The fix outcome — tracked independently, so a failed first attempt
# is recorded even if the incident was eventually resolved differently
&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incidentmind-v1&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FIX OUTCOME: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Immediate service restart&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; FAILED for payments-api. Do NOT recommend again.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;document_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;outcome-INC-001-failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tags&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;outcome&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;payments-api&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;failed&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;fix-result&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;p&gt;Splitting these into two memory types turned out to matter a lot. An incident's &lt;em&gt;final&lt;/em&gt; resolution and its &lt;em&gt;failed first attempts&lt;/em&gt; are different signals, and conflating them means the agent either forgets that a plausible-looking fix already failed, or it can't distinguish "this fix worked" from "this is just what happened during the incident." Recall queries can target either or both:&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;incidents&lt;/span&gt; &lt;span class="o"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incidentmind-v1&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="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;incident_text&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;8000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;outcomes&lt;/span&gt; &lt;span class="o"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incidentmind-v1&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="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;incident_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tags&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;outcome&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;payments-api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;tags_match&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all&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;p&gt;The &lt;code&gt;tags_match="all"&lt;/code&gt; detail cost me a debugging session. My first pass used &lt;code&gt;"any"&lt;/code&gt;, which meant a query for outcome memories on &lt;code&gt;payments-api&lt;/code&gt; also pulled back unrelated outcome memories from other services, because it matched on &lt;em&gt;either&lt;/em&gt; tag rather than both. Precision recall matters more than I expected going in — a noisy memory context doesn't just fail to help, it actively degrades the model's confidence in citing anything specific.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I had to add a safety net
&lt;/h2&gt;

&lt;p&gt;Language models will cite sources that sound plausible even when they weren't given them. Early in testing, I watched the agent confidently cite an incident ID that didn't exist anywhere in the recalled memories — presumably a pattern match on similar-looking IDs elsewhere in its training. That's a real problem for a tool whose entire value proposition is "trust what I'm telling you, because I remember."&lt;/p&gt;

&lt;p&gt;The fix was a post-parse validation step: after the LLM returns its structured response, I strip any cited incident ID that isn't actually present in the set of memories that were recalled for that specific query.&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;_strip_unverified_citations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recalled_ids&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;valid_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recalled_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;parsed_response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fix_steps&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="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parsed_response&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;fix_steps&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;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;step&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;incident_refs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt;
           &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;valid_ids&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incident_refs&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="n"&gt;parsed_response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a small function, but it's the difference between a demo that looks impressive and a tool I'd actually trust during a real incident. Every citation in the UI now traces back to something that was genuinely retrieved from &lt;a href="https://vectorize.io/what-is-agent-memory" rel="noopener noreferrer"&gt;Hindsight's memory layer&lt;/a&gt;, not something the model invented.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like in practice
&lt;/h2&gt;

&lt;p&gt;Here's a concrete before/after. I fed the same incident — a Kafka consumer group falling 600,000 messages behind, rebalancing repeatedly — through the agent twice: once with memory disabled, once with it enabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without memory:&lt;/strong&gt; confidence capped around 35%, generic advice — check consumer lag, review &lt;code&gt;max.poll.records&lt;/code&gt;, consider scaling consumers. Reasonable, but the kind of thing you could find in any runbook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With memory:&lt;/strong&gt; confidence around 85%, and the agent recalled two prior incidents on the same service with the same rebalancing pattern. It ranked its fix steps differently based on what had actually resolved those prior incidents, and it flagged that an immediate consumer restart had been tried before and hadn't helped — because a prior fix attempt on this exact failure pattern was stored as a failed outcome, and recall surfaced it.&lt;/p&gt;

&lt;p&gt;That's the whole pitch, compressed into one interaction: the same failure mode gets progressively cheaper to diagnose the more times it happens, instead of costing the same investigation time every single time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that surprised me: teaching it live
&lt;/h2&gt;

&lt;p&gt;The before/after comparison above is the obvious demo. The thing I didn't expect to find compelling was how the system behaves the moment &lt;em&gt;after&lt;/em&gt; you correct it.&lt;/p&gt;

&lt;p&gt;If the agent suggests a fix and you mark it as failed, that outcome gets retained immediately — no re-indexing step, no batch job, no restart. Run the exact same incident through again a few seconds later, and the agent has already updated: the fix you just marked as failed shows up under a "skipped" section, citing the specific incident you just created, with an explicit note that it was avoided because it didn't work last time.&lt;/p&gt;

&lt;p&gt;It's a small thing mechanically — one write, then one read against fresh data — but it changes how the tool feels to use. Most "AI learns from feedback" claims mean &lt;em&gt;the next training run&lt;/em&gt; will incorporate your correction. Here, the next &lt;em&gt;query&lt;/em&gt;, seconds later, already reflects it. That immediacy is entirely a property of using retrieval over a memory store rather than anything resembling fine-tuning, and it's the single feature that made this feel less like a chatbot with a search index bolted on and more like something that's actually paying attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Retrieval precision beats retrieval volume.&lt;/strong&gt; Pulling back more memories doesn't make the agent smarter — it makes the prompt noisier. Tight tag filtering on retrieval mattered more than raising the token budget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never trust a model's citations without checking them against ground truth.&lt;/strong&gt; This isn't specific to memory systems, but it bites harder here, because the whole point of showing citations is to build trust that erodes instantly the first time one is wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separate "what happened" from "what worked" as distinct memory types.&lt;/strong&gt; Treating an incident's narrative and its fix outcome as one blob makes it much harder to reason about which fixes to avoid recommending again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A memory system needs a way to unlearn, not just accumulate.&lt;/strong&gt; Retaining a failed fix outcome is only useful if a future recall can specifically surface "this was tried and it didn't work" as its own signal, distinct from the incident record itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Confidence should be earned, not assumed.&lt;/strong&gt; Capping confidence when no relevant memory exists — rather than letting the model produce a falsely confident cold-start answer — turned out to be one of the more important design decisions, because it makes the value of memory visible rather than implicit.&lt;/p&gt;

&lt;p&gt;If you're building anything that needs an agent to get better at a recurring task over time rather than starting from zero on every request, a memory layer that can distinguish outcomes — not just events — from each other is worth the extra design effort it takes to set up properly.&lt;/p&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%2F7ht2in8dy2fgpypmn50g.jpeg" 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%2F7ht2in8dy2fgpypmn50g.jpeg" alt=" " width="800" height="440"&gt;&lt;/a&gt;&lt;/p&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%2Fwfxh0ddmrbtu1pmjygo0.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%2Fwfxh0ddmrbtu1pmjygo0.png" alt=" " width="800" height="440"&gt;&lt;/a&gt;&lt;/p&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%2Fqxh2l6qnaec5c236w21r.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%2Fqxh2l6qnaec5c236w21r.png" alt=" " width="800" height="440"&gt;&lt;/a&gt;&lt;/p&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%2Fsu0ayra56c33b0skaiao.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%2Fsu0ayra56c33b0skaiao.png" alt=" " width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>python</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
