<?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: Nicola Mastromarino</title>
    <description>The latest articles on DEV Community by Nicola Mastromarino (@nicolamastromarino).</description>
    <link>https://dev.to/nicolamastromarino</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%2F4060145%2F3f2e1b38-0a47-4c64-aaeb-a6b4b51339d4.jpg</url>
      <title>DEV Community: Nicola Mastromarino</title>
      <link>https://dev.to/nicolamastromarino</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicolamastromarino"/>
    <language>en</language>
    <item>
      <title>5 RAG mistakes that looked fine in the demo and broke in production</title>
      <dc:creator>Nicola Mastromarino</dc:creator>
      <pubDate>Sat, 03 Oct 2026 05:06:32 +0000</pubDate>
      <link>https://dev.to/nicolamastromarino/5-rag-mistakes-that-looked-fine-in-the-demo-and-broke-in-production-cp9</link>
      <guid>https://dev.to/nicolamastromarino/5-rag-mistakes-that-looked-fine-in-the-demo-and-broke-in-production-cp9</guid>
      <description>&lt;p&gt;Every RAG demo works. You pick five questions, the system answers them beautifully, and everyone nods.&lt;/p&gt;

&lt;p&gt;I've built RAG pipelines over clinical notes and over a knowledge graph, and the gap between "works in the demo" and "works on real questions" is bigger than you'd expect. Real users ask messy questions, use acronyms nobody documented, and expect answers from documents that changed last Tuesday.&lt;/p&gt;

&lt;p&gt;Here are five mistakes that pass the demo and fail on real data.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Judging quality by vibes
&lt;/h3&gt;

&lt;p&gt;The demo set is five questions &lt;em&gt;you&lt;/em&gt; wrote, about documents &lt;em&gt;you&lt;/em&gt; know. Of course it works.&lt;/p&gt;

&lt;p&gt;Without an evaluation set you can't tell whether a change to chunking or embeddings made things better or just different. On a clinical QA project (about 40K MIMIC-III notes) I tracked Token F1 and hallucination rate against a baseline. That's the only reason I can say QLoRA fine-tuning cut hallucinations by roughly 40% and lifted Token F1 by 190%, instead of "the answers felt better."&lt;/p&gt;

&lt;p&gt;The same applies to retrieval. Build a golden set of 30-50 real questions, each mapped to the document that should answer it, and measure retrieval &lt;strong&gt;separately&lt;/strong&gt; from generation. If the right chunk never reaches the model, no prompt will save you.&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;hit_rate_at_k&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eval_set&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;hits&lt;/span&gt; &lt;span class="o"&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;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;eval_set&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;relevant_ids&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;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eval_set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Twenty lines of code, and it changes how you work.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Fixed-size chunking
&lt;/h3&gt;

&lt;p&gt;Splitting every document into 500-token blocks is fast and wrong. It cuts tables in half, separates a list from its heading, and ends chunks mid-sentence. The chunk that says "the limit is 10,000" no longer says &lt;em&gt;what&lt;/em&gt; limit.&lt;/p&gt;

&lt;p&gt;Chunk along the document's structure (sections, headings, paragraphs), keep the section title attached as metadata, and consider retrieving small chunks but passing the larger parent section to the model.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Vector search only
&lt;/h3&gt;

&lt;p&gt;Embeddings are great at meaning and mediocre at exact strings. Error codes, product IDs, contract numbers, internal acronyms: this is exactly what users search for, and exactly where pure semantic search is weakest.&lt;/p&gt;

&lt;p&gt;The retriever in my clinical system combines BM25 with a biomedical embedding model, fused with Reciprocal Rank Fusion. Medical text is full of abbreviations and drug names, exactly the kind of string where keyword matching earns its place next to embeddings. Add a reranker on top and you get one of the cheapest upgrades with one of the biggest effects.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Letting the model answer no matter what
&lt;/h3&gt;

&lt;p&gt;When retrieval returns nothing useful, most systems still pass the top-k chunks to the LLM, and the LLM still produces a fluent answer. That's the worst failure mode, because it looks like success.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set a relevance threshold and let the system say "I couldn't find this in the documents."&lt;/li&gt;
&lt;li&gt;Require citations, so a wrong answer is at least checkable.&lt;/li&gt;
&lt;li&gt;Don't stuff the context with 20 chunks "just in case." More context often means more noise, not more accuracy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My clinical QA system keeps a human in the loop (it was designed with the EU AI Act in mind). When the domain is medical, a fluent wrong answer isn't a UX bug, it's a risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Treating the index as finished
&lt;/h3&gt;

&lt;p&gt;The demo index was built once. Real documents change, get deleted, get replaced by newer versions, and some of them shouldn't be visible to every user.&lt;/p&gt;

&lt;p&gt;You need an ingestion pipeline, not a script: updates and deletions handled, versions tracked, metadata filters for permissions, and a plan for re-embedding when you change the embedding model. An answer based on a policy that was withdrawn two months ago is worse than no answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  The pattern behind all five
&lt;/h3&gt;

&lt;p&gt;Every one of these is invisible in a demo and obvious on real data. The demo tests whether the &lt;em&gt;pipeline runs&lt;/em&gt;. Real usage tests whether it &lt;em&gt;retrieves the right thing, says no when it should, and stays correct over time&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Build the evaluation set first. Everything else gets easier once you can measure it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the worst RAG failure you've seen that passed the demo? I'd love to hear the war stories in the comments.&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>ai</category>
      <category>rag</category>
      <category>llm</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>I build LLMs for a living. Here's why I wrote a book about slowing down.</title>
      <dc:creator>Nicola Mastromarino</dc:creator>
      <pubDate>Mon, 03 Aug 2026 13:30:00 +0000</pubDate>
      <link>https://dev.to/nicolamastromarino/i-build-llms-for-a-living-heres-why-i-wrote-a-book-about-slowing-down-3196</link>
      <guid>https://dev.to/nicolamastromarino/i-build-llms-for-a-living-heres-why-i-wrote-a-book-about-slowing-down-3196</guid>
      <description>&lt;p&gt;My job is to make machines think faster.&lt;/p&gt;

&lt;p&gt;I work daily with large language models and generative AI systems. I fine-tune, optimize, reduce latency, eliminate friction. My entire professional value is measured in throughput, tokens per second, inference speed.&lt;/p&gt;

&lt;p&gt;And then one evening I noticed something: it was 11 PM. I had been "productive" for 14 hours straight. My thumb was scrolling through my phone — screen off. Just muscle memory. My brain was too fried to even choose what to look at, but it kept reaching for stimulation anyway.&lt;/p&gt;

&lt;p&gt;That was the moment I realized something was deeply wrong. Not just with me — with how we, as people who build fast systems, have started treating ourselves like fast systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  The paradox nobody talks about in tech
&lt;/h2&gt;

&lt;p&gt;We spend our careers removing friction, automating repetitive tasks, optimizing pipelines. The promise is always the same: "this will save you time."&lt;/p&gt;

&lt;p&gt;But somehow, the more time-saving tools we build and adopt, the less time we feel we have. We're busier than ever. More anxious than ever. More connected than ever, and more exhausted than ever.&lt;/p&gt;

&lt;p&gt;I started digging into the neuroscience behind this. What I found changed how I think about work, attention, and time.&lt;/p&gt;

&lt;p&gt;The ancient Greeks had two completely different words for time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kronos&lt;/strong&gt; — chronological, measurable, ticking time. The kind you track in Jira tickets and calendar blocks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kairos&lt;/strong&gt; — qualitative, dense, meaningful time. The kind where an hour feels like a minute because you're fully present.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern knowledge work, and especially tech culture, has become obsessed with Kronos. We fill every second. We context-switch 50 times a day. We treat rest as wasted clock cycles.&lt;/p&gt;

&lt;p&gt;But here's what the neuroscience actually says: &lt;strong&gt;your brain does its most important work — creativity, memory consolidation, emotional regulation — precisely when you stop optimizing it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Default Mode Network (the part of your brain that activates during rest and "mind wandering") is not idle. It's processing. It's connecting dots you couldn't connect while you were sprinting.&lt;/p&gt;

&lt;p&gt;We've been so busy optimizing Kronos that we've completely destroyed our Kairos.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I did about it
&lt;/h2&gt;

&lt;p&gt;I started writing down protocols for myself. Not productivity hacks. Not "wake up at 5 AM" routines. Just practical, neuroscience-backed ways to protect my attention and reclaim some sense of pace in a job that constantly demands more speed.&lt;/p&gt;

&lt;p&gt;Things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Monotasking blocks&lt;/strong&gt;: single-context work sessions where notifications don't exist&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognitive cooldowns&lt;/strong&gt;: intentional transition rituals between deep work and shallow work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Digital friction by design&lt;/strong&gt;: making the default action the slow one, not the fast one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The notes grew. I kept refining them. Eventually they became a short book: &lt;em&gt;The Art of Slowing Down in the Age of Hyper-Speed&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Writing it felt deeply ironic — an AI engineer writing a manifesto against the very culture his work accelerates. But that's exactly the point. We're the ones building the machines. We're the ones who should understand, better than anyone, why the human brain can't run like one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one thing I'd leave you with
&lt;/h2&gt;

&lt;p&gt;If you work in AI, ML, or any fast-moving area of tech, you probably already feel this tension. The industry screams FASTER every single day. New model, new framework, new benchmark every week.&lt;/p&gt;

&lt;p&gt;You don't have to opt out of all of it. But you do have to protect some space for Kairos. Otherwise, you're just a very expensive server running at 99% CPU with no garbage collection.&lt;/p&gt;

&lt;p&gt;And we all know what happens to systems with no garbage collection.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading. If this resonated, I'd love to hear how you deal with the pressure to optimize everything — including yourself.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>career</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
