<?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: Parth Sarthi Sharma</title>
    <description>The latest articles on DEV Community by Parth Sarthi Sharma (@parth_sarthisharma_105e7).</description>
    <link>https://dev.to/parth_sarthisharma_105e7</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%2F3676140%2F76dc188c-9a29-40da-ad4b-85b4b05c3306.jpg</url>
      <title>DEV Community: Parth Sarthi Sharma</title>
      <link>https://dev.to/parth_sarthisharma_105e7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/parth_sarthisharma_105e7"/>
    <language>en</language>
    <item>
      <title>Golden Paths: Why Platform Engineering Matters More Than Your Repo Strategy</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Sun, 04 Oct 2026 04:12:13 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/golden-paths-why-platform-engineering-matters-more-than-your-repo-strategy-34b6</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/golden-paths-why-platform-engineering-matters-more-than-your-repo-strategy-34b6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A repo strategy decides where your code lives. A golden path decides how fast your team can ship it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A few days ago I wrote about &lt;a href="https://dev.to/parth_sarthisharma_105e7/monorepo-vs-polyrepo-what-actually-matters-when-youre-building-at-scale-42pp"&gt;monorepo vs polyrepo&lt;/a&gt;, and one line in that article kept coming back to me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The repository structure isn't necessarily the problem. Lack of platform engineering is."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article is that sentence, expanded.&lt;/p&gt;

&lt;p&gt;Because here's a pattern I keep seeing: a team spends weeks in architecture meetings debating repo boundaries, naming conventions, ownership models — and then a brand-new service still takes three weeks to reach production. Not because the code was hard. Because setting up CI, security scanning, secrets, logging, and a deployment pipeline from scratch was hard.&lt;/p&gt;

&lt;p&gt;The repo was never the bottleneck. The &lt;em&gt;paved road&lt;/em&gt; was missing.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Question We Keep Asking Wrong
&lt;/h2&gt;

&lt;p&gt;Most platform conversations start with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Should this be a shared library, a shared repo, a shared pipeline?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more useful question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"When an engineer wants to build and ship something new, what is the fastest, safest way for them to do it — without reinventing infrastructure every time?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question has a name: a &lt;strong&gt;golden path&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. What a Golden Path Actually Is
&lt;/h2&gt;

&lt;p&gt;A golden path (sometimes called a "paved road") is the opinionated, well-supported, default way of doing something inside an engineering organisation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New service needed
        ↓
Golden path exists?
        ↓
   Yes ──────────────► Use the template
                        CI/CD pre-wired
                        Security scans included
                        Observability included
                        Deploy in hours

   No ───────────────► Build pipeline from scratch
                        Negotiate access
                        Copy-paste from another team
                        Deploy in weeks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's not a mandate. It's not the &lt;em&gt;only&lt;/em&gt; way. It's the way that requires the least thought, because the platform team has already made the hard decisions for you — and tested them.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. A Familiar Scenario
&lt;/h2&gt;

&lt;p&gt;Imagine two engineers, same company, same week, both asked to ship a new internal service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineer A&lt;/strong&gt; (no golden path):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copies a Dockerfile from a service that "looked similar"&lt;/li&gt;
&lt;li&gt;Manually requests CI runners&lt;/li&gt;
&lt;li&gt;Asks three people how secrets are supposed to be managed&lt;/li&gt;
&lt;li&gt;Finds out the logging format is inconsistent with the rest of the org&lt;/li&gt;
&lt;li&gt;Ships in week 3, with gaps the security team finds a month later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Engineer B&lt;/strong&gt; (golden path exists):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runs &lt;code&gt;platform create-service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Gets a repo with CI, linting, test scaffolding, a Dockerfile, and a deployment manifest already wired to the org's standards&lt;/li&gt;
&lt;li&gt;Observability and secrets are configured by default&lt;/li&gt;
&lt;li&gt;Ships by day 2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same company. Same skill level. Different experience entirely — because of infrastructure, not ability.&lt;/p&gt;

&lt;p&gt;This is the gap platform engineering exists to close.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Why "Just Pick Monorepo or Polyrepo" Doesn't Fix This
&lt;/h2&gt;

&lt;p&gt;A monorepo makes code &lt;em&gt;visible&lt;/em&gt;. A polyrepo makes ownership &lt;em&gt;explicit&lt;/em&gt;. Neither one, by itself, gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a pre-approved way to stand up a new service&lt;/li&gt;
&lt;li&gt;consistent security scanning&lt;/li&gt;
&lt;li&gt;consistent CI/CD behaviour&lt;/li&gt;
&lt;li&gt;a known, supported way to deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can have a perfectly organised monorepo and still have every team building CI pipelines from scratch inside it. You can have 80 polyrepos and still have them all following the exact same paved road, because a platform team maintains the template they were all created from.&lt;/p&gt;

&lt;p&gt;Repo strategy is about &lt;strong&gt;where code lives&lt;/strong&gt;.&lt;br&gt;
Platform engineering is about &lt;strong&gt;how code gets from an engineer's laptop to production, safely, repeatedly, and without reinventing the wheel every time.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  5. What This Looks Like in Practice
&lt;/h2&gt;

&lt;p&gt;This isn't a new idea — several engineering orgs have publicly written about building exactly this kind of paved road:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spotify&lt;/strong&gt; popularised the term "golden path" itself, and open-sourced &lt;strong&gt;Backstage&lt;/strong&gt; as a developer portal so engineers could discover services, templates, and documentation in one place instead of hunting through wikis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netflix&lt;/strong&gt; has talked publicly about its "paved road" philosophy — teams are free to go off-road, but the paved road is deliberately the path of least resistance, kept effortless on purpose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uber&lt;/strong&gt; and several other large engineering orgs built internal developer portals specifically because the cost of onboarding a new microservice had quietly become one of their biggest sources of engineering time loss.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common thread isn't the tooling. It's the philosophy: &lt;strong&gt;make the right way the easy way.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  6. The Anatomy of a Golden Path
&lt;/h2&gt;

&lt;p&gt;A good golden path usually bundles together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Golden Path
   │
   ├── Service template (language, folder structure, linting)
   ├── CI pipeline (build, test, security scan — pre-wired)
   ├── Deployment manifest (Kubernetes/Terraform defaults)
   ├── Observability (logging, metrics, tracing — on by default)
   ├── Secrets &amp;amp; access management (no manual requests)
   └── Documentation (how it works, how to deviate)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the last item: &lt;strong&gt;how to deviate.&lt;/strong&gt; A golden path that has no escape hatch isn't a golden path — it's a mandate wearing a nicer name. More on that below.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Golden Path vs Guardrail vs Mandate
&lt;/h2&gt;

&lt;p&gt;These three get confused constantly, so it's worth separating them:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Golden path&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The easiest default. Optional but heavily incentivised.&lt;/td&gt;
&lt;td&gt;A pre-built service template with CI/CD included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Guardrail&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;An automated check that prevents unsafe behaviour.&lt;/td&gt;
&lt;td&gt;A pipeline that blocks deploys without passing security scans&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mandate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A rule enforced regardless of context.&lt;/td&gt;
&lt;td&gt;"All services must be written in Go"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Healthy platform engineering leans on golden paths and guardrails. Mandates, used too liberally, create resentment and workarounds — engineers will always find a way around a rule they don't believe in.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. The Hidden Cost of &lt;em&gt;Not&lt;/em&gt; Having a Golden Path
&lt;/h2&gt;

&lt;p&gt;When there's no paved road, every team quietly builds their own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Team A → Jenkins, custom Dockerfile, manual secrets
Team B → GitHub Actions, different base image, different logging format
Team C → GitLab CI, yet another deployment pattern
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nobody did anything wrong. Each team solved their own problem reasonably. But now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security has to audit N different pipelines instead of one&lt;/li&gt;
&lt;li&gt;Incident response is slower because every service logs differently&lt;/li&gt;
&lt;li&gt;Onboarding a new engineer means re-learning infrastructure per team&lt;/li&gt;
&lt;li&gt;Upgrading a shared dependency (say, a security patch) means N different manual rollouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the same "hidden coupling" problem from the repo-strategy article — just moved from code to infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Treat the Platform Like a Product
&lt;/h2&gt;

&lt;p&gt;The single biggest mindset shift that makes platform engineering work: &lt;strong&gt;the platform team's users are other engineers, and the platform is a product they chose to use — not a policy they're forced to follow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Golden paths should be genuinely &lt;em&gt;easier&lt;/em&gt; than the alternative, not just officially sanctioned&lt;/li&gt;
&lt;li&gt;Platform teams should gather feedback like a product team does — adoption metrics, friction points, feature requests&lt;/li&gt;
&lt;li&gt;Deviating from the golden path should be &lt;em&gt;possible&lt;/em&gt;, just slightly more effort — never blocked outright without a very good reason&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If engineers are opting out of the golden path en masse, that's not a compliance problem. That's a product-market-fit problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. A Practical Decision Framework
&lt;/h2&gt;

&lt;p&gt;Instead of asking "do we need a platform team," ask:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Are multiple teams solving the same infra problem independently?&lt;/td&gt;
&lt;td&gt;Build a golden path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Does onboarding a new service take days instead of hours?&lt;/td&gt;
&lt;td&gt;Build a golden path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Are security/compliance checks inconsistent across services?&lt;/td&gt;
&lt;td&gt;Add guardrails&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is the platform team becoming a bottleneck for every deploy?&lt;/td&gt;
&lt;td&gt;Loosen the mandate, strengthen self-service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Are engineers bypassing the golden path regularly?&lt;/td&gt;
&lt;td&gt;Treat it as product feedback, not a discipline issue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is the org under ~20 engineers?&lt;/td&gt;
&lt;td&gt;A lightweight template may beat a full platform team&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Platform engineering, like repo strategy, is a set of trade-offs — not a universal answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. What I'd Avoid
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern 1: Building the platform before anyone asks for it&lt;/strong&gt;&lt;br&gt;
Platform teams that build in isolation from product teams tend to build the wrong thing, beautifully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern 2: No escape hatch&lt;/strong&gt;&lt;br&gt;
If the golden path is the &lt;em&gt;only&lt;/em&gt; path, it becomes a bottleneck the moment it doesn't fit an edge case — and it always eventually doesn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern 3: Treating the platform as "done"&lt;/strong&gt;&lt;br&gt;
A golden path that isn't updated as the org's needs evolve becomes the exact legacy problem it was built to prevent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern 4: Measuring success by mandate compliance&lt;/strong&gt;&lt;br&gt;
"90% of services use our template" is a vanity metric if engineers are using it because they have to, not because it's genuinely the fastest option.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. How to Start, Practically
&lt;/h2&gt;

&lt;p&gt;If there's no golden path today, you don't need a platform team of twenty to begin:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick the single most repeated piece of setup pain (usually CI/CD scaffolding or service bootstrapping)&lt;/li&gt;
&lt;li&gt;Build one opinionated template for it&lt;/li&gt;
&lt;li&gt;Use it yourself on the next real service — don't theorise it&lt;/li&gt;
&lt;li&gt;Get one other team to adopt it and listen hard to their friction&lt;/li&gt;
&lt;li&gt;Only then formalise it into a platform with documentation and ownership&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Golden paths earn trust by being used, not by being announced.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. The Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Repo strategy and platform engineering solve different problems.&lt;/strong&gt; One is about code organisation, the other is about developer experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A golden path is the easiest default, not a mandate.&lt;/strong&gt; It should be fast enough that engineers want to use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guardrails, not rules, keep things safe at scale.&lt;/strong&gt; Automate the check, don't just write the policy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The platform is a product.&lt;/strong&gt; Its users can, and will, opt out if it isn't good.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start small.&lt;/strong&gt; One good template beats a grand, unused platform roadmap.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;The monorepo vs polyrepo debate gets attention because it's visible — you can see it in the folder structure. Platform engineering is invisible when it's working, which is exactly why it's underinvested.&lt;/p&gt;

&lt;p&gt;But ask any engineer who has shipped a service in three hours on a well-paved road, and then shipped one in three weeks without it — they'll tell you which decision actually mattered more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose your repo strategy deliberately. But build the road before you argue about where it should lead.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is the second article in a series on engineering decisions that look architectural but are really about people and workflow. First one was on &lt;a href="https://dev.to/parth_sarthisharma_105e7/monorepo-vs-polyrepo-what-actually-matters-when-youre-building-at-scale-42pp"&gt;monorepo vs polyrepo&lt;/a&gt; — next one's on single-agent vs multi-agent systems, and it turns out the same boundary questions show up there too.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>platformengineering</category>
      <category>devops</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>The Architecture of AI-Native Software Teams: What Changes When AI Writes the Code?</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Mon, 28 Sep 2026 09:53:31 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/the-architecture-of-ai-native-software-teams-what-changes-when-ai-writes-the-code-4884</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/the-architecture-of-ai-native-software-teams-what-changes-when-ai-writes-the-code-4884</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI is making code cheaper to produce. That doesn't make architecture less important. It makes good architecture more valuable.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A few years ago, the limiting factor for many engineering teams was simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How quickly can we write the code?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Today, that question is changing.&lt;/p&gt;

&lt;p&gt;AI coding tools can already generate features, write tests, fix bugs, refactor code, update documentation and work through GitHub pull requests with increasing autonomy. GitHub's coding agent, for example, can take an issue, work in an isolated development environment, modify the code, run tests and open a pull request for human review.&lt;/p&gt;

&lt;p&gt;Tools such as Claude Code are also moving beyond autocomplete toward agents that can navigate a codebase, edit multiple files, execute commands, test and debug software.&lt;/p&gt;

&lt;p&gt;So here's the question I think engineering leaders should be asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If producing code is no longer the primary bottleneck, what becomes the bottleneck?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context, architecture, verification and decision-making.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that changes how we should design software teams.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Old Software Engineering Loop
&lt;/h2&gt;

&lt;p&gt;The traditional development loop looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requirement
    ↓
Engineer understands requirement
    ↓
Design
    ↓
Write code
    ↓
Write tests
    ↓
Code review
    ↓
CI/CD
    ↓
Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A significant amount of engineering time is spent on implementation.&lt;/p&gt;

&lt;p&gt;Now introduce an AI coding agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requirement
    ↓
Engineer + AI
    ↓
Design
    ↓
AI implements
    ↓
AI writes tests
    ↓
AI runs validation
    ↓
Engineer reviews
    ↓
CI/CD
    ↓
Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation step becomes dramatically cheaper.&lt;/p&gt;

&lt;p&gt;But notice something interesting.&lt;/p&gt;

&lt;p&gt;The human still needs to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are we actually building?&lt;/li&gt;
&lt;li&gt;What should the architecture look like?&lt;/li&gt;
&lt;li&gt;What constraints matter?&lt;/li&gt;
&lt;li&gt;What should the agent not touch?&lt;/li&gt;
&lt;li&gt;Is this API boundary correct?&lt;/li&gt;
&lt;li&gt;Is this database model correct?&lt;/li&gt;
&lt;li&gt;Is this security model acceptable?&lt;/li&gt;
&lt;li&gt;Does this code belong here?&lt;/li&gt;
&lt;li&gt;What happens when this fails?&lt;/li&gt;
&lt;li&gt;What happens at 10x scale?&lt;/li&gt;
&lt;li&gt;What happens during partial failure?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The human role is moving &lt;strong&gt;up the abstraction stack&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. AI Doesn't Remove Engineering Work
&lt;/h2&gt;

&lt;p&gt;This is where I think some AI discussions go wrong.&lt;/p&gt;

&lt;p&gt;The assumption is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI writes code faster
        ↓
Software engineering becomes easier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The more realistic model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI writes code faster
        ↓
More code gets produced
        ↓
More code needs validation
        ↓
More architectural decisions become important
        ↓
More system-level risks become possible
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DORA's recent research describes AI as an &lt;strong&gt;amplifier&lt;/strong&gt; of an organisation's existing strengths and weaknesses. Its 2026 analysis also found that the time saved during initial code creation is frequently reallocated to auditing and verification.&lt;/p&gt;

&lt;p&gt;That's a really important signal.&lt;/p&gt;

&lt;p&gt;The bottleneck may simply move.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The New Engineering Bottleneck
&lt;/h2&gt;

&lt;p&gt;Imagine an engineer could previously produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100 lines/day
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and an AI-assisted workflow can produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,000 lines/day
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That sounds like a 10x improvement.&lt;/p&gt;

&lt;p&gt;But what if your team can only effectively review:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;300 lines/day
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;?&lt;/p&gt;

&lt;p&gt;You haven't created a 10x engineering organisation.&lt;/p&gt;

&lt;p&gt;You've created a review queue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                  AI
                   │
                   ↓
             ┌──────────┐
             │  Code    │
             │ generated│
             └────┬─────┘
                  ↓
        ┌───────────────────┐
        │ Human verification│
        └─────────┬─────────┘
                  ↓
              Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the most important shifts I see coming:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Code generation is becoming cheaper. Code verification is becoming more valuable.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. The New Division of Labour
&lt;/h2&gt;

&lt;p&gt;I don't think the future is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Humans → code
AI → code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's closer to:&lt;/p&gt;

&lt;h3&gt;
  
  
  Humans own
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intent
Architecture
Boundaries
Business rules
Security decisions
Trade-offs
Risk
Quality bar
Production accountability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AI agents own more of
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Implementation
Boilerplate
Tests
Refactoring
Documentation
Dependency upgrades
Migration scripts
Code exploration
Bug investigation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This doesn't mean AI should blindly own the second list.&lt;/p&gt;

&lt;p&gt;It means those are areas where &lt;strong&gt;delegation can often provide high leverage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The interesting engineering problem becomes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How much autonomy should we give the agent for each type of change?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Not All Code Changes Should Have the Same Autonomy
&lt;/h2&gt;

&lt;p&gt;This is one of the practical patterns I would introduce in an AI-native engineering team.&lt;/p&gt;

&lt;p&gt;Classify changes by risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 1 — Low risk
&lt;/h2&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Documentation
Unit tests
Formatting
Simple refactoring
Boilerplate
Non-production tooling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI can potentially operate with high autonomy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 2 — Medium risk
&lt;/h2&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business logic
API changes
Database queries
Performance changes
Dependency upgrades
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI can implement.&lt;/p&gt;

&lt;p&gt;Human reviews carefully.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 3 — High risk
&lt;/h2&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication
Authorisation
Payment logic
Data migrations
Encryption
Infrastructure
Production configuration
Security controls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI can assist heavily.&lt;/p&gt;

&lt;p&gt;But humans should retain strong approval and verification controls.&lt;/p&gt;

&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 AI autonomy
                     ↑
                     │
Low risk ────────────┤ High autonomy
                     │
Medium risk ─────────┤ Human review
                     │
High risk ───────────┤ Strong human control
                     │
                     ↓
                 Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let AI do everything."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Give AI as much autonomy as the risk model allows."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Architecture Becomes the Agent's Constraint System
&lt;/h2&gt;

&lt;p&gt;Here's an interesting change.&lt;/p&gt;

&lt;p&gt;Humans have always relied on architecture to constrain developers.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Controller
    ↓
Service
    ↓
Repository
    ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that architecture also constrains AI agents.&lt;/p&gt;

&lt;p&gt;This becomes extremely important.&lt;/p&gt;

&lt;p&gt;If an agent sees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services/
├── payments/
├── orders/
├── customers/
└── shared/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but there are no clear boundaries, it may make perfectly valid code changes that are architecturally wrong.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;payments-service
        ↓
directly queries
        ↓
customers database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code might compile.&lt;/p&gt;

&lt;p&gt;Tests might pass.&lt;/p&gt;

&lt;p&gt;The architecture is still wrong.&lt;/p&gt;

&lt;p&gt;So architecture needs to become increasingly &lt;strong&gt;machine-readable&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Make Architecture Explicit
&lt;/h2&gt;

&lt;p&gt;One practical pattern is to put architectural context directly into the repository.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;repository/
│
├── README.md
├── ARCHITECTURE.md
├── ADR/
│   ├── 001-service-boundaries.md
│   ├── 002-database-choice.md
│   └── 003-event-driven-integration.md
│
├── services/
│
├── libraries/
│
├── tests/
│
└── docs/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the agent has something better than:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Figure out how this system works."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It has explicit context.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Payments service

Owns:
- Payment lifecycle
- Payment state
- Payment reconciliation

Does not own:
- Customer identity
- Product catalogue

Integration:
- Customer information via Customer API
- Events published through Event Bus

Never:
- Access another service's database directly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't documentation for humans only anymore.&lt;/p&gt;

&lt;p&gt;It becomes part of the &lt;strong&gt;agent's operating context&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Your README Is Becoming Part of the Development Interface
&lt;/h2&gt;

&lt;p&gt;We've historically treated documentation as something developers read.&lt;/p&gt;

&lt;p&gt;With coding agents, documentation increasingly becomes something agents &lt;strong&gt;consume before making changes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This changes what good documentation looks like.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This service handles payments.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Payment Service

## Responsibilities

Owns payment lifecycle and reconciliation.

## Boundaries

DO:
- Create payment
- Authorise payment
- Capture payment
- Refund payment

DO NOT:
- Read customer database
- Modify order state directly
- Store authentication credentials

## Dependencies

Customer information:
Customer API

Order information:
Order API

## Testing

Run:
./gradlew test

Integration tests:
./gradlew integrationTest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful to humans.&lt;/p&gt;

&lt;p&gt;It is also much more useful to agents.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. The Codebase Needs a "Constitution"
&lt;/h2&gt;

&lt;p&gt;This is one of the patterns I think will become increasingly common.&lt;/p&gt;

&lt;p&gt;Create a small set of explicit engineering rules.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENGINEERING_RULES.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Containing things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Services must not access another service's database.

2. Public APIs require backward compatibility.

3. Database migrations must be backward compatible.

4. All external calls require timeouts.

5. Retries must use bounded exponential backoff.

6. New APIs require contract tests.

7. Authentication logic must not be implemented inside
   individual business services.

8. Production infrastructure changes require human approval.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now an AI agent doesn't need to infer all of these rules from thousands of lines of code.&lt;/p&gt;

&lt;p&gt;You've made the constraints explicit.&lt;/p&gt;

&lt;p&gt;The industry is already moving toward this idea of giving agents structured procedural and organisational context. Anthropic, for example, describes "Agent Skills" as a way to package instructions, scripts and resources so agents can perform specialised work more reliably.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Tests Become More Important Than Ever
&lt;/h2&gt;

&lt;p&gt;There's another major shift.&lt;/p&gt;

&lt;p&gt;Previously:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tests protect us from developer mistakes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In an AI-native workflow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tests become executable specifications for agents.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requirement:

A payment must never be captured twice.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A human can understand that.&lt;/p&gt;

&lt;p&gt;But a much stronger contract is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;shouldNotCapturePaymentTwice&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the agent has a deterministic boundary.&lt;/p&gt;

&lt;p&gt;This creates a powerful loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requirement
     ↓
Architecture
     ↓
Tests
     ↓
AI implementation
     ↓
Run tests
     ↓
Fix
     ↓
Run tests again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The better your tests are, the more autonomy you can safely give the agent.&lt;/p&gt;

&lt;p&gt;This is one reason coding agents tend to work better in well-tested codebases. GitHub explicitly highlights well-tested repositories as a strong environment for coding-agent tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. CI/CD Becomes an AI Safety Boundary
&lt;/h2&gt;

&lt;p&gt;In traditional development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer
   ↓
PR
   ↓
CI
   ↓
Review
   ↓
Merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With agents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human
  ↓
Task
  ↓
AI agent
  ↓
Code
  ↓
Tests
  ↓
Security checks
  ↓
Policy checks
  ↓
PR
  ↓
Human approval
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CI is no longer just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Does the code compile?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It becomes an executable governance layer.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PR
 │
 ├── Compile
 ├── Unit tests
 ├── Integration tests
 ├── Contract tests
 ├── Static analysis
 ├── Dependency scan
 ├── Secret scan
 ├── Security tests
 ├── Architecture rules
 └── Policy checks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how you allow agents to move faster &lt;strong&gt;without removing engineering controls&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. Don't Give Agents Production Access by Default
&lt;/h2&gt;

&lt;p&gt;This sounds obvious.&lt;/p&gt;

&lt;p&gt;But agentic workflows change the threat model.&lt;/p&gt;

&lt;p&gt;An agent that can:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;read code
write code
run commands
access network
modify infrastructure
deploy software
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;has a very different risk profile from autocomplete.&lt;/p&gt;

&lt;p&gt;Modern agent tooling is therefore increasingly introducing sandboxing, scoped credentials and filesystem/network boundaries. Anthropic, for example, describes sandboxing Claude Code with filesystem and network isolation as part of making autonomous coding safer.&lt;/p&gt;

&lt;p&gt;A practical model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer Agent
       │
       ├── Read repository
       ├── Modify branch
       ├── Run tests
       └── Build artifacts
              │
              ↓
         Human approval
              │
              ↓
          Deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI
 ↓
Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. Small PRs Become Even More Important
&lt;/h2&gt;

&lt;p&gt;Imagine an agent generates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;27 files
4,000 lines changed
3 new dependencies
2 database migrations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Technically impressive.&lt;/p&gt;

&lt;p&gt;Practically horrible to review.&lt;/p&gt;

&lt;p&gt;The human reviewer is now the bottleneck.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task
 ↓
Small change
 ↓
Tests
 ↓
PR
 ↓
Review
 ↓
Next change
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Small changes make:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reviews easier&lt;/li&gt;
&lt;li&gt;failures easier to diagnose&lt;/li&gt;
&lt;li&gt;rollbacks safer&lt;/li&gt;
&lt;li&gt;AI mistakes easier to detect&lt;/li&gt;
&lt;li&gt;context easier to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI gives us the ability to generate huge changes.&lt;/p&gt;

&lt;p&gt;Engineering discipline should prevent us from automatically accepting them.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Context Is Becoming an Engineering Resource
&lt;/h2&gt;

&lt;p&gt;Here's another subtle change.&lt;/p&gt;

&lt;p&gt;An AI agent is only as effective as the context it can access.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task:
"Add customer notifications."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's almost useless.&lt;/p&gt;

&lt;p&gt;Compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Goal:
Send an email when a payment succeeds.

Architecture:
Notifications are owned by notification-service.

Constraints:
- Payment service publishes PaymentCaptured event.
- Notification service consumes the event.
- Payment service must not call the notification service synchronously.
- Email delivery must be idempotent.

Acceptance criteria:
- Duplicate events must not send duplicate emails.
- Failed delivery must retry.
- Retry must be bounded.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second task is dramatically easier for both humans and agents.&lt;/p&gt;

&lt;p&gt;This leads to a new engineering skill:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Context engineering for software development.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not prompt tricks.&lt;/p&gt;

&lt;p&gt;Actual engineering context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;architecture&lt;/li&gt;
&lt;li&gt;domain vocabulary&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;constraints&lt;/li&gt;
&lt;li&gt;tests&lt;/li&gt;
&lt;li&gt;examples&lt;/li&gt;
&lt;li&gt;ADRs&lt;/li&gt;
&lt;li&gt;operational knowledge&lt;/li&gt;
&lt;li&gt;security rules&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  15. The New Staff Engineer Job
&lt;/h2&gt;

&lt;p&gt;This is where I think the role of Staff and Principal Engineers changes significantly.&lt;/p&gt;

&lt;p&gt;The question becomes less:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I write this code?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And more:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I create a system where humans and agents can safely produce good software?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That means investing in:&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;Clear boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer experience
&lt;/h3&gt;

&lt;p&gt;Easy local setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;p&gt;Machine-readable context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;Strong executable specifications.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD
&lt;/h3&gt;

&lt;p&gt;Automated verification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;Least privilege and isolation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Observability
&lt;/h3&gt;

&lt;p&gt;Fast feedback from production.&lt;/p&gt;

&lt;h3&gt;
  
  
  Engineering standards
&lt;/h3&gt;

&lt;p&gt;Explicit constraints.&lt;/p&gt;

&lt;h3&gt;
  
  
  Platform engineering
&lt;/h3&gt;

&lt;p&gt;Reusable capabilities for every team.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Staff engineering becomes increasingly about designing the environment in which software gets produced.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  16. The Architecture of an AI-Native Team
&lt;/h2&gt;

&lt;p&gt;Putting this together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    HUMAN
                      │
                      │
              Intent / Architecture
                      │
                      ↓
             ┌─────────────────┐
             │   AI Agent(s)   │
             └────────┬────────┘
                      │
        ┌─────────────┼──────────────┐
        ↓             ↓              ↓
     Code           Tests       Documentation
        │             │              │
        └─────────────┼──────────────┘
                      ↓
                 CI / Policy
                      │
        ┌─────────────┼─────────────┐
        ↓             ↓             ↓
     Security      Architecture   Quality
      checks          checks       checks
        │             │             │
        └─────────────┼─────────────┘
                      ↓
               Human Approval
                      │
                      ↓
                 Production
                      │
                      ↓
              Observability
                      │
                      ↓
                  Feedback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice what's missing?&lt;/p&gt;

&lt;p&gt;A human manually writing every line.&lt;/p&gt;

&lt;p&gt;The human is instead controlling:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;intent → architecture → constraints → verification → risk → outcome&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  17. What Happens to Junior Engineers?
&lt;/h2&gt;

&lt;p&gt;This is an uncomfortable question.&lt;/p&gt;

&lt;p&gt;If AI can handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;boilerplate&lt;/li&gt;
&lt;li&gt;basic CRUD&lt;/li&gt;
&lt;li&gt;straightforward tests&lt;/li&gt;
&lt;li&gt;simple refactoring&lt;/li&gt;
&lt;li&gt;documentation&lt;/li&gt;
&lt;li&gt;basic debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;then some traditional entry-level tasks become less valuable as learning mechanisms.&lt;/p&gt;

&lt;p&gt;That doesn't mean junior engineers become unnecessary.&lt;/p&gt;

&lt;p&gt;It means the learning path has to change.&lt;/p&gt;

&lt;p&gt;A junior engineer shouldn't only learn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How to write CRUD APIs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They should increasingly learn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Why this API exists
Why this boundary exists
How failure happens
How data flows
How systems behave under load
How to test assumptions
How to review generated code
How to reason about security
How to operate software
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ability to &lt;strong&gt;judge code&lt;/strong&gt; becomes more important than the ability to produce large amounts of code.&lt;/p&gt;




&lt;h2&gt;
  
  
  18. Measure the Right Things
&lt;/h2&gt;

&lt;p&gt;One of the easiest mistakes is measuring AI adoption by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lines of code generated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Number of AI prompts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those aren't meaningful engineering outcomes.&lt;/p&gt;

&lt;p&gt;I'd rather measure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lead time for change
Change failure rate
Review time
PR size
Defect rate
Rollback rate
Incident rate
Test coverage
Developer satisfaction
Time from idea → production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And perhaps one of the most interesting metrics:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How much human attention does each production change require?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because that's potentially the new scarce resource.&lt;/p&gt;




&lt;h2&gt;
  
  
  19. A Practical AI-Native Development Workflow
&lt;/h2&gt;

&lt;p&gt;If I were introducing agentic development into an engineering team tomorrow, I'd start relatively conservatively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Give the agent context
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;README
ARCHITECTURE
ADRs
ENGINEERING_RULES
API contracts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 — Give it a bounded task
&lt;/h3&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Improve the payment system."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Add idempotency handling to POST /payments.

Do not change the API contract.

Use the existing IdempotencyStore.

Add unit and integration tests.

Do not modify database schema."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 — Let the agent implement
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
 ↓
Code
 ↓
Tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4 — Run automated verification
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build
Tests
Security
Architecture
Contracts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5 — Human reviews the important things
&lt;/h3&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Did the AI write valid Java?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Did it implement the correct behaviour?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Did it preserve the architecture?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 6 — Merge small changes
&lt;/h3&gt;

&lt;p&gt;Keep the feedback loop tight.&lt;/p&gt;




&lt;h2&gt;
  
  
  20. The Biggest Anti-Pattern: AI + Bad Architecture
&lt;/h2&gt;

&lt;p&gt;Here's the scenario I'm most concerned about.&lt;/p&gt;

&lt;p&gt;You have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Poor boundaries
+
Poor tests
+
Poor documentation
+
AI coding agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens?&lt;/p&gt;

&lt;p&gt;The AI doesn't magically fix the architecture.&lt;/p&gt;

&lt;p&gt;It can actually make the problem worse faster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bad architecture
       ↓
AI generates more code
       ↓
More coupling
       ↓
More complexity
       ↓
Harder reviews
       ↓
More technical debt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is exactly why the "AI makes developers 10x" narrative needs context.&lt;/p&gt;

&lt;p&gt;AI can amplify good engineering.&lt;/p&gt;

&lt;p&gt;It can also amplify bad engineering.&lt;/p&gt;

&lt;p&gt;DORA's research makes essentially this broader point: AI tends to amplify the underlying capabilities and weaknesses of the organisation using it.&lt;/p&gt;




&lt;h2&gt;
  
  
  21. So What Actually Changes?
&lt;/h2&gt;

&lt;p&gt;I don't think the fundamental principles of software engineering disappear.&lt;/p&gt;

&lt;p&gt;They become more important.&lt;/p&gt;

&lt;p&gt;We still need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Good boundaries
Good APIs
Good data models
Good tests
Good observability
Good security
Good failure handling
Good operational practices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But now we also need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Machine-readable architecture
Explicit engineering rules
Agent-friendly documentation
Risk-based autonomy
Automated verification
Strong CI/CD guardrails
Scoped agent permissions
Small change sets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's what I would call an &lt;strong&gt;AI-native engineering environment&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  22. My Rule of Thumb
&lt;/h2&gt;

&lt;p&gt;If I had to summarise the whole article in one sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;When AI makes implementation cheap, invest more heavily in the things AI cannot safely decide for you: intent, architecture, constraints, verification and accountability.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or, even more simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before AI:

Code was expensive.
Review was cheaper.

With AI:

Code is cheaper.
Good judgment is expensive.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that changes where engineering organisations should invest.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;I don't think the future of software engineering is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Humans stop coding and AI writes everything.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think it looks more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human
  ↓
Defines intent
  ↓
Designs boundaries
  ↓
Sets constraints
  ↓
AI implements
  ↓
AI validates
  ↓
Automated systems verify
  ↓
Human judges
  ↓
Production learns
  ↓
Architecture evolves
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting competitive advantage won't simply be &lt;strong&gt;who has access to the best coding model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most teams will have access to very capable models.&lt;/p&gt;

&lt;p&gt;The advantage will increasingly come from:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who has the best architecture, context, engineering constraints, feedback loops and ability to safely turn AI-generated code into production outcomes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's the real architecture of an AI-native software team.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>ai</category>
      <category>softwaredevelopment</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Monorepo vs Polyrepo: What Actually Matters When You’re Building at Scale</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Sat, 26 Sep 2026 08:21:16 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/monorepo-vs-polyrepo-what-actually-matters-when-youre-building-at-scale-42pp</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/monorepo-vs-polyrepo-what-actually-matters-when-youre-building-at-scale-42pp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The repository strategy is not really a Git decision. It is an architecture, ownership, and team-boundary decision.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When a team starts building multiple services, one question usually appears sooner or later:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should we keep everything in a monorepo, or should every service have its own repository?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The discussion often turns into a familiar list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monorepo = easier collaboration&lt;/li&gt;
&lt;li&gt;Polyrepo = better isolation&lt;/li&gt;
&lt;li&gt;Monorepo = easier refactoring&lt;/li&gt;
&lt;li&gt;Polyrepo = better team autonomy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these can be true.&lt;/p&gt;

&lt;p&gt;And yet, they don't answer the question that actually matters:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Which repository structure will make our engineers more effective as the system and organisation grow?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After working with distributed systems, microservices, shared libraries, CI/CD pipelines and multiple engineering teams, I've found that the repository itself is rarely the root problem.&lt;/p&gt;

&lt;p&gt;The more important questions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who owns the code?&lt;/li&gt;
&lt;li&gt;How often do services change together?&lt;/li&gt;
&lt;li&gt;How tightly coupled are the teams?&lt;/li&gt;
&lt;li&gt;How are dependencies managed?&lt;/li&gt;
&lt;li&gt;How expensive is CI/CD?&lt;/li&gt;
&lt;li&gt;How easy is cross-service refactoring?&lt;/li&gt;
&lt;li&gt;Where do security and access boundaries exist?&lt;/li&gt;
&lt;li&gt;How much autonomy do teams actually need?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article looks at monorepo vs polyrepo from that perspective.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. First: What Are We Actually Deciding?
&lt;/h2&gt;

&lt;p&gt;At first glance, the decision seems simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monorepo
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;company/
├── services/
│   ├── orders/
│   ├── payments/
│   ├── customers/
│   └── notifications/
├── libraries/
│   ├── auth/
│   ├── logging/
│   └── common/
├── frontend/
└── infrastructure/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One repository contains multiple applications, services and shared components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Polyrepo
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;orders-service       → repository
payments-service     → repository
customers-service    → repository
notifications        → repository
common-library       → repository
frontend             → repository
infrastructure       → repository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But Git repository boundaries don't necessarily equal architectural boundaries.&lt;/p&gt;

&lt;p&gt;A system can have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50 repositories&lt;/li&gt;
&lt;li&gt;20 deployable services&lt;/li&gt;
&lt;li&gt;5 teams&lt;/li&gt;
&lt;li&gt;shared libraries&lt;/li&gt;
&lt;li&gt;tightly coupled release processes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and still effectively behave like one system.&lt;/p&gt;

&lt;p&gt;Likewise, a monorepo can contain completely independent applications owned by different teams.&lt;/p&gt;

&lt;p&gt;So the real decision is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How many Git repositories should we have?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Where should we place boundaries between teams, code, dependencies and delivery pipelines?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a much more useful question.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Monorepo: What It Gives You
&lt;/h2&gt;

&lt;p&gt;A monorepo provides one major capability that becomes extremely valuable as systems evolve:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You can see and change the system as one codebase.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;orders-service
payments-service
customer-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and we need to change an API contract.&lt;/p&gt;

&lt;p&gt;In a monorepo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Change API contract
       ↓
Update producer
       ↓
Update consumers
       ↓
Compile/test everything affected
       ↓
Review one change
       ↓
Merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler and CI system can help us identify the blast radius.&lt;/p&gt;

&lt;p&gt;This becomes particularly valuable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API contract changes&lt;/li&gt;
&lt;li&gt;shared libraries&lt;/li&gt;
&lt;li&gt;security changes&lt;/li&gt;
&lt;li&gt;large refactoring&lt;/li&gt;
&lt;li&gt;framework upgrades&lt;/li&gt;
&lt;li&gt;dependency upgrades&lt;/li&gt;
&lt;li&gt;consistent engineering standards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Java 17 → Java 21

        ↓

orders
payments
customers
notifications
reporting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A monorepo makes it much easier to discover what needs to change.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The Hidden Superpower: Refactoring
&lt;/h2&gt;

&lt;p&gt;This is one of the biggest practical advantages of a monorepo.&lt;/p&gt;

&lt;p&gt;Suppose we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CustomerService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCustomer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;used by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Orders
Payments
Invoices
Reporting
Notifications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine changing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;getCustomer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;getCustomer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CustomerId&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a monorepo, the IDE/compiler/test system can often identify the impact immediately.&lt;/p&gt;

&lt;p&gt;With multiple repositories, you may need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change the shared library&lt;/li&gt;
&lt;li&gt;Publish a new version&lt;/li&gt;
&lt;li&gt;Update repository A&lt;/li&gt;
&lt;li&gt;Update repository B&lt;/li&gt;
&lt;li&gt;Update repository C&lt;/li&gt;
&lt;li&gt;Wait for their CI pipelines&lt;/li&gt;
&lt;li&gt;Deal with version compatibility&lt;/li&gt;
&lt;li&gt;Eventually remove the old API&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The technical change may be tiny.&lt;/p&gt;

&lt;p&gt;The organisational change can be much larger.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. But Monorepos Are Not Free
&lt;/h2&gt;

&lt;p&gt;A monorepo can become painful if we don't invest in engineering tooling.&lt;/p&gt;

&lt;p&gt;Imagine this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;monorepo
│
├── 100 services
├── 20 libraries
├── 10 frontend applications
└── millions of lines of code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A developer changes one line in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;payments-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and CI responds with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build everything
Test everything
Deploy everything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the repository becomes the bottleneck.&lt;/p&gt;

&lt;p&gt;This is where people sometimes incorrectly conclude:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Monorepos don't scale."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more accurate conclusion is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Naive monorepo tooling doesn't scale.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A serious monorepo needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependency graphs&lt;/li&gt;
&lt;li&gt;incremental builds&lt;/li&gt;
&lt;li&gt;affected-test detection&lt;/li&gt;
&lt;li&gt;remote build caching&lt;/li&gt;
&lt;li&gt;parallel CI&lt;/li&gt;
&lt;li&gt;clear ownership&lt;/li&gt;
&lt;li&gt;CODEOWNERS&lt;/li&gt;
&lt;li&gt;good developer tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer changes payments
          ↓
Dependency graph
          ↓
Identify affected components
          ↓
Build/test only what matters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer changes payments
          ↓
Build the entire company
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Polyrepo: Why Teams Choose It
&lt;/h2&gt;

&lt;p&gt;Polyrepo usually starts with a very reasonable requirement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This team should be able to own and deploy its service independently."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Team A
 └── orders-service

Team B
 └── payments-service

Team C
 └── notifications-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each team gets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;its own repository&lt;/li&gt;
&lt;li&gt;its own CI pipeline&lt;/li&gt;
&lt;li&gt;its own deployment lifecycle&lt;/li&gt;
&lt;li&gt;its own permissions&lt;/li&gt;
&lt;li&gt;its own release cadence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can work extremely well.&lt;/p&gt;

&lt;p&gt;Especially when services have genuinely independent ownership.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. The Hidden Cost of Polyrepo
&lt;/h2&gt;

&lt;p&gt;The problem appears when repositories are technically separate but operationally coupled.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;orders-service
       ↓
payments-service
       ↓
customer-service
       ↓
shared-library
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now a breaking change happens in the shared library.&lt;/p&gt;

&lt;p&gt;The change becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shared-library v2
       ↓
orders → update
payments → update
customer → update
reporting → update
notifications → update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suddenly we have a distributed coordination problem.&lt;/p&gt;

&lt;p&gt;The repositories are separate.&lt;/p&gt;

&lt;p&gt;The architecture isn't.&lt;/p&gt;

&lt;p&gt;This can lead to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependency version drift&lt;/li&gt;
&lt;li&gt;duplicated code&lt;/li&gt;
&lt;li&gt;inconsistent frameworks&lt;/li&gt;
&lt;li&gt;inconsistent security fixes&lt;/li&gt;
&lt;li&gt;incompatible API versions&lt;/li&gt;
&lt;li&gt;difficult cross-repository refactoring&lt;/li&gt;
&lt;li&gt;pull-request coordination across teams&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. One of the Biggest Lessons: Microservices ≠ Polyrepo
&lt;/h2&gt;

&lt;p&gt;This is worth calling out explicitly.&lt;/p&gt;

&lt;p&gt;A common architecture evolution looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Monolith
   ↓
Microservices
   ↓
One repository per microservice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last step is not mandatory.&lt;/p&gt;

&lt;p&gt;You can absolutely have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Monorepo
                    │
       ┌────────────┼────────────┐
       ↓            ↓            ↓
    Orders       Payments     Customers
       │            │            │
       └────── independently ────┘
              deployable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deployment boundary and repository boundary can be different.&lt;/p&gt;

&lt;p&gt;That's an important architectural distinction.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Real Engineering Scenario: Shared Libraries
&lt;/h2&gt;

&lt;p&gt;Let's look at a common example.&lt;/p&gt;

&lt;p&gt;Suppose we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;common-auth
common-logging
common-observability
common-http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a polyrepo architecture, these often become separate repositories.&lt;/p&gt;

&lt;p&gt;Then teams consume versions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;common-auth: 1.4.2
common-logging: 3.1.0
common-http: 2.7.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Over time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service A → auth 1.4
Service B → auth 1.5
Service C → auth 1.3
Service D → auth 1.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the organisation has effectively created multiple versions of the same engineering standards.&lt;/p&gt;

&lt;p&gt;This isn't automatically wrong.&lt;/p&gt;

&lt;p&gt;Sometimes independent versioning is exactly what we want.&lt;/p&gt;

&lt;p&gt;But we should recognise the trade-off.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. A Useful Rule for Shared Libraries
&lt;/h2&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Does this library represent a reusable capability or an organisational coupling mechanism?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;h3&gt;
  
  
  Good candidate
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Observability SDK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may evolve independently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Potentially problematic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CompanyBusinessLogicUtils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can become a dumping ground for code that should actually belong to a domain.&lt;/p&gt;

&lt;p&gt;A common anti-pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;common/
├── StringUtils
├── DateUtils
├── CustomerUtils
├── PaymentUtils
├── OrderUtils
├── ValidationUtils
└── EverythingElseUtils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually every service depends on &lt;code&gt;common&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Congratulations.&lt;/p&gt;

&lt;p&gt;You've created a distributed monolith with a shared library.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Repository Boundaries Should Follow Ownership
&lt;/h2&gt;

&lt;p&gt;One of the strongest signals for repository boundaries is &lt;strong&gt;team ownership&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Team: Payments

Owns:
├── payments-api
├── payment-processing
├── reconciliation
└── payment-risk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These components may benefit from being in the same repository.&lt;/p&gt;

&lt;p&gt;Because the same team:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;changes them together&lt;/li&gt;
&lt;li&gt;reviews them&lt;/li&gt;
&lt;li&gt;deploys them&lt;/li&gt;
&lt;li&gt;understands their dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Payments team
        ↓
Customer team
        ↓
Identity team
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If every change requires three teams to coordinate, the problem may not be the repository.&lt;/p&gt;

&lt;p&gt;It may be the architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Repository Boundaries Should Follow Change Patterns
&lt;/h2&gt;

&lt;p&gt;This is one of the questions I now ask when evaluating repository structure:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What code tends to change together?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If these always change together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;orders
orders-api
orders-domain
orders-tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;keeping them together makes sense.&lt;/p&gt;

&lt;p&gt;If these change independently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;marketing-website
payment-processing
internal-data-platform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;there is little value in forcing them into one repository purely for consistency.&lt;/p&gt;

&lt;p&gt;A useful mental model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;High change coupling
        ↓
Keep closer together

Low change coupling
        ↓
Separate when useful
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. CI/CD Changes the Equation
&lt;/h2&gt;

&lt;p&gt;Repository strategy and CI/CD strategy are tightly connected.&lt;/p&gt;

&lt;p&gt;A monorepo without good CI/CD becomes painful.&lt;/p&gt;

&lt;p&gt;A polyrepo without standardised CI/CD also becomes painful.&lt;/p&gt;

&lt;p&gt;Imagine 80 repositories.&lt;/p&gt;

&lt;p&gt;If every repository has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jenkinsfile
Dockerfile
Terraform
security-scan.yml
deployment.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and every team maintains its own version, you eventually get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Repo A → Java 17
Repo B → Java 21
Repo C → old security scanner
Repo D → custom deployment
Repo E → completely different pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository structure isn't necessarily the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lack of platform engineering is.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A mature organisation should provide reusable delivery capabilities.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Platform Engineering
                    │
        ┌───────────┼───────────┐
        ↓           ↓           ↓
      Build       Security    Deploy
        │           │           │
        └───────────┼───────────┘
                    ↓
              Product Teams
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Teams should be able to own their applications without having to reinvent the delivery platform.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Developer Experience Matters More Than We Think
&lt;/h2&gt;

&lt;p&gt;Ask a developer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How long does it take you to make a change across three services?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's often more useful than asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Do we use a monorepo?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consider the workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monorepo
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clone
 ↓
Find services
 ↓
Make change
 ↓
Run affected tests
 ↓
Single PR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Polyrepo
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clone repo A
 ↓
Clone repo B
 ↓
Clone repo C
 ↓
Change shared contract
 ↓
PR A
 ↓
PR B
 ↓
PR C
 ↓
Version library
 ↓
Update dependencies
 ↓
Wait for pipelines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither is inherently better.&lt;/p&gt;

&lt;p&gt;The important question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Which workflow reflects how your engineers actually work?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  14. Security and Compliance Can Change the Decision
&lt;/h2&gt;

&lt;p&gt;There are cases where separate repositories make practical sense.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Public product
        │
        ├── repository A

Highly restricted system
        │
        └── repository B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different access requirements can be a legitimate reason for separation.&lt;/p&gt;

&lt;p&gt;Other examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;regulated workloads&lt;/li&gt;
&lt;li&gt;sensitive infrastructure&lt;/li&gt;
&lt;li&gt;different organisational ownership&lt;/li&gt;
&lt;li&gt;acquisition boundaries&lt;/li&gt;
&lt;li&gt;external/open-source projects&lt;/li&gt;
&lt;li&gt;different security classifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where repository boundaries can become more than a developer-experience decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. The Hybrid Model
&lt;/h2&gt;

&lt;p&gt;In larger organisations, the answer doesn't have to be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Everything → monorepo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Everything → polyrepo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A hybrid approach can be very practical.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Engineering Organisation
                              │
          ┌───────────────────┼───────────────────┐
          ↓                   ↓                   ↓
     Product Monorepo     Platform Repo      Data Platform
          │                   │                   │
     ┌────┼────┐              │              ┌────┼────┐
     ↓    ↓    ↓              ↓              ↓    ↓    ↓
   API  Worker UI        Infrastructure     ETL  ML  Analytics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key is that each boundary has a reason.&lt;/p&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We have always done it this way."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  16. A Practical Decision Framework
&lt;/h2&gt;

&lt;p&gt;Instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which is better?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I prefer asking these questions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Do multiple teams frequently modify the same code?&lt;/td&gt;
&lt;td&gt;Monorepo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do services have genuinely independent ownership?&lt;/td&gt;
&lt;td&gt;Polyrepo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Are cross-service refactors common?&lt;/td&gt;
&lt;td&gt;Monorepo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do systems have different security/access boundaries?&lt;/td&gt;
&lt;td&gt;Polyrepo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do components share many libraries?&lt;/td&gt;
&lt;td&gt;Monorepo can simplify this&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do teams have very different release lifecycles?&lt;/td&gt;
&lt;td&gt;Polyrepo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can CI efficiently build only affected components?&lt;/td&gt;
&lt;td&gt;Makes monorepo more viable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do teams require strong repository-level isolation?&lt;/td&gt;
&lt;td&gt;Polyrepo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Are services actually independent despite being in one repo?&lt;/td&gt;
&lt;td&gt;Monorepo can still work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Are many repos creating duplicated tooling?&lt;/td&gt;
&lt;td&gt;Consider consolidation/platform tooling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important thing is that these are &lt;strong&gt;signals&lt;/strong&gt;, not absolute rules.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. What I Would Avoid
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Anti-pattern 1: "Microservices means one repo per service"
&lt;/h2&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;Repository boundaries and service boundaries solve different problems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Anti-pattern 2: "Monorepo means one giant application"
&lt;/h2&gt;

&lt;p&gt;Also not necessarily.&lt;/p&gt;

&lt;p&gt;A monorepo can contain independently deployable services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Monorepo
                    │
       ┌────────────┼────────────┐
       ↓            ↓            ↓
   Service A    Service B    Service C
       │            │            │
       ↓            ↓            ↓
   Deploy A     Deploy B     Deploy C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Anti-pattern 3: "Every shared class belongs in common"
&lt;/h2&gt;

&lt;p&gt;This usually creates coupling.&lt;/p&gt;

&lt;p&gt;Before creating a shared library, ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is this genuinely reusable infrastructure, or are we hiding domain ownership problems?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Anti-pattern 4: "Every repository needs its own pipeline"
&lt;/h2&gt;

&lt;p&gt;Standardise the platform.&lt;/p&gt;

&lt;p&gt;Teams should own their delivery outcomes without necessarily owning every line of CI/CD implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Anti-pattern 5: "Repository count is an architecture metric"
&lt;/h2&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;I'd rather know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deployment frequency&lt;/li&gt;
&lt;li&gt;lead time for change&lt;/li&gt;
&lt;li&gt;change failure rate&lt;/li&gt;
&lt;li&gt;dependency coupling&lt;/li&gt;
&lt;li&gt;build time&lt;/li&gt;
&lt;li&gt;test time&lt;/li&gt;
&lt;li&gt;ownership clarity&lt;/li&gt;
&lt;li&gt;developer productivity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;than simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We have 47 repositories."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  18. What I'd Do on a New Project
&lt;/h2&gt;

&lt;p&gt;If I were starting a new product today, I wouldn't begin with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let's choose monorepo."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let's choose polyrepo."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'd start with:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Identify teams
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Who owns what?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 — Identify deployment boundaries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What needs independent deployment?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 — Identify change coupling
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What changes together?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4 — Identify security boundaries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What requires separate access?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5 — Understand developer workflows
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How will engineers build and test changes locally?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6 — Design CI/CD accordingly
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can we build/test only what changed?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7 — Choose repository boundaries
&lt;/h3&gt;

&lt;p&gt;Only now would I decide:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;monorepo
        OR
polyrepo
        OR
hybrid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository strategy becomes an outcome of the architecture rather than the starting point.&lt;/p&gt;




&lt;h2&gt;
  
  
  19. My Rule of Thumb
&lt;/h2&gt;

&lt;p&gt;If I had to reduce the whole discussion to one principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Put things together when they need to change together. Separate things when they need to be owned, secured, or released independently.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And there is an important second principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't use repository boundaries to solve problems that actually belong to architecture, ownership, or platform engineering.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A monorepo won't fix poor service boundaries.&lt;/p&gt;

&lt;p&gt;A polyrepo won't create team autonomy by itself.&lt;/p&gt;

&lt;p&gt;Microservices won't automatically give independent deployment.&lt;/p&gt;

&lt;p&gt;And multiple Git repositories won't automatically create a scalable engineering organisation.&lt;/p&gt;




&lt;h2&gt;
  
  
  20. The Takeaways
&lt;/h2&gt;

&lt;p&gt;If you're deciding between monorepo and polyrepo, I'd keep these points in mind:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Repository boundaries are architectural boundaries
&lt;/h3&gt;

&lt;p&gt;Treat them deliberately.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Microservices do not require polyrepos
&lt;/h3&gt;

&lt;p&gt;Services can be independently deployable from a monorepo.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Monorepos need good tooling
&lt;/h3&gt;

&lt;p&gt;Incremental builds, dependency graphs, caching and affected-test execution become important at scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Polyrepos need platform engineering
&lt;/h3&gt;

&lt;p&gt;Otherwise every team ends up maintaining its own CI/CD, security and developer tooling.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Shared libraries can create hidden coupling
&lt;/h3&gt;

&lt;p&gt;Especially when they contain business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Team ownership matters
&lt;/h3&gt;

&lt;p&gt;Repository boundaries should make ownership clearer, not more complicated.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Look at change patterns
&lt;/h3&gt;

&lt;p&gt;Ask what actually changes together.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Optimise for developer flow
&lt;/h3&gt;

&lt;p&gt;The best architecture is often the one that reduces unnecessary coordination while preserving the boundaries the organisation genuinely needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;The monorepo vs polyrepo debate is often presented as if there is a universally correct answer.&lt;/p&gt;

&lt;p&gt;There isn't.&lt;/p&gt;

&lt;p&gt;The better question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What repository structure allows our teams to change the system safely, independently and efficiently?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you start looking at the problem through:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ownership → coupling → change patterns → security → deployment → developer experience&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;the decision becomes much less ideological and much more engineering-driven.&lt;/p&gt;

&lt;p&gt;And that's probably the most important lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Choose repository boundaries based on how your organisation and software actually change — not based on what architecture is fashionable today.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>softwareengineering</category>
      <category>sre</category>
      <category>software</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Stop Mocking Your Test Dependencies— Get the Real Thing, Locally and in CI, in 3 Commands</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Tue, 25 Aug 2026 02:27:08 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/stop-mocking-your-test-dependencies-get-the-real-thing-locally-and-in-ci-in-3-commands-2lnd</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/stop-mocking-your-test-dependencies-get-the-real-thing-locally-and-in-ci-in-3-commands-2lnd</guid>
      <description>&lt;p&gt;It's 2pm. You need to ship a fix before end of day. You run the integration suite and it fails — not because your code is wrong, but because staging is down. Someone else's bad migration took it out an hour ago, and now you're in the "is it up yet" channel with six other engineers, watching a thread instead of shipping.&lt;/p&gt;

&lt;p&gt;Sound familiar? This is the actual, daily cost of how most teams do integration testing. And it usually comes down to one of two bad options.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two options, and why both are bad
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mock everything.&lt;/strong&gt; Fast, deterministic, runs anywhere — and proves almost nothing. Your mock says Postgres returns rows in this shape. Real Postgres doesn't care what your mock thinks. The bug that matters — the one your mock can't see by definition — ships to production and pages someone at 2am.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Share a staging environment.&lt;/strong&gt; Real dependencies, finally — but now you're queued behind whoever's deploying, debugging, or has just quietly broken it for everyone. It's slow, it's flaky in ways that have nothing to do with your code, and "is staging even up right now" becomes a real question you ask multiple times a week.&lt;/p&gt;

&lt;p&gt;Neither of these is a testing strategy. They're both just different ways of accepting risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  There's a third option: real dependencies, but yours alone
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/morarixhq/morarix" rel="noopener noreferrer"&gt;&lt;strong&gt;Morarix&lt;/strong&gt;&lt;/a&gt; is a CLI that reads a small, hand-authored dependency graph for your service and provisions the real thing — Postgres, Redis, Kafka, and eight AWS services via LocalStack — as disposable, isolated containers on your laptop or in CI. Not a shared environment you wait for. Not a mock you have to trust. The real dependency, health-checked, torn down when you're done, every time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;morarix init                &lt;span class="c"&gt;# scaffold morarix.graph.json&lt;/span&gt;
morarix import compose      &lt;span class="c"&gt;# or: convert an existing docker-compose.yml&lt;/span&gt;
morarix up                  &lt;span class="c"&gt;# provision + validate — real Postgres, Redis, S3... on localhost&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you run your existing test suite — completely unmodified — against those real dependencies. Same commands, locally and in CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show, don't tell
&lt;/h2&gt;

&lt;p&gt;Here's the whole &lt;code&gt;morarix.graph.json&lt;/code&gt; for a FastAPI service backed by Postgres, Redis, and S3 (one of the &lt;a href="https://github.com/morarixhq/morarix-examples/tree/main/python-fastapi" rel="noopener noreferrer"&gt;reference examples&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"schema_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python-fastapi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"repo_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"framework"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fastapi"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"db"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"fidelity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"real"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"manual"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"required_env_vars"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"MORARIX_DB_CONNECTION_STRING"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"optional"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cache"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"redis"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"fidelity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"real"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"manual"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"required_env_vars"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"MORARIX_CACHE_CONNECTION_STRING"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"optional"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"redis"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"7"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"fidelity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"real"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"manual"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"required_env_vars"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"MORARIX_ASSETS_HOST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MORARIX_ASSETS_PORT"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"optional"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"bucket_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"widget-assets"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No YAML you have to hand-sync with your CI config. &lt;code&gt;fidelity: "real"&lt;/code&gt; means Morarix actually provisions a container &lt;em&gt;and&lt;/em&gt; health-checks it — not "the process started," but "Postgres will accept a connection," "Redis responds to &lt;code&gt;PING&lt;/code&gt;," "the LocalStack S3 endpoint is reachable."&lt;/p&gt;

&lt;p&gt;Here's the actual output of running it — nothing hand-written for this post:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;morarix up
&lt;span class="go"&gt;morarix: loaded 3 dependencies for "python-fastapi"
  - db                   postgres       fidelity=real
  - cache                redis          fidelity=real
  - assets               s3             fidelity=real

morarix: environment ready (run_id=morarix-3f16480cfbc9-1786016512, mode=isolated) — morarix.connections.json and .env.morarix written

&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pytest &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;span class="go"&gt;============================= test session starts =============================
collecting ... collected 9 items

tests/test_api.py::test_health_reports_ok PASSED                         [ 11%]
tests/test_api.py::test_create_widget_then_list_returns_it PASSED        [ 33%]
tests/test_api.py::test_get_widgets_is_cached_across_consecutive_calls PASSED [ 44%]
tests/test_data_access.py::test_insert_and_list_widgets_round_trips_through_postgres PASSED [ 77%]
tests/test_data_access.py::test_cache_set_and_get_round_trips_through_redis PASSED [ 88%]
tests/test_data_access.py::test_spec_upload_and_download_round_trips_through_s3 PASSED [100%]

======================= 9 passed, 3 warnings in 24.13s ========================

&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;morarix down
&lt;span class="go"&gt;morarix: environment torn down (was: isolated)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No compose file in the app repo. No mocks. No manual container wrangling. Just the real dependencies, up, tested against, and gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Isn't this just docker-compose / Testcontainers / Tilt?"
&lt;/h2&gt;

&lt;p&gt;Fair question — here's the actual difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;vs. &lt;code&gt;docker-compose&lt;/code&gt; by hand&lt;/strong&gt; — compose has no fidelity concept (a service is either &lt;code&gt;real&lt;/code&gt; or entirely absent), no per-type health checks (&lt;code&gt;depends_on&lt;/code&gt; isn't "Postgres will actually accept a connection"), and nothing stops your compose file and your CI YAML from silently drifting apart over time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;vs. &lt;a href="https://testcontainers.com/" rel="noopener noreferrer"&gt;Testcontainers&lt;/a&gt;&lt;/strong&gt; — Testcontainers is a library embedded in your test code, per language, with its own API to learn per dependency type. Morarix is a CLI: one graph, one &lt;code&gt;morarix up&lt;/code&gt;, zero test-code changes, and the same graph works across every language in a polyglot org instead of being re-implemented per service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;vs. Tilt / Skaffold / Garden&lt;/strong&gt; — those solve your whole live-reload dev loop, usually against Kubernetes, often building and deploying your app itself. Morarix deliberately doesn't touch your app — it only provisions what's &lt;em&gt;around&lt;/em&gt; it, so your app keeps running exactly how you already run it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The same three commands in CI
&lt;/h2&gt;

&lt;p&gt;This is the actual payoff — not a separate CI-specific setup that quietly drifts from what you run locally, but the literal same commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install morarix&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;go install github.com/morarixhq/morarix/cmd/morarix@latest&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;morarix up&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pytest&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;morarix down&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ubuntu-latest&lt;/code&gt; already has Docker. That's the whole prerequisite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;install &lt;/span&gt;github.com/morarixhq/morarix/cmd/morarix@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prebuilt binaries for Linux, macOS, and Windows (amd64 + arm64) are on the &lt;a href="https://github.com/morarixhq/morarix/releases/tag/v0.1.0" rel="noopener noreferrer"&gt;v0.1.0 release&lt;/a&gt; — no Go toolchain required.&lt;/p&gt;

&lt;p&gt;Currently working end-to-end for Go, Node.js, TypeScript, Java, .NET, and Python, with six runnable &lt;a href="https://github.com/morarixhq/morarix-examples" rel="noopener noreferrer"&gt;reference examples&lt;/a&gt; covering both onboarding paths (&lt;code&gt;init&lt;/code&gt; from scratch and &lt;code&gt;import compose&lt;/code&gt; from an existing &lt;code&gt;docker-compose.yml&lt;/code&gt;), plus Postgres, MySQL, Redis, Kafka, REST, and LocalStack health checkers already built in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it, then tell me where it breaks
&lt;/h2&gt;

&lt;p&gt;This is genuinely early — &lt;code&gt;v0.1.0&lt;/code&gt;, not a polished v3. If you've got a service with a Postgres/Redis/Kafka dependency sitting behind mocks or a shared staging environment you're tired of waiting on, that's exactly the case this is for. Point it at that service and see what breaks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;strong&gt;Repo&lt;/strong&gt;: &lt;a href="https://github.com/morarixhq/morarix" rel="noopener noreferrer"&gt;github.com/morarixhq/morarix&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📖 &lt;strong&gt;Why Morarix&lt;/strong&gt; (the full case): &lt;a href="https://github.com/morarixhq/morarix-docs/blob/main/concepts/why-morarix.md" rel="noopener noreferrer"&gt;morarix-docs/concepts/why-morarix.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🧭 &lt;strong&gt;Usage guide&lt;/strong&gt;: &lt;a href="https://github.com/morarixhq/morarix-docs/blob/main/docs/usage-guide.md" rel="noopener noreferrer"&gt;morarix-docs/docs/usage-guide.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🧪 &lt;strong&gt;Examples&lt;/strong&gt;: &lt;a href="https://github.com/morarixhq/morarix-examples" rel="noopener noreferrer"&gt;morarix-examples&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it saves you a "is staging up" Slack thread, a star helps other people find it. If it breaks on your setup, &lt;a href="https://github.com/morarixhq/morarix/issues" rel="noopener noreferrer"&gt;open an issue&lt;/a&gt; — that's exactly the feedback this stage needs.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>software</category>
      <category>productivity</category>
      <category>automation</category>
    </item>
    <item>
      <title>The Golden Pipeline for AI/ML Systems in Production</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Sun, 28 Jun 2026 09:45:37 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/the-golden-pipeline-for-aiml-systems-in-production-407m</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/the-golden-pipeline-for-aiml-systems-in-production-407m</guid>
      <description>&lt;p&gt;Most AI/ML tutorials stop at training a model.&lt;/p&gt;

&lt;p&gt;Real systems start after that.&lt;/p&gt;

&lt;p&gt;In production, the hardest problems are not modeling — they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data quality drift&lt;/li&gt;
&lt;li&gt;Evaluation reliability&lt;/li&gt;
&lt;li&gt;Deployment safety&lt;/li&gt;
&lt;li&gt;Monitoring failure modes&lt;/li&gt;
&lt;li&gt;Continuous improvement loops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article breaks down a practical &lt;strong&gt;Golden Pipeline for AI/ML systems&lt;/strong&gt; based on real production engineering practices.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Golden Pipeline (End-to-End View)
&lt;/h2&gt;

&lt;p&gt;A real production ML/AI system looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data Ingestion → Validation → Feature Engineering → Training →
Evaluation → Model Registry → Deployment →
Shadow Testing → A/B Testing → Monitoring → Feedback Loop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each stage is independently versioned and testable.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Data Ingestion Layer
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Core Principle:
&lt;/h3&gt;

&lt;p&gt;Never trust raw data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Best Practices:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use streaming ingestion (Kafka / Kinesis / PubSub)&lt;/li&gt;
&lt;li&gt;Store raw + processed data separately&lt;/li&gt;
&lt;li&gt;Enforce schema validation at ingestion time&lt;/li&gt;
&lt;li&gt;Track full data lineage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common Failure:
&lt;/h3&gt;

&lt;p&gt;Most ML failures are NOT model failures — they are data pipeline failures.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Data Validation Layer
&lt;/h2&gt;

&lt;p&gt;Before training:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate schema&lt;/li&gt;
&lt;li&gt;Check missing values&lt;/li&gt;
&lt;li&gt;Detect anomalies&lt;/li&gt;
&lt;li&gt;Ensure type consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recommended Tools:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Great Expectations&lt;/li&gt;
&lt;li&gt;Pandera&lt;/li&gt;
&lt;li&gt;Pydantic (very effective in Python systems)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Feature Engineering Layer
&lt;/h2&gt;

&lt;p&gt;=============================&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule:
&lt;/h3&gt;

&lt;p&gt;If a feature is not reproducible → it does not exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Best Practices:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Make feature pipelines deterministic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid inline feature computation during training&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use feature stores when possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Feast&lt;/li&gt;
&lt;li&gt;  Tecton&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Training Pipeline
&lt;/h2&gt;

&lt;p&gt;=====================&lt;/p&gt;

&lt;h3&gt;
  
  
  Principles:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Training must be stateless&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Every run must be reproducible&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Log all hyperparameters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Version datasets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tools:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MLflow&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Weights &amp;amp; Biases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DVC&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hydra&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Evaluation Layer (Critical)
&lt;/h2&gt;

&lt;p&gt;===============================&lt;/p&gt;

&lt;p&gt;This is where most systems fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Never rely on a single metric.
&lt;/h3&gt;

&lt;p&gt;Use layered evaluation:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Exact Metrics
&lt;/h4&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Accuracy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Precision / Recall&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;F1&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Task-Specific Metrics
&lt;/h4&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Exact match&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Numeric tolerance (important in finance systems)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Structured output validation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. LLM-Based Evaluation (if applicable)
&lt;/h4&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Pairwise comparison&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rubric scoring&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LLM-as-judge (carefully calibrated)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Insight:
&lt;/h3&gt;

&lt;p&gt;Exact match is often WRONG in real-world systems.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Gold: -32%&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prediction: -32.82%&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should be considered correct under tolerance rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Model Registry
&lt;/h2&gt;

&lt;p&gt;==================&lt;/p&gt;

&lt;p&gt;Never deploy models directly.&lt;/p&gt;

&lt;p&gt;Use a model registry:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MLflow Model Registry&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SageMaker Registry&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Custom versioned storage (S3/GCS)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Store:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Model version&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dataset version&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Metrics&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Git commit hash&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Config snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Deployment Strategies
&lt;/h2&gt;

&lt;p&gt;=========================&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 1: Direct deployment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Risky&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No rollback&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Option 2: Blue-Green Deployment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Two environments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instant rollback possible&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Option 3: Canary Deployment (Best Practice)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deploy to small % of traffic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gradually scale&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitor closely&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Shadow Mode (Highly Underrated)
&lt;/h2&gt;

&lt;p&gt;===================================&lt;/p&gt;

&lt;p&gt;Run new model in parallel with production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No user impact&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compare outputs silently&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detect silent failures&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why it matters:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prevents production incidents&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detects drift early&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validates behavior safely&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. A/B Testing
&lt;/h2&gt;

&lt;p&gt;================&lt;/p&gt;

&lt;p&gt;After shadow validation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Split traffic between models&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Measure real impact&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Metrics:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Accuracy proxies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Latency&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User engagement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Business KPIs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  11. Monitoring
&lt;/h2&gt;

&lt;p&gt;===============&lt;/p&gt;

&lt;p&gt;If you don’t monitor, your model is broken already.&lt;/p&gt;

&lt;p&gt;Monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Data drift&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prediction drift&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Latency&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error rates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confidence distributions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tools:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prometheus&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Grafana&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Evidently AI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Arize&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  12. Feedback Loop
&lt;/h2&gt;

&lt;p&gt;==================&lt;/p&gt;

&lt;p&gt;This is where production ML systems improve.&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;User corrections&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Human labeling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implicit feedback (clicks, edits)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This becomes future training data.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. What Most Engineers Miss
&lt;/h2&gt;

&lt;p&gt;=============================&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Everything must be versioned&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assume models will fail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always have rollback strategy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data is more important than model&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Evaluation is a first-class system&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  14. Final Takeaway
&lt;/h2&gt;

&lt;p&gt;===================&lt;/p&gt;

&lt;p&gt;A production AI system is NOT:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;model training + deployment&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a continuous loop of:data → training → evaluation → deployment → monitoring → feedback&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model is just one part of the system.&lt;/p&gt;

&lt;p&gt;The pipeline is the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  If You’re Building This
&lt;/h2&gt;

&lt;p&gt;Start simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add strict data validation first&lt;/li&gt;
&lt;li&gt;Build evaluation before improving models&lt;/li&gt;
&lt;li&gt;Introduce shadow mode early&lt;/li&gt;
&lt;li&gt;Log everything from day one&lt;/li&gt;
&lt;li&gt;Always design for failure&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>cicd</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>9 Practical Ways Senior ML Engineers Reduce Inference Latency</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Sat, 20 Jun 2026 07:37:31 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/9-practical-ways-senior-ml-engineers-reduce-inference-latency-j9f</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/9-practical-ways-senior-ml-engineers-reduce-inference-latency-j9f</guid>
      <description>&lt;p&gt;Most teams blame the model when an AI application feels slow.&lt;/p&gt;

&lt;p&gt;In reality, the model is often only one part of the latency budget.&lt;/p&gt;

&lt;p&gt;A typical AI request may involve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Request
    ↓
Authentication
    ↓
Feature Retrieval
    ↓
Vector Search
    ↓
Agent Orchestration
    ↓
LLM Inference
    ↓
Guardrails
    ↓
Response Generation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the time the user sees a response, latency has accumulated across multiple layers of the system.&lt;/p&gt;

&lt;p&gt;After working on cloud-native systems, GenAI platforms, and distributed architectures, I've noticed that the best AI engineers focus on optimizing the entire pipeline—not just the model.&lt;/p&gt;

&lt;p&gt;Here are 9 practical techniques commonly used in production AI systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Optimize Feature Retrieval Before Touching the Model
&lt;/h2&gt;

&lt;p&gt;Many AI and ML systems spend more time fetching data than generating predictions.&lt;/p&gt;

&lt;p&gt;Common examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fraud detection systems fetching customer risk profiles&lt;/li&gt;
&lt;li&gt;Recommendation systems retrieving user interaction history&lt;/li&gt;
&lt;li&gt;Personalization engines loading customer attributes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A model that takes 50ms to infer becomes a 500ms system if feature retrieval takes 450ms.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
 ↓
Database Queries
 ↓
Model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
 ↓
Online Feature Store
 ↓
Model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Technologies commonly used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;DynamoDB&lt;/li&gt;
&lt;li&gt;Feast Online Store&lt;/li&gt;
&lt;li&gt;Tecton Online Store&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fastest prediction is often achieved by reducing feature lookup latency.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Separate Real-Time and Batch Features
&lt;/h2&gt;

&lt;p&gt;Not every feature needs to be calculated at request time.&lt;/p&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
 ↓
Calculate 30-day spending history
 ↓
Model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nightly Batch Pipeline
 ↓
Precompute Features
 ↓
Store in Feature Store

Request
 ↓
Feature Lookup
 ↓
Model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples of batch features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Average spend last 30 days&lt;/li&gt;
&lt;li&gt;Customer lifetime value&lt;/li&gt;
&lt;li&gt;Product affinity scores&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples of real-time features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transactions in last 5 minutes&lt;/li&gt;
&lt;li&gt;Products viewed in current session&lt;/li&gt;
&lt;li&gt;Failed login attempts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This reduces inference latency dramatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Cache Aggressively
&lt;/h2&gt;

&lt;p&gt;One of the highest ROI optimizations.&lt;/p&gt;

&lt;p&gt;Many requests are repetitive.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frequently asked support questions&lt;/li&gt;
&lt;li&gt;Popular product recommendations&lt;/li&gt;
&lt;li&gt;Repeated vector search results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
 ↓
RAG
 ↓
LLM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
 ↓
Cache Check
 ↓
Return Cached Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;CloudFront&lt;/li&gt;
&lt;li&gt;Application-level caches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A cache hit often reduces latency from seconds to milliseconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Reduce Retrieval Latency
&lt;/h2&gt;

&lt;p&gt;In RAG systems, retrieval often becomes the bottleneck.&lt;/p&gt;

&lt;p&gt;Typical latency contributors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large vector indexes&lt;/li&gt;
&lt;li&gt;Excessive top-K retrieval&lt;/li&gt;
&lt;li&gt;Poor filtering strategies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search Entire Knowledge Base
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Metadata Filters
 +
Vector Search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search only banking documents&lt;/li&gt;
&lt;li&gt;Search only relevant departments&lt;/li&gt;
&lt;li&gt;Search only customer-specific data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reducing search space significantly improves response times.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Use Hybrid Retrieval Carefully
&lt;/h2&gt;

&lt;p&gt;Many teams combine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vector Search
+
Keyword Search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which improves quality but increases latency.&lt;/p&gt;

&lt;p&gt;Practical approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Keyword Search
 ↓
Candidate Set
 ↓
Vector Ranking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of searching the entire corpus twice.&lt;/p&gt;

&lt;p&gt;Quality matters, but so does speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Parallelize Tool Calls and Agent Workflows
&lt;/h2&gt;

&lt;p&gt;One of the most common mistakes in agentic systems is sequential execution.&lt;/p&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
 ↓
Tool A
 ↓
Tool B
 ↓
Tool C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Total latency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A + B + C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
 ↓
Parallel Execution
 ↓
Tool A
Tool B
Tool C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Total latency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;max(A,B,C)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can reduce response time by several seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Use Smaller Models Where Possible
&lt;/h2&gt;

&lt;p&gt;Not every task requires a large model.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Better Choice&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Classification&lt;/td&gt;
&lt;td&gt;Small Model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intent Detection&lt;/td&gt;
&lt;td&gt;Small Model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Routing&lt;/td&gt;
&lt;td&gt;Small Model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Summarization&lt;/td&gt;
&lt;td&gt;Medium Model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex Reasoning&lt;/td&gt;
&lt;td&gt;Large Model&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A common production pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Small Model
 ↓
Route Request
 ↓
Large Model (only when needed)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reduces both latency and cost.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Quantize Models
&lt;/h2&gt;

&lt;p&gt;A technique heavily used in production ML systems.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FP32 Model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INT8
INT4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or similar quantized formats.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smaller memory footprint&lt;/li&gt;
&lt;li&gt;Faster inference&lt;/li&gt;
&lt;li&gt;Lower infrastructure costs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Especially useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edge deployments&lt;/li&gt;
&lt;li&gt;Real-time recommendation systems&lt;/li&gt;
&lt;li&gt;High-throughput inference workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trade-off is a small accuracy reduction.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Measure the Entire Latency Budget
&lt;/h2&gt;

&lt;p&gt;This is where observability becomes critical.&lt;/p&gt;

&lt;p&gt;Many teams optimize the model while ignoring everything else.&lt;/p&gt;

&lt;p&gt;Track latency across:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feature Retrieval
Vector Search
Agent Routing
Tool Calls
LLM Inference
Guardrails
Response Validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A typical breakdown might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feature Retrieval      50ms
Vector Search         120ms
Tool Calls            300ms
LLM Inference        2200ms
Guardrails            150ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without tracing, teams often optimize the wrong component.&lt;/p&gt;

&lt;p&gt;Platforms such as Langfuse, HoneyHive, Arize Phoenix, and OpenTelemetry-based observability stacks make these bottlenecks visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Lesson
&lt;/h2&gt;

&lt;p&gt;The fastest AI systems are rarely the ones with the fastest models.&lt;/p&gt;

&lt;p&gt;They are the systems with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficient feature retrieval&lt;/li&gt;
&lt;li&gt;Smart caching&lt;/li&gt;
&lt;li&gt;Optimized retrieval pipelines&lt;/li&gt;
&lt;li&gt;Parallel execution&lt;/li&gt;
&lt;li&gt;Right-sized models&lt;/li&gt;
&lt;li&gt;Strong observability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Senior AI engineers optimize the entire system.&lt;/p&gt;

&lt;p&gt;Because users don't care whether the delay comes from a vector database, a feature store, an agent, or an LLM.&lt;/p&gt;

&lt;p&gt;They only notice one thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long it takes to get an answer.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>machinelearning</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>I Compared 7 AI Observability Platforms So You Don’t Have To (2026 Edition)</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Thu, 11 Jun 2026 05:50:50 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/i-compared-7-ai-observability-platforms-so-you-dont-have-to-2026-edition-3jdc</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/i-compared-7-ai-observability-platforms-so-you-dont-have-to-2026-edition-3jdc</guid>
      <description>&lt;p&gt;The AI tooling ecosystem is exploding.&lt;/p&gt;

&lt;p&gt;Every week there seems to be a new platform promising:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better traces&lt;/li&gt;
&lt;li&gt;Better evaluations&lt;/li&gt;
&lt;li&gt;Better prompt debugging&lt;/li&gt;
&lt;li&gt;Better monitoring&lt;/li&gt;
&lt;li&gt;Better cost visibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The challenge isn’t finding an AI observability tool anymore.&lt;/p&gt;

&lt;p&gt;The challenge is choosing one.&lt;/p&gt;

&lt;p&gt;If you’re building AI applications today, chances are you’ve come across names like Langfuse, LangSmith, HoneyHive, Helicone, Arize, Braintrust, or Phoenix.&lt;/p&gt;

&lt;p&gt;After exploring these platforms, I noticed something interesting:&lt;/p&gt;

&lt;p&gt;Most tools overlap in functionality, but each one is optimized for a very different workflow.&lt;/p&gt;

&lt;p&gt;This article focuses on comparing the tools themselves—not explaining AI observability concepts.&lt;/p&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Evaluation Criteria&lt;/p&gt;

&lt;p&gt;For this comparison I evaluated each platform across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracing and debugging&lt;/li&gt;
&lt;li&gt;Prompt monitoring&lt;/li&gt;
&lt;li&gt;Evaluations (Evals)&lt;/li&gt;
&lt;li&gt;Cost tracking&lt;/li&gt;
&lt;li&gt;Dataset management&lt;/li&gt;
&lt;li&gt;Self-hosting support&lt;/li&gt;
&lt;li&gt;Enterprise readiness&lt;/li&gt;
&lt;li&gt;Ease of adoption&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Quick Comparison Table&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Open Source&lt;/th&gt;
&lt;th&gt;Tracing&lt;/th&gt;
&lt;th&gt;Evaluations&lt;/th&gt;
&lt;th&gt;Cost Monitoring&lt;/th&gt;
&lt;th&gt;Self Host&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Langfuse&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Most teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HoneyHive&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;Enterprise AI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangSmith&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;LangChain users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Helicone&lt;/td&gt;
&lt;td&gt;⚠️ Partial&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Cost visibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arize&lt;/td&gt;
&lt;td&gt;⚠️ Partial&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⚠️ Limited&lt;/td&gt;
&lt;td&gt;Large production systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Braintrust&lt;/td&gt;
&lt;td&gt;⚠️ Partial&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;td&gt;⚠️ Limited&lt;/td&gt;
&lt;td&gt;Evaluation-first workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phoenix&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Lightweight OSS setups&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Langfuse&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What Stands Out&lt;/p&gt;

&lt;p&gt;Langfuse has become one of the most popular choices for AI engineering teams.&lt;/p&gt;

&lt;p&gt;It combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracing&lt;/li&gt;
&lt;li&gt;Prompt management&lt;/li&gt;
&lt;li&gt;Evaluations&lt;/li&gt;
&lt;li&gt;Dataset tracking&lt;/li&gt;
&lt;li&gt;Cost analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in a single platform.&lt;/p&gt;

&lt;p&gt;The biggest advantage is flexibility.&lt;/p&gt;

&lt;p&gt;Unlike many commercial products, Langfuse does not lock you into a specific framework.&lt;/p&gt;

&lt;p&gt;You can use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI&lt;/li&gt;
&lt;li&gt;Anthropic&lt;/li&gt;
&lt;li&gt;Gemini&lt;/li&gt;
&lt;li&gt;Bedrock&lt;/li&gt;
&lt;li&gt;LangChain&lt;/li&gt;
&lt;li&gt;LangGraph&lt;/li&gt;
&lt;li&gt;Custom agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without major friction.&lt;/p&gt;

&lt;p&gt;Strengths&lt;/p&gt;

&lt;p&gt;✅ Open source&lt;/p&gt;

&lt;p&gt;✅ Self-hosting available&lt;/p&gt;

&lt;p&gt;✅ Strong evaluation workflows&lt;/p&gt;

&lt;p&gt;✅ Framework agnostic&lt;/p&gt;

&lt;p&gt;✅ Excellent developer experience&lt;/p&gt;

&lt;p&gt;Weaknesses&lt;/p&gt;

&lt;p&gt;❌ More setup than fully managed platforms&lt;/p&gt;

&lt;p&gt;❌ Enterprise features may require additional work&lt;/p&gt;

&lt;p&gt;Best For&lt;/p&gt;

&lt;p&gt;Teams wanting a long-term observability platform without vendor lock-in.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;HoneyHive&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What Stands Out&lt;/p&gt;

&lt;p&gt;HoneyHive focuses heavily on enterprise AI quality and testing.&lt;/p&gt;

&lt;p&gt;The platform goes beyond simple tracing and emphasizes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evaluation pipelines&lt;/li&gt;
&lt;li&gt;Regression testing&lt;/li&gt;
&lt;li&gt;Prompt experimentation&lt;/li&gt;
&lt;li&gt;AI system quality measurement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it particularly attractive for organizations deploying AI into production at scale.&lt;/p&gt;

&lt;p&gt;Strengths&lt;/p&gt;

&lt;p&gt;✅ Enterprise-grade workflows&lt;/p&gt;

&lt;p&gt;✅ Strong evaluation capabilities&lt;/p&gt;

&lt;p&gt;✅ Regression testing&lt;/p&gt;

&lt;p&gt;✅ Production monitoring&lt;/p&gt;

&lt;p&gt;Weaknesses&lt;/p&gt;

&lt;p&gt;❌ Less attractive for hobby projects&lt;/p&gt;

&lt;p&gt;❌ Commercial-first offering&lt;/p&gt;

&lt;p&gt;Best For&lt;/p&gt;

&lt;p&gt;Organizations that treat AI systems like mission-critical software.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;LangSmith&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What Stands Out&lt;/p&gt;

&lt;p&gt;If your stack is already built around LangChain or LangGraph, LangSmith feels almost automatic.&lt;/p&gt;

&lt;p&gt;The integration is excellent.&lt;/p&gt;

&lt;p&gt;You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent traces&lt;/li&gt;
&lt;li&gt;Execution paths&lt;/li&gt;
&lt;li&gt;Prompt inspection&lt;/li&gt;
&lt;li&gt;Chain debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;with minimal effort.&lt;/p&gt;

&lt;p&gt;Strengths&lt;/p&gt;

&lt;p&gt;✅ Best LangChain integration&lt;/p&gt;

&lt;p&gt;✅ Excellent trace visualization&lt;/p&gt;

&lt;p&gt;✅ Fast setup&lt;/p&gt;

&lt;p&gt;✅ Agent debugging experience&lt;/p&gt;

&lt;p&gt;Weaknesses&lt;/p&gt;

&lt;p&gt;❌ Less attractive outside LangChain ecosystems&lt;/p&gt;

&lt;p&gt;❌ Limited self-hosting options&lt;/p&gt;

&lt;p&gt;Best For&lt;/p&gt;

&lt;p&gt;Teams deeply invested in LangChain or LangGraph.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Helicone&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What Stands Out&lt;/p&gt;

&lt;p&gt;Helicone is probably the easiest way to understand where your AI budget is going.&lt;/p&gt;

&lt;p&gt;Its focus is much more operational than evaluation-centric.&lt;/p&gt;

&lt;p&gt;You get visibility into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request volume&lt;/li&gt;
&lt;li&gt;Token usage&lt;/li&gt;
&lt;li&gt;Model consumption&lt;/li&gt;
&lt;li&gt;Cost breakdowns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without significant complexity.&lt;/p&gt;

&lt;p&gt;Strengths&lt;/p&gt;

&lt;p&gt;✅ Excellent cost analytics&lt;/p&gt;

&lt;p&gt;✅ Quick integration&lt;/p&gt;

&lt;p&gt;✅ OpenAI proxy model&lt;/p&gt;

&lt;p&gt;✅ Lightweight deployment&lt;/p&gt;

&lt;p&gt;Weaknesses&lt;/p&gt;

&lt;p&gt;❌ Evaluation capabilities lag competitors&lt;/p&gt;

&lt;p&gt;❌ Less sophisticated tracing&lt;/p&gt;

&lt;p&gt;Best For&lt;/p&gt;

&lt;p&gt;Startups trying to control AI infrastructure costs.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Arize&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What Stands Out&lt;/p&gt;

&lt;p&gt;Arize comes from the machine learning observability world.&lt;/p&gt;

&lt;p&gt;As a result, it brings strong production monitoring capabilities that many AI-native tools still lack.&lt;/p&gt;

&lt;p&gt;The platform is particularly strong when organizations combine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traditional ML systems&lt;/li&gt;
&lt;li&gt;Recommendation systems&lt;/li&gt;
&lt;li&gt;LLM applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;inside the same environment.&lt;/p&gt;

&lt;p&gt;Strengths&lt;/p&gt;

&lt;p&gt;✅ Mature monitoring platform&lt;/p&gt;

&lt;p&gt;✅ Strong evaluation tooling&lt;/p&gt;

&lt;p&gt;✅ Enterprise scale&lt;/p&gt;

&lt;p&gt;✅ ML + LLM support&lt;/p&gt;

&lt;p&gt;Weaknesses&lt;/p&gt;

&lt;p&gt;❌ Can feel overwhelming for small teams&lt;/p&gt;

&lt;p&gt;❌ Higher operational complexity&lt;/p&gt;

&lt;p&gt;Best For&lt;/p&gt;

&lt;p&gt;Large-scale AI platforms operating in production.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Braintrust&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What Stands Out&lt;/p&gt;

&lt;p&gt;Braintrust takes a different approach.&lt;/p&gt;

&lt;p&gt;Rather than starting with traces, it starts with evaluations.&lt;/p&gt;

&lt;p&gt;The philosophy is simple:&lt;/p&gt;

&lt;p&gt;“If you can’t measure quality, you can’t improve quality.”&lt;/p&gt;

&lt;p&gt;This makes Braintrust especially useful for teams focused on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prompt optimization&lt;/li&gt;
&lt;li&gt;Model comparisons&lt;/li&gt;
&lt;li&gt;Benchmarking&lt;/li&gt;
&lt;li&gt;Continuous evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Strengths&lt;/p&gt;

&lt;p&gt;✅ Excellent evaluation workflows&lt;/p&gt;

&lt;p&gt;✅ Dataset management&lt;/p&gt;

&lt;p&gt;✅ Benchmarking capabilities&lt;/p&gt;

&lt;p&gt;✅ Model comparison workflows&lt;/p&gt;

&lt;p&gt;Weaknesses&lt;/p&gt;

&lt;p&gt;❌ Less focused on operational monitoring&lt;/p&gt;

&lt;p&gt;❌ Tracing is not the primary strength&lt;/p&gt;

&lt;p&gt;Best For&lt;/p&gt;

&lt;p&gt;Teams building evaluation-driven AI development processes.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Phoenix&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What Stands Out&lt;/p&gt;

&lt;p&gt;Phoenix is one of the strongest open-source alternatives available.&lt;/p&gt;

&lt;p&gt;It provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracing&lt;/li&gt;
&lt;li&gt;Evaluation workflows&lt;/li&gt;
&lt;li&gt;Debugging capabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without introducing significant operational overhead.&lt;/p&gt;

&lt;p&gt;Many engineers adopt Phoenix because they want observability without committing to a larger commercial ecosystem.&lt;/p&gt;

&lt;p&gt;Strengths&lt;/p&gt;

&lt;p&gt;✅ Open source&lt;/p&gt;

&lt;p&gt;✅ Lightweight deployment&lt;/p&gt;

&lt;p&gt;✅ Good tracing&lt;/p&gt;

&lt;p&gt;✅ Simple adoption&lt;/p&gt;

&lt;p&gt;Weaknesses&lt;/p&gt;

&lt;p&gt;❌ Smaller ecosystem&lt;/p&gt;

&lt;p&gt;❌ Fewer enterprise features&lt;/p&gt;

&lt;p&gt;Best For&lt;/p&gt;

&lt;p&gt;Engineers wanting lightweight observability with minimal complexity.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;My Recommendations&lt;/p&gt;

&lt;p&gt;If I had to choose today:&lt;/p&gt;

&lt;h2&gt;
  
  
  My Recommendations
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Best Overall&lt;/td&gt;
&lt;td&gt;Langfuse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best Enterprise Choice&lt;/td&gt;
&lt;td&gt;HoneyHive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best LangChain Experience&lt;/td&gt;
&lt;td&gt;LangSmith&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best Cost Tracking&lt;/td&gt;
&lt;td&gt;Helicone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best Evaluation Platform&lt;/td&gt;
&lt;td&gt;Braintrust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best Production Monitoring&lt;/td&gt;
&lt;td&gt;Arize&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best Lightweight Open Source Option&lt;/td&gt;
&lt;td&gt;Phoenix&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;The interesting thing about AI observability tools is that most of them solve similar problems.&lt;/p&gt;

&lt;p&gt;The real difference is where they place their emphasis.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Langfuse focuses on flexibility.&lt;/li&gt;
&lt;li&gt;HoneyHive focuses on enterprise quality.&lt;/li&gt;
&lt;li&gt;LangSmith focuses on developer productivity.&lt;/li&gt;
&lt;li&gt;Helicone focuses on costs.&lt;/li&gt;
&lt;li&gt;Arize focuses on production monitoring.&lt;/li&gt;
&lt;li&gt;Braintrust focuses on evaluations.&lt;/li&gt;
&lt;li&gt;Phoenix focuses on lightweight open-source adoption.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no universally “best” platform.&lt;/p&gt;

&lt;p&gt;The right choice depends on what bottleneck you’re trying to solve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debugging?&lt;/li&gt;
&lt;li&gt;Evaluation?&lt;/li&gt;
&lt;li&gt;Monitoring?&lt;/li&gt;
&lt;li&gt;Cost optimization?&lt;/li&gt;
&lt;li&gt;Enterprise governance?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose the tool that aligns with that bottleneck, and you’ll likely get far more value than chasing feature checklists.&lt;/p&gt;

&lt;p&gt;What AI observability platform are you currently using, and what made you choose it?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>observability</category>
      <category>softwareengineering</category>
      <category>sre</category>
    </item>
    <item>
      <title>How Senior Engineers Use AI Without Burning Through Token Limits - Reduce AI Token Usage by 60–90%</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Sat, 06 Jun 2026 12:16:25 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/how-senior-ai-engineers-use-ai-without-burning-through-token-limits-reduce-ai-token-usage-by-4cpl</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/how-senior-ai-engineers-use-ai-without-burning-through-token-limits-reduce-ai-token-usage-by-4cpl</guid>
      <description>&lt;p&gt;Last month I watched a developer exhaust their Claude usage limit in less than a week.&lt;/p&gt;

&lt;p&gt;They weren't generating massive applications.&lt;/p&gt;

&lt;p&gt;They weren't building complex AI systems.&lt;/p&gt;

&lt;p&gt;They were simply asking AI to repeatedly scan the same repository, read the same files, and explain the same architecture over and over again.&lt;/p&gt;

&lt;p&gt;Sound familiar?&lt;/p&gt;

&lt;p&gt;As AI-assisted development becomes mainstream, many teams are discovering a new engineering challenge:&lt;/p&gt;

&lt;p&gt;Token efficiency.&lt;/p&gt;

&lt;p&gt;Just as experienced engineers learned to optimize cloud spend, senior engineers are now learning to optimize AI context.&lt;/p&gt;

&lt;p&gt;The difference between a developer who runs out of tokens every few days and one who comfortably works all month often isn't the AI model.&lt;/p&gt;

&lt;p&gt;It's how they manage context.&lt;/p&gt;

&lt;p&gt;Here's the toolkit and workflow I've seen work consistently.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Hidden Cost of Vibe Coding
&lt;/h2&gt;

&lt;p&gt;Imagine you ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix a bug in PaymentService.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your AI assistant proceeds to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scan the entire repository&lt;/li&gt;
&lt;li&gt;Read infrastructure code&lt;/li&gt;
&lt;li&gt;Explore frontend folders&lt;/li&gt;
&lt;li&gt;Traverse documentation&lt;/li&gt;
&lt;li&gt;Load previous conversations&lt;/li&gt;
&lt;li&gt;Inspect unrelated dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You asked about one file.&lt;/p&gt;

&lt;p&gt;The model consumed context from hundreds.&lt;/p&gt;

&lt;p&gt;That's where your tokens disappear.&lt;/p&gt;

&lt;p&gt;The goal isn't to reduce intelligence.&lt;/p&gt;

&lt;p&gt;The goal is to reduce unnecessary context.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. RTK: Stop Paying For Useless Command Output
&lt;/h2&gt;

&lt;p&gt;One of the biggest hidden token sinks is terminal output.&lt;/p&gt;

&lt;p&gt;Many AI coding agents automatically consume:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;npm install logs&lt;/li&gt;
&lt;li&gt;build outputs&lt;/li&gt;
&lt;li&gt;test results&lt;/li&gt;
&lt;li&gt;deployment logs&lt;/li&gt;
&lt;li&gt;dependency resolution messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of this information is irrelevant.&lt;/p&gt;

&lt;p&gt;Tools like RTK solve this problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What RTK Does
&lt;/h2&gt;

&lt;p&gt;RTK acts as a proxy layer between your development environment and the LLM.&lt;/p&gt;

&lt;p&gt;Instead of forwarding everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RTK filters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;redundant messages&lt;/li&gt;
&lt;li&gt;repeated warnings&lt;/li&gt;
&lt;li&gt;progress indicators&lt;/li&gt;
&lt;li&gt;noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;before they ever reach the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;p&gt;Reported reductions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;60–90% reduction in token consumption for common development workflows&lt;/li&gt;
&lt;li&gt;Faster agent reasoning&lt;/li&gt;
&lt;li&gt;Cleaner context windows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The principle is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If a human wouldn't read it, the model probably shouldn't either.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. Lean-CTX: Compress Context Before It Reaches The Model
&lt;/h2&gt;

&lt;p&gt;Most developers optimize prompts.&lt;/p&gt;

&lt;p&gt;Few optimize files.&lt;/p&gt;

&lt;p&gt;Large source files often contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generated code&lt;/li&gt;
&lt;li&gt;comments&lt;/li&gt;
&lt;li&gt;repetitive structures&lt;/li&gt;
&lt;li&gt;boilerplate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lean-CTX dynamically compresses and optimizes file content before it gets sent to the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It Matters
&lt;/h2&gt;

&lt;p&gt;Instead of sending:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4,000 line file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you might send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Relevant functions
Dependencies
Symbols
Interfaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI receives the information it needs while consuming significantly fewer tokens.&lt;/p&gt;

&lt;p&gt;Think of it as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;gzip for AI context.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. AI Codex &amp;amp; Repository Indexers
&lt;/h2&gt;

&lt;p&gt;One of the most expensive activities in AI coding is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Explore my codebase."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model begins reading dozens of files trying to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;routes&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;schemas&lt;/li&gt;
&lt;li&gt;services&lt;/li&gt;
&lt;li&gt;components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This exploratory phase can easily burn tens of thousands of tokens.&lt;/p&gt;

&lt;p&gt;Repository indexing tools solve this.&lt;/p&gt;

&lt;h2&gt;
  
  
  What They Generate
&lt;/h2&gt;

&lt;p&gt;Instead of scanning everything:&lt;/p&gt;

&lt;p&gt;Generate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROUTES.md
DATABASE_SCHEMA.md
COMPONENTS.md
SERVICES.md
DEPENDENCIES.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the AI can understand the system from five small files instead of 500 source files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typical Savings
&lt;/h2&gt;

&lt;p&gt;Many teams report avoiding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;30k–50k tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;during initial codebase exploration.&lt;/p&gt;

&lt;p&gt;This is one of the highest ROI improvements you can make.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Caveman Rule: My Favorite Token Hack
&lt;/h2&gt;

&lt;p&gt;This sounds ridiculous.&lt;/p&gt;

&lt;p&gt;But it works.&lt;/p&gt;

&lt;p&gt;When you need code, you don't need essays.&lt;/p&gt;

&lt;p&gt;You don't need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Certainly! Here's a detailed explanation...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bug here.
Fix this.
Run test.
Done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Caveman Rule instructs the AI to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;skip conversational filler&lt;/li&gt;
&lt;li&gt;avoid lengthy summaries&lt;/li&gt;
&lt;li&gt;communicate with minimal words&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I've identified several possible root causes...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Null value here.
Add guard clause.
Problem solved.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The technical accuracy remains.&lt;/p&gt;

&lt;p&gt;The verbosity disappears.&lt;/p&gt;

&lt;p&gt;Many developers report output token reductions approaching 75%.&lt;/p&gt;




&lt;h2&gt;
  
  
  Create A Project Brain
&lt;/h2&gt;

&lt;p&gt;One of the biggest mistakes I see:&lt;/p&gt;

&lt;p&gt;Developers repeatedly explaining their project.&lt;/p&gt;

&lt;p&gt;Every new session starts with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We're using:
- Node.js
- PostgreSQL
- Kubernetes
- OpenTelemetry
- GitHub Actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again.&lt;/p&gt;

&lt;p&gt;And again.&lt;/p&gt;

&lt;p&gt;And again.&lt;/p&gt;

&lt;p&gt;Instead create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLAUDE.md
AGENTS.md
PROJECT_CONTEXT.md
ARCHITECTURE.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;architecture&lt;/li&gt;
&lt;li&gt;conventions&lt;/li&gt;
&lt;li&gt;coding standards&lt;/li&gt;
&lt;li&gt;deployment patterns&lt;/li&gt;
&lt;li&gt;repository structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now every session starts with shared understanding.&lt;/p&gt;

&lt;p&gt;The AI spends less time learning.&lt;/p&gt;

&lt;p&gt;You spend fewer tokens teaching.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fragmented Code Approach
&lt;/h2&gt;

&lt;p&gt;Another expensive habit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rewrite the entire file.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI responds with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2,000 lines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You pay for all of it.&lt;/p&gt;

&lt;p&gt;Instead ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modify only lines 120–150.
Return patch only.
No summary.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer output tokens&lt;/li&gt;
&lt;li&gt;smaller future context&lt;/li&gt;
&lt;li&gt;easier reviews&lt;/li&gt;
&lt;li&gt;lower costs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best AI engineers increasingly think in patches, not rewrites.&lt;/p&gt;




&lt;h2&gt;
  
  
  Native IDE Features Most Developers Ignore
&lt;/h2&gt;

&lt;p&gt;Many modern AI IDEs already provide token optimization features.&lt;/p&gt;

&lt;p&gt;Most people never use them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cost Caps
&lt;/h2&gt;

&lt;p&gt;Set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;maximum tool calls&lt;/li&gt;
&lt;li&gt;session budgets&lt;/li&gt;
&lt;li&gt;usage limits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Treat tokens like cloud spend.&lt;/p&gt;

&lt;p&gt;Because they are.&lt;/p&gt;




&lt;h2&gt;
  
  
  Compact Sessions
&lt;/h2&gt;

&lt;p&gt;Claude and other tools support context compaction.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/compact
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This removes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;redundant conversation history&lt;/li&gt;
&lt;li&gt;obsolete decisions&lt;/li&gt;
&lt;li&gt;resolved issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;while preserving important context.&lt;/p&gt;

&lt;p&gt;Think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;garbage collection for conversations.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  New Session, New Problem
&lt;/h2&gt;

&lt;p&gt;One of the easiest wins:&lt;/p&gt;

&lt;p&gt;Start fresh.&lt;/p&gt;

&lt;p&gt;When:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a feature is complete&lt;/li&gt;
&lt;li&gt;a bug is resolved&lt;/li&gt;
&lt;li&gt;you're switching domains&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;create a new session.&lt;/p&gt;

&lt;p&gt;Old conversations become baggage.&lt;/p&gt;

&lt;p&gt;The model keeps re-reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mistakes&lt;/li&gt;
&lt;li&gt;abandoned approaches&lt;/li&gt;
&lt;li&gt;irrelevant context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fresh context often produces better results.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Personal Context Engineering Checklist
&lt;/h2&gt;

&lt;p&gt;Before asking AI anything:&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;

&lt;p&gt;Exclude:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules/
dist/
coverage/
build/
.next/
target/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;Maintain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLAUDE.md
AGENTS.md
ARCHITECTURE.md
PROJECT_CONTEXT.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Tooling
&lt;/h2&gt;

&lt;p&gt;Use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RTK&lt;/li&gt;
&lt;li&gt;Lean-CTX&lt;/li&gt;
&lt;li&gt;AI Codex&lt;/li&gt;
&lt;li&gt;Repository Indexers&lt;/li&gt;
&lt;li&gt;Semantic Search&lt;/li&gt;
&lt;li&gt;Code Graphs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Prompting
&lt;/h2&gt;

&lt;p&gt;Prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Patch only.
No summary.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explain everything.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Sessions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Compact regularly&lt;/li&gt;
&lt;li&gt;Start fresh often&lt;/li&gt;
&lt;li&gt;Keep contexts small&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;For years we optimized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cloud costs&lt;/li&gt;
&lt;li&gt;compute costs&lt;/li&gt;
&lt;li&gt;storage costs&lt;/li&gt;
&lt;li&gt;network costs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we need to optimize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;context costs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next generation of high-performing AI engineers won't be the people with the biggest context windows.&lt;/p&gt;

&lt;p&gt;They'll be the people who know exactly what context to send.&lt;/p&gt;

&lt;p&gt;Prompt engineering helped us talk to AI.&lt;/p&gt;

&lt;p&gt;Context engineering helps us scale AI.&lt;/p&gt;

&lt;p&gt;And in the age of vibe coding, context is the new compute.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vibecoding</category>
      <category>machinelearning</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Reflection vs Reflexion Agents: The Next Leap in Agentic AI</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Sun, 22 Mar 2026 03:04:03 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/reflection-vs-reflexion-agents-the-next-leap-in-agentic-ai-1k0m</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/reflection-vs-reflexion-agents-the-next-leap-in-agentic-ai-1k0m</guid>
      <description>&lt;p&gt;As generative AI systems evolve from simple prompt-response tools into &lt;strong&gt;autonomous agents&lt;/strong&gt;, one capability is becoming increasingly critical:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The ability for AI systems to &lt;strong&gt;improve themselves during execution&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is where two powerful concepts come into play:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reflection&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reflexion&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They sound similar. They are often confused.&lt;br&gt;&lt;br&gt;
But architecturally — and practically — they are very different.&lt;/p&gt;

&lt;p&gt;Let’s break them down.&lt;/p&gt;


&lt;h2&gt;
  
  
  🚀 Why This Matters
&lt;/h2&gt;

&lt;p&gt;If you're building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI copilots&lt;/li&gt;
&lt;li&gt;Autonomous workflows&lt;/li&gt;
&lt;li&gt;Multi-step reasoning systems&lt;/li&gt;
&lt;li&gt;Or agentic architectures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then &lt;strong&gt;how your system learns from mistakes&lt;/strong&gt; will define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accuracy&lt;/li&gt;
&lt;li&gt;Reliability&lt;/li&gt;
&lt;li&gt;Cost efficiency&lt;/li&gt;
&lt;li&gt;User trust&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧠 What is Reflection?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Reflection&lt;/strong&gt; is when an AI system:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reviews its own output and improves it &lt;strong&gt;within the same execution loop&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  🔁 How it works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Generate response
&lt;/li&gt;
&lt;li&gt;Evaluate response (self-critique or evaluator model)
&lt;/li&gt;
&lt;li&gt;Refine response
&lt;/li&gt;
&lt;li&gt;Repeat until acceptable
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  🧩 Architecture Pattern
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input
↓
LLM → Output
↓
Self-Evaluation (LLM or rule-based)
↓
Refinement Loop
↓
Final Output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  ✅ Key Characteristics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Happens &lt;strong&gt;within a single session&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;No memory across runs&lt;/li&gt;
&lt;li&gt;Iterative improvement&lt;/li&gt;
&lt;li&gt;Often uses:

&lt;ul&gt;
&lt;li&gt;Self-critique prompts&lt;/li&gt;
&lt;li&gt;Evaluation models&lt;/li&gt;
&lt;li&gt;Chain-of-thought refinement&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  💡 Example
&lt;/h3&gt;

&lt;p&gt;User asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Summarize this legal document."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reflection agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generates summary&lt;/li&gt;
&lt;li&gt;Checks:

&lt;ul&gt;
&lt;li&gt;Missing clauses?&lt;/li&gt;
&lt;li&gt;Ambiguity?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Refines output&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  👍 Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Improves output quality instantly
&lt;/li&gt;
&lt;li&gt;No infrastructure complexity
&lt;/li&gt;
&lt;li&gt;Easy to implement
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  👎 Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No long-term learning
&lt;/li&gt;
&lt;li&gt;Repeats same mistakes across sessions
&lt;/li&gt;
&lt;li&gt;Increased latency (multiple LLM calls)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🔁 What is Reflexion?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Reflexion&lt;/strong&gt; goes a step further.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It enables an AI system to &lt;strong&gt;learn from past mistakes and improve future performance&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This concept was popularized by research on &lt;strong&gt;self-improving agents with memory&lt;/strong&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  🔄 How it works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Perform task
&lt;/li&gt;
&lt;li&gt;Evaluate outcome
&lt;/li&gt;
&lt;li&gt;Store feedback in memory
&lt;/li&gt;
&lt;li&gt;Use memory to improve future decisions
&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;
  
  
  🧩 Architecture Pattern
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input
↓
Agent Execution
↓
Outcome Evaluation
↓
Memory Store (success/failure insights)
↓
Future Runs Use Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧠 Key Difference
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Reflection&lt;/th&gt;
&lt;th&gt;Reflexion&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Session-based&lt;/td&gt;
&lt;td&gt;Cross-session&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No memory&lt;/td&gt;
&lt;td&gt;Persistent memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Improves current output&lt;/td&gt;
&lt;td&gt;Improves future outputs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stateless&lt;/td&gt;
&lt;td&gt;Stateful&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h3&gt;
  
  
  💡 Example
&lt;/h3&gt;

&lt;p&gt;AI agent writing grant applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attempt 1: Rejected ❌
&lt;/li&gt;
&lt;li&gt;Stores feedback:

&lt;ul&gt;
&lt;li&gt;"Too generic"&lt;/li&gt;
&lt;li&gt;"Lacks domain-specific references"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next attempt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses stored insights&lt;/li&gt;
&lt;li&gt;Produces better output ✅&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🔥 Why Reflexion is a Big Deal
&lt;/h2&gt;

&lt;p&gt;Reflexion introduces something critical:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Learning without retraining the model&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of fine-tuning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You &lt;strong&gt;store experiences&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You &lt;strong&gt;adapt behavior dynamically&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🏗️ Real-World Implementation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Reflection (simple)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Prompt chaining&lt;/li&gt;
&lt;li&gt;Self-critique prompts&lt;/li&gt;
&lt;li&gt;ReAct-style loops&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Reflexion (advanced)
&lt;/h3&gt;

&lt;p&gt;Requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memory layer:

&lt;ul&gt;
&lt;li&gt;Vector DB (e.g., embeddings)&lt;/li&gt;
&lt;li&gt;Key-value store&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Feedback signals:

&lt;ul&gt;
&lt;li&gt;Human feedback&lt;/li&gt;
&lt;li&gt;Automated scoring&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Retrieval mechanism:

&lt;ul&gt;
&lt;li&gt;Inject past learnings into prompts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ⚙️ Example Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;LLM: Claude / GPT / Nova
&lt;/li&gt;
&lt;li&gt;Memory: Vector DB (FAISS, OpenSearch)
&lt;/li&gt;
&lt;li&gt;Orchestration: LangChain / custom agents
&lt;/li&gt;
&lt;li&gt;Evaluation: Rule-based or LLM-as-judge
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ⚖️ When to Use What?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Use Reflection when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need &lt;strong&gt;better answers now&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;No need for memory&lt;/li&gt;
&lt;li&gt;Simpler workflows&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Use Reflexion when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tasks are &lt;strong&gt;repetitive and evolving&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Feedback is available&lt;/li&gt;
&lt;li&gt;Long-term improvement matters&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧠 Combining Both (Best Practice)
&lt;/h2&gt;

&lt;p&gt;The most powerful systems use &lt;strong&gt;both&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reflexion (long-term learning)
+
Reflection (short-term refinement)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 This creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immediate quality improvement
&lt;/li&gt;
&lt;li&gt;Continuous learning over time
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧪 Real-World Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AI coding assistants
&lt;/li&gt;
&lt;li&gt;Customer support agents
&lt;/li&gt;
&lt;li&gt;Financial advisory copilots
&lt;/li&gt;
&lt;li&gt;Healthcare decision support
&lt;/li&gt;
&lt;li&gt;Autonomous research assistants
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reflection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Cost (multiple LLM calls)&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reflexion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Memory design complexity
&lt;/li&gt;
&lt;li&gt;Signal quality (bad feedback = bad learning)
&lt;/li&gt;
&lt;li&gt;Retrieval accuracy
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧭 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;We are moving from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Prompt → Response  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Prompt → Reason → Reflect → Learn → Improve  &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  🔥 Key Insight
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Reflection makes AI &lt;strong&gt;smarter in the moment&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Reflexion makes AI &lt;strong&gt;smarter over time&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ✍️ Closing
&lt;/h2&gt;

&lt;p&gt;If you're building next-gen AI systems,&lt;br&gt;&lt;br&gt;
understanding this difference is not optional — it's foundational.&lt;/p&gt;

&lt;p&gt;The future of AI is not just about &lt;strong&gt;better models&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s about &lt;strong&gt;better systems around those models&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;💬 Curious how to implement Reflexion in production?&lt;br&gt;&lt;br&gt;
Happy to share a deep dive in the next post.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agentskills</category>
      <category>llm</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Prompt Engineering Is Not Enough: Enter Flow Engineering for Production LLM Systems</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Sat, 07 Mar 2026 03:20:46 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/prompt-engineering-is-not-enough-enter-flow-engineering-for-production-llm-systems-47ic</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/prompt-engineering-is-not-enough-enter-flow-engineering-for-production-llm-systems-47ic</guid>
      <description>&lt;p&gt;Large Language Models have unlocked a new generation of applications — copilots, assistants, RAG systems, autonomous agents, and internal AI tools.&lt;/p&gt;

&lt;p&gt;But many teams building with LLMs hit the same wall.&lt;/p&gt;

&lt;p&gt;Their application works in demos… but becomes unreliable in production.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because &lt;strong&gt;prompt engineering alone is not enough.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To build reliable AI systems, we need something more powerful:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flow Engineering.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why prompt engineering alone fails in production&lt;/li&gt;
&lt;li&gt;What &lt;strong&gt;Flow Engineering&lt;/strong&gt; actually means&lt;/li&gt;
&lt;li&gt;The architecture of real-world LLM systems&lt;/li&gt;
&lt;li&gt;Practical examples engineers can implement today&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Era of Prompt Engineering
&lt;/h2&gt;

&lt;p&gt;When GPT-style models first became popular, the focus was on &lt;strong&gt;prompt engineering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Prompt engineering is the art of crafting instructions to guide the LLM to produce better responses.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are a helpful assistant. 
Summarise the following meeting transcript in bullet points.
Focus only on action items.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developers quickly discovered techniques like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Few-shot prompting&lt;/li&gt;
&lt;li&gt;Chain-of-thought prompts&lt;/li&gt;
&lt;li&gt;Role prompting&lt;/li&gt;
&lt;li&gt;Structured output prompts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These techniques &lt;strong&gt;improve individual LLM calls.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But they only solve part of the problem.&lt;/p&gt;

&lt;p&gt;Prompt engineering optimises one interaction.&lt;/p&gt;

&lt;p&gt;Real applications involve &lt;strong&gt;many interactions and system components.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Prompt-Only Systems
&lt;/h2&gt;

&lt;p&gt;Let's imagine we are building a simple &lt;strong&gt;customer support AI assistant.&lt;/strong&gt;&lt;br&gt;
A naive architecture might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Question
      ↓
     LLM
      ↓
   Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works in simple demos.&lt;/p&gt;

&lt;p&gt;But real systems quickly require more complexity.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieve relevant documents&lt;/li&gt;
&lt;li&gt;Use tools (APIs, databases)&lt;/li&gt;
&lt;li&gt;Validate outputs&lt;/li&gt;
&lt;li&gt;Retry on errors&lt;/li&gt;
&lt;li&gt;Maintain conversation context&lt;/li&gt;
&lt;li&gt;Apply guardrails&lt;/li&gt;
&lt;li&gt;Log reasoning steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suddenly, our architecture looks more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Question
      ↓
Context Retrieval (RAG)
      ↓
Tool Selection
      ↓
LLM Reasoning
      ↓
Output Validation
      ↓
Response Generation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;strong&gt;multi-step pipeline&lt;/strong&gt; is where &lt;strong&gt;Flow Engineering&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Flow Engineering?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Flow Engineering&lt;/strong&gt; is the design of structured execution flows around LLMs.&lt;/p&gt;

&lt;p&gt;Instead of focusing on a single prompt, engineers design &lt;strong&gt;end-to-end reasoning pipelines.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt Engineering = How the LLM thinks

Flow Engineering = How the system operates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flow engineering involves designing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execution pipelines&lt;/li&gt;
&lt;li&gt;Tool orchestration&lt;/li&gt;
&lt;li&gt;State management&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Validation&lt;/li&gt;
&lt;li&gt;Feedback loops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Flow engineering treats LLM applications as distributed systems, not chatbots.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Real Production Flow
&lt;/h2&gt;

&lt;p&gt;Let's look at a simplified &lt;strong&gt;production AI flow.&lt;/strong&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 Question
   ↓
Input Guardrails
   ↓
Context Retrieval (Vector DB)
   ↓
Tool Routing
   ↓
LLM Reasoning
   ↓
Tool Execution
   ↓
Response Validation
   ↓
Final Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each step solves a real engineering problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Guardrails&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Prevent prompt injection or malicious input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context Retrieval&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fetch relevant documents using vector search.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tool Routing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Determine which tools the AI should use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ensure output matches schema or safety rules.&lt;/p&gt;

&lt;p&gt;Without this flow, AI systems become &lt;strong&gt;unpredictable.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Prompt vs Flow
&lt;/h2&gt;

&lt;p&gt;Let's compare two implementations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt Engineering Only&lt;/strong&gt;&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarise this transcript and extract action items.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may work sometimes.&lt;/p&gt;

&lt;p&gt;But what if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;transcript is too long&lt;/li&gt;
&lt;li&gt;model hallucinate action items&lt;/li&gt;
&lt;li&gt;output format changes&lt;/li&gt;
&lt;li&gt;context is missing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's see a &lt;strong&gt;flow-based approach.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Flow Engineered System
&lt;/h2&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;generate_meeting_summary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;split_transcript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;summaries&lt;/span&gt; &lt;span class="o"&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;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&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;Summarise this transcript section:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;chunk&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;summaries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;combined_summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&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;Combine these summaries and extract action items:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;summaries&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;validated_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validate_schema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combined_summary&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;validated_output&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chunking&lt;/li&gt;
&lt;li&gt;intermediate reasoning&lt;/li&gt;
&lt;li&gt;structured validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This dramatically improves reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Components of Flow Engineering
&lt;/h2&gt;

&lt;p&gt;Most production LLM flows include these components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. State Management&lt;/strong&gt;&lt;br&gt;
Flows maintain state across steps.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Conversation History
Retrieved Documents
Tool Results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Frameworks like &lt;strong&gt;LangGraph&lt;/strong&gt; model this using state machines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Tool Orchestration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LLMs often interact with tools.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;databases&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;search engines&lt;/li&gt;
&lt;li&gt;internal systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flow engineering controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which tool to use&lt;/li&gt;
&lt;li&gt;when to call it&lt;/li&gt;
&lt;li&gt;how to merge results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Retry &amp;amp; Error Handling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LLMs are probabilistic.&lt;/p&gt;

&lt;p&gt;Sometimes outputs are invalid.&lt;/p&gt;

&lt;p&gt;A flow can automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retry generation&lt;/li&gt;
&lt;li&gt;correct formatting&lt;/li&gt;
&lt;li&gt;request clarification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Guardrails &amp;amp; Validation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before returning outputs, systems often validate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON schema&lt;/li&gt;
&lt;li&gt;safety policies&lt;/li&gt;
&lt;li&gt;hallucinations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This prevents unreliable responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flow Engineering Frameworks
&lt;/h2&gt;

&lt;p&gt;Several frameworks help engineers implement LLM flows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LangGraph&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Models AI workflows as state machines.&lt;/p&gt;

&lt;p&gt;Great for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;complex agent workflows&lt;/li&gt;
&lt;li&gt;branching logic&lt;/li&gt;
&lt;li&gt;memory management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Semantic Kernel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Popular in enterprise environments.&lt;/p&gt;

&lt;p&gt;Supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;planners&lt;/li&gt;
&lt;li&gt;function calling&lt;/li&gt;
&lt;li&gt;workflow orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Custom Orchestration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many teams implement flows directly using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;serverless pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because flows are essentially application logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Flow Engineering Matters
&lt;/h2&gt;

&lt;p&gt;Companies deploying production AI systems quickly discover:&lt;/p&gt;

&lt;p&gt;The challenge is not the model.&lt;/p&gt;

&lt;p&gt;The challenge is system design around the model.&lt;/p&gt;

&lt;p&gt;Flow engineering provides:&lt;/p&gt;

&lt;p&gt;✔ reliability&lt;br&gt;
✔ reproducibility&lt;br&gt;
✔ observability&lt;br&gt;
✔ safety&lt;br&gt;
✔ scalability&lt;/p&gt;

&lt;p&gt;Without it, LLM applications behave unpredictably.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Shift AI Engineers Must Make
&lt;/h2&gt;

&lt;p&gt;Early LLM development focused on prompts.&lt;/p&gt;

&lt;p&gt;But the industry is moving toward AI systems engineering.&lt;/p&gt;

&lt;p&gt;That means thinking in terms of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pipelines&lt;/li&gt;
&lt;li&gt;workflows&lt;/li&gt;
&lt;li&gt;orchestration&lt;/li&gt;
&lt;li&gt;tool ecosystems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI applications are evolving from prompt-driven apps to flow-driven systems.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Prompt engineering is still important.&lt;/p&gt;

&lt;p&gt;But in production systems, prompts are only one component.&lt;/p&gt;

&lt;p&gt;The real power of modern AI systems comes from well-designed execution flows.&lt;/p&gt;

&lt;p&gt;If you want reliable AI applications, start thinking like a systems engineer, not just a prompt writer.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s Next
&lt;/h3&gt;

&lt;p&gt;In upcoming articles, we'll dive deeper into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reflection vs Reflexion agents&lt;/li&gt;
&lt;li&gt;LangGraph state machines&lt;/li&gt;
&lt;li&gt;Semantic Kernel orchestration&lt;/li&gt;
&lt;li&gt;Model Context Protocol (MCP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These concepts build on flow engineering to create more capable AI systems.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>promptengineering</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Secrets Management for LLM Tools: Don’t Let Your OpenAI Keys End Up on GitHub 🚨</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Sat, 14 Feb 2026 04:04:56 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/secrets-management-for-llm-tools-dont-let-your-openai-keys-end-up-on-github-38c0</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/secrets-management-for-llm-tools-dont-let-your-openai-keys-end-up-on-github-38c0</guid>
      <description>&lt;h2&gt;
  
  
  "A practical guide to securing LLM API keys, embeddings, vector
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: If you're building with LLMs and you're not treating secrets as first-class infrastructure, you're already at risk.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every week, we see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI keys pushed to GitHub&lt;/li&gt;
&lt;li&gt;API keys logged in CloudWatch&lt;/li&gt;
&lt;li&gt;Secrets hardcoded in Streamlit demos that later go to production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LLM systems multiply secrets quickly. If you don’t design for this early, things get messy fast.&lt;/p&gt;

&lt;p&gt;This is a production-ready blueprint for securing LLM systems properly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: LLM Secrets Multiply Fast 🐰
&lt;/h2&gt;

&lt;p&gt;One LLM integration turns into dozens of credentials:&lt;/p&gt;

&lt;p&gt;1 LLM API key (OpenAI / Anthropic)&lt;br&gt;
→ 3 embedding endpoints&lt;br&gt;
→ 5 vector store connections (Pinecone / Weaviate)&lt;br&gt;
→ 2 RAG databases&lt;br&gt;
→ 10 external tools (SerpAPI, Wolfram, etc.)&lt;br&gt;
→ 50 microservices&lt;br&gt;
= 70+ secrets&lt;/p&gt;

&lt;p&gt;The bigger your AI system gets, the larger your attack surface becomes.&lt;/p&gt;


&lt;h2&gt;
  
  
  1️⃣ Never Hardcode Secrets
&lt;/h2&gt;

&lt;p&gt;❌ Wrong (guaranteed leak eventually)&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;# NEVER DO THIS
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sk-123...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hardcoded secrets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;End up in git history&lt;/li&gt;
&lt;li&gt;Get copied into logs&lt;/li&gt;
&lt;li&gt;Leak via screenshots or stack traces&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✅ Right: Runtime Environment Injection&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;# config.py
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;OPENAI_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Principle:&lt;/strong&gt;&lt;br&gt;
Secrets should be injected at runtime, never committed to source code.&lt;/p&gt;
&lt;h2&gt;
  
  
  2️⃣ Use Cloud-Native Secrets Managers
&lt;/h2&gt;

&lt;p&gt;If you're in production, use a managed secrets service.&lt;/p&gt;

&lt;p&gt;AWS Secrets Manager + Lambda Example&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;# lambda_function.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_secrets&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secretsmanager&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;secret&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;get_secret_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SecretId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llm-prod/openai&lt;/span&gt;&lt;span class="sh"&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;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SecretString&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;secrets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_secrets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="c1"&gt;# LLM logic here
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Centralized storage&lt;/li&gt;
&lt;li&gt;IAM-based access control&lt;/li&gt;
&lt;li&gt;Audit logs&lt;/li&gt;
&lt;li&gt;Automatic rotation support&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Terraform for Secret Infrastructure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_secretsmanager_secret"&lt;/span&gt; &lt;span class="s2"&gt;"llm_keys"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"llm-prod/openai"&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Environment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Production"&lt;/span&gt;
    &lt;span class="nx"&gt;Team&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AI"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_secretsmanager_secret_version"&lt;/span&gt; &lt;span class="s2"&gt;"llm_keys_version"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;secret_id&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_secretsmanager_secret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;llm_keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;secret_string&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;OPENAI_API_KEY&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sk-..."&lt;/span&gt;
    &lt;span class="nx"&gt;ANTHROPIC_API_KEY&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sk-ant-..."&lt;/span&gt;
    &lt;span class="nx"&gt;PINECONE_API_KEY&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pxl-..."&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;Infrastructure-as-Code ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repeatability&lt;/li&gt;
&lt;li&gt;Auditability&lt;/li&gt;
&lt;li&gt;No manual copy-paste secret management&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3️⃣ Prefer Dynamic Credentials Over Static API Keys ⚡
&lt;/h2&gt;

&lt;p&gt;Static API keys are long-lived and high risk.&lt;/p&gt;

&lt;p&gt;Dynamic credentials reduce blast radius.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IAM Roles for Service Accounts (Kubernetes + AWS IRSA)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ServiceAccount&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;llm-worker&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;eks.amazonaws.com/role-arn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::123456789012:role/llm-worker-role&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;llm-worker&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;serviceAccountName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;llm-worker&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;llm-worker&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OPENAI_API_KEY&lt;/span&gt;
              &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;llm-secrets&lt;/span&gt;
                  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai-key&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Even better:&lt;/strong&gt; eliminate API keys entirely where possible and use workload identity federation.&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ Secure CI/CD with OIDC (No Long-Lived AWS Keys)
&lt;/h2&gt;

&lt;p&gt;Never store AWS credentials in GitHub secrets if you can avoid it.&lt;/p&gt;

&lt;p&gt;Use OIDC federation instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy LLM Pipeline&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;role-to-assume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::123456789012:role/github-actions-llm-deploy&lt;/span&gt;
          &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python deploy.py&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This avoids:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static AWS access keys&lt;/li&gt;
&lt;li&gt;Manual credential rotation&lt;/li&gt;
&lt;li&gt;CI secret sprawl&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5️⃣ Agentic LLM Systems Need Scoped Secrets 🧠
&lt;/h2&gt;

&lt;p&gt;When building multi-agent systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each agent should have scoped credentials&lt;/li&gt;
&lt;li&gt;Short-lived tokens preferred&lt;/li&gt;
&lt;li&gt;No shared global API key across agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example pattern:&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;class&lt;/span&gt; &lt;span class="nc"&gt;LLMAgentSecrets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&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;sm_client&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;sm_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sm_client&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_agent_secret&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;agent_id&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;secret_name&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;llm-agent-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;secret&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;sm_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_secret_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SecretId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;secret_name&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;secret&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SecretString&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Design for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolation&lt;/li&gt;
&lt;li&gt;Least privilege&lt;/li&gt;
&lt;li&gt;Auditable access&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Production Security Checklist
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="err"&gt;☐&lt;/span&gt; &lt;span class="nc"&gt;No&lt;/span&gt; &lt;span class="n"&gt;hardcoded&lt;/span&gt; &lt;span class="nf"&gt;secrets&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;grep&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="s"&gt;"sk-"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;☐&lt;/span&gt; &lt;span class="nc"&gt;Cloud&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt;
&lt;span class="err"&gt;☐&lt;/span&gt; &lt;span class="no"&gt;IAM&lt;/span&gt; &lt;span class="n"&gt;roles&lt;/span&gt; &lt;span class="n"&gt;preferred&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;
&lt;span class="err"&gt;☐&lt;/span&gt; &lt;span class="no"&gt;OIDC&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="no"&gt;CI&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;CD&lt;/span&gt;
&lt;span class="err"&gt;☐&lt;/span&gt; &lt;span class="nc"&gt;Secrets&lt;/span&gt; &lt;span class="n"&gt;scanning&lt;/span&gt; &lt;span class="nf"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TruffleHog&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;GitGuardian&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;☐&lt;/span&gt; &lt;span class="nc"&gt;Log&lt;/span&gt; &lt;span class="n"&gt;sanitization&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;place&lt;/span&gt;
&lt;span class="err"&gt;☐&lt;/span&gt; &lt;span class="nc"&gt;Rotation&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="nf"&gt;defined&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;≤&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;☐&lt;/span&gt; &lt;span class="nc"&gt;Audit&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;
&lt;span class="err"&gt;☐&lt;/span&gt; &lt;span class="nc"&gt;Least&lt;/span&gt; &lt;span class="n"&gt;privilege&lt;/span&gt; &lt;span class="n"&gt;enforced&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Leak Vectors 🚫
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Leak Vector&lt;/th&gt;
&lt;th&gt;Detection&lt;/th&gt;
&lt;th&gt;Prevention&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Git commits&lt;/td&gt;
&lt;td&gt;`git log -p&lt;/td&gt;
&lt;td&gt;grep sk-`&lt;/td&gt;
&lt;td&gt;Pre-commit hooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logs&lt;/td&gt;
&lt;td&gt;CloudWatch Insights&lt;/td&gt;
&lt;td&gt;Log scrubbing&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker images&lt;/td&gt;
&lt;td&gt;Inspect image layers&lt;/td&gt;
&lt;td&gt;Multi-stage builds&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory dumps&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/proc/[pid]/environ&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Container hardening&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Cost vs Risk 💰
&lt;/h3&gt;

&lt;p&gt;Typical monthly cost for secure secrets management:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Secrets Manager: ~$0.40 per secret&lt;/li&gt;
&lt;li&gt;Secret scanning tools: modest monthly fee&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OIDC: no additional cost&lt;br&gt;
Compare that to:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Revoking leaked keys&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service outages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Customer trust damage&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security is cheaper than cleanup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Takeaways 🎯
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Dynamic &amp;gt; Static&lt;/li&gt;
&lt;li&gt;Inject at runtime, never commit&lt;/li&gt;
&lt;li&gt;Audit secret access&lt;/li&gt;
&lt;li&gt;Rotate regularly&lt;/li&gt;
&lt;li&gt;Scan continuously&lt;/li&gt;
&lt;li&gt;Apply least privilege everywhere&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;LLMs are powerful.&lt;/p&gt;

&lt;h2&gt;
  
  
  But API keys are still just credentials — treat them like production infrastructure.
&lt;/h2&gt;

&lt;p&gt;Have you ever dealt with an exposed LLM API key in production? What happened?&lt;br&gt;
Let’s discuss 👇&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>llm</category>
      <category>devops</category>
    </item>
    <item>
      <title>Observability in AI Systems</title>
      <dc:creator>Parth Sarthi Sharma</dc:creator>
      <pubDate>Tue, 27 Jan 2026 13:17:25 +0000</pubDate>
      <link>https://dev.to/parth_sarthisharma_105e7/observability-in-ai-systems-27ag</link>
      <guid>https://dev.to/parth_sarthisharma_105e7/observability-in-ai-systems-27ag</guid>
      <description>&lt;h2&gt;
  
  
  Why RAG Pipelines Fail Silently (and How to See It)
&lt;/h2&gt;

&lt;p&gt;Traditional software taught us a hard lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you can’t observe it, you can’t operate it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI systems — especially &lt;strong&gt;RAG pipelines&lt;/strong&gt; — are repeating the same mistakes we made with distributed systems a decade ago.&lt;/p&gt;

&lt;p&gt;They look fine.&lt;br&gt;
They respond fast.&lt;br&gt;
They return answers.&lt;/p&gt;

&lt;p&gt;And yet — they are &lt;strong&gt;quietly wrong&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article explains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why observability is fundamentally harder in AI systems&lt;/li&gt;
&lt;li&gt;What observability &lt;em&gt;actually means&lt;/em&gt; for RAG pipelines&lt;/li&gt;
&lt;li&gt;What signals matter (and which ones don’t)&lt;/li&gt;
&lt;li&gt;How mature teams design observable AI systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No dashboards for the sake of dashboards — only what helps you debug reality.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why AI Observability Is Different From Traditional Observability
&lt;/h2&gt;

&lt;p&gt;In classic systems, we observe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU&lt;/li&gt;
&lt;li&gt;memory&lt;/li&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;li&gt;error rates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In AI systems, the hardest failures are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Semantic&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Probabilistic&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contextual&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A RAG pipeline can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;return HTTP 200&lt;/li&gt;
&lt;li&gt;respond in 300ms&lt;/li&gt;
&lt;li&gt;use the correct model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and still give a &lt;strong&gt;wrong answer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s why AI observability must go deeper.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Core Problem With RAG Pipelines
&lt;/h2&gt;

&lt;p&gt;A basic RAG flow looks like this:&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
↓
Embedding
↓
Vector Search
↓
Top-K Chunks
↓
Prompt Assembly
↓
LLM Generation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the output is wrong, &lt;strong&gt;where did it fail?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bad query?&lt;/li&gt;
&lt;li&gt;Wrong chunks?&lt;/li&gt;
&lt;li&gt;Missing chunks?&lt;/li&gt;
&lt;li&gt;Prompt formatting?&lt;/li&gt;
&lt;li&gt;Model hallucination?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without observability, you’re guessing.&lt;/p&gt;




&lt;h2&gt;
  
  
  What “Observability” Means in the AI World
&lt;/h2&gt;

&lt;p&gt;AI observability is the ability to answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why did the system produce &lt;em&gt;this&lt;/em&gt; answer for &lt;em&gt;this&lt;/em&gt; input at &lt;em&gt;this&lt;/em&gt; time?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That requires &lt;strong&gt;traceability&lt;/strong&gt;, not just metrics.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Four Pillars of RAG Observability
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ Query Observability
&lt;/h3&gt;

&lt;p&gt;You must log:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Original user query&lt;/li&gt;
&lt;li&gt;Rewritten / normalized query (if any)&lt;/li&gt;
&lt;li&gt;Detected intent or routing decision&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many failures start with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ambiguous questions&lt;/li&gt;
&lt;li&gt;underspecified intent&lt;/li&gt;
&lt;li&gt;bad query rewriting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can’t see the &lt;em&gt;effective query&lt;/em&gt;, you can’t debug retrieval.&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ Retrieval Observability (Most Important)
&lt;/h3&gt;

&lt;p&gt;This is where &lt;strong&gt;most RAG systems fail&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You should observe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieved chunk IDs&lt;/li&gt;
&lt;li&gt;Source documents&lt;/li&gt;
&lt;li&gt;Similarity scores&lt;/li&gt;
&lt;li&gt;Chunk rank&lt;/li&gt;
&lt;li&gt;Retrieval strategy used (vector, keyword, hybrid)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example questions observability should answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Which chunks were retrieved?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Which chunk influenced the answer most?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Was relevant information missing?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don’t log retrieved chunks, &lt;strong&gt;you don’t have RAG observability&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  3️⃣ Prompt Observability
&lt;/h3&gt;

&lt;p&gt;Your prompt is your &lt;strong&gt;runtime program&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You must capture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Final prompt sent to the LLM&lt;/li&gt;
&lt;li&gt;Context size and token count&lt;/li&gt;
&lt;li&gt;Chunk ordering&lt;/li&gt;
&lt;li&gt;System instructions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why?&lt;br&gt;
Because subtle changes in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ordering&lt;/li&gt;
&lt;li&gt;truncation&lt;/li&gt;
&lt;li&gt;formatting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;can completely change answers.&lt;/p&gt;


&lt;h3&gt;
  
  
  4️⃣ Generation &amp;amp; Answer Observability
&lt;/h3&gt;

&lt;p&gt;Beyond the final answer, log:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model name &amp;amp; version&lt;/li&gt;
&lt;li&gt;Temperature / decoding params&lt;/li&gt;
&lt;li&gt;Token usage&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Safety or refusal triggers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Advanced systems also track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Answer confidence&lt;/li&gt;
&lt;li&gt;Self-evaluation scores (Self-RAG)&lt;/li&gt;
&lt;li&gt;Groundedness signals&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Most Common RAG Failure Modes (Seen in Production)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  ❌ “The model hallucinated”
&lt;/h3&gt;

&lt;p&gt;Usually false.&lt;/p&gt;

&lt;p&gt;More often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wrong chunk retrieved&lt;/li&gt;
&lt;li&gt;Right chunk ranked too low&lt;/li&gt;
&lt;li&gt;Context truncated&lt;/li&gt;
&lt;li&gt;Outdated document used&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observability makes this visible.&lt;/p&gt;


&lt;h3&gt;
  
  
  ❌ “Vector search is bad”
&lt;/h3&gt;

&lt;p&gt;Often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chunking is wrong&lt;/li&gt;
&lt;li&gt;Embedding mismatch&lt;/li&gt;
&lt;li&gt;Query rewriting failed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again — visible with the right signals.&lt;/p&gt;


&lt;h2&gt;
  
  
  Tracing a Single RAG Request (What Good Looks Like)
&lt;/h2&gt;

&lt;p&gt;A single request trace should show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request ID: 9f23...

Query:
"Can I carry forward unused leave?"

Rewritten Query:
"Leave carry forward policy Australia"

Retrieved Chunks:

handbook.md#leave-carry-forward (score: 0.89)

policy.md#exceptions (score: 0.81)

Prompt Tokens:
3,214

Model:
gpt-4.1-mini

Answer:
"Yes, up to 10 days can be carried forward..."

Confidence:
High
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you can’t reconstruct this — you can’t debug.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Traditional Metrics Are Not Enough
&lt;/h2&gt;

&lt;p&gt;Latency and cost are necessary — but insufficient.&lt;/p&gt;

&lt;p&gt;AI systems need &lt;strong&gt;semantic metrics&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Groundedness&lt;/li&gt;
&lt;li&gt;Faithfulness&lt;/li&gt;
&lt;li&gt;Retrieval coverage&lt;/li&gt;
&lt;li&gt;Answer stability over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are harder — but essential.&lt;/p&gt;




&lt;h2&gt;
  
  
  Observability Enables Advanced RAG Patterns
&lt;/h2&gt;

&lt;p&gt;You cannot safely implement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adaptive RAG&lt;/li&gt;
&lt;li&gt;Corrective RAG&lt;/li&gt;
&lt;li&gt;Self-RAG&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without observability.&lt;/p&gt;

&lt;p&gt;Why?&lt;br&gt;
Because all of them rely on &lt;strong&gt;feedback signals&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Was retrieval good?&lt;/li&gt;
&lt;li&gt;Was the answer grounded?&lt;/li&gt;
&lt;li&gt;Should we retry?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No signals → no control loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple Observability Checklist
&lt;/h2&gt;

&lt;p&gt;If you’re building RAG in production, you should be able to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which document influenced this answer?&lt;/li&gt;
&lt;li&gt;Why was this chunk chosen over others?&lt;/li&gt;
&lt;li&gt;What changed compared to yesterday?&lt;/li&gt;
&lt;li&gt;Would a different retrieval strategy help?&lt;/li&gt;
&lt;li&gt;Can I replay this request?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is “no” — observability is missing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;RAG pipelines don’t usually fail loudly.&lt;/p&gt;

&lt;p&gt;They fail:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;quietly&lt;/li&gt;
&lt;li&gt;confidently&lt;/li&gt;
&lt;li&gt;at scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The future of AI systems isn’t just better models.&lt;/p&gt;

&lt;p&gt;It’s &lt;strong&gt;systems that can explain themselves&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And observability is how that starts.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you’ve debugged a RAG issue that turned out to be “invisible” at first, I’d love to hear what signal finally revealed it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>softwareengineering</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
